10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-11-19 12:32:21 +01:00
QCaml/Parallel/Farm.ml

101 lines
1.9 KiB
OCaml
Raw Normal View History

2018-10-22 13:12:43 +02:00
(* Single process function *)
2018-10-21 23:54:28 +02:00
let run_sequential f stream =
2018-10-22 13:12:43 +02:00
let rec next _ =
try
let task = Stream.next stream in
Some (f task)
with Stream.Failure -> None in
Stream.from next
2018-10-21 23:54:28 +02:00
2018-10-22 13:12:43 +02:00
(* Multi-process functions *)
2018-10-21 23:54:28 +02:00
2018-10-22 13:12:43 +02:00
(* Server side *)
2018-10-21 23:54:28 +02:00
let run_parallel_server stream =
let fetch_result () =
2018-10-22 13:12:43 +02:00
let result, rank, _tag =
2018-10-21 23:54:28 +02:00
Mpi.receive_status Mpi.any_source Mpi.any_tag Mpi.comm_world
in
result, rank
in
2018-10-22 13:39:02 +02:00
let send_task client_rank =
let task =
try Some (Stream.next stream)
with Stream.Failure -> None
2018-10-21 23:54:28 +02:00
in
2018-10-22 13:39:02 +02:00
Mpi.send task client_rank 0 Mpi.comm_world
2018-10-21 23:54:28 +02:00
in
2018-10-22 13:39:02 +02:00
let rec run result_list n_todo =
let n_todo =
match Stream.peek stream with
| None -> n_todo-1
| _ -> n_todo
in
match n_todo with
2018-10-21 23:54:28 +02:00
| 0 -> result_list
2018-10-22 13:39:02 +02:00
| _ ->
2018-10-21 23:54:28 +02:00
begin
let result, client = fetch_result () in
2018-10-22 13:12:43 +02:00
let new_result_list =
match result with
| None -> result_list
| Some result -> result :: result_list
in
2018-10-22 13:39:02 +02:00
send_task client;
run new_result_list n_todo
2018-10-21 23:54:28 +02:00
end
in
let result =
2018-10-22 13:39:02 +02:00
let n_todo = Mpi.comm_size Mpi.comm_world in
run [] n_todo
2018-10-21 23:54:28 +02:00
|> Stream.of_list
in
Mpi.barrier Mpi.comm_world;
result
(** Client side *)
let run_parallel_client f =
Mpi.send None 0 0 Mpi.comm_world;
let rec run () =
let task =
Mpi.receive 0 Mpi.any_tag Mpi.comm_world
in
match task with
2018-10-22 13:12:43 +02:00
| None -> Mpi.barrier Mpi.comm_world
2018-10-21 23:54:28 +02:00
| Some task ->
let result = f task in
begin
Mpi.send (Some result) 0 0 Mpi.comm_world;
run ()
end
in
run ();
Stream.of_list []
let run_parallel f stream =
match Mpi.comm_rank Mpi.comm_world with
| 0 -> run_parallel_server stream
| _ -> run_parallel_client f
2018-10-22 13:12:43 +02:00
let run f stream =
match Mpi.comm_size Mpi.comm_world with
| 1 -> run_sequential f stream
| _ -> run_parallel f stream