Skip to content

Instantly share code, notes, and snippets.

@darkf
Created August 31, 2012 01:50
Show Gist options
  • Select an option

  • Save darkf/3547645 to your computer and use it in GitHub Desktop.

Select an option

Save darkf/3547645 to your computer and use it in GitHub Desktop.
Parallel (N-process) factorial in Erlang
-module(prog).
-export([main/0, take/2, drop/2, par/2, splitAt/2, product/1, manager/3, worker/3, fact/2]).
take(0, _) -> [];
take(_, []) -> [];
take(N, Lst) ->
[hd(Lst) | take(N-1, tl(Lst))].
drop(0, Lst) -> Lst;
drop(_, []) -> [];
drop(N, Lst) ->
drop(N-1, tl(Lst)).
splitAt(N, Lst) ->
{take(N, Lst), drop(N, Lst)}.
mypar(_, _, []) -> [];
mypar(S, N, Lst) ->
[take(S, Lst) | mypar(S, N, drop(S, Lst))].
par(Lst, N) ->
S = (length(Lst) div N) + 1,
mypar(S, N, Lst).
product(Lst) -> lists:foldl(fun(L, R) -> L*R end, 1, Lst).
worker(Lst, Id, Pid) ->
R = product(Lst),
Pid ! {finished, Id, R}.
manager(Queue, M, Reporter) ->
receive
{finished, Id, Result} ->
io:format("worker ~w finished with ~w~n", [Id, Result]),
if length(Queue) < M-1 -> manager([Result | Queue], M, Reporter); % Add to queue
true ->
R = product([Result | Queue]), % final computation
io:format("done. result: ~w~n", [R]),
Reporter ! {result, R}
end
end.
fact(N, M) ->
Lst = lists:seq(1, N),
Parts = par(Lst, M),
io:format("Spawning manager~n", []),
Man = spawn(?MODULE, manager, [[], M, self()]),
io:format("Spawning workers~n", []),
% spawn workers
lists:foreach(fun(Id) -> spawn(?MODULE, worker, [lists:nth(Id, Parts), Id, Man]) end, lists:seq(1, M)),
receive
{result, R} -> R;
_ -> error
end.
main() ->
R = fact(60, 4),
io:format("output: ~w~n", [R]).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment