1e5c89e4eSSatish Balay 2c6db04a5SJed Brown #include <petscsys.h> /*I "petscsys.h" I*/ 3*76eed172SJunchao Zhang #include <petsc/private/mpiutils.h> 4e5c89e4eSSatish Balay 5e5c89e4eSSatish Balay /*@C 6e5c89e4eSSatish Balay PetscGatherNumberOfMessages - Computes the number of messages a node expects to receive 7e5c89e4eSSatish Balay 8d083f849SBarry Smith Collective 9e5c89e4eSSatish Balay 10e5c89e4eSSatish Balay Input Parameters: 11e5c89e4eSSatish Balay + comm - Communicator 12e5c89e4eSSatish Balay . iflags - an array of integers of length sizeof(comm). A '1' in ilengths[i] represent a 130298fd71SBarry Smith message from current node to ith node. Optionally NULL 14e5c89e4eSSatish Balay - ilengths - Non zero ilengths[i] represent a message to i of length ilengths[i]. 150298fd71SBarry Smith Optionally NULL. 16e5c89e4eSSatish Balay 17e5c89e4eSSatish Balay Output Parameters: 18e5c89e4eSSatish Balay . nrecvs - number of messages received 19e5c89e4eSSatish Balay 20e5c89e4eSSatish Balay Level: developer 21e5c89e4eSSatish Balay 22e5c89e4eSSatish Balay Notes: 23e5c89e4eSSatish Balay With this info, the correct message lengths can be determined using 24e5c89e4eSSatish Balay PetscGatherMessageLengths() 25e5c89e4eSSatish Balay 26e5c89e4eSSatish Balay Either iflags or ilengths should be provided. If iflags is not 270298fd71SBarry Smith provided (NULL) it can be computed from ilengths. If iflags is 28e5c89e4eSSatish Balay provided, ilengths is not required. 29e5c89e4eSSatish Balay 30e5c89e4eSSatish Balay .seealso: PetscGatherMessageLengths() 31e5c89e4eSSatish Balay @*/ 327087cfbeSBarry Smith PetscErrorCode PetscGatherNumberOfMessages(MPI_Comm comm,const PetscMPIInt iflags[],const PetscMPIInt ilengths[],PetscMPIInt *nrecvs) 33e5c89e4eSSatish Balay { 340298fd71SBarry Smith PetscMPIInt size,rank,*recv_buf,i,*iflags_local = NULL,*iflags_localm = NULL; 35e5c89e4eSSatish Balay PetscErrorCode ierr; 36e5c89e4eSSatish Balay 37e5c89e4eSSatish Balay PetscFunctionBegin; 38ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 39ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 40e5c89e4eSSatish Balay 41dcca6d9dSJed Brown ierr = PetscMalloc2(size,&recv_buf,size,&iflags_localm);CHKERRQ(ierr); 42e5c89e4eSSatish Balay 43e5c89e4eSSatish Balay /* If iflags not provided, compute iflags from ilengths */ 44e5c89e4eSSatish Balay if (!iflags) { 45e32f2f54SBarry Smith if (!ilengths) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Either iflags or ilengths should be provided"); 46e5c89e4eSSatish Balay iflags_local = iflags_localm; 47e5c89e4eSSatish Balay for (i=0; i<size; i++) { 48e5c89e4eSSatish Balay if (ilengths[i]) iflags_local[i] = 1; 49e5c89e4eSSatish Balay else iflags_local[i] = 0; 50e5c89e4eSSatish Balay } 51a297a907SKarl Rupp } else iflags_local = (PetscMPIInt*) iflags; 52e5c89e4eSSatish Balay 53e5c89e4eSSatish Balay /* Post an allreduce to determine the numer of messages the current node will receive */ 54820f2d46SBarry Smith ierr = MPIU_Allreduce(iflags_local,recv_buf,size,MPI_INT,MPI_SUM,comm);CHKERRMPI(ierr); 55e5c89e4eSSatish Balay *nrecvs = recv_buf[rank]; 56e5c89e4eSSatish Balay 57e5c89e4eSSatish Balay ierr = PetscFree2(recv_buf,iflags_localm);CHKERRQ(ierr); 58e5c89e4eSSatish Balay PetscFunctionReturn(0); 59e5c89e4eSSatish Balay } 60e5c89e4eSSatish Balay 61e5c89e4eSSatish Balay /*@C 62e5c89e4eSSatish Balay PetscGatherMessageLengths - Computes info about messages that a MPI-node will receive, 63e5c89e4eSSatish Balay including (from-id,length) pairs for each message. 64e5c89e4eSSatish Balay 65d083f849SBarry Smith Collective 66e5c89e4eSSatish Balay 67e5c89e4eSSatish Balay Input Parameters: 68e5c89e4eSSatish Balay + comm - Communicator 69e5c89e4eSSatish Balay . nsends - number of messages that are to be sent. 70e5c89e4eSSatish Balay . nrecvs - number of messages being received 71e5c89e4eSSatish Balay - ilengths - an array of integers of length sizeof(comm) 72e5c89e4eSSatish Balay a non zero ilengths[i] represent a message to i of length ilengths[i] 73e5c89e4eSSatish Balay 74e5c89e4eSSatish Balay Output Parameters: 75e5c89e4eSSatish Balay + onodes - list of node-ids from which messages are expected 76e5c89e4eSSatish Balay - olengths - corresponding message lengths 77e5c89e4eSSatish Balay 78e5c89e4eSSatish Balay Level: developer 79e5c89e4eSSatish Balay 80e5c89e4eSSatish Balay Notes: 81e5c89e4eSSatish Balay With this info, the correct MPI_Irecv() can be posted with the correct 82e5c89e4eSSatish Balay from-id, with a buffer with the right amount of memory required. 83e5c89e4eSSatish Balay 84e5c89e4eSSatish Balay The calling function deallocates the memory in onodes and olengths 85e5c89e4eSSatish Balay 86c2916339SPierre Jolivet To determine nrecvs, one can use PetscGatherNumberOfMessages() 87e5c89e4eSSatish Balay 88e5c89e4eSSatish Balay .seealso: PetscGatherNumberOfMessages() 89e5c89e4eSSatish Balay @*/ 907087cfbeSBarry Smith PetscErrorCode PetscGatherMessageLengths(MPI_Comm comm,PetscMPIInt nsends,PetscMPIInt nrecvs,const PetscMPIInt ilengths[],PetscMPIInt **onodes,PetscMPIInt **olengths) 91e5c89e4eSSatish Balay { 92e5c89e4eSSatish Balay PetscErrorCode ierr; 936bfd7d4fSJunchao Zhang PetscMPIInt size,rank,tag,i,j; 940298fd71SBarry Smith MPI_Request *s_waits = NULL,*r_waits = NULL; 950298fd71SBarry Smith MPI_Status *w_status = NULL; 96e5c89e4eSSatish Balay 97e5c89e4eSSatish Balay PetscFunctionBegin; 98ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 99ffc4695bSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 100e5c89e4eSSatish Balay ierr = PetscCommGetNewTag(comm,&tag);CHKERRQ(ierr); 101e5c89e4eSSatish Balay 102e5c89e4eSSatish Balay /* cannot use PetscMalloc3() here because in the call to MPI_Waitall() they MUST be contiguous */ 103dcca6d9dSJed Brown ierr = PetscMalloc2(nrecvs+nsends,&r_waits,nrecvs+nsends,&w_status);CHKERRQ(ierr); 104e5c89e4eSSatish Balay s_waits = r_waits+nrecvs; 105e5c89e4eSSatish Balay 106e5c89e4eSSatish Balay /* Post the Irecv to get the message length-info */ 107785e854fSJed Brown ierr = PetscMalloc1(nrecvs,olengths);CHKERRQ(ierr); 108e5c89e4eSSatish Balay for (i=0; i<nrecvs; i++) { 109ffc4695bSBarry Smith ierr = MPI_Irecv((*olengths)+i,1,MPI_INT,MPI_ANY_SOURCE,tag,comm,r_waits+i);CHKERRMPI(ierr); 110e5c89e4eSSatish Balay } 111e5c89e4eSSatish Balay 112e5c89e4eSSatish Balay /* Post the Isends with the message length-info */ 113e5c89e4eSSatish Balay for (i=0,j=0; i<size; ++i) { 114e5c89e4eSSatish Balay if (ilengths[i]) { 115ffc4695bSBarry Smith ierr = MPI_Isend((void*)(ilengths+i),1,MPI_INT,i,tag,comm,s_waits+j);CHKERRMPI(ierr); 116e5c89e4eSSatish Balay j++; 117e5c89e4eSSatish Balay } 118e5c89e4eSSatish Balay } 119e5c89e4eSSatish Balay 120e5c89e4eSSatish Balay /* Post waits on sends and receivs */ 121ffc4695bSBarry Smith if (nrecvs+nsends) {ierr = MPI_Waitall(nrecvs+nsends,r_waits,w_status);CHKERRMPI(ierr);} 122e5c89e4eSSatish Balay 123e5c89e4eSSatish Balay /* Pack up the received data */ 124785e854fSJed Brown ierr = PetscMalloc1(nrecvs,onodes);CHKERRQ(ierr); 1256bfd7d4fSJunchao Zhang for (i=0; i<nrecvs; ++i) { 1266bfd7d4fSJunchao Zhang (*onodes)[i] = w_status[i].MPI_SOURCE; 1276bfd7d4fSJunchao Zhang #if defined(PETSC_HAVE_OMPI_MAJOR_VERSION) 1286bfd7d4fSJunchao Zhang /* This line is a workaround for a bug in OpenMPI-2.1.1 distributed by Ubuntu-18.04.2 LTS. 1296bfd7d4fSJunchao Zhang It happens in self-to-self MPI_Send/Recv using MPI_ANY_SOURCE for message matching. OpenMPI 1306bfd7d4fSJunchao Zhang does not put correct value in recv buffer. See also 1316bfd7d4fSJunchao Zhang https://lists.mcs.anl.gov/pipermail/petsc-dev/2019-July/024803.html 1326bfd7d4fSJunchao Zhang https://www.mail-archive.com/users@lists.open-mpi.org//msg33383.html 1336bfd7d4fSJunchao Zhang */ 1346bfd7d4fSJunchao Zhang if (w_status[i].MPI_SOURCE == rank) (*olengths)[i] = ilengths[rank]; 1356bfd7d4fSJunchao Zhang #endif 1366bfd7d4fSJunchao Zhang } 137e5c89e4eSSatish Balay ierr = PetscFree2(r_waits,w_status);CHKERRQ(ierr); 138e5c89e4eSSatish Balay PetscFunctionReturn(0); 139e5c89e4eSSatish Balay } 140dd6ea824SBarry Smith 141*76eed172SJunchao Zhang /* Same as PetscGatherNumberOfMessages(), except using PetscInt for ilengths[] */ 142*76eed172SJunchao Zhang PetscErrorCode PetscGatherNumberOfMessages_Private(MPI_Comm comm,const PetscMPIInt iflags[],const PetscInt ilengths[],PetscMPIInt *nrecvs) 143*76eed172SJunchao Zhang { 144*76eed172SJunchao Zhang PetscMPIInt size,rank,*recv_buf,i,*iflags_local = NULL,*iflags_localm = NULL; 145*76eed172SJunchao Zhang PetscErrorCode ierr; 146*76eed172SJunchao Zhang 147*76eed172SJunchao Zhang PetscFunctionBegin; 148*76eed172SJunchao Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 149*76eed172SJunchao Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 150*76eed172SJunchao Zhang 151*76eed172SJunchao Zhang ierr = PetscMalloc2(size,&recv_buf,size,&iflags_localm);CHKERRQ(ierr); 152*76eed172SJunchao Zhang 153*76eed172SJunchao Zhang /* If iflags not provided, compute iflags from ilengths */ 154*76eed172SJunchao Zhang if (!iflags) { 155*76eed172SJunchao Zhang if (!ilengths) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Either iflags or ilengths should be provided"); 156*76eed172SJunchao Zhang iflags_local = iflags_localm; 157*76eed172SJunchao Zhang for (i=0; i<size; i++) { 158*76eed172SJunchao Zhang if (ilengths[i]) iflags_local[i] = 1; 159*76eed172SJunchao Zhang else iflags_local[i] = 0; 160*76eed172SJunchao Zhang } 161*76eed172SJunchao Zhang } else iflags_local = (PetscMPIInt*) iflags; 162*76eed172SJunchao Zhang 163*76eed172SJunchao Zhang /* Post an allreduce to determine the numer of messages the current node will receive */ 164*76eed172SJunchao Zhang ierr = MPIU_Allreduce(iflags_local,recv_buf,size,MPI_INT,MPI_SUM,comm);CHKERRMPI(ierr); 165*76eed172SJunchao Zhang *nrecvs = recv_buf[rank]; 166*76eed172SJunchao Zhang 167*76eed172SJunchao Zhang ierr = PetscFree2(recv_buf,iflags_localm);CHKERRQ(ierr); 168*76eed172SJunchao Zhang PetscFunctionReturn(0); 169*76eed172SJunchao Zhang } 170*76eed172SJunchao Zhang 171*76eed172SJunchao Zhang /* Same as PetscGatherMessageLengths(), except using PetscInt for message lengths */ 172*76eed172SJunchao Zhang PetscErrorCode PetscGatherMessageLengths_Private(MPI_Comm comm,PetscMPIInt nsends,PetscMPIInt nrecvs,const PetscInt ilengths[],PetscMPIInt **onodes,PetscInt **olengths) 173*76eed172SJunchao Zhang { 174*76eed172SJunchao Zhang PetscErrorCode ierr; 175*76eed172SJunchao Zhang PetscMPIInt size,rank,tag,i,j; 176*76eed172SJunchao Zhang MPI_Request *s_waits = NULL,*r_waits = NULL; 177*76eed172SJunchao Zhang MPI_Status *w_status = NULL; 178*76eed172SJunchao Zhang 179*76eed172SJunchao Zhang PetscFunctionBegin; 180*76eed172SJunchao Zhang ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 181*76eed172SJunchao Zhang ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 182*76eed172SJunchao Zhang ierr = PetscCommGetNewTag(comm,&tag);CHKERRQ(ierr); 183*76eed172SJunchao Zhang 184*76eed172SJunchao Zhang /* cannot use PetscMalloc3() here because in the call to MPI_Waitall() they MUST be contiguous */ 185*76eed172SJunchao Zhang ierr = PetscMalloc2(nrecvs+nsends,&r_waits,nrecvs+nsends,&w_status);CHKERRQ(ierr); 186*76eed172SJunchao Zhang s_waits = r_waits+nrecvs; 187*76eed172SJunchao Zhang 188*76eed172SJunchao Zhang /* Post the Irecv to get the message length-info */ 189*76eed172SJunchao Zhang ierr = PetscMalloc1(nrecvs,olengths);CHKERRQ(ierr); 190*76eed172SJunchao Zhang for (i=0; i<nrecvs; i++) { 191*76eed172SJunchao Zhang ierr = MPI_Irecv((*olengths)+i,1,MPIU_INT,MPI_ANY_SOURCE,tag,comm,r_waits+i);CHKERRMPI(ierr); 192*76eed172SJunchao Zhang } 193*76eed172SJunchao Zhang 194*76eed172SJunchao Zhang /* Post the Isends with the message length-info */ 195*76eed172SJunchao Zhang for (i=0,j=0; i<size; ++i) { 196*76eed172SJunchao Zhang if (ilengths[i]) { 197*76eed172SJunchao Zhang ierr = MPI_Isend((void*)(ilengths+i),1,MPIU_INT,i,tag,comm,s_waits+j);CHKERRMPI(ierr); 198*76eed172SJunchao Zhang j++; 199*76eed172SJunchao Zhang } 200*76eed172SJunchao Zhang } 201*76eed172SJunchao Zhang 202*76eed172SJunchao Zhang /* Post waits on sends and receivs */ 203*76eed172SJunchao Zhang if (nrecvs+nsends) {ierr = MPI_Waitall(nrecvs+nsends,r_waits,w_status);CHKERRMPI(ierr);} 204*76eed172SJunchao Zhang 205*76eed172SJunchao Zhang /* Pack up the received data */ 206*76eed172SJunchao Zhang ierr = PetscMalloc1(nrecvs,onodes);CHKERRQ(ierr); 207*76eed172SJunchao Zhang for (i=0; i<nrecvs; ++i) { 208*76eed172SJunchao Zhang (*onodes)[i] = w_status[i].MPI_SOURCE; 209*76eed172SJunchao Zhang if (w_status[i].MPI_SOURCE == rank) (*olengths)[i] = ilengths[rank]; /* See comments in PetscGatherMessageLengths */ 210*76eed172SJunchao Zhang } 211*76eed172SJunchao Zhang ierr = PetscFree2(r_waits,w_status);CHKERRQ(ierr); 212*76eed172SJunchao Zhang PetscFunctionReturn(0); 213*76eed172SJunchao Zhang } 214*76eed172SJunchao Zhang 215e5c89e4eSSatish Balay /*@C 216e5c89e4eSSatish Balay PetscGatherMessageLengths2 - Computes info about messages that a MPI-node will receive, 217e5c89e4eSSatish Balay including (from-id,length) pairs for each message. Same functionality as PetscGatherMessageLengths() 218e5c89e4eSSatish Balay except it takes TWO ilenths and output TWO olengths. 219e5c89e4eSSatish Balay 220d083f849SBarry Smith Collective 221e5c89e4eSSatish Balay 222e5c89e4eSSatish Balay Input Parameters: 223e5c89e4eSSatish Balay + comm - Communicator 224e5c89e4eSSatish Balay . nsends - number of messages that are to be sent. 225e5c89e4eSSatish Balay . nrecvs - number of messages being received 2266b867d5aSJose E. Roman . ilengths1 - first array of integers of length sizeof(comm) 2276b867d5aSJose E. Roman - ilengths2 - second array of integers of length sizeof(comm) 228e5c89e4eSSatish Balay 229e5c89e4eSSatish Balay Output Parameters: 230e5c89e4eSSatish Balay + onodes - list of node-ids from which messages are expected 2316b867d5aSJose E. Roman . olengths1 - first corresponding message lengths 2326b867d5aSJose E. Roman - olengths2 - second message lengths 233e5c89e4eSSatish Balay 234e5c89e4eSSatish Balay Level: developer 235e5c89e4eSSatish Balay 236e5c89e4eSSatish Balay Notes: 237e5c89e4eSSatish Balay With this info, the correct MPI_Irecv() can be posted with the correct 238e5c89e4eSSatish Balay from-id, with a buffer with the right amount of memory required. 239e5c89e4eSSatish Balay 240e5c89e4eSSatish Balay The calling function deallocates the memory in onodes and olengths 241e5c89e4eSSatish Balay 242c2916339SPierre Jolivet To determine nrecvs, one can use PetscGatherNumberOfMessages() 243e5c89e4eSSatish Balay 244e5c89e4eSSatish Balay .seealso: PetscGatherMessageLengths() and PetscGatherNumberOfMessages() 245e5c89e4eSSatish Balay @*/ 2467087cfbeSBarry Smith PetscErrorCode PetscGatherMessageLengths2(MPI_Comm comm,PetscMPIInt nsends,PetscMPIInt nrecvs,const PetscMPIInt ilengths1[],const PetscMPIInt ilengths2[],PetscMPIInt **onodes,PetscMPIInt **olengths1,PetscMPIInt **olengths2) 247e5c89e4eSSatish Balay { 248e5c89e4eSSatish Balay PetscErrorCode ierr; 2490298fd71SBarry Smith PetscMPIInt size,tag,i,j,*buf_s = NULL,*buf_r = NULL,*buf_j = NULL; 2500298fd71SBarry Smith MPI_Request *s_waits = NULL,*r_waits = NULL; 2510298fd71SBarry Smith MPI_Status *w_status = NULL; 252e5c89e4eSSatish Balay 253e5c89e4eSSatish Balay PetscFunctionBegin; 254ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 255e5c89e4eSSatish Balay ierr = PetscCommGetNewTag(comm,&tag);CHKERRQ(ierr); 256e5c89e4eSSatish Balay 2573bf92927SBarry Smith /* cannot use PetscMalloc5() because r_waits and s_waits must be contiguous for the call to MPI_Waitall() */ 258dcca6d9dSJed Brown ierr = PetscMalloc4(nrecvs+nsends,&r_waits,2*nrecvs,&buf_r,2*nsends,&buf_s,nrecvs+nsends,&w_status);CHKERRQ(ierr); 259e5c89e4eSSatish Balay s_waits = r_waits + nrecvs; 260e5c89e4eSSatish Balay 261e5c89e4eSSatish Balay /* Post the Irecv to get the message length-info */ 262854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,olengths1);CHKERRQ(ierr); 263854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,olengths2);CHKERRQ(ierr); 264e5c89e4eSSatish Balay for (i=0; i<nrecvs; i++) { 265e5c89e4eSSatish Balay buf_j = buf_r + (2*i); 26655b25c41SPierre Jolivet ierr = MPI_Irecv(buf_j,2,MPI_INT,MPI_ANY_SOURCE,tag,comm,r_waits+i);CHKERRMPI(ierr); 267e5c89e4eSSatish Balay } 268e5c89e4eSSatish Balay 269e5c89e4eSSatish Balay /* Post the Isends with the message length-info */ 270e5c89e4eSSatish Balay for (i=0,j=0; i<size; ++i) { 271e5c89e4eSSatish Balay if (ilengths1[i]) { 272e5c89e4eSSatish Balay buf_j = buf_s + (2*j); 273e5c89e4eSSatish Balay buf_j[0] = *(ilengths1+i); 274e5c89e4eSSatish Balay buf_j[1] = *(ilengths2+i); 275ffc4695bSBarry Smith ierr = MPI_Isend(buf_j,2,MPI_INT,i,tag,comm,s_waits+j);CHKERRMPI(ierr); 276e5c89e4eSSatish Balay j++; 277e5c89e4eSSatish Balay } 278e5c89e4eSSatish Balay } 279f327f304SBarry Smith if (j != nsends) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"j %d not equal to expected number of sends %d\n",j,nsends); 280e5c89e4eSSatish Balay 281e5c89e4eSSatish Balay /* Post waits on sends and receivs */ 282ffc4695bSBarry Smith if (nrecvs+nsends) {ierr = MPI_Waitall(nrecvs+nsends,r_waits,w_status);CHKERRMPI(ierr);} 283e5c89e4eSSatish Balay 284e5c89e4eSSatish Balay /* Pack up the received data */ 285854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,onodes);CHKERRQ(ierr); 286e5c89e4eSSatish Balay for (i=0; i<nrecvs; ++i) { 287e5c89e4eSSatish Balay (*onodes)[i] = w_status[i].MPI_SOURCE; 288e5c89e4eSSatish Balay buf_j = buf_r + (2*i); 289e5c89e4eSSatish Balay (*olengths1)[i] = buf_j[0]; 290e5c89e4eSSatish Balay (*olengths2)[i] = buf_j[1]; 291e5c89e4eSSatish Balay } 292e5c89e4eSSatish Balay 293e5c89e4eSSatish Balay ierr = PetscFree4(r_waits,buf_r,buf_s,w_status);CHKERRQ(ierr); 294e5c89e4eSSatish Balay PetscFunctionReturn(0); 295e5c89e4eSSatish Balay } 296e5c89e4eSSatish Balay 297e5c89e4eSSatish Balay /* 298e5c89e4eSSatish Balay 299a5b23f4aSJose E. Roman Allocate a buffer sufficient to hold messages of size specified in olengths. 300e5c89e4eSSatish Balay And post Irecvs on these buffers using node info from onodes 301e5c89e4eSSatish Balay 302e5c89e4eSSatish Balay */ 3037087cfbeSBarry Smith PetscErrorCode PetscPostIrecvInt(MPI_Comm comm,PetscMPIInt tag,PetscMPIInt nrecvs,const PetscMPIInt onodes[],const PetscMPIInt olengths[],PetscInt ***rbuf,MPI_Request **r_waits) 304e5c89e4eSSatish Balay { 305e5c89e4eSSatish Balay PetscErrorCode ierr; 306c05d87d6SBarry Smith PetscInt **rbuf_t,i,len = 0; 307e5c89e4eSSatish Balay MPI_Request *r_waits_t; 308e5c89e4eSSatish Balay 309e5c89e4eSSatish Balay PetscFunctionBegin; 310e5c89e4eSSatish Balay /* compute memory required for recv buffers */ 311e5c89e4eSSatish Balay for (i=0; i<nrecvs; i++) len += olengths[i]; /* each message length */ 312e5c89e4eSSatish Balay 313e5c89e4eSSatish Balay /* allocate memory for recv buffers */ 314854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&rbuf_t);CHKERRQ(ierr); 315785e854fSJed Brown ierr = PetscMalloc1(len,&rbuf_t[0]);CHKERRQ(ierr); 316e5c89e4eSSatish Balay for (i=1; i<nrecvs; ++i) rbuf_t[i] = rbuf_t[i-1] + olengths[i-1]; 317e5c89e4eSSatish Balay 318e5c89e4eSSatish Balay /* Post the receives */ 319785e854fSJed Brown ierr = PetscMalloc1(nrecvs,&r_waits_t);CHKERRQ(ierr); 320e5c89e4eSSatish Balay for (i=0; i<nrecvs; ++i) { 321ffc4695bSBarry Smith ierr = MPI_Irecv(rbuf_t[i],olengths[i],MPIU_INT,onodes[i],tag,comm,r_waits_t+i);CHKERRMPI(ierr); 322e5c89e4eSSatish Balay } 323e5c89e4eSSatish Balay 324e5c89e4eSSatish Balay *rbuf = rbuf_t; 325e5c89e4eSSatish Balay *r_waits = r_waits_t; 326e5c89e4eSSatish Balay PetscFunctionReturn(0); 327e5c89e4eSSatish Balay } 328e5c89e4eSSatish Balay 3297087cfbeSBarry Smith PetscErrorCode PetscPostIrecvScalar(MPI_Comm comm,PetscMPIInt tag,PetscMPIInt nrecvs,const PetscMPIInt onodes[],const PetscMPIInt olengths[],PetscScalar ***rbuf,MPI_Request **r_waits) 330e5c89e4eSSatish Balay { 331e5c89e4eSSatish Balay PetscErrorCode ierr; 332052f0c41SBarry Smith PetscMPIInt i; 333e5c89e4eSSatish Balay PetscScalar **rbuf_t; 334e5c89e4eSSatish Balay MPI_Request *r_waits_t; 335c05d87d6SBarry Smith PetscInt len = 0; 336e5c89e4eSSatish Balay 337fe28d99cSBarry Smith PetscFunctionBegin; 338e5c89e4eSSatish Balay /* compute memory required for recv buffers */ 339e5c89e4eSSatish Balay for (i=0; i<nrecvs; i++) len += olengths[i]; /* each message length */ 340e5c89e4eSSatish Balay 341e5c89e4eSSatish Balay /* allocate memory for recv buffers */ 342854ce69bSBarry Smith ierr = PetscMalloc1(nrecvs+1,&rbuf_t);CHKERRQ(ierr); 343785e854fSJed Brown ierr = PetscMalloc1(len,&rbuf_t[0]);CHKERRQ(ierr); 344e5c89e4eSSatish Balay for (i=1; i<nrecvs; ++i) rbuf_t[i] = rbuf_t[i-1] + olengths[i-1]; 345e5c89e4eSSatish Balay 346e5c89e4eSSatish Balay /* Post the receives */ 347785e854fSJed Brown ierr = PetscMalloc1(nrecvs,&r_waits_t);CHKERRQ(ierr); 348e5c89e4eSSatish Balay for (i=0; i<nrecvs; ++i) { 349ffc4695bSBarry Smith ierr = MPI_Irecv(rbuf_t[i],olengths[i],MPIU_SCALAR,onodes[i],tag,comm,r_waits_t+i);CHKERRMPI(ierr); 350e5c89e4eSSatish Balay } 351e5c89e4eSSatish Balay 352e5c89e4eSSatish Balay *rbuf = rbuf_t; 353e5c89e4eSSatish Balay *r_waits = r_waits_t; 354e5c89e4eSSatish Balay PetscFunctionReturn(0); 355e5c89e4eSSatish Balay } 356