/*@@ @file PostReceiveGA.c @date Wed Feb 2 11:28:06 1997 @author Gabrielle Allen @desc Routines which post all the IRecv commands for a GA. These allow the asyncronous model proposed in, for example, @seeroutine SyncGA to go! @enddesc @version $Header$ @@*/ #include #include "pugh.h" static char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusPUGH_PUGH_PostReceiveGA_c) /*#define DEBUG_PUGH*/ /*@@ @routine PostReceiveGA @date Thu Apr 3 12:10:46 1997 @author Paul Walker @desc This routine posts a recieve (MPI_Irecv) of the buffer we want to get the send from another processor, which will be sent by @seeroutine pGA_PostSend and then finalized by @seeroutoine pGA_FinishRecv.

Aside from a silly calculation to get a unique tag based on neigbors and processors, this is a very straightforward routine. @enddesc @history @hdate Nov 4 1998 @hauthor Gabrielle Allen @hdesc Allow for forced synchronization of all GAs with storage @endhistory @@*/ void PostReceiveGA(pGH *GH, pGA *GA, int dir) { #ifdef CCTK_MPI int rtag; MPI_Datatype mpi_type; MPI_Datatype *recv_dt; if (!(GA->storage)) { CCTK_VWarn(2, __LINE__, __FILE__, CCTK_THORNSTRING, "Trying to synchronize variable '%s' with no storage", GA->name); return; } /* Return if communication not required and no forced synchronisation */ if (!(GH->forceSync || GA->docomm[dir])) { return; } if (GA->connectivity->neighbours[GH->myproc][dir] < 0) { return; } switch (GA->vtype) { case CCTK_VARIABLE_CHAR: mpi_type = PUGH_MPI_CHAR; recv_dt = GH->recv_char_dt [GA->stagger]; break; case CCTK_VARIABLE_INT: mpi_type = PUGH_MPI_INT; recv_dt = GH->recv_int_dt [GA->stagger]; break; case CCTK_VARIABLE_REAL: mpi_type = PUGH_MPI_REAL; recv_dt = GH->recv_real_dt [GA->stagger]; break; case CCTK_VARIABLE_COMPLEX: mpi_type = GH->PUGH_mpi_complex; recv_dt = GH->recv_complex_dt [GA->stagger]; break; default: CCTK_WARN (1, "Unknown variable type in PostReceiveGA"); return; } rtag = 1000 + dir + 2 * (GH->myproc + GH->nprocs * GA->id); /* mod the tag to force MPI compliance */ rtag = rtag % 32768; #ifdef DEBUG_PUGH printf ("RECV GA %s Side %d Proc %d rtag %d size %d from proc %d\n", GA->name, dir, GH->myproc, rtag, GA->buffer_sz[dir], GA->connectivity->neighbours[GH->myproc][dir]); #endif if (GH->commmodel == PUGH_ALLOCATEDBUFFERS) { CACTUS_MPI_ERROR (MPI_Irecv (GA->recv_buffer [dir], GA->buffer_sz [dir], mpi_type, GA->connectivity->neighbours [GH->myproc][dir], rtag, GH->PUGH_COMM_WORLD, &(GA->rreq [dir]))); } if (GH->commmodel == PUGH_DERIVEDTYPES) { CACTUS_MPI_ERROR (MPI_Irecv (GA->data, 1, recv_dt [dir], GA->connectivity->neighbours [GH->myproc][dir], rtag, GH->PUGH_COMM_WORLD, &(GA->rreq [dir]))); } #endif }