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
|
|
|
|
|