Actual source code: sfgatherv.c
petsc-3.12.5 2020-03-29
2: #include <../src/vec/is/sf/impls/basic/gatherv/sfgatherv.h>
4: #define PetscSFPackGet_Gatherv PetscSFPackGet_Allgatherv
6: /* Reuse the type. The difference is some fields (displs, recvcounts) are only significant
7: on rank 0 in Gatherv. On other ranks they are harmless NULL.
8: */
9: typedef PetscSF_Allgatherv PetscSF_Gatherv;
11: PETSC_INTERN PetscErrorCode PetscSFBcastAndOpBegin_Gatherv(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,const void *rootdata,PetscMemType leafmtype,void *leafdata,MPI_Op op)
12: {
13: PetscErrorCode ierr;
14: PetscSFPack link;
15: PetscMPIInt rank,sendcount;
16: MPI_Comm comm;
17: char *recvbuf;
18: PetscSF_Gatherv *dat = (PetscSF_Gatherv*)sf->data;
21: PetscSFPackGet_Gatherv(sf,unit,rootmtype,rootdata,leafmtype,leafdata,&link);
22: PetscObjectGetComm((PetscObject)sf,&comm);
23: PetscMPIIntCast(sf->nroots,&sendcount);
24: MPI_Comm_rank(comm,&rank);
26: if (op == MPIU_REPLACE) {
27: recvbuf = (char*)leafdata;
28: } else {
29: if (!link->leafbuf[leafmtype] && !rank) {PetscMallocWithMemType(leafmtype,sf->nleaves*link->unitbytes,(void**)&link->leafbuf[leafmtype]);} /* Alloate leafbuf on rank 0 */
30: recvbuf = link->leafbuf[leafmtype];
31: }
33: MPIU_Igatherv(rootdata,sendcount,unit,recvbuf,dat->recvcounts,dat->displs,unit,0/*rank 0*/,comm,link->rootreqs[PETSCSF_../../../../../..2LEAF_BCAST][rootmtype]);
34: return(0);
35: }
37: static PetscErrorCode PetscSFReduceBegin_Gatherv(PetscSF sf,MPI_Datatype unit,PetscMemType leafmtype,const void *leafdata,PetscMemType rootmtype,void *rootdata,MPI_Op op)
38: {
39: PetscErrorCode ierr;
40: PetscSFPack link;
41: PetscMPIInt recvcount;
42: MPI_Comm comm;
43: char *recvbuf;
44: PetscSF_Gatherv *dat = (PetscSF_Gatherv*)sf->data;
47: PetscSFPackGet_Gatherv(sf,unit,rootmtype,rootdata,leafmtype,leafdata,&link);
48: PetscObjectGetComm((PetscObject)sf,&comm);
50: if (op == MPIU_REPLACE) {
51: recvbuf = (char*)rootdata;
52: } else {
53: if (!link->rootbuf[rootmtype]) {PetscMallocWithMemType(rootmtype,sf->nroots*link->unitbytes,(void**)&link->rootbuf[rootmtype]);}
54: recvbuf = link->rootbuf[rootmtype];
55: }
57: PetscMPIIntCast(sf->nroots,&recvcount);
58: MPIU_Iscatterv(leafdata,dat->recvcounts,dat->displs,unit,recvbuf,recvcount,unit,0,comm,link->rootreqs[PETSCSF_LEAF2../../../../../.._REDUCE][rootmtype]);
59: return(0);
60: }
62: PETSC_INTERN PetscErrorCode PetscSFFetchAndOpBegin_Gatherv(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,void *rootdata,PetscMemType leafmtype,const void *leafdata,void *leafupdate,MPI_Op op)
63: {
64: PetscErrorCode ierr;
67: /* In Gatherv, each root only has one leaf. So we just need to bcast rootdata to leafupdate and then reduce leafdata to rootdata */
68: PetscSFBcastAndOpBegin(sf,unit,rootdata,leafupdate,MPIU_REPLACE);
69: PetscSFBcastAndOpEnd(sf,unit,rootdata,leafupdate,MPIU_REPLACE);
70: PetscSFReduceBegin(sf,unit,leafdata,rootdata,op);
71: return(0);
72: }
74: PETSC_INTERN PetscErrorCode PetscSFCreate_Gatherv(PetscSF sf)
75: {
76: PetscErrorCode ierr;
77: PetscSF_Gatherv *dat = (PetscSF_Gatherv*)sf->data;
80: /* Inherit from Allgatherv */
81: sf->ops->SetUp = PetscSFSetUp_Allgatherv;
82: sf->ops->Reset = PetscSFReset_Allgatherv;
83: sf->ops->Destroy = PetscSFDestroy_Allgatherv;
84: sf->ops->GetGraph = PetscSFGetGraph_Allgatherv;
85: sf->ops->GetLeafRanks = PetscSFGetLeafRanks_Allgatherv;
86: sf->ops->GetRootRanks = PetscSFGetRootRanks_Allgatherv;
87: sf->ops->BcastAndOpEnd = PetscSFBcastAndOpEnd_Allgatherv;
88: sf->ops->ReduceEnd = PetscSFReduceEnd_Allgatherv;
89: sf->ops->FetchAndOpEnd = PetscSFFetchAndOpEnd_Allgatherv;
90: sf->ops->CreateLocalSF = PetscSFCreateLocalSF_Allgatherv;
92: /* Gatherv stuff */
93: sf->ops->BcastAndOpBegin = PetscSFBcastAndOpBegin_Gatherv;
94: sf->ops->ReduceBegin = PetscSFReduceBegin_Gatherv;
95: sf->ops->FetchAndOpBegin = PetscSFFetchAndOpBegin_Gatherv;
97: PetscNewLog(sf,&dat);
98: sf->data = (void*)dat;
99: return(0);
100: }