13 #include <sys/types.h> 24 _Bool skipmpiwork = 0;
32 printf(
"test5:empty-map-fn[%d]: called.\n", (
int)ii);
42 KMR *mr = kmr_get_context_of_kvs(kvi);
47 if (
sizeof(
int) !=
sizeof(
void *) &&
sizeof(ic) ==
sizeof(
void *)) {
48 printf(
"test5:empty-map-fn[%d]: sleeping 12 sec (icomm=%p)...\n",
51 printf(
"test5:empty-map-fn[%d]: sleeping 12 sec (icomm=%d)...\n",
63 KMR *mr = kmr_get_context_of_kvs(kvi);
68 if (
sizeof(
int) !=
sizeof(
void *) &&
sizeof(ic) ==
sizeof(
void *)) {
69 printf(
"test5:empty-map-fn[%d]: called (icomm=%p).\n",
72 printf(
"test5:empty-map-fn[%d]: called (icomm=%d).\n",
80 simple0(
int nprocs,
int rank)
83 mr->trace_map_spawn = 1;
84 mr->spawn_max_processes = 4;
86 MPI_Barrier(MPI_COMM_WORLD);
90 MPI_Barrier(MPI_COMM_WORLD);
94 printf(
"** CHECK kmr_map_via_spawn WITH RETURNING KVS.\n");
95 printf(
"** Spawn 2-rank work 4 times" 96 " using %d dynamic processes.\n",
97 mr->spawn_max_processes);
106 snprintf(kbuf,
sizeof(kbuf),
"key");
107 snprintf(vbuf,
sizeof(vbuf),
108 "maxprocs=2 %s ./a.out mpi returnkvs a0 a1 a2",
109 "info0=value0 info1=value1 info2=value2");
111 .klen = (int)(strlen(kbuf) + 1),
112 .vlen = (
int)(strlen(vbuf) + 1),
115 for (
int i = 0; i < 4; i++) {
122 .separator_space = 1};
127 assert(kvs01->c.element_count == 32);
129 assert(kvs01->c.element_count == 0);
138 simple1(
int nprocs,
int rank)
141 mr->trace_map_spawn = 1;
142 mr->spawn_max_processes = 4;
144 MPI_Barrier(MPI_COMM_WORLD);
148 MPI_Barrier(MPI_COMM_WORLD);
152 printf(
"** CHECK kmr_map_via_spawn WITH WAITING IN MAP-FN.\n");
153 printf(
"** Spawn 2-rank work 4 times" 154 " using %d dynamic processes.\n",
155 mr->spawn_max_processes);
164 snprintf(kbuf,
sizeof(kbuf),
"key");
165 snprintf(vbuf,
sizeof(vbuf),
166 "maxprocs=2 ./a.out mpi noreply a0 a1 a2");
168 .klen = (int)(strlen(kbuf) + 1),
169 .vlen = (
int)(strlen(vbuf) + 1),
172 for (
int i = 0; i < 4; i++) {
180 MPI_INFO_NULL, opt, empty_map_fn_mpi_noreply);
185 MPI_Barrier(MPI_COMM_WORLD);
189 printf(
"** CHECK kmr_map_via_spawn WITH REPLY (EACH).\n");
190 printf(
"** Spawn 2-rank work 4 times" 191 " using %d dynamic processes.\n",
192 mr->spawn_max_processes);
201 snprintf(kbuf,
sizeof(kbuf),
"key");
202 snprintf(vbuf,
sizeof(vbuf),
203 "maxprocs=2 ./a.out mpi eachreply a0 a1 a2");
205 .klen = (int)(strlen(kbuf) + 1),
206 .vlen = (
int)(strlen(vbuf) + 1),
209 for (
int i = 0; i < 4; i++) {
216 .separator_space = 1};
218 MPI_INFO_NULL, opt, empty_map_fn_mpi_with_reply);
223 MPI_Barrier(MPI_COMM_WORLD);
227 printf(
"** CHECK kmr_map_via_spawn WITH REPLY (ROOT).\n");
228 printf(
"Spawn 2-rank work 4 times" 229 " using %d dynamic processes.\n",
230 mr->spawn_max_processes);
239 snprintf(kbuf,
sizeof(kbuf),
"key");
240 snprintf(vbuf,
sizeof(vbuf),
241 "maxprocs=2 ./a.out mpi rootreply a0 a1 a2");
243 .klen = (int)(strlen(kbuf) + 1),
244 .vlen = (
int)(strlen(vbuf) + 1),
247 for (
int i = 0; i < 4; i++) {
254 .separator_space = 1};
256 MPI_INFO_NULL, opt, empty_map_fn_mpi_with_reply);
264 simple2(
int nprocs,
int rank)
267 mr->trace_map_spawn = 1;
268 mr->spawn_max_processes = 4;
270 MPI_Barrier(MPI_COMM_WORLD);
274 MPI_Barrier(MPI_COMM_WORLD);
278 printf(
"** CHECK kmr_map_processes (SERIAL)...\n");
279 printf(
"** Spawn 2 serial processes 4 times.\n");
288 snprintf(kbuf,
sizeof(kbuf),
"key");
289 snprintf(vbuf,
sizeof(vbuf),
290 "maxprocs=2 ./a.out seq noreply a0 a1 a2");
292 .klen = (int)(strlen(kbuf) + 1),
293 .vlen = (
int)(strlen(vbuf) + 1),
296 for (
int i = 0; i < 8; i++) {
309 MPI_Barrier(MPI_COMM_WORLD);
313 printf(
"** CHECK kmr_map_processes (MPI)...\n");
314 printf(
"** Spawn 2-rank work 4 times" 315 " using %d dynamic processes.\n",
316 mr->spawn_max_processes);
317 printf(
"** THIS TEST MAY BLOCK INDEFINITELY" 318 " ON SOME IMPLEMENTATIONS OF MPI.\n");
319 printf(
"** THEN, RUN THIS TEST WITH a.out 0" 320 " TO SKIP THIS PART.\n");
329 snprintf(kbuf,
sizeof(kbuf),
"key");
330 snprintf(vbuf,
sizeof(vbuf),
331 "maxprocs=2 ./a.out mpi noreply a0 a1 a2");
333 .klen = (int)(strlen(kbuf) + 1),
334 .vlen = (
int)(strlen(vbuf) + 1),
337 for (
int i = 0; i < 4; i++) {
353 spawned(
int argc,
char *argv[])
357 assert(strcmp(argv[1],
"seq") == 0 || strcmp(argv[1],
"mpi") == 0);
358 if (strcmp(argv[1],
"seq") == 0) {
359 printf(
"test5:spawned(serial): started (%s,%s,%s).\n",
360 argv[0], argv[1], argv[3]);
361 printf(
"test5:spawned(serial): sleeping 3 sec...\n");
364 printf(
"test5:spawned(serial): exits.\n");
366 }
else if (strcmp(argv[1],
"mpi") == 0) {
367 int nprocs, rank, lev;
368 MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &lev);
369 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
370 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
373 MPI_Comm_get_parent(&parent);
374 assert(parent != MPI_COMM_NULL);
377 MPI_Comm_remote_size(parent, &peer_nprocs);
378 assert(peer_nprocs == 1);
379 printf(
"test5:spawned(mpi;rank=%d/%d): started (%s,%s,%s).\n",
380 rank, nprocs, argv[0], argv[1], argv[2]);
381 printf(
"test5:spawned(mpi;rank=%d/%d): sleeping 3 sec...\n",
386 assert((strcmp(argv[2],
"noreply") == 0)
387 || (strcmp(argv[2],
"eachreply") == 0)
388 || (strcmp(argv[2],
"rootreply") == 0)
389 || (strcmp(argv[2],
"returnkvs") == 0));
390 if (strcmp(argv[2],
"noreply") == 0) {
392 printf(
"test5:spawned(mpi;rank=%d/%d):" 395 }
else if (strcmp(argv[2],
"eachreply") == 0) {
397 printf(
"test5:spawned(mpi;rank=%d/%d):" 398 " sending a reply.\n",
401 MPI_Send(0, 0, MPI_BYTE, peer,
402 KMR_TAG_SPAWN_REPLY, parent);
403 }
else if (strcmp(argv[2],
"rootreply") == 0) {
406 printf(
"test5:spawned(mpi;rank=%d/%d):" 407 " sending a root reply.\n",
410 MPI_Send(0, 0, MPI_BYTE, peer,
411 KMR_TAG_SPAWN_REPLY, parent);
413 }
else if (strcmp(argv[2],
"returnkvs") == 0) {
414 printf(
"test5:spawned(mpi;rank=%d/%d):" 417 KMR *mr = kmr_create_dummy_context();
420 for (
int i = 0; i < 4; i++) {
423 snprintf(k,
sizeof(k),
"k%d", i);
424 snprintf(v,
sizeof(v),
"v%d", i);
434 printf(
"test5:spawned(mpi;rank=%d/%d):" 435 " call MPI_Comm_free (could block)...\n",
438 MPI_Comm_free(&parent);
439 printf(
"test5:spawned(mpi;rank=%d/%d):" 440 " MPI_Comm_free done.\n",
443 printf(
"test5:spawned(mpi;rank=%d/%d):" 444 " call MPI_Finalize...\n",
447 printf(
"test5:spawned(mpi;rank=%d/%d):" 448 " MPI_Finalize done; exits.\n",
457 main(
int argc,
char *argv[])
459 if (argc == 1 || argc == 2) {
462 int nprocs, rank, lev;
463 MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &lev);
464 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
465 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
469 skipmpiwork = (argc == 2 && argv[1][0] ==
'0');
472 printf(
"Check spawning mapper.\n");
473 printf(
"Running this test needs 4 or more" 474 " dynamic processes.\n");
478 simple0(nprocs, rank);
479 simple1(nprocs, rank);
480 simple2(nprocs, rank);
482 MPI_Barrier(MPI_COMM_WORLD);
484 if (rank == 0) {printf(
"OK\n");}
Key-Value Stream (abstract).
Utilities Private Part (do not include from applications).
int kmr_add_kv(KMR_KVS *kvs, const struct kmr_kv_box kv)
Adds a key-value pair.
#define kmr_create_kvs(MR, KF, VF)
Makes a new key-value stream (of type KMR_KVS) with the specified field datatypes.
MPI_Comm * kmr_get_spawner_communicator(KMR *mr, long index)
Obtains (a reference to) a parent inter-communicator of a spawned process.
int kmr_send_kvs_to_spawner(KMR *mr, KMR_KVS *kvs)
Sends the KVS from a spawned process to the map-function of the spawner.
int kmr_add_kv_done(KMR_KVS *kvs)
Marks finished adding key-value pairs.
int kmr_reply_to_spawner(KMR *mr)
Sends a reply message in the spawned process, which tells it is ready to finish and may have some dat...
int kmr_free_kvs(KMR_KVS *kvs)
Releases a key-value stream (type KMR_KVS).
Handy Copy of a Key-Value Field.
Options to Mapping by Spawns.
int kmr_fin(void)
Clears the environment.
#define kmr_init()
Sets up the environment.
int kmr_map_via_spawn(KMR_KVS *kvi, KMR_KVS *kvo, void *arg, MPI_Info info, struct kmr_spawn_option opt, kmr_mapfn_t mapfn)
Maps on processes started by MPI_Comm_spawn().
int kmr_free_context(KMR *mr)
Releases a context created with kmr_create_context().
int kmr_add_string(KMR_KVS *kvs, const char *k, const char *v)
Adds a key-value pair of strings.
int kmr_receive_kvs_from_spawned_fn(const struct kmr_kv_box kv, const KMR_KVS *kvi, KMR_KVS *kvo, void *arg, const long index)
Collects key-value pairs generated by spawned processes.
int kmr_map_processes(_Bool nonmpi, KMR_KVS *kvi, KMR_KVS *kvo, void *arg, MPI_Info info, struct kmr_spawn_option opt, kmr_mapfn_t mapfn)
Maps on processes started by MPI_Comm_spawn() to run independent processes.
KMR * kmr_create_context(const MPI_Comm comm, const MPI_Info conf, const char *name)
Makes a new KMR context (a context has type KMR).