12 #include <sys/types.h> 26 #define MINIMINITEST (1) 28 const int MINNPROCS = (32+1);
32 int lanes0vector[4][20] = {
35 {2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, 0},
69 iindex(
int e,
int *vector,
int length)
71 for (
int i = 0; i < length; i++) {
85 minimini(
int TESTCASE,
int nprocs,
int rank)
87 int masterrank = (nprocs - 1);
90 assert(0 <= TESTCASE && TESTCASE <= 9);
94 MPI_Barrier(MPI_COMM_WORLD);
97 printf(
"MINI RUN (case %d)...\n", TESTCASE);
105 mr->swf_spawner_library = strdup(
"NONE.so");
107 mr->trace_map_spawn = 0;
109 char *lanesdesc0[] = {
113 char *lanesdesc1[] = {
117 char *lanesdesc2[] = {
121 char *lanesdesc3[] = {
125 char *lanesdesc4[] = {
130 char *lanesdesc5[] = {
137 char *lanesdesc6[] = {
141 char **lanesdesclist[10] = {
142 lanesdesc0, lanesdesc1, lanesdesc2, lanesdesc3, lanesdesc4,
143 lanesdesc5, lanesdesc6, lanesdesc0, lanesdesc0, lanesdesc0
146 char **lanesdesc = lanesdesclist[TESTCASE];
149 printf(
"Lane description of tests:\n");
159 MPI_Comm splitcomms[4];
161 assert(cc == MPI_SUCCESS);
163 mr->swf_debug_master = 1;
165 assert(cc == MPI_SUCCESS);
167 if (rank == masterrank) {
168 printf(
"Test runs using the following lanes:\n");
173 mr->trace_map_spawn = 0;
176 assert(cc == MPI_SUCCESS);
180 assert(rank == masterrank);
184 printf(
"Minimini 10 works. Check the trace log...\n");
192 for (
int i = 0; i < 10; i++) {
197 snprintf(kbuf,
sizeof(kbuf),
"0");
198 }
else if (TESTCASE == 1) {
200 snprintf(kbuf,
sizeof(kbuf),
"0");
202 snprintf(kbuf,
sizeof(kbuf),
"0.0");
204 }
else if (TESTCASE == 2) {
206 snprintf(kbuf,
sizeof(kbuf),
"0");
208 snprintf(kbuf,
sizeof(kbuf),
"0.0.0");
210 }
else if (TESTCASE == 3) {
212 snprintf(kbuf,
sizeof(kbuf),
"0");
214 snprintf(kbuf,
sizeof(kbuf),
"0.0.0.0");
216 }
else if (TESTCASE == 4) {
218 snprintf(kbuf,
sizeof(kbuf),
"0");
219 }
else if (i % 2 == 0) {
220 snprintf(kbuf,
sizeof(kbuf),
"0.0");
222 snprintf(kbuf,
sizeof(kbuf),
"0.1");
224 }
else if (TESTCASE == 5) {
225 snprintf(kbuf,
sizeof(kbuf),
"%d", (i % 4));
226 }
else if (TESTCASE == 6) {
227 snprintf(kbuf,
sizeof(kbuf),
"0");
229 snprintf(kbuf,
sizeof(kbuf),
"0");
235 snprintf(vbuf,
sizeof(vbuf),
236 (
"maxprocs=2 ./a.out work! index=%d lane=%s" 237 " blah blah blah"), i, kbuf);
238 }
else if (TESTCASE == 5) {
239 snprintf(vbuf,
sizeof(vbuf),
240 (
"maxprocs=1 ./a.out work! index=%d lane=%s" 241 " blah blah blah"), i, kbuf);
242 }
else if (TESTCASE == 6) {
243 snprintf(vbuf,
sizeof(vbuf),
244 (
"maxprocs=2 ./a.out work! index=%d lane=%s" 245 " blah blah blah"), i, kbuf);
247 snprintf(vbuf,
sizeof(vbuf),
248 (
"maxprocs=2 ./a.out work! index=%d lane=%s" 249 " blah blah blah"), i, kbuf);
253 .klen = (int)(strlen(kbuf) + 1),
254 .vlen = (
int)(strlen(vbuf) + 1),
263 mr->trace_map_spawn = 1;
264 mr->swf_record_history = 1;
273 printf(
"Minimini 10 works done.\n");
277 MPI_Barrier(MPI_COMM_SELF);
280 assert(cc == MPI_SUCCESS);
282 assert(cc == MPI_SUCCESS);
289 simple0(
int nprocs,
int rank)
291 int masterrank = (nprocs - 1);
296 MPI_Barrier(MPI_COMM_WORLD);
299 printf(
"CHECK WORKFLOW-MAPPER...\n");
300 printf(
"Run this test with 33 or more processes.\n");
304 if (nprocs < MINNPROCS) {
306 printf(
"THIS TEST NEEDS 32+1 OR MORE PROCESSES.\n");
316 mr->trace_map_spawn = 0;
318 MPI_Comm splitcomms[4];
322 assert(cc == MPI_SUCCESS);
325 assert(cc == MPI_SUCCESS);
330 mr->swf_debug_master = 1;
332 assert(cc == MPI_SUCCESS);
334 if (rank == masterrank) {
335 printf(
"Test runs using the following lanes:\n");
342 printf(
"[%05d] Detaching workers...\n", rank);
345 mr->trace_map_spawn = 0;
347 assert(cc == MPI_SUCCESS);
353 assert(rank == masterrank);
359 printf(
"Simple 100 works. Check the trace log...\n");
366 int n_lanes = (level0 * level1 * level2);
372 for (
int i = 0; i < 100; i++) {
373 int lane = (rand() % n_lanes);
374 int index1 = ((lane / level2) % level1);
375 int index0 = (lane / (level1 * level2));
376 snprintf(kbuf,
sizeof(kbuf),
377 "%d.%d.*", index0, index1);
378 snprintf(vbuf,
sizeof(vbuf),
379 (
"maxprocs=2 ./a.out work! index=%d lane=%s" 380 " blah blah blah"), i, kbuf);
382 .klen = (int)(strlen(kbuf) + 1),
383 .vlen = (
int)(strlen(vbuf) + 1),
392 mr->trace_map_spawn = 1;
393 mr->swf_record_history = 1;
408 printf(
"History (finish ordering of work-items):\n");
409 for (
int i = 0; i < count; i++) {
411 printf(
"%d", history[i]);
412 }
else if ((i % 15) == 0) {
414 printf(
"%d", history[i]);
416 printf(
",%d", history[i]);
423 printf(
"Simple 100 works done.\n");
431 printf(
"Simple 400 works...\n");
452 for (
int iteration = 0; iteration < ITERATION; iteration++) {
453 for (
int group = 0; group < 4; group++) {
457 for (
int i = 0; i < (SETSIZE - 1); i++) {
458 snprintf(kbuf,
sizeof(kbuf),
"%d.%d.*", a, b);
459 snprintf(vbuf,
sizeof(vbuf),
460 "maxprocs=2 ./a.out simple0 blah blah");
462 .klen = (int)(strlen(kbuf) + 1),
463 .vlen = (
int)(strlen(vbuf) + 1),
469 snprintf(kbuf,
sizeof(kbuf),
"%d.%d", a, b);
470 snprintf(vbuf,
sizeof(vbuf),
471 (
"maxprocs=8 ./a.out simple0" 472 " iteration=%d blah blah"),
475 .klen = (int)(strlen(kbuf) + 1),
476 .vlen = (
int)(strlen(vbuf) + 1),
486 mr->trace_map_spawn = 0;
487 mr->swf_record_history = 1;
496 int count = (4 * SETSIZE * 10);
502 printf(
"History (finish ordering of work-items):\n");
503 for (
int i = 0; i < count; i++) {
505 printf(
"%d", history[i]);
506 }
else if ((i % 15) == 0) {
508 printf(
"%d", history[i]);
510 printf(
",%d", history[i]);
520 printf(
"Checking ordering constraint...\n");
522 for (
int group = 0; group < 4; group++) {
523 for (
int i = 0; i < ITERATION; i++) {
524 int barrier = (4*SETSIZE*i+SETSIZE-1);
525 int pos0 = iindex(barrier, history, count);
527 for (
int i1 = 0; i1 < i; i1++) {
528 for (
int j = 0; j < (SETSIZE - 1); j++) {
529 int prea = (4*SETSIZE*i1+j);
530 int pos1 = iindex(prea, history, count);
535 for (
int i2 = (i + 1); i2 < ITERATION; i2++) {
536 for (
int j = 0; j < (SETSIZE - 1); j++) {
537 int post = (4*SETSIZE*i2+j);
538 int pos2 = iindex(post, history, count);
547 printf(
"Simple 400 works done.\n");
551 MPI_Barrier(MPI_COMM_SELF);
554 assert(cc == MPI_SUCCESS);
556 assert(cc == MPI_SUCCESS);
563 main(
int argc,
char *argv[])
565 #define digitp(X) ('0' <= (X) && (X) <= '9') 568 printf(
"AHOAHO argc=%d\n", argc); fflush(0);
569 printf(
"AHOAHO argv[0]=%s\n", argv[0]); fflush(0);
570 printf(
"AHOAHO argv[1]=%s\n", argv[1]); fflush(0);
571 printf(
"AHOAHO argv[1]=%s strcmp(argv[1], work!)=%d\n",
572 argv[1], (strcmp(argv[1],
"work!") == 0));
577 if (argc == 1 || (argc == 2 && argv[1][1] == 0 && digitp(argv[1][0]))) {
581 int testcase = ((argc == 2) ? (argv[1][0] -
'0') : 0);
582 assert(0 <= testcase && testcase <= 9);
584 int nprocs, rank, thlv;
585 MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &thlv);
586 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
587 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
596 kmr_error(0,
"Assertion disabled; recompile this test");
605 if (nprocs < MINNPROCS) {
606 fprintf(stderr,
"RUN THIS WITH 33 PROCS OR MORE.\n");
612 simple0(nprocs, rank);
614 minimini(testcase, nprocs, rank);
622 }
else if (argc >= 2 && strcmp(argv[1],
"work!") == 0) {
626 {printf(
"A work started\n"); fflush(0);}
629 MPI_Init_thread(&argc, &argv, MPI_THREAD_SERIALIZED, &thlv);
631 MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
632 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
634 {printf(
"A work with nprocs=%d rank=%d\n", nprocs, rank); fflush(0);}
640 fprintf(stderr,
"RUN WITH BAD ARGUMENTS.\n");
Key-Value Stream (abstract).
Utilities Private Part (do not include from applications).
int kmr_map_swf(KMR_KVS *kvi, KMR_KVS *kvo, void *arg, struct kmr_spawn_option opt, kmr_mapfn_t mapfn)
Maps with a simple workflow.
int kmr_add_kv(KMR_KVS *kvs, const struct kmr_kv_box kv)
Adds a key-value pair.
int kmr_init_swf(KMR *mr, MPI_Comm lanecomms[KMR_LANE_LEVELS], int master)
Initializes the lanes of simple workflow.
#define kmr_create_kvs(MR, KF, VF)
Makes a new key-value stream (of type KMR_KVS) with the specified field datatypes.
void kmr_set_swf_verbosity(KMR *mr, int level)
Sets the verbosity of the spawn-library.
int kmr_add_kv_done(KMR_KVS *kvs)
Marks finished adding key-value pairs.
int kmr_free_kvs(KMR_KVS *kvs)
Releases a key-value stream (type KMR_KVS).
int kmr_split_swf_lanes_a(KMR *mr, MPI_Comm splitcomms[KMR_LANE_LEVELS], int root, int *description[], _Bool dump)
Splits a communicator in a KMR context to ones to be used for kmr_init_swf().
Handy Copy of a Key-Value Field.
Options to Mapping by Spawns.
int kmr_stop_swf_workers(KMR *mr)
Finishes the workers of workflow.
int kmr_fin(void)
Clears the environment.
void kmr_dump_swf_history(KMR *mr)
Prints the history of kmr_map_swf(), which is the start ordering the work-items.
#define kmr_init()
Sets up the environment.
int kmr_detach_swf_workers(KMR *mr)
Disengages the workers from main processing and puts them in the service loop for spawning...
int kmr_split_swf_lanes(KMR *mr, MPI_Comm splitcomms[KMR_LANE_LEVELS], int root, char *description[], _Bool dump)
Splits a communicator in a KMR context to ones to be used for kmr_init_swf().
void kmr_dump_swf_lanes(KMR *mr)
Dumps lanes created by kmr_init_swf().
int kmr_free_context(KMR *mr)
Releases a context created with kmr_create_context().
void kmr_dump_swf_order_history(KMR *mr, int *history, size_t length)
Returns a list of start ordering of the work-items.
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).