1 /*****************************************************************************/
2 /* "NetPIPE" -- Network Protocol Independent Performance Evaluator. */
3 /* Copyright 1997, 1998 Iowa State University Research Foundation, Inc. */
4 /* */
5 /* This program is free software; you can redistribute it and/or modify */
6 /* it under the terms of the GNU General Public License as published by */
7 /* the Free Software Foundation. You should have received a copy of the */
8 /* GNU General Public License along with this program; if not, write to the */
9 /* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
10 /* */
11 /* * MPI.c ---- MPI calls source */
12 /*****************************************************************************/
13 #include "netpipe.h"
14 #include <mpi.h>
15
16 #ifdef BSEND
17 char *messbuff;
18 #define MAXBUFSIZE (10*1024*1024)
19 #endif
20
Setup(ArgStruct * p)21 int Setup(ArgStruct * p)
22 {
23 int nproc;
24
25 MPI_Comm_rank(MPI_COMM_WORLD, &p->prot.iproc);
26 MPI_Comm_size(MPI_COMM_WORLD, &nproc);
27 {
28 char s[255];
29 gethostname(s, 253);
30 printf("%d: %s\n", p->prot.iproc, s);
31 fflush(stdout);
32 }
33 p->prot.nbor = !p->prot.iproc;
34
35 if (nproc != 2) {
36 printf("Need two processes\n");
37 exit(-2);
38 }
39
40 if (p->prot.iproc == 0)
41 p->tr = 1;
42 else
43 p->tr = 0;
44
45 #ifdef BSEND
46 messbuff = (char *)malloc(MAXBUFSIZE * sizeof(char));
47 if (messbuff == NULL) {
48 printf("Can't allocate for message buffer\n");
49 exit(-1);
50 }
51 MPI_Buffer_attach(messbuff, MAXBUFSIZE);
52 #endif
53
54 }
55
Sync(ArgStruct * p)56 void Sync(ArgStruct * p)
57 {
58 MPI_Barrier(MPI_COMM_WORLD);
59 }
60
61 static int recvPosted = 0;
62 static MPI_Request recvRequest;
63
PrepareToReceive(ArgStruct * p)64 void PrepareToReceive(ArgStruct * p)
65 {
66 /*
67 Providing a buffer for reception of data in advance of
68 the sender sending the data provides a major performance
69 boost on some implementations of MPI, particularly shared
70 memory implementations on the Cray T3E and Intel Paragon.
71 */
72 if (recvPosted) {
73 printf("Can't prepare to receive: outstanding receive!\n");
74 exit(-1);
75 }
76 MPI_Irecv(p->buff, p->bufflen, MPI_BYTE,
77 p->prot.nbor, 1, MPI_COMM_WORLD, &recvRequest);
78 recvPosted = -1;
79 }
80
SendData(ArgStruct * p)81 void SendData(ArgStruct * p)
82 {
83 #ifdef BSEND
84 MPI_Bsend(p->buff, p->bufflen, MPI_BYTE, p->prot.nbor, 1,
85 MPI_COMM_WORLD);
86 #else
87 MPI_Send(p->buff, p->bufflen, MPI_BYTE, p->prot.nbor, 1,
88 MPI_COMM_WORLD);
89 #endif
90 }
91
RecvData(ArgStruct * p)92 void RecvData(ArgStruct * p)
93 {
94 MPI_Status status;
95 if (recvPosted) {
96 MPI_Wait(&recvRequest, &status);
97 recvPosted = 0;
98 } else {
99 MPI_Recv(p->buff, p->bufflen, MPI_BYTE,
100 p->prot.nbor, 1, MPI_COMM_WORLD, &status);
101 }
102 }
103
SendTime(ArgStruct * p,double * t)104 void SendTime(ArgStruct * p, double *t)
105 {
106 #ifdef BSEND
107 MPI_Bsend(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD);
108 #else
109 MPI_Send(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD);
110 #endif
111 }
112
RecvTime(ArgStruct * p,double * t)113 void RecvTime(ArgStruct * p, double *t)
114 {
115 MPI_Status status;
116
117 MPI_Recv(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD, &status);
118 }
119
SendRepeat(ArgStruct * p,int rpt)120 void SendRepeat(ArgStruct * p, int rpt)
121 {
122 #ifdef BSEND
123 MPI_Bsend(&rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD);
124 #else
125 MPI_Send(&rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD);
126 #endif
127 }
128
RecvRepeat(ArgStruct * p,int * rpt)129 void RecvRepeat(ArgStruct * p, int *rpt)
130 {
131 MPI_Status status;
132
133 MPI_Recv(rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD, &status);
134 }
135
Establish(ArgStruct * p)136 int Establish(ArgStruct * p)
137 {
138 }
139
CleanUp(ArgStruct * p)140 int CleanUp(ArgStruct * p)
141 {
142 MPI_Finalize();
143 }
144