#include <stdio.h> #include <stdlib.h> #include "mpi.h" #define NUMBER_OF_TESTS 10 #define PAD 4096 #define CHAR 1 #define DOUBLE 2 #define INT 3 int main( argc, argv ) int argc; char **argv; { double *sbuf, *rbuf, *r_ptr, *s_ptr; int rank; int n; double t1, t2, tmin; int j, k, nloop; MPI_Status status; MPI_Datatype dtype; int dtype_size, dtype_kind; char *type_name; MPI_Init( &argc, &argv ); MPI_Comm_rank( MPI_COMM_WORLD, &rank ); /* Do 3 different datatypes */ for (dtype_kind = 1; dtype_kind <= 3; dtype_kind++) { switch (dtype_kind) { case CHAR: dtype = MPI_CHAR; type_name = "char"; break; case DOUBLE: dtype = MPI_DOUBLE; type_name = "double"; break; case INT: dtype = MPI_INT; type_name = "int"; break; } if (rank == 0) printf( "Kind %s\t\tn\ttime (sec)\tRate (MB/sec)\n", type_name ); MPI_Type_size( dtype, &dtype_size ); for (n=1; n<1100000; n*=2) { if (n == 0) nloop = 1000; else nloop = 1000/n; if (nloop < 1) nloop = 1; sbuf = s_ptr = (double *) malloc( n * dtype_size + PAD ); rbuf = r_ptr = (double *) malloc( n * dtype_size + PAD ); if (!sbuf || !rbuf) { fprintf( stderr, "Could not allocate send/recv buffers of size %d\n", n ); MPI_Abort( MPI_COMM_WORLD, 1 ); } /* Must keep the data aligned to type size, but no more */ sbuf += dtype_size * 3; rbuf += dtype_size * 10; tmin = 1000; for (k=0; k<NUMBER_OF_TESTS; k++) { if (rank == 0) { /* Make sure both processes are ready */ MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, 1, 14, MPI_BOTTOM, 0, MPI_INT, 1, 14, MPI_COMM_WORLD, &status ); t1 = MPI_Wtime(); for (j=0; j<nloop; j++) { MPI_Send( sbuf, n, dtype, 1, k, MPI_COMM_WORLD ); MPI_Recv( rbuf, n, dtype, 1, k, MPI_COMM_WORLD, &status ); } t2 = (MPI_Wtime() - t1) / nloop; if (t2 < tmin) tmin = t2; } else if (rank == 1) { /* Make sure both processes are ready */ MPI_Sendrecv( MPI_BOTTOM, 0, MPI_INT, 0, 14, MPI_BOTTOM, 0, MPI_INT, 0, 14, MPI_COMM_WORLD, &status ); for (j=0; j<nloop; j++) { MPI_Recv( sbuf, n, dtype, 0, k, MPI_COMM_WORLD, &status ); MPI_Send( rbuf, n, dtype, 0, k, MPI_COMM_WORLD ); } } } /* Convert to half the round-trip time */ tmin = tmin / 2.0; if (rank == 0) { double rate; if (tmin > 0) rate = n * dtype_size * 1.0e-6 /tmin; else rate = 0.0; printf( "Send/Recv\t\t%d\t%f\t%f\n", n, tmin, rate ); } free( s_ptr ); free( r_ptr ); } } MPI_Finalize( ); return 0; }