xref: /petsc/src/vec/is/sf/impls/basic/gather/sfgather.c (revision 872ab141943dee616010b2ad741aa550bd53b329)
1dd5b3ca6SJunchao Zhang #include <../src/vec/is/sf/impls/basic/gatherv/sfgatherv.h>
2cd620004SJunchao Zhang #include <../src/vec/is/sf/impls/basic/allgather/sfallgather.h>
3dd5b3ca6SJunchao Zhang 
4dd5b3ca6SJunchao Zhang /* Reuse the type. The difference is some fields (i.e., displs, recvcounts) are not used in Gather, which is not a big deal */
5dd5b3ca6SJunchao Zhang typedef PetscSF_Allgatherv PetscSF_Gather;
6dd5b3ca6SJunchao Zhang 
PetscSFLinkStartCommunication_Gather(PetscSF sf,PetscSFLink link,PetscSFDirection direction)7f5d27ee7SJunchao Zhang static PetscErrorCode PetscSFLinkStartCommunication_Gather(PetscSF sf, PetscSFLink link, PetscSFDirection direction)
8d71ae5a4SJacob Faibussowitsch {
9f5d27ee7SJunchao Zhang   MPI_Comm     comm    = MPI_COMM_NULL;
10cd620004SJunchao Zhang   void        *rootbuf = NULL, *leafbuf = NULL;
11f5d27ee7SJunchao Zhang   MPI_Request *req = NULL;
12f5d27ee7SJunchao Zhang   PetscMPIInt  count;
13f5d27ee7SJunchao Zhang   MPI_Datatype unit = link->unit;
14dd5b3ca6SJunchao Zhang 
15dd5b3ca6SJunchao Zhang   PetscFunctionBegin;
16f5d27ee7SJunchao Zhang   if (direction == PETSCSF_ROOT2LEAF) {
179566063dSJacob Faibussowitsch     PetscCall(PetscSFLinkCopyRootBufferInCaseNotUseGpuAwareMPI(sf, link, PETSC_TRUE /* device2host before sending */));
18f5d27ee7SJunchao Zhang   } else {
19f5d27ee7SJunchao Zhang     PetscCall(PetscSFLinkCopyLeafBufferInCaseNotUseGpuAwareMPI(sf, link, PETSC_TRUE /* device2host */));
20f5d27ee7SJunchao Zhang   }
219566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)sf, &comm));
22f5d27ee7SJunchao Zhang   PetscCall(PetscMPIIntCast(sf->nroots, &count));
23f5d27ee7SJunchao Zhang   PetscCall(PetscSFLinkGetMPIBuffersAndRequests(sf, link, direction, &rootbuf, &leafbuf, &req, NULL));
24*646b835dSJunchao Zhang   PetscCall(PetscSFLinkSyncStreamBeforeCallMPI(sf, link));
25f5d27ee7SJunchao Zhang 
26f5d27ee7SJunchao Zhang   if (direction == PETSCSF_ROOT2LEAF) {
27f5d27ee7SJunchao Zhang     PetscCallMPI(MPIU_Igather(rootbuf == leafbuf ? MPI_IN_PLACE : rootbuf, count, unit, leafbuf, count, unit, 0 /*rank 0*/, comm, req));
28f5d27ee7SJunchao Zhang   } else {
29f5d27ee7SJunchao Zhang     PetscCallMPI(MPIU_Iscatter(leafbuf, count, unit, rootbuf == leafbuf ? MPI_IN_PLACE : rootbuf, count, unit, 0 /*rank 0*/, comm, req));
30f5d27ee7SJunchao Zhang   }
313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32dd5b3ca6SJunchao Zhang }
33dd5b3ca6SJunchao Zhang 
PetscSFSetCommunicationOps_Gather(PetscSF sf,PetscSFLink link)34f5d27ee7SJunchao Zhang static PetscErrorCode PetscSFSetCommunicationOps_Gather(PetscSF sf, PetscSFLink link)
35d71ae5a4SJacob Faibussowitsch {
36dd5b3ca6SJunchao Zhang   PetscFunctionBegin;
37f5d27ee7SJunchao Zhang   link->StartCommunication = PetscSFLinkStartCommunication_Gather;
383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39dd5b3ca6SJunchao Zhang }
40dd5b3ca6SJunchao Zhang 
PetscSFCreate_Gather(PetscSF sf)41d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscSFCreate_Gather(PetscSF sf)
42d71ae5a4SJacob Faibussowitsch {
43dd5b3ca6SJunchao Zhang   PetscSF_Gather *dat = (PetscSF_Gather *)sf->data;
44dd5b3ca6SJunchao Zhang 
45dd5b3ca6SJunchao Zhang   PetscFunctionBegin;
46f5d27ee7SJunchao Zhang   sf->ops->BcastBegin  = PetscSFBcastBegin_Basic;
47ad227feaSJunchao Zhang   sf->ops->BcastEnd    = PetscSFBcastEnd_Basic;
48f5d27ee7SJunchao Zhang   sf->ops->ReduceBegin = PetscSFReduceBegin_Basic;
49cd620004SJunchao Zhang   sf->ops->ReduceEnd   = PetscSFReduceEnd_Basic;
50cd620004SJunchao Zhang 
51dd5b3ca6SJunchao Zhang   /* Inherit from Allgatherv */
52dd5b3ca6SJunchao Zhang   sf->ops->Reset         = PetscSFReset_Allgatherv;
53dd5b3ca6SJunchao Zhang   sf->ops->Destroy       = PetscSFDestroy_Allgatherv;
54dd5b3ca6SJunchao Zhang   sf->ops->GetGraph      = PetscSFGetGraph_Allgatherv;
55dd5b3ca6SJunchao Zhang   sf->ops->GetRootRanks  = PetscSFGetRootRanks_Allgatherv;
56dd5b3ca6SJunchao Zhang   sf->ops->GetLeafRanks  = PetscSFGetLeafRanks_Allgatherv;
57dd5b3ca6SJunchao Zhang   sf->ops->FetchAndOpEnd = PetscSFFetchAndOpEnd_Allgatherv;
58dd5b3ca6SJunchao Zhang   sf->ops->CreateLocalSF = PetscSFCreateLocalSF_Allgatherv;
59dd5b3ca6SJunchao Zhang 
60cd620004SJunchao Zhang   /* Inherit from Allgather */
61cd620004SJunchao Zhang   sf->ops->SetUp = PetscSFSetUp_Allgather;
62cd620004SJunchao Zhang 
63dd5b3ca6SJunchao Zhang   /* Inherit from Gatherv */
64dd5b3ca6SJunchao Zhang   sf->ops->FetchAndOpBegin = PetscSFFetchAndOpBegin_Gatherv;
65dd5b3ca6SJunchao Zhang 
66f5d27ee7SJunchao Zhang   sf->ops->SetCommunicationOps = PetscSFSetCommunicationOps_Gather;
67dd5b3ca6SJunchao Zhang 
686677b1c1SJunchao Zhang   sf->collective = PETSC_TRUE;
696677b1c1SJunchao Zhang 
704dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&dat));
71dd5b3ca6SJunchao Zhang   sf->data = (void *)dat;
723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
73dd5b3ca6SJunchao Zhang }
74