| /*****************************************************************************/ |
| /* "NetPIPE" -- Network Protocol Independent Performance Evaluator. */ |
| /* Copyright 1997, 1998 Iowa State University Research Foundation, Inc. */ |
| /* */ |
| /* This program is free software; you can redistribute it and/or modify */ |
| /* it under the terms of the GNU General Public License as published by */ |
| /* the Free Software Foundation. You should have received a copy of the */ |
| /* GNU General Public License along with this program; if not, write to the */ |
| /* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
| /* */ |
| /* * MPI.c ---- MPI calls source */ |
| /*****************************************************************************/ |
| #include "netpipe.h" |
| #include <mpi.h> |
| |
| #ifdef BSEND |
| char *messbuff; |
| #define MAXBUFSIZE (10*1024*1024) |
| #endif |
| |
| |
| int Setup(ArgStruct *p) |
| { |
| int nproc; |
| |
| MPI_Comm_rank(MPI_COMM_WORLD, &p->prot.iproc); |
| MPI_Comm_size(MPI_COMM_WORLD, &nproc); |
| { |
| char s[255]; |
| gethostname(s,253); |
| printf("%d: %s\n",p->prot.iproc,s); |
| fflush(stdout); |
| } |
| p->prot.nbor = !p->prot.iproc; |
| |
| if (nproc != 2) |
| { |
| printf("Need two processes\n"); |
| exit(-2); |
| } |
| |
| if (p->prot.iproc == 0) |
| p->tr = 1; |
| else |
| p->tr = 0; |
| |
| #ifdef BSEND |
| messbuff = (char *)malloc(MAXBUFSIZE * sizeof(char)); |
| if (messbuff == NULL) |
| { |
| printf("Can't allocate for message buffer\n"); |
| exit(-1); |
| } |
| MPI_Buffer_attach(messbuff, MAXBUFSIZE); |
| #endif |
| |
| } |
| |
| void Sync(ArgStruct *p) |
| { |
| MPI_Barrier(MPI_COMM_WORLD); |
| } |
| |
| static int recvPosted = 0; |
| static MPI_Request recvRequest; |
| |
| void PrepareToReceive(ArgStruct *p) |
| { |
| /* |
| Providing a buffer for reception of data in advance of |
| the sender sending the data provides a major performance |
| boost on some implementations of MPI, particularly shared |
| memory implementations on the Cray T3E and Intel Paragon. |
| */ |
| if (recvPosted) |
| { |
| printf("Can't prepare to receive: outstanding receive!\n"); |
| exit(-1); |
| } |
| MPI_Irecv(p->buff, p->bufflen, MPI_BYTE, |
| p->prot.nbor, 1, MPI_COMM_WORLD, &recvRequest); |
| recvPosted = -1; |
| } |
| |
| void SendData(ArgStruct *p) |
| { |
| #ifdef BSEND |
| MPI_Bsend(p->buff, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD); |
| #else |
| MPI_Send(p->buff, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD); |
| #endif |
| } |
| |
| void RecvData(ArgStruct *p) |
| { |
| MPI_Status status; |
| if (recvPosted) |
| { |
| MPI_Wait(&recvRequest, &status); |
| recvPosted = 0; |
| } |
| else |
| { |
| MPI_Recv(p->buff, p->bufflen, MPI_BYTE, |
| p->prot.nbor, 1, MPI_COMM_WORLD, &status); |
| } |
| } |
| |
| |
| void SendTime(ArgStruct *p, double *t) |
| { |
| #ifdef BSEND |
| MPI_Bsend(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD); |
| #else |
| MPI_Send(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD); |
| #endif |
| } |
| |
| void RecvTime(ArgStruct *p, double *t) |
| { |
| MPI_Status status; |
| |
| MPI_Recv(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD, &status); |
| } |
| |
| |
| void SendRepeat(ArgStruct *p, int rpt) |
| { |
| #ifdef BSEND |
| MPI_Bsend(&rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD); |
| #else |
| MPI_Send(&rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD); |
| #endif |
| } |
| |
| void RecvRepeat(ArgStruct *p, int *rpt) |
| { |
| MPI_Status status; |
| |
| MPI_Recv(rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD, &status); |
| } |
| |
| |
| int Establish(ArgStruct *p) |
| { |
| } |
| |
| int CleanUp(ArgStruct *p) |
| { |
| MPI_Finalize(); |
| } |
| |