2009-07-31 18:57:03 +04:00
|
|
|
/*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
2009-08-14 07:12:43 +04:00
|
|
|
#include "mpi.h"
|
|
|
|
|
2009-07-31 18:57:03 +04:00
|
|
|
int main(int argc, char *argv[])
|
2015-06-24 06:59:57 +03:00
|
|
|
{
|
2009-07-31 18:57:03 +04:00
|
|
|
MPI_Status status; /* MPI status */
|
|
|
|
int mpierr; /* MPI function return code */
|
|
|
|
int rank; /* Process rank within MPI_COMM_WORLD */
|
2009-08-14 07:12:43 +04:00
|
|
|
int size;
|
|
|
|
int dest, src;
|
2009-07-31 18:57:03 +04:00
|
|
|
int tag0=41; /* MPI message tag */
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-08-14 07:12:43 +04:00
|
|
|
int inject;
|
|
|
|
int report;
|
|
|
|
int iterations;
|
2015-06-24 06:59:57 +03:00
|
|
|
int n_bytes;
|
2009-07-31 18:57:03 +04:00
|
|
|
unsigned char* send_buff;
|
|
|
|
unsigned char* recv_buff;
|
2009-08-14 07:12:43 +04:00
|
|
|
char* tmp;
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-07-31 18:57:03 +04:00
|
|
|
int i, j, count;
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-07-31 18:57:03 +04:00
|
|
|
float fraction, randval;
|
|
|
|
struct timeval tp;
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-08-14 07:12:43 +04:00
|
|
|
if (1 < argc) {
|
|
|
|
if (0 == strncmp(argv[1], "-h", 2) ||
|
|
|
|
0 == strncmp(argv[1], "--h", 3)) {
|
|
|
|
printf("Usage: mpirun --options-- ./sendrecv_blaster <options> where options are:\n"
|
|
|
|
"\tpattern=[self | pair | ring] where\n"
|
|
|
|
"\t\tself => sendrecv with self\n"
|
|
|
|
"\t\tpair => sendrecv with a complementary partner [0 <-> N-1, 1 <-> N-2...]\n"
|
|
|
|
"\t\tring [default] => sendrecv around a ring [0 recvs from N-1 and sends to 1]\n"
|
|
|
|
"\tsize=[value < 0 => max message size in kbytes, value > 0 => max message size in Mbytes (default=1MByte)]\n"
|
|
|
|
"\tinject=[value = #iterations before injecting MPI_Sendrecv to self (default: never)]\n"
|
|
|
|
"\treport=[value = #iterations/reporting point (default: 1000)\n"
|
2009-08-25 17:06:14 +04:00
|
|
|
"\titerations=[value = #iterations before stopping (default: 1000000)\n");
|
2009-08-14 07:12:43 +04:00
|
|
|
return 0;
|
|
|
|
}
|
2009-07-31 18:57:03 +04:00
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-07-31 18:57:03 +04:00
|
|
|
mpierr = MPI_Init(&argc, &argv);
|
|
|
|
if (mpierr != MPI_SUCCESS)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "MPI Error %d (MPI_Init)\n",mpierr);
|
|
|
|
fflush(stderr);
|
|
|
|
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2015-02-11 20:09:59 +03:00
|
|
|
MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-07-31 18:57:03 +04:00
|
|
|
mpierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
|
|
|
if (mpierr != MPI_SUCCESS || rank < 0)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "MPI Error %d (MPI_Comm_rank)\n",mpierr);
|
|
|
|
fflush(stderr);
|
|
|
|
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-08-14 07:12:43 +04:00
|
|
|
mpierr = MPI_Comm_size(MPI_COMM_WORLD, &size);
|
|
|
|
if (mpierr != MPI_SUCCESS || size < 0)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "MPI Error %d (MPI_Comm_size)\n",mpierr);
|
|
|
|
fflush(stderr);
|
|
|
|
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* setup defaults in lieu of args */
|
|
|
|
n_bytes = 1024*1024;
|
|
|
|
inject = -1;
|
|
|
|
report = 1000;
|
|
|
|
iterations = 1000000;
|
|
|
|
/* do a ring */
|
|
|
|
src = rank - 1;
|
|
|
|
if (src < 0) {
|
|
|
|
src = size - 1;
|
|
|
|
}
|
|
|
|
dest = rank + 1;
|
|
|
|
if (dest > size-1) {
|
|
|
|
dest = 0;
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-08-14 07:12:43 +04:00
|
|
|
for (i=1; i < argc; i++) {
|
|
|
|
fprintf(stderr, "got %s\n", argv[i]);
|
|
|
|
if (0 == strncmp(argv[i], "pattern", strlen("pattern"))) {
|
|
|
|
tmp = strchr(argv[i], '=');
|
|
|
|
tmp++;
|
|
|
|
if (0 == strcmp(tmp, "self")) {
|
|
|
|
/* just do it with myself */
|
|
|
|
src = rank;
|
|
|
|
dest = rank;
|
|
|
|
} else if (0 == strcmp(tmp, "pair")) {
|
|
|
|
/* do it pair-wise */
|
|
|
|
src = (size-1) - rank;
|
|
|
|
dest = src;
|
|
|
|
} else {
|
|
|
|
/* do a ring */
|
|
|
|
src = rank - 1;
|
|
|
|
if (src < 0) {
|
|
|
|
src = size - 1;
|
|
|
|
}
|
|
|
|
dest = rank + 1;
|
|
|
|
if (dest > size-1) {
|
|
|
|
dest = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (0 == strncmp(argv[i], "size", strlen("size"))) {
|
|
|
|
tmp = strchr(argv[i], '=');
|
|
|
|
tmp++;
|
|
|
|
n_bytes = atoi(tmp);
|
|
|
|
if (n_bytes < 0) {
|
|
|
|
n_bytes = -1 * n_bytes * 1024;
|
|
|
|
} else {
|
|
|
|
n_bytes = n_bytes * 1024*1024;
|
|
|
|
}
|
|
|
|
} else if (0 == strncmp(argv[i], "inject", strlen("inject"))) {
|
|
|
|
tmp = strchr(argv[i], '=');
|
|
|
|
tmp++;
|
|
|
|
inject = atoi(tmp);
|
|
|
|
} else if (0 == strncmp(argv[i], "report", strlen("report"))) {
|
|
|
|
tmp = strchr(argv[i], '=');
|
|
|
|
tmp++;
|
|
|
|
report = atoi(tmp);
|
|
|
|
} else if (0 == strncmp(argv[i], "iter", strlen("iter"))) {
|
|
|
|
tmp = strchr(argv[i], '=');
|
|
|
|
tmp++;
|
|
|
|
iterations = atoi(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
send_buff = (unsigned char *) valloc(n_bytes);
|
|
|
|
recv_buff = (unsigned char *) valloc(n_bytes);
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-08-14 07:12:43 +04:00
|
|
|
/* seed the random number generator */
|
|
|
|
gettimeofday (&tp, NULL);
|
|
|
|
srand (tp.tv_usec);
|
|
|
|
|
|
|
|
for ( i=0; i<n_bytes; i++ )
|
|
|
|
{
|
|
|
|
send_buff[i] = i%128;
|
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-08-14 07:12:43 +04:00
|
|
|
fprintf(stderr, "Rank %d: recving from src %d sending to dest %d with max buff size %dKbytes\n",
|
|
|
|
rank, src, dest, n_bytes/1024);
|
|
|
|
|
2009-07-31 18:57:03 +04:00
|
|
|
i=0;
|
2009-08-14 07:12:43 +04:00
|
|
|
while (i < iterations)
|
2009-07-31 18:57:03 +04:00
|
|
|
{
|
|
|
|
randval = rand();
|
|
|
|
fraction = randval/RAND_MAX;
|
|
|
|
count = fraction * n_bytes;
|
2009-08-14 07:12:43 +04:00
|
|
|
mpierr = MPI_Sendrecv(send_buff, count, MPI_CHAR, dest, tag0,
|
|
|
|
recv_buff, n_bytes, MPI_CHAR, src, tag0, MPI_COMM_WORLD, &status);
|
2009-07-31 18:57:03 +04:00
|
|
|
if (mpierr != MPI_SUCCESS)
|
|
|
|
{
|
2009-08-14 07:12:43 +04:00
|
|
|
fprintf(stderr,"MPI Error %d (MPI_Sendrecv) [%d,%d] at iteration %d\n",mpierr,src,dest,i);
|
2009-07-31 18:57:03 +04:00
|
|
|
fflush(stderr);
|
|
|
|
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
|
|
}
|
|
|
|
i++;
|
2009-08-14 07:12:43 +04:00
|
|
|
if (0 == (i % report)) {
|
2009-08-14 07:33:59 +04:00
|
|
|
fprintf(stderr, "Rank %d has completed %dk iterations\n", rank, i/1000);
|
2009-08-14 07:12:43 +04:00
|
|
|
}
|
|
|
|
if (0 < inject && 0 == (i % inject)) {
|
|
|
|
mpierr = MPI_Sendrecv(send_buff, count, MPI_CHAR, rank, tag0,
|
|
|
|
recv_buff, n_bytes, MPI_CHAR, rank, tag0, MPI_COMM_WORLD, &status);
|
|
|
|
if (mpierr != MPI_SUCCESS)
|
|
|
|
{
|
|
|
|
fprintf(stderr,"MPI Error %d (MPI_Sendrecv) [%d,%d] at iteration %d\n",mpierr,rank,rank,i);
|
|
|
|
fflush(stderr);
|
|
|
|
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "Rank %d has completed MPI_Sendrecv with myself\n", rank);
|
|
|
|
}
|
|
|
|
}
|
2009-07-31 18:57:03 +04:00
|
|
|
}
|
2015-06-24 06:59:57 +03:00
|
|
|
|
2009-07-31 18:57:03 +04:00
|
|
|
fprintf(stderr, "Rank %d completed test\n", rank);
|
|
|
|
MPI_Finalize();
|
|
|
|
}
|