The following is the test program, pthread_sendrecv.c, used in the previous experiment.
/*
(C) 2007 by Argonne National Laboratory.
See COPYRIGHT in top-level directory.
*/
#include "mpi.h"
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#define BUFLEN 512
#define NTIMES 100
#define MAX_THREADS 10
/*
Concurrent send and recv by multiple threads on each process.
*/
void *thd_sendrecv( void * );
void *thd_sendrecv( void *comm_ptr )
{
MPI_Comm comm;
int my_rank, num_procs, next, buffer_size, namelen, idx;
char buffer[BUFLEN], processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Status status;
comm = *(MPI_Comm *) comm_ptr;
MPI_Comm_size( comm, &num_procs );
MPI_Comm_rank( comm, &my_rank );
MPI_Get_processor_name( processor_name, &namelen );
fprintf( stderr, "Process %d on %s\n", my_rank, processor_name );
strcpy( buffer, "hello there" );
buffer_size = strlen(buffer)+1;
if ( my_rank == num_procs-1 )
next = 0;
else
next = my_rank+1;
for ( idx = 0; idx < NTIMES; idx++ ) {
if (my_rank == 0) {
MPI_Send(buffer, buffer_size, MPI_CHAR, next, 99, comm);
MPI_Send(buffer, buffer_size, MPI_CHAR, MPI_PROC_NULL, 299, comm);
MPI_Recv(buffer, BUFLEN, MPI_CHAR, MPI_ANY_SOURCE, 99,
comm, &status);
}
else {
MPI_Recv(buffer, BUFLEN, MPI_CHAR, MPI_ANY_SOURCE, 99,
comm, &status);
MPI_Recv(buffer, BUFLEN, MPI_CHAR, MPI_PROC_NULL, 299,
comm, &status);
MPI_Send(buffer, buffer_size, MPI_CHAR, next, 99, comm);
}
/* MPI_Barrier(comm); */
}
pthread_exit( NULL );
return 0;
}
int main( int argc,char *argv[] )
{
MPI_Comm comm[ MAX_THREADS ];
pthread_t thd_id[ MAX_THREADS ];
int my_rank, ii, provided;
int num_threads;
MPI_Init_thread( &argc, &argv, MPI_THREAD_MULTIPLE, &provided );
if ( provided != MPI_THREAD_MULTIPLE ) {
printf( "Aborting, MPI_THREAD_MULTIPLE is needed...\n" );
MPI_Abort( MPI_COMM_WORLD, 1 );
}
MPI_Comm_rank( MPI_COMM_WORLD, &my_rank );
if ( my_rank == 0 ) {
if (argc != 2) {
printf( "Error: %s num_threads\n", argv[0] );
MPI_Abort( MPI_COMM_WORLD, 1 );
}
num_threads = atoi( argv[1] );
MPI_Bcast( &num_threads, 1, MPI_INT, 0, MPI_COMM_WORLD );
}
else
MPI_Bcast( &num_threads, 1, MPI_INT, 0, MPI_COMM_WORLD );
MPI_Barrier( MPI_COMM_WORLD );
for ( ii=0; ii < num_threads; ii++ ) {
MPI_Comm_dup( MPI_COMM_WORLD, &comm[ii] );
pthread_create( &thd_id[ii], NULL, thd_sendrecv, (void *) &comm[ii] );
}
for ( ii=0; ii < num_threads; ii++ )
pthread_join( thd_id[ii], NULL );
MPI_Finalize();
return 0;
}