"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/mpi.c" between
NetPIPE_4.x.tar.gz and NetPIPE-3.7.2.tar.gz

About: NetPIPE - a Network Protocol Independent Performance Evaluator

mpi.c  (NetPIPE_4.x):mpi.c  (NetPIPE-3.7.2)
skipping to change at line 16 skipping to change at line 16
/* it under the terms of the GNU General Public License as published by */ /* 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 */ /* 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 */ /* GNU General Public License along with this program; if not, write to the */
/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */ /* */
/* * MPI.c ---- MPI calls source */ /* * MPI.c ---- MPI calls source */
/*****************************************************************************/ /*****************************************************************************/
#include "netpipe.h" #include "netpipe.h"
#include <mpi.h> #include <mpi.h>
#ifdef BSEND
char *messbuff;
#define MAXBUFSIZE (10*1024*1024)
#endif
/* Initialize vars in Init() that may be changed by parsing the command args */ /* Initialize vars in Init() that may be changed by parsing the command args */
void Init(ArgStruct *p, int* pargc, char*** pargv) void Init(ArgStruct *p, int* pargc, char*** pargv)
{ {
p->source = 0; /* Default source node */ p->source_node = 0; /* Default source node */
MPI_Init(pargc, pargv); MPI_Init(pargc, pargv);
} }
void Setup(ArgStruct *p) void Setup(ArgStruct *p)
{ {
char s[255], *ptr; int nprocs;
FILE *fd;
int i, np, mp = -1, node; MPI_Comm_rank(MPI_COMM_WORLD, &p->prot.iproc);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &p->myproc);
MPI_Comm_size(MPI_COMM_WORLD, &np); {
char s[255], *ptr;
gethostname(s,253); gethostname(s,253);
if( s[0] != '.' ) { /* just print the base name */ if( s[0] != '.' ) { /* just print the base name */
ptr = strchr( s, '.'); ptr = strchr( s, '.');
if( ptr != NULL ) *ptr = '\0'; if( ptr != NULL ) *ptr = '\0';
} }
fprintf(stderr,"%d: %s\n",p->myproc,s); printf("%d: %s\n",p->prot.iproc,s);
fflush(stdout);
if( np != p->nprocs && p->nprocs != 2 ) { }
if( p->myproc == 0 ) {
fprintf(stderr,"MPI_Comm_size doesn't match default or command line npr if (nprocs < 2)
ocs,\n"); {
fprintf(stderr,"nprocs will be reset to %d in mpi.c#setup()\n",np); printf("Need at least two processes (only given %d)\n", nprocs);
} exit(-2);
} }
p->nprocs = np;
p->tr = p->rcv = 0;
if (p->nprocs < 2 || p->nprocs%2 == 1) { if( p->prot.iproc == 0 ) {
fprintf(stderr, "tcp.c: nprocs = %d must be even and at least 2\n", p->npr p->tr = 1;
ocs); p->prot.nbor = nprocs-1;
exit(0); } else if( p->prot.iproc == nprocs-1 ) {
} p->rcv = 1;
p->prot.nbor = 0;
p->dest = (p->nprocs - 1) - p->myproc; }
/* You can change the communication pairs using the <-H hostfile>
* where hostfile has a listing of the new process numbers,
* with the first and last communicating, etc.
* In this code, it changes each procs myproc and dest.
*/
/* DDT - This could use better error checking on the input file */
if( p->hostfile != NULL ) {
if( (fd = fopen( p->hostfile, "r")) == NULL ) {
fprintf(stderr, "Could not open the hostfile %s\n", p->hostfile );
exit(0);
}
p->host = (char **) malloc( p->nprocs * sizeof(char *) );
for( i=0; i<p->nprocs; i++ )
p->host[i] = (char *) malloc( 100 * sizeof(char) );
for( i=0; i<p->nprocs; i++ ) {
fscanf( fd, "%s", p->host[i]);
if( atoi(p->host[i]) == p->myproc ) mp = i;
}
if( mp < 0 ) {
fprintf(stderr, "%d NetPIPE: Error reading the hostfile, mp=%d\n",
p->myproc, mp);
exit(0);
}
p->dest = atoi( p->host[ p->nprocs - 1 - mp ] );
/*fprintf(stderr,"%d proc mp=%d dest=%d\n", p->myproc, mp, p->dest);*/
p->myproc = mp;
}
/* The first half are transmitters by default. */
p->tr = p->rcv = 0;
if( p->myproc < p->nprocs/2 ) p->tr = 1;
else p->rcv = 1;
/* p->source may already have been set to -1 (MPI_ANY_SOURCE) /* p->source_node may already have been set to -1 (MPI_ANY_SOURCE)
* by specifying a -z on the command line. If not, set the source * by specifying a -z on the command line. If not, set the source
* node normally. */ * node normally. */
if( p->source == 0 ) p->source = p->dest; if( p->source_node == 0 ) p->source_node = p->prot.nbor;
if( p->bidir && p->myproc == 0 ) { #ifdef BSEND
fprintf(stderr,"MPI implementations do not have to guarantee message progr messbuff = (char *)malloc(MAXBUFSIZE * sizeof(char));
ess.\n"); if (messbuff == NULL)
fprintf(stderr,"You may need to run using -a to avoid locking up.\n\n"); {
} printf("Can't allocate for message buffer\n");
exit(-1);
}
MPI_Buffer_attach(messbuff, MAXBUFSIZE);
p->upper = MAXBUFSIZE;
#endif
if( p->bidir ) {
printf("MPI implementations do not have to guarantee message progress.\n
");
printf("You may need to run using -a to avoid locking up.\n\n");
}
} }
void Sync(ArgStruct *p) void Sync(ArgStruct *p)
{ {
MPI_Barrier(MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD);
} }
static int recvPosted = 0; static int recvPosted = 0;
static MPI_Request recvRequest; static MPI_Request recvRequest;
void PrepareToReceive(ArgStruct *p) void PrepareToReceive(ArgStruct *p)
{ {
static int tag = 0; /*
Providing a buffer for reception of data in advance of
/* Providing a buffer for reception of data in advance of the sender sending the data provides a major performance
* the sender sending the data provides a major performance boost on some implementations of MPI, particularly shared
* boost on some implementations of MPI, particularly shared memory implementations on the Cray T3E and Intel Paragon.
* memory implementations on the Cray T3E and Intel Paragon.
*/ */
if (recvPosted)
if (recvPosted) { {
fprintf(stderr,"Can't prepare to receive: outstanding receive!\n"); printf("Can't prepare to receive: outstanding receive!\n");
exit(-1); exit(-1);
} }
MPI_Irecv(p->r_ptr, p->bufflen, MPI_BYTE,
if( p->source < 0 ) { /* Receive using MPI_ANY_SOURCE */ p->source_node, 1, MPI_COMM_WORLD, &recvRequest);
recvPosted = -1;
MPI_Irecv(p->r_ptr, p->bufflen, MPI_BYTE, MPI_ANY_SOURCE, tag, MPI_COMM_WO
RLD, &recvRequest);
} else {
MPI_Irecv(p->r_ptr, p->bufflen, MPI_BYTE, p->source, tag, MPI_COMM_WORLD,
&recvRequest);
}
tag = (tag+1) % 100;
recvPosted = -1;
} }
void SendData(ArgStruct *p) void SendData(ArgStruct *p)
{ {
static int tag = 0; #ifdef BSEND
MPI_Bsend(p->s_ptr, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD);
/* char *cbuf = p->s_ptr;*/ #else
/*fprintf(stderr,"%d putting %d bytes from %p to %d (%d %d %d)\n", */
/* p->myproc, p->bufflen, p->s_ptr, p->dest, */
/* cbuf[0], cbuf[p->bufflen/2], cbuf[p->bufflen-1]);*/
if(p->syncflag) if(p->syncflag)
MPI_Ssend(p->s_ptr, p->bufflen, MPI_BYTE, p->dest, tag, MPI_COMM_WORLD); MPI_Ssend(p->s_ptr,p->bufflen, MPI_BYTE, p->prot.nbor,1,MPI_COMM_WORLD);
else else
MPI_Send( p->s_ptr, p->bufflen, MPI_BYTE, p->dest, tag, MPI_COMM_WORLD); MPI_Send(p->s_ptr, p->bufflen, MPI_BYTE, p->prot.nbor, 1, MPI_COMM_WORLD);
#endif
tag = (tag+1) % 100;
} }
int TestForCompletion( ArgStruct *p ) void RecvData(ArgStruct *p)
{ {
int complete; MPI_Status status;
if (recvPosted)
MPI_Test( &recvRequest, &complete, MPI_STATUS_IGNORE ); {
MPI_Wait(&recvRequest, &status);
return complete; recvPosted = 0;
}
else
{
MPI_Recv(p->r_ptr, p->bufflen, MPI_BYTE,
p->source_node, 1, MPI_COMM_WORLD, &status);
}
} }
void RecvData(ArgStruct *p) void SendTime(ArgStruct *p, double *t)
{ {
MPI_Status status; MPI_Send(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD);
static int tag = 0; }
/* char *cbuf = p->r_ptr;*/
/*fprintf(stderr,"%d receiving %d bytes into %p (%d %d %d), expecting %d\n", */
/* p->myproc, p->bufflen, p->r_ptr, */
/* cbuf[0], cbuf[p->bufflen/2], cbuf[p->bufflen-1], (char) p->expected);*
/
if (recvPosted) {
MPI_Wait(&recvRequest, &status);
recvPosted = 0;
} else {
if( p->source < 0 ) { /* Receive using MPI_ANY_SOURCE */
MPI_Recv(p->r_ptr, p->bufflen, MPI_BYTE, MPI_ANY_SOURCE, tag, MPI_COMM_
WORLD, &status);
} else {
MPI_Recv(p->r_ptr, p->bufflen, MPI_BYTE, p->source, tag, MPI_COMM_WORLD
, &status);
} void RecvTime(ArgStruct *p, double *t)
} {
tag = (tag+1) % 100; MPI_Status status;
/*fprintf(stderr,"%d received %d bytes into %p (%d %d %d), wanted %d\n", */ MPI_Recv(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD, &status);
/* p->myproc, p->bufflen, p->r_ptr, */
/* cbuf[0], cbuf[p->bufflen/2], cbuf[p->bufflen-1], (char) p->expected);*
/
} }
/* Gather the times from all procs to proc 0 for output */ void SendRepeat(ArgStruct *p, int rpt)
void Gather(ArgStruct *p, double *buf)
{ {
MPI_Gather( &buf[p->myproc], 1, MPI_DOUBLE, MPI_Send(&rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD);
buf, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
} }
/* Proc 0 sets nrepeats then broadcasts it to all procs */ void RecvRepeat(ArgStruct *p, int *rpt)
void Broadcast(ArgStruct *p, unsigned int *nrepeat)
{ {
MPI_Bcast(nrepeat, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Status status;
MPI_Recv(rpt, 1, MPI_INT, p->source_node, 2, MPI_COMM_WORLD, &status);
} }
void CleanUp(ArgStruct *p) void CleanUp(ArgStruct *p)
{ {
MPI_Finalize(); MPI_Finalize();
} }
void Reset(ArgStruct *p) { } void Reset(ArgStruct *p)
{
}
void AfterAlignmentInit(ArgStruct *p)
{
}
 End of changes. 22 change blocks. 
165 lines changed or deleted 98 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS