|
Packit |
0848f5 |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* (C) 2008 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
* See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
* This (is a placeholder for a) test that creates 4 threads, each of which
|
|
Packit |
0848f5 |
* does a concurrent spawn of 4 more processes, for a total of 17 MPI processes
|
|
Packit |
0848f5 |
* The resulting intercomms are tested for consistency (to ensure that the
|
|
Packit |
0848f5 |
* spawns didn't get confused among the threads).
|
|
Packit |
0848f5 |
*
|
|
Packit |
0848f5 |
* As an option, it will time the Spawn calls. If the spawn calls block the
|
|
Packit |
0848f5 |
* calling thread, this may show up in the timing of the calls
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#include "mpi.h"
|
|
Packit |
0848f5 |
#include <stdio.h>
|
|
Packit |
0848f5 |
#include <stdlib.h>
|
|
Packit |
0848f5 |
#include "mpitest.h"
|
|
Packit |
0848f5 |
#include "mpithreadtest.h"
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
static char MTEST_Descrip[] = "Spawn jobs from multiple threads";
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define NTHREADS 4
|
|
Packit |
0848f5 |
#define NPERTHREAD 4
|
|
Packit |
0848f5 |
int activeThreads = 0;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm intercomms[NTHREADS];
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTEST_THREAD_RETURN_TYPE spawnProcess(void *p);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MTEST_THREAD_RETURN_TYPE spawnProcess(void *p)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int rank, i;
|
|
Packit |
0848f5 |
int errcodes[NPERTHREAD];
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* The thread number is passed into this routine through the value of the
|
|
Packit |
0848f5 |
* argument */
|
|
Packit |
0848f5 |
i = (int) (long) p;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Synchronize */
|
|
Packit |
0848f5 |
MTest_thread_barrier(NTHREADS);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Spawn */
|
|
Packit |
0848f5 |
MPI_Comm_spawn((char *) "./multispawn", MPI_ARGV_NULL, NPERTHREAD,
|
|
Packit |
0848f5 |
MPI_INFO_NULL, 0, MPI_COMM_SELF, &intercomms[i], errcodes);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Bcast(&i, 1, MPI_INT, MPI_ROOT, intercomms[i]);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return MTEST_THREAD_RETVAL_IGN;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int main(int argc, char *argv[])
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int rank, size, i, wasParent = 0;
|
|
Packit |
0848f5 |
int provided;
|
|
Packit |
0848f5 |
int err;
|
|
Packit |
0848f5 |
MPI_Comm parentcomm;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
|
|
Packit |
0848f5 |
MPI_Comm_size(MPI_COMM_WORLD, &size);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (provided != MPI_THREAD_MULTIPLE) {
|
|
Packit |
0848f5 |
if (rank == 0) {
|
|
Packit |
0848f5 |
printf
|
|
Packit |
0848f5 |
("MPI_Init_thread must return MPI_THREAD_MULTIPLE in order for this test to run.\n");
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
return -1;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_get_parent(&parentcomm);
|
|
Packit |
0848f5 |
if (parentcomm == MPI_COMM_NULL) {
|
|
Packit |
0848f5 |
wasParent = 1;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
err = MTest_thread_barrier_init();
|
|
Packit |
0848f5 |
if (err) {
|
|
Packit |
0848f5 |
printf("barrier_init failed\n");
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
return 1;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i = 0; i < NTHREADS - 1; i++) {
|
|
Packit |
0848f5 |
MTest_Start_thread(spawnProcess, (void *) (long) i);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* spawn the processes */
|
|
Packit |
0848f5 |
spawnProcess((void *) (NTHREADS - 1));
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Exit the threads (but the spawned processes remain) */
|
|
Packit |
0848f5 |
MTest_Join_threads();
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
err = MTest_thread_barrier_free();
|
|
Packit |
0848f5 |
if (err) {
|
|
Packit |
0848f5 |
printf("barrier_free failed\n");
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
return 1;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* The master thread (this thread) checks the created communicators */
|
|
Packit |
0848f5 |
for (i = 0; i < NTHREADS; i++) {
|
|
Packit |
0848f5 |
MPI_Bcast(&i, 1, MPI_INT, MPI_ROOT, intercomms[i]);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Free the created processes */
|
|
Packit |
0848f5 |
for (i = 0; i < NTHREADS; i++) {
|
|
Packit |
0848f5 |
MPI_Comm_disconnect(&intercomms[i]);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
int num, threadnum;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* I'm the created process */
|
|
Packit |
0848f5 |
MPI_Bcast(&threadnum, 1, MPI_INT, 0, parentcomm);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Form an intra comm with my parent */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* receive from my parent */
|
|
Packit |
0848f5 |
MPI_Bcast(&num, 1, MPI_INT, 0, parentcomm);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (num != threadnum) {
|
|
Packit |
0848f5 |
fprintf(stderr, "Unexpected thread num (%d != %d)\n", threadnum, num);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Let the parent free the intercomms */
|
|
Packit |
0848f5 |
MPI_Comm_disconnect(&parentcomm);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (wasParent)
|
|
Packit |
0848f5 |
MTest_Finalize(0);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
}
|