OcamlP3l на эрланге

Jun 23, 2007 11:48

Если JoCaml кажется просто забавным трюком, то в OcamlP3l уже видится что-то более серьезное.
Это попытка ввести шаблоны параллелизма, а фактически - функции высшего порядка(map,foldl,...) для независимых процессов, скрывая при этом особенности межпроцессного взаимодействия.
Ниже приведена наивная реализация шаблонов(skeleton) OcamlP3l на эрланге. В OcamlP3l есть еще такой интересный параметр - уровень(degree) параллелизма - число параллельных процессов в вычислении, соответственно при уровне==1 вычисление превращается в последовательное. У меня этого, конечно, нет.
Пример работы шаблона "ферма" на OcamlP3l

let farm_worker _ = fun x -> x * x;;
let print_result x = print_int x; print_newline();;
let compute = parfun (fun () -> (farm (seq(farm_worker),4)));;
pardo(fun () ->
let is = P3lstream.of_list [1;2;3;4;5;6;7;8] in
let s' = compute is in P3lstream.iter print_result s';
);;
И на эрланге:

farm(fun(X) -> X*X end, lists:seq(1,10)).

В коде еще используется модуль utils: foreach,map с векторами, y-комбинатор и сбор заданного числа ответов в список/вектор.


-module(ep3l).
-import(lists, [map/2,foreach/2, foldl/3]).
-import(erlang, [make_tuple/2]).

-compile(export_all).

testReduce() ->
reduce(fun(X,Y) -> X + Y end, [1,2,3,4]).

reduceworker(Seq,A,B,To) ->
R = Seq(A,B),
To ! {from, self(), R}.

reduce(Seq, X) ->
Self = self(),
foldl(fun(A,B) ->
spawn(?MODULE, reduceworker, [Seq,A,B,Self]),
receive {from, _From, Res} ->
Res
end
end,
hd(X),
tl(X)).

testMapvector() ->
mapvector(fun(X) -> X*X end,
{1,2,3,4,5}).

mapworker(Seq,{Pos,Arg},To) ->
Msg = Seq(Arg),
To ! {from, self(), {Pos,Msg}}.

mapvector(Seq, X) ->
Self = self(),
Num = utils:foreach(fun(I,A) ->
spawn(?MODULE, mapworker, [Seq,{I,A},Self])
end,
X),
utils:collect(Num,make_tuple(Num,0)).

testLoop() ->
loop(fun(X) -> (X rem 5 =/= 0) end,
fun(X) -> X+1 end,
[3,7,10,14]).

body(Cond, Seq, Arg, To) ->
R = Seq(Arg),
C = Cond(R),
if C ->
body(Cond, Seq, R, To); true ->
To ! {from, self(), R}
end.

loop(Cond, Seq, X) ->
Self = self(),
Num = foldl(fun(A,I) ->
spawn(?MODULE, body, [Cond,Seq,A,Self]),
I+1
end,
0,
X),
utils:collect(Num,[]).

testPipeline() ->
pipeline([fun(X) -> X*X end,
fun(X) -> X*2 end,
fun(X) -> X+1 end],
3).

pipe(Seq, X, Master) ->
Res = Seq(X),
Master ! {from, self(), Res}.

pipeline(Seqs,X) ->
Self = self(),
foldl(fun(A,Res) ->
Pid = spawn(?MODULE, pipe, [A,Res,Self]),
receive
{from, Pid, NewRes} ->
NewRes
end
end,
X,
Seqs).

testFarm() ->
farm(fun(X) -> X-1 end, lists:seq(1,10)).

worker(Seq,Arg,To) ->
Msg = Seq(Arg),
To ! {from, self(), Msg}.

farm(Worker, List) ->
Self = self(),
Num = foldl(fun(A,I) ->
spawn(?MODULE, worker, [Worker,A,Self]),
I+1
end,
0,
List),
utils:collect(Num,[]).

ocaml, erlang, ||

Previous post Next post
Up