/***************************************************************************** * FILE: mpithreads.c * DESCRIPTION: * This program illustrates the simultaneous use of MPI and Pthreads. * It is essentially a simple combination of a code that implements a dot * product using threads, and a code that uses MPI for the same purpose. * All the internode MPI communication is done by the main thread on each * node - the other threads within that node need not even be aware that * internode communication is being performed. Use of the SPMD model for * MPI was chosen for convenience, with replication of the main data on * all nodes. A more memory efficient implementation would be advisable * for larger data sets. This is the simplest model for mixed MPI/Pthreads * programming. * Usage note: MAXTHRDS should equal the number of cpus on a node * SOURCE: Vijay Sonnad, IBM * LAST REVISED: 05/19/17 Blaise Barney ******************************************************************************/ #include "mpi.h" #include #include #include /* Define a global structure for vectors, global sum, etc. */ typedef struct { double *a; double *b; double sum; int veclen; int numthrds; } DOTDATA; /* Define globally accessible variables and a mutex. MAXTHREADS set to equal number of cores on a TOSS 3 machine */ #define MAXTHRDS 36 #define VECLEN 100 DOTDATA dotstr; pthread_t callThd[MAXTHRDS]; pthread_mutex_t mutexsum; /* The function dotprod has only minor changes from the code that used threads or MPI. */ void *dotprod(void *arg) { /* Define and use local variables for convenience */ int i, start, end, mythrd, len, numthrds, myid; double mysum, *x, *y; /* The number of threads and nodes defines the beginning and ending for the dot product; each thread does work on a vector of length VECLENGTH. */ mythrd = (int)arg; MPI_Comm_rank (MPI_COMM_WORLD, &myid); numthrds = dotstr.numthrds; len = dotstr.veclen; start = myid*numthrds*len + mythrd*len; end = start + len; x = dotstr.a; y = dotstr.b; /* Perform the dot product and assign result to the appropriate variable in the structure. */ mysum = 0; for (i=start; i