31 #define MSG_CTRL_RAW (MSG_CTRL_TERMINATION + 1)
33 #ifdef ROOTSIM_MPI_SERIALIZABLE
35 static bool mpi_serialize;
38 #define mpi_lock() if (mpi_serialize) spin_lock(&mpi_spinlock)
39 #define mpi_unlock() if (mpi_serialize) spin_unlock(&mpi_spinlock)
40 #define mpi_trylock() (!mpi_serialize || spin_trylock(&mpi_spinlock))
46 #define mpi_trylock() (true)
65 char err_str[MPI_MAX_ERROR_STRING];
66 MPI_Error_string(*err_code_p, err_str, &err_len);
79 int thread_lvl = MPI_THREAD_SINGLE;
80 MPI_Init_thread(argc_p, argv_p, MPI_THREAD_MULTIPLE, &thread_lvl);
82 if (thread_lvl < MPI_THREAD_MULTIPLE) {
83 if (thread_lvl < MPI_THREAD_SERIALIZED) {
85 "This MPI implementation does not support threaded access");
88 #ifdef ROOTSIM_MPI_SERIALIZABLE
93 "This MPI implementation only supports serialized calls: you need to build ROOT-Sim with -Dserialized_mpi=true");
99 MPI_Errhandler err_handler;
105 MPI_Comm_set_errhandler(MPI_COMM_WORLD, err_handler);
108 MPI_Comm_rank(MPI_COMM_WORLD, &helper);
110 MPI_Comm_size(MPI_COMM_WORLD, &helper);
119 MPI_Errhandler err_handler;
120 MPI_Comm_get_errhandler(MPI_COMM_WORLD, &err_handler);
121 MPI_Errhandler_free(&err_handler);
140 msg->
msg_id = msg_id_get(msg, gvt_phase_get());
141 gvt_on_remote_msg_send(dest_nid);
145 MPI_Isend(msg, msg_bare_size(msg), MPI_BYTE, dest_nid, 0,
146 MPI_COMM_WORLD, &req);
147 MPI_Request_free(&req);
165 msg_id_anti_phase_set(msg->
msg_id, gvt_phase_get());
166 gvt_on_remote_msg_send(dest_nid);
170 MPI_Isend(&msg->
msg_id,
sizeof(msg->
msg_id), MPI_BYTE, dest_nid, 0,
171 MPI_COMM_WORLD, &req);
172 MPI_Request_free(&req);
188 MPI_Isend(NULL, 0, MPI_BYTE, i, ctrl, MPI_COMM_WORLD, &req);
189 MPI_Request_free(&req);
203 MPI_Isend(NULL, 0, MPI_BYTE,
dest, ctrl, MPI_COMM_WORLD, &req);
204 MPI_Request_free(&req);
228 MPI_Improbe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD,
229 &pending, &mpi_msg, &status);
237 MPI_Mrecv(NULL, 0, MPI_BYTE, &mpi_msg, MPI_STATUS_IGNORE);
239 switch(status.MPI_TAG){
247 termination_on_ctrl_msg();
252 MPI_Get_count(&status, MPI_BYTE, &size);
254 if (
unlikely(size ==
sizeof(uintptr_t))) {
256 MPI_Mrecv(&anti_id, size, MPI_BYTE, &mpi_msg,
260 remote_msg_map_match(anti_id,
261 status.MPI_SOURCE, NULL);
262 gvt_on_remote_msg_receive(
263 msg_id_anti_phase_get(anti_id));
267 struct lp_msg *msg = msg_allocator_alloc(size -
271 MPI_Mrecv(msg, size, MPI_BYTE, &mpi_msg,
276 atomic_store_explicit(&msg->
flags, 0U,
277 memory_order_relaxed);
278 remote_msg_map_match(
msg_id,
279 status.MPI_SOURCE, msg);
281 gvt_on_remote_msg_receive(
282 msg_id_phase_get(
msg_id));
288 static MPI_Request reduce_sum_scatter_req = MPI_REQUEST_NULL;
306 MPI_Ireduce_scatter_block(node_vals, result, 1, MPI_UNSIGNED, MPI_SUM,
307 MPI_COMM_WORLD, &reduce_sum_scatter_req);
319 MPI_Test(&reduce_sum_scatter_req, &flag, MPI_STATUS_IGNORE);
324 static MPI_Request reduce_min_req = MPI_REQUEST_NULL;
342 min_buff = *node_min_p;
344 MPI_Iallreduce(&min_buff, node_min_p, 1, MPI_DOUBLE, MPI_MIN,
345 MPI_COMM_WORLD, &reduce_min_req);
357 MPI_Test(&reduce_min_req, &flag, MPI_STATUS_IGNORE);
368 MPI_Barrier(MPI_COMM_WORLD);
384 MPI_Send(data, data_size, MPI_BYTE,
dest, MSG_CTRL_RAW, MPI_COMM_WORLD);
402 MPI_Mprobe(src, MSG_CTRL_RAW, MPI_COMM_WORLD, &mpi_msg, &status);
404 MPI_Get_count(&status, MPI_BYTE, &data_size);
406 MPI_Mrecv(ret, data_size, MPI_BYTE, &mpi_msg, MPI_STATUS_IGNORE);
407 if (data_size_p != NULL)
408 *data_size_p = data_size;