Actual source code: sfgather.c

  1: #include <../src/vec/is/sf/impls/basic/gatherv/sfgatherv.h>
  2: #include <../src/vec/is/sf/impls/basic/allgather/sfallgather.h>

  4: /* Reuse the type. The difference is some fields (i.e., displs, recvcounts) are not used in Gather, which is not a big deal */
  5: typedef PetscSF_Allgatherv PetscSF_Gather;

  7: static PetscErrorCode PetscSFLinkStartCommunication_Gather(PetscSF sf, PetscSFLink link, PetscSFDirection direction)
  8: {
  9:   MPI_Comm     comm    = MPI_COMM_NULL;
 10:   void        *rootbuf = NULL, *leafbuf = NULL;
 11:   MPI_Request *req = NULL;
 12:   PetscMPIInt  count;
 13:   MPI_Datatype unit = link->unit;

 15:   PetscFunctionBegin;
 16:   if (direction == PETSCSF_ROOT2LEAF) {
 17:     PetscCall(PetscSFLinkCopyRootBufferInCaseNotUseGpuAwareMPI(sf, link, PETSC_TRUE /* device2host before sending */));
 18:   } else {
 19:     PetscCall(PetscSFLinkCopyLeafBufferInCaseNotUseGpuAwareMPI(sf, link, PETSC_TRUE /* device2host */));
 20:   }
 21:   PetscCall(PetscObjectGetComm((PetscObject)sf, &comm));
 22:   PetscCall(PetscMPIIntCast(sf->nroots, &count));
 23:   PetscCall(PetscSFLinkGetMPIBuffersAndRequests(sf, link, direction, &rootbuf, &leafbuf, &req, NULL));
 24:   PetscCall(PetscSFLinkSyncStreamBeforeCallMPI(sf, link));

 26:   if (direction == PETSCSF_ROOT2LEAF) {
 27:     PetscCallMPI(MPIU_Igather(rootbuf == leafbuf ? MPI_IN_PLACE : rootbuf, count, unit, leafbuf, count, unit, 0 /*rank 0*/, comm, req));
 28:   } else {
 29:     PetscCallMPI(MPIU_Iscatter(leafbuf, count, unit, rootbuf == leafbuf ? MPI_IN_PLACE : rootbuf, count, unit, 0 /*rank 0*/, comm, req));
 30:   }
 31:   PetscFunctionReturn(PETSC_SUCCESS);
 32: }

 34: static PetscErrorCode PetscSFSetCommunicationOps_Gather(PetscSF sf, PetscSFLink link)
 35: {
 36:   PetscFunctionBegin;
 37:   link->StartCommunication = PetscSFLinkStartCommunication_Gather;
 38:   PetscFunctionReturn(PETSC_SUCCESS);
 39: }

 41: PETSC_INTERN PetscErrorCode PetscSFCreate_Gather(PetscSF sf)
 42: {
 43:   PetscSF_Gather *dat = (PetscSF_Gather *)sf->data;

 45:   PetscFunctionBegin;
 46:   sf->ops->BcastBegin  = PetscSFBcastBegin_Basic;
 47:   sf->ops->BcastEnd    = PetscSFBcastEnd_Basic;
 48:   sf->ops->ReduceBegin = PetscSFReduceBegin_Basic;
 49:   sf->ops->ReduceEnd   = PetscSFReduceEnd_Basic;

 51:   /* Inherit from Allgatherv */
 52:   sf->ops->Reset         = PetscSFReset_Allgatherv;
 53:   sf->ops->Destroy       = PetscSFDestroy_Allgatherv;
 54:   sf->ops->GetGraph      = PetscSFGetGraph_Allgatherv;
 55:   sf->ops->GetRootRanks  = PetscSFGetRootRanks_Allgatherv;
 56:   sf->ops->GetLeafRanks  = PetscSFGetLeafRanks_Allgatherv;
 57:   sf->ops->FetchAndOpEnd = PetscSFFetchAndOpEnd_Allgatherv;
 58:   sf->ops->CreateLocalSF = PetscSFCreateLocalSF_Allgatherv;

 60:   /* Inherit from Allgather */
 61:   sf->ops->SetUp = PetscSFSetUp_Allgather;

 63:   /* Inherit from Gatherv */
 64:   sf->ops->FetchAndOpBegin = PetscSFFetchAndOpBegin_Gatherv;

 66:   sf->ops->SetCommunicationOps = PetscSFSetCommunicationOps_Gather;

 68:   sf->collective = PETSC_TRUE;

 70:   PetscCall(PetscNew(&dat));
 71:   sf->data = (void *)dat;
 72:   PetscFunctionReturn(PETSC_SUCCESS);
 73: }