Actual source code: sfgatherv.c
petsc-3.13.6 2020-09-29
2: #include <../src/vec/is/sf/impls/basic/gatherv/sfgatherv.h>
4: /* Reuse the type. The difference is some fields (displs, recvcounts) are only significant
5: on rank 0 in Gatherv. On other ranks they are harmless NULL.
6: */
7: typedef PetscSF_Allgatherv PetscSF_Gatherv;
9: PETSC_INTERN PetscErrorCode PetscSFBcastAndOpBegin_Gatherv(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,const void *rootdata,PetscMemType leafmtype,void *leafdata,MPI_Op op)
10: {
11: PetscErrorCode ierr;
12: PetscSFLink link;
13: PetscMPIInt sendcount;
14: MPI_Comm comm;
15: PetscSF_Gatherv *dat = (PetscSF_Gatherv*)sf->data;
16: void *rootbuf = NULL,*leafbuf = NULL; /* buffer seen by MPI */
17: MPI_Request *req;
20: PetscSFLinkCreate(sf,unit,rootmtype,rootdata,leafmtype,leafdata,op,PETSCSF_BCAST,&link);
21: PetscSFLinkPackRootData(sf,link,PETSCSF_REMOTE,rootdata);
22: PetscObjectGetComm((PetscObject)sf,&comm);
23: PetscMPIIntCast(sf->nroots,&sendcount);
24: PetscSFLinkGetMPIBuffersAndRequests(sf,link,PETSCSF_../../../../../..2LEAF,&rootbuf,&leafbuf,&req,NULL);
25: MPIU_Igatherv(rootbuf,sendcount,unit,leafbuf,dat->recvcounts,dat->displs,unit,0/*rank 0*/,comm,req);
26: return(0);
27: }
29: static PetscErrorCode PetscSFReduceBegin_Gatherv(PetscSF sf,MPI_Datatype unit,PetscMemType leafmtype,const void *leafdata,PetscMemType rootmtype,void *rootdata,MPI_Op op)
30: {
31: PetscErrorCode ierr;
32: PetscSFLink link;
33: PetscMPIInt recvcount;
34: MPI_Comm comm;
35: PetscSF_Gatherv *dat = (PetscSF_Gatherv*)sf->data;
36: void *rootbuf = NULL,*leafbuf = NULL; /* buffer seen by MPI */
37: MPI_Request *req;
40: PetscSFLinkCreate(sf,unit,rootmtype,rootdata,leafmtype,leafdata,op,PETSCSF_REDUCE,&link);
41: PetscSFLinkPackLeafData(sf,link,PETSCSF_REMOTE,leafdata);
42: PetscObjectGetComm((PetscObject)sf,&comm);
43: PetscMPIIntCast(sf->nroots,&recvcount);
44: PetscSFLinkGetMPIBuffersAndRequests(sf,link,PETSCSF_LEAF2../../../../../..,&rootbuf,&leafbuf,&req,NULL);
45: MPIU_Iscatterv(leafbuf,dat->recvcounts,dat->displs,unit,rootbuf,recvcount,unit,0,comm,req);
46: return(0);
47: }
49: PETSC_INTERN PetscErrorCode PetscSFFetchAndOpBegin_Gatherv(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,void *rootdata,PetscMemType leafmtype,const void *leafdata,void *leafupdate,MPI_Op op)
50: {
51: PetscErrorCode ierr;
54: /* In Gatherv, each root only has one leaf. So we just need to bcast rootdata to leafupdate and then reduce leafdata to rootdata */
55: PetscSFBcastAndOpBegin(sf,unit,rootdata,leafupdate,MPIU_REPLACE);
56: PetscSFBcastAndOpEnd(sf,unit,rootdata,leafupdate,MPIU_REPLACE);
57: PetscSFReduceBegin(sf,unit,leafdata,rootdata,op);
58: return(0);
59: }
61: PETSC_INTERN PetscErrorCode PetscSFCreate_Gatherv(PetscSF sf)
62: {
63: PetscErrorCode ierr;
64: PetscSF_Gatherv *dat = (PetscSF_Gatherv*)sf->data;
67: sf->ops->BcastAndOpEnd = PetscSFBcastAndOpEnd_Basic;
68: sf->ops->ReduceEnd = PetscSFReduceEnd_Basic;
70: /* Inherit from Allgatherv */
71: sf->ops->SetUp = PetscSFSetUp_Allgatherv;
72: sf->ops->Reset = PetscSFReset_Allgatherv;
73: sf->ops->Destroy = PetscSFDestroy_Allgatherv;
74: sf->ops->GetGraph = PetscSFGetGraph_Allgatherv;
75: sf->ops->GetLeafRanks = PetscSFGetLeafRanks_Allgatherv;
76: sf->ops->GetRootRanks = PetscSFGetRootRanks_Allgatherv;
77: sf->ops->FetchAndOpEnd = PetscSFFetchAndOpEnd_Allgatherv;
78: sf->ops->CreateLocalSF = PetscSFCreateLocalSF_Allgatherv;
80: /* Gatherv stuff */
81: sf->ops->BcastAndOpBegin = PetscSFBcastAndOpBegin_Gatherv;
82: sf->ops->ReduceBegin = PetscSFReduceBegin_Gatherv;
83: sf->ops->FetchAndOpBegin = PetscSFFetchAndOpBegin_Gatherv;
85: PetscNewLog(sf,&dat);
86: sf->data = (void*)dat;
87: return(0);
88: }