1af0996ceSBarry Smith #include <petsc/private/sfimpl.h> /*I "petscsf.h" I*/ 295fce210SBarry Smith 395fce210SBarry Smith typedef struct _n_PetscSFDataLink *PetscSFDataLink; 495fce210SBarry Smith typedef struct _n_PetscSFWinLink *PetscSFWinLink; 595fce210SBarry Smith 695fce210SBarry Smith typedef struct { 795fce210SBarry Smith PetscSFWindowSyncType sync; /* FENCE, LOCK, or ACTIVE synchronization */ 8*5b0d146aSStefano Zampini PetscSFDataLink link; /* List of MPI data types, lazily constructed for each data type */ 995fce210SBarry Smith PetscSFWinLink wins; /* List of active windows */ 10*5b0d146aSStefano Zampini PetscSFWindowFlavorType flavor; /* Current PETSCSF_WINDOW_FLAVOR_ */ 11*5b0d146aSStefano Zampini PetscSF dynsf; 12*5b0d146aSStefano Zampini MPI_Info info; 1395fce210SBarry Smith } PetscSF_Window; 1495fce210SBarry Smith 1595fce210SBarry Smith struct _n_PetscSFDataLink { 1695fce210SBarry Smith MPI_Datatype unit; 1795fce210SBarry Smith MPI_Datatype *mine; 1895fce210SBarry Smith MPI_Datatype *remote; 1995fce210SBarry Smith PetscSFDataLink next; 2095fce210SBarry Smith }; 2195fce210SBarry Smith 2295fce210SBarry Smith struct _n_PetscSFWinLink { 2395fce210SBarry Smith PetscBool inuse; 2495fce210SBarry Smith size_t bytes; 2595fce210SBarry Smith void *addr; 26*5b0d146aSStefano Zampini void *paddr; 2795fce210SBarry Smith MPI_Win win; 28*5b0d146aSStefano Zampini PetscSFWindowFlavorType flavor; 29*5b0d146aSStefano Zampini MPI_Aint *dyn_target_addr; 3095fce210SBarry Smith PetscBool epoch; 3195fce210SBarry Smith PetscSFWinLink next; 3295fce210SBarry Smith }; 3395fce210SBarry Smith 3495fce210SBarry Smith const char *const PetscSFWindowSyncTypes[] = {"FENCE","LOCK","ACTIVE","PetscSFWindowSyncType","PETSCSF_WINDOW_SYNC_",0}; 35*5b0d146aSStefano Zampini const char *const PetscSFWindowFlavorTypes[] = {"CREATE","DYNAMIC","ALLOCATE","SHARED","PetscSFWindowFlavorType","PETSCSF_WINDOW_FLAVOR_",0}; 3695fce210SBarry Smith 37b2566f29SBarry Smith /* Built-in MPI_Ops act elementwise inside MPI_Accumulate, but cannot be used with composite types inside collectives (MPIU_Allreduce) */ 3895fce210SBarry Smith static PetscErrorCode PetscSFWindowOpTranslate(MPI_Op *op) 3995fce210SBarry Smith { 4095fce210SBarry Smith PetscFunctionBegin; 4195fce210SBarry Smith if (*op == MPIU_SUM) *op = MPI_SUM; 4295fce210SBarry Smith else if (*op == MPIU_MAX) *op = MPI_MAX; 4395fce210SBarry Smith else if (*op == MPIU_MIN) *op = MPI_MIN; 4495fce210SBarry Smith PetscFunctionReturn(0); 4595fce210SBarry Smith } 4695fce210SBarry Smith 4795fce210SBarry Smith /*@C 4895fce210SBarry Smith PetscSFWindowGetDataTypes - gets composite local and remote data types for each rank 4995fce210SBarry Smith 5095fce210SBarry Smith Not Collective 5195fce210SBarry Smith 5295fce210SBarry Smith Input Arguments: 5395fce210SBarry Smith + sf - star forest 5495fce210SBarry Smith - unit - data type for each node 5595fce210SBarry Smith 5695fce210SBarry Smith Output Arguments: 5795fce210SBarry Smith + localtypes - types describing part of local leaf buffer referencing each remote rank 5895fce210SBarry Smith - remotetypes - types describing part of remote root buffer referenced for each remote rank 5995fce210SBarry Smith 6095fce210SBarry Smith Level: developer 6195fce210SBarry Smith 6295fce210SBarry Smith .seealso: PetscSFSetGraph(), PetscSFView() 6395fce210SBarry Smith @*/ 6495fce210SBarry Smith static PetscErrorCode PetscSFWindowGetDataTypes(PetscSF sf,MPI_Datatype unit,const MPI_Datatype **localtypes,const MPI_Datatype **remotetypes) 6595fce210SBarry Smith { 6695fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 6795fce210SBarry Smith PetscErrorCode ierr; 6895fce210SBarry Smith PetscSFDataLink link; 6995fce210SBarry Smith PetscInt i,nranks; 7095fce210SBarry Smith const PetscInt *roffset,*rmine,*rremote; 7195fce210SBarry Smith const PetscMPIInt *ranks; 7295fce210SBarry Smith 7395fce210SBarry Smith PetscFunctionBegin; 7495fce210SBarry Smith /* Look for types in cache */ 7595fce210SBarry Smith for (link=w->link; link; link=link->next) { 7695fce210SBarry Smith PetscBool match; 7795fce210SBarry Smith ierr = MPIPetsc_Type_compare(unit,link->unit,&match);CHKERRQ(ierr); 7895fce210SBarry Smith if (match) { 7995fce210SBarry Smith *localtypes = link->mine; 8095fce210SBarry Smith *remotetypes = link->remote; 8195fce210SBarry Smith PetscFunctionReturn(0); 8295fce210SBarry Smith } 8395fce210SBarry Smith } 8495fce210SBarry Smith 8595fce210SBarry Smith /* Create new composite types for each send rank */ 86dec1416fSJunchao Zhang ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,&roffset,&rmine,&rremote);CHKERRQ(ierr); 8795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 8895fce210SBarry Smith ierr = MPI_Type_dup(unit,&link->unit);CHKERRQ(ierr); 89dcca6d9dSJed Brown ierr = PetscMalloc2(nranks,&link->mine,nranks,&link->remote);CHKERRQ(ierr); 9095fce210SBarry Smith for (i=0; i<nranks; i++) { 91*5b0d146aSStefano Zampini PetscInt rcount = roffset[i+1] - roffset[i]; 9295fce210SBarry Smith PetscMPIInt *rmine,*rremote; 9395fce210SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 9495fce210SBarry Smith rmine = sf->rmine + sf->roffset[i]; 9595fce210SBarry Smith rremote = sf->rremote + sf->roffset[i]; 9695fce210SBarry Smith #else 9795fce210SBarry Smith PetscInt j; 98dcca6d9dSJed Brown ierr = PetscMalloc2(rcount,&rmine,rcount,&rremote);CHKERRQ(ierr); 9995fce210SBarry Smith for (j=0; j<rcount; j++) { 10095fce210SBarry Smith ierr = PetscMPIIntCast(sf->rmine[sf->roffset[i]+j],rmine+j);CHKERRQ(ierr); 10195fce210SBarry Smith ierr = PetscMPIIntCast(sf->rremote[sf->roffset[i]+j],rremote+j);CHKERRQ(ierr); 10295fce210SBarry Smith } 10395fce210SBarry Smith #endif 104*5b0d146aSStefano Zampini 10595fce210SBarry Smith ierr = MPI_Type_create_indexed_block(rcount,1,rmine,link->unit,&link->mine[i]);CHKERRQ(ierr); 10695fce210SBarry Smith ierr = MPI_Type_create_indexed_block(rcount,1,rremote,link->unit,&link->remote[i]);CHKERRQ(ierr); 10795fce210SBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 10895fce210SBarry Smith ierr = PetscFree2(rmine,rremote);CHKERRQ(ierr); 10995fce210SBarry Smith #endif 11095fce210SBarry Smith ierr = MPI_Type_commit(&link->mine[i]);CHKERRQ(ierr); 11195fce210SBarry Smith ierr = MPI_Type_commit(&link->remote[i]);CHKERRQ(ierr); 11295fce210SBarry Smith } 11395fce210SBarry Smith link->next = w->link; 11495fce210SBarry Smith w->link = link; 11595fce210SBarry Smith 11695fce210SBarry Smith *localtypes = link->mine; 11795fce210SBarry Smith *remotetypes = link->remote; 11895fce210SBarry Smith PetscFunctionReturn(0); 11995fce210SBarry Smith } 12095fce210SBarry Smith 12195fce210SBarry Smith /*@C 122*5b0d146aSStefano Zampini PetscSFWindowSetFlavorType - Set flavor type for MPI_Win creation 123*5b0d146aSStefano Zampini 124*5b0d146aSStefano Zampini Logically Collective 125*5b0d146aSStefano Zampini 126*5b0d146aSStefano Zampini Input Arguments: 127*5b0d146aSStefano Zampini + sf - star forest for communication 128*5b0d146aSStefano Zampini - flavor - flavor type 129*5b0d146aSStefano Zampini 130*5b0d146aSStefano Zampini Options Database Key: 131*5b0d146aSStefano Zampini . -sf_window_flavor <flavor> - sets the flavor type CREATE, DYNAMIC, ALLOCATE or SHARED (see PetscSFWindowFlavorType) 132*5b0d146aSStefano Zampini 133*5b0d146aSStefano Zampini Level: advanced 134*5b0d146aSStefano Zampini 135*5b0d146aSStefano Zampini Notes: Windows reusage follow this rules: 136*5b0d146aSStefano Zampini 137*5b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_CREATE: creates a new window every time, uses MPI_Win_create 138*5b0d146aSStefano Zampini 139*5b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_DYNAMIC: uses MPI_Win_create_dynamic/MPI_Win_attach and tries to reuse windows by comparing the root array. Intended to be used on repeated applications of the same SF, e.g. 140*5b0d146aSStefano Zampini for i=1 to K 141*5b0d146aSStefano Zampini PetscSFOperationBegin(rootdata1,leafdata_whatever); 142*5b0d146aSStefano Zampini PetscSFOperationEnd(rootdata1,leafdata_whatever); 143*5b0d146aSStefano Zampini ... 144*5b0d146aSStefano Zampini PetscSFOperationBegin(rootdataN,leafdata_whatever); 145*5b0d146aSStefano Zampini PetscSFOperationEnd(rootdataN,leafdata_whatever); 146*5b0d146aSStefano Zampini endfor 147*5b0d146aSStefano Zampini The following pattern will instead raise an error 148*5b0d146aSStefano Zampini PetscSFOperationBegin(rootdata1,leafdata_whatever); 149*5b0d146aSStefano Zampini PetscSFOperationEnd(rootdata1,leafdata_whatever); 150*5b0d146aSStefano Zampini PetscSFOperationBegin(rank ? rootdata1 : rootdata2,leafdata_whatever); 151*5b0d146aSStefano Zampini PetscSFOperationEnd(rank ? rootdata1 : rootdata2,leafdata_whatever); 152*5b0d146aSStefano Zampini 153*5b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_ALLOCATE: uses MPI_Win_allocate, reuses any pre-existing window which fits the data and it is not in use 154*5b0d146aSStefano Zampini 155*5b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_SHARED: uses MPI_Win_allocate_shared, reusage policy as for PETSCSF_WINDOW_FLAVOR_ALLOCATE 156*5b0d146aSStefano Zampini 157*5b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowGetFlavorType() 158*5b0d146aSStefano Zampini @*/ 159*5b0d146aSStefano Zampini PetscErrorCode PetscSFWindowSetFlavorType(PetscSF sf,PetscSFWindowFlavorType flavor) 160*5b0d146aSStefano Zampini { 161*5b0d146aSStefano Zampini PetscErrorCode ierr; 162*5b0d146aSStefano Zampini 163*5b0d146aSStefano Zampini PetscFunctionBegin; 164*5b0d146aSStefano Zampini PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 165*5b0d146aSStefano Zampini PetscValidLogicalCollectiveEnum(sf,flavor,2); 166*5b0d146aSStefano Zampini ierr = PetscTryMethod(sf,"PetscSFWindowSetFlavorType_C",(PetscSF,PetscSFWindowFlavorType),(sf,flavor));CHKERRQ(ierr); 167*5b0d146aSStefano Zampini PetscFunctionReturn(0); 168*5b0d146aSStefano Zampini } 169*5b0d146aSStefano Zampini 170*5b0d146aSStefano Zampini static PetscErrorCode PetscSFWindowSetFlavorType_Window(PetscSF sf,PetscSFWindowFlavorType flavor) 171*5b0d146aSStefano Zampini { 172*5b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 173*5b0d146aSStefano Zampini 174*5b0d146aSStefano Zampini PetscFunctionBegin; 175*5b0d146aSStefano Zampini w->flavor = flavor; 176*5b0d146aSStefano Zampini PetscFunctionReturn(0); 177*5b0d146aSStefano Zampini } 178*5b0d146aSStefano Zampini 179*5b0d146aSStefano Zampini /*@C 180*5b0d146aSStefano Zampini PetscSFWindowGetFlavorType - Get flavor type for PetscSF communication 181*5b0d146aSStefano Zampini 182*5b0d146aSStefano Zampini Logically Collective 183*5b0d146aSStefano Zampini 184*5b0d146aSStefano Zampini Input Argument: 185*5b0d146aSStefano Zampini . sf - star forest for communication 186*5b0d146aSStefano Zampini 187*5b0d146aSStefano Zampini Output Argument: 188*5b0d146aSStefano Zampini . flavor - flavor type 189*5b0d146aSStefano Zampini 190*5b0d146aSStefano Zampini Level: advanced 191*5b0d146aSStefano Zampini 192*5b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowSetFlavorType() 193*5b0d146aSStefano Zampini @*/ 194*5b0d146aSStefano Zampini PetscErrorCode PetscSFWindowGetFlavorType(PetscSF sf,PetscSFWindowFlavorType *flavor) 195*5b0d146aSStefano Zampini { 196*5b0d146aSStefano Zampini PetscErrorCode ierr; 197*5b0d146aSStefano Zampini 198*5b0d146aSStefano Zampini PetscFunctionBegin; 199*5b0d146aSStefano Zampini PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 200*5b0d146aSStefano Zampini PetscValidPointer(flavor,2); 201*5b0d146aSStefano Zampini ierr = PetscUseMethod(sf,"PetscSFWindowGetFlavorType_C",(PetscSF,PetscSFWindowFlavorType*),(sf,flavor));CHKERRQ(ierr); 202*5b0d146aSStefano Zampini PetscFunctionReturn(0); 203*5b0d146aSStefano Zampini } 204*5b0d146aSStefano Zampini 205*5b0d146aSStefano Zampini static PetscErrorCode PetscSFWindowGetFlavorType_Window(PetscSF sf,PetscSFWindowFlavorType *flavor) 206*5b0d146aSStefano Zampini { 207*5b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 208*5b0d146aSStefano Zampini 209*5b0d146aSStefano Zampini PetscFunctionBegin; 210*5b0d146aSStefano Zampini *flavor = w->flavor; 211*5b0d146aSStefano Zampini PetscFunctionReturn(0); 212*5b0d146aSStefano Zampini } 213*5b0d146aSStefano Zampini 214*5b0d146aSStefano Zampini /*@C 215*5b0d146aSStefano Zampini PetscSFWindowSetSyncType - Set synchronization type for PetscSF communication 21695fce210SBarry Smith 21795fce210SBarry Smith Logically Collective 21895fce210SBarry Smith 21995fce210SBarry Smith Input Arguments: 22095fce210SBarry Smith + sf - star forest for communication 22195fce210SBarry Smith - sync - synchronization type 22295fce210SBarry Smith 22395fce210SBarry Smith Options Database Key: 22460263706SJed Brown . -sf_window_sync <sync> - sets the synchronization type FENCE, LOCK, or ACTIVE (see PetscSFWindowSyncType) 22595fce210SBarry Smith 22695fce210SBarry Smith Level: advanced 22795fce210SBarry Smith 22895fce210SBarry Smith .seealso: PetscSFSetFromOptions(), PetscSFWindowGetSyncType() 22995fce210SBarry Smith @*/ 23095fce210SBarry Smith PetscErrorCode PetscSFWindowSetSyncType(PetscSF sf,PetscSFWindowSyncType sync) 23195fce210SBarry Smith { 23295fce210SBarry Smith PetscErrorCode ierr; 23395fce210SBarry Smith 23495fce210SBarry Smith PetscFunctionBegin; 23595fce210SBarry Smith PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 23695fce210SBarry Smith PetscValidLogicalCollectiveEnum(sf,sync,2); 237*5b0d146aSStefano Zampini ierr = PetscTryMethod(sf,"PetscSFWindowSetSyncType_C",(PetscSF,PetscSFWindowSyncType),(sf,sync));CHKERRQ(ierr); 23895fce210SBarry Smith PetscFunctionReturn(0); 23995fce210SBarry Smith } 24095fce210SBarry Smith 241f7a08781SBarry Smith static PetscErrorCode PetscSFWindowSetSyncType_Window(PetscSF sf,PetscSFWindowSyncType sync) 24295fce210SBarry Smith { 24395fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 24495fce210SBarry Smith 24595fce210SBarry Smith PetscFunctionBegin; 24695fce210SBarry Smith w->sync = sync; 24795fce210SBarry Smith PetscFunctionReturn(0); 24895fce210SBarry Smith } 24995fce210SBarry Smith 25095fce210SBarry Smith /*@C 251*5b0d146aSStefano Zampini PetscSFWindowGetSyncType - Get synchronization type for PetscSF communication 25295fce210SBarry Smith 25395fce210SBarry Smith Logically Collective 25495fce210SBarry Smith 25595fce210SBarry Smith Input Argument: 25695fce210SBarry Smith . sf - star forest for communication 25795fce210SBarry Smith 25895fce210SBarry Smith Output Argument: 25995fce210SBarry Smith . sync - synchronization type 26095fce210SBarry Smith 26195fce210SBarry Smith Level: advanced 26295fce210SBarry Smith 263*5b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowSetSyncType() 26495fce210SBarry Smith @*/ 26595fce210SBarry Smith PetscErrorCode PetscSFWindowGetSyncType(PetscSF sf,PetscSFWindowSyncType *sync) 26695fce210SBarry Smith { 26795fce210SBarry Smith PetscErrorCode ierr; 26895fce210SBarry Smith 26995fce210SBarry Smith PetscFunctionBegin; 27095fce210SBarry Smith PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 27195fce210SBarry Smith PetscValidPointer(sync,2); 272163d334eSBarry Smith ierr = PetscUseMethod(sf,"PetscSFWindowGetSyncType_C",(PetscSF,PetscSFWindowSyncType*),(sf,sync));CHKERRQ(ierr); 27395fce210SBarry Smith PetscFunctionReturn(0); 27495fce210SBarry Smith } 27595fce210SBarry Smith 276f7a08781SBarry Smith static PetscErrorCode PetscSFWindowGetSyncType_Window(PetscSF sf,PetscSFWindowSyncType *sync) 27795fce210SBarry Smith { 27895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 27995fce210SBarry Smith 28095fce210SBarry Smith PetscFunctionBegin; 28195fce210SBarry Smith *sync = w->sync; 28295fce210SBarry Smith PetscFunctionReturn(0); 28395fce210SBarry Smith } 28495fce210SBarry Smith 28595fce210SBarry Smith /*@C 286*5b0d146aSStefano Zampini PetscSFWindowSetInfo - Set the MPI_Info handle that will be used for subsequent windows allocation 287*5b0d146aSStefano Zampini 288*5b0d146aSStefano Zampini Logically Collective 289*5b0d146aSStefano Zampini 290*5b0d146aSStefano Zampini Input Argument: 291*5b0d146aSStefano Zampini + sf - star forest for communication 292*5b0d146aSStefano Zampini - info - MPI_Info handle 293*5b0d146aSStefano Zampini 294*5b0d146aSStefano Zampini Level: advanced 295*5b0d146aSStefano Zampini 296*5b0d146aSStefano Zampini Notes: the info handle is duplicated with a call to MPI_Info_dup unless info = MPI_INFO_NULL. 297*5b0d146aSStefano Zampini 298*5b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowGetInfo() 299*5b0d146aSStefano Zampini @*/ 300*5b0d146aSStefano Zampini PetscErrorCode PetscSFWindowSetInfo(PetscSF sf,MPI_Info info) 301*5b0d146aSStefano Zampini { 302*5b0d146aSStefano Zampini PetscErrorCode ierr; 303*5b0d146aSStefano Zampini 304*5b0d146aSStefano Zampini PetscFunctionBegin; 305*5b0d146aSStefano Zampini PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 306*5b0d146aSStefano Zampini ierr = PetscTryMethod(sf,"PetscSFWindowSetInfo_C",(PetscSF,MPI_Info),(sf,info));CHKERRQ(ierr); 307*5b0d146aSStefano Zampini PetscFunctionReturn(0); 308*5b0d146aSStefano Zampini } 309*5b0d146aSStefano Zampini 310*5b0d146aSStefano Zampini static PetscErrorCode PetscSFWindowSetInfo_Window(PetscSF sf,MPI_Info info) 311*5b0d146aSStefano Zampini { 312*5b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 313*5b0d146aSStefano Zampini PetscErrorCode ierr; 314*5b0d146aSStefano Zampini 315*5b0d146aSStefano Zampini PetscFunctionBegin; 316*5b0d146aSStefano Zampini if (w->info != MPI_INFO_NULL) { 317*5b0d146aSStefano Zampini ierr = MPI_Info_free(&w->info);CHKERRQ(ierr); 318*5b0d146aSStefano Zampini } 319*5b0d146aSStefano Zampini if (info != MPI_INFO_NULL) { 320*5b0d146aSStefano Zampini ierr = MPI_Info_dup(info,&w->info);CHKERRQ(ierr); 321*5b0d146aSStefano Zampini } 322*5b0d146aSStefano Zampini PetscFunctionReturn(0); 323*5b0d146aSStefano Zampini } 324*5b0d146aSStefano Zampini 325*5b0d146aSStefano Zampini /*@C 326*5b0d146aSStefano Zampini PetscSFWindowGetInfo - Get the MPI_Info handle used for windows allocation 327*5b0d146aSStefano Zampini 328*5b0d146aSStefano Zampini Logically Collective 329*5b0d146aSStefano Zampini 330*5b0d146aSStefano Zampini Input Argument: 331*5b0d146aSStefano Zampini . sf - star forest for communication 332*5b0d146aSStefano Zampini 333*5b0d146aSStefano Zampini Output Argument: 334*5b0d146aSStefano Zampini . info - MPI_Info handle 335*5b0d146aSStefano Zampini 336*5b0d146aSStefano Zampini Level: advanced 337*5b0d146aSStefano Zampini 338*5b0d146aSStefano Zampini Notes: if PetscSFWindowSetInfo() has not be called, this returns MPI_INFO_NULL 339*5b0d146aSStefano Zampini 340*5b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowSetInfo() 341*5b0d146aSStefano Zampini @*/ 342*5b0d146aSStefano Zampini PetscErrorCode PetscSFWindowGetInfo(PetscSF sf,MPI_Info *info) 343*5b0d146aSStefano Zampini { 344*5b0d146aSStefano Zampini PetscErrorCode ierr; 345*5b0d146aSStefano Zampini 346*5b0d146aSStefano Zampini PetscFunctionBegin; 347*5b0d146aSStefano Zampini PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 348*5b0d146aSStefano Zampini PetscValidPointer(info,2); 349*5b0d146aSStefano Zampini ierr = PetscUseMethod(sf,"PetscSFWindowGetInfo_C",(PetscSF,MPI_Info*),(sf,info));CHKERRQ(ierr); 350*5b0d146aSStefano Zampini PetscFunctionReturn(0); 351*5b0d146aSStefano Zampini } 352*5b0d146aSStefano Zampini 353*5b0d146aSStefano Zampini static PetscErrorCode PetscSFWindowGetInfo_Window(PetscSF sf,MPI_Info *info) 354*5b0d146aSStefano Zampini { 355*5b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 356*5b0d146aSStefano Zampini 357*5b0d146aSStefano Zampini PetscFunctionBegin; 358*5b0d146aSStefano Zampini *info = w->info; 359*5b0d146aSStefano Zampini PetscFunctionReturn(0); 360*5b0d146aSStefano Zampini } 361*5b0d146aSStefano Zampini 362*5b0d146aSStefano Zampini /* 36395fce210SBarry Smith PetscSFGetWindow - Get a window for use with a given data type 36495fce210SBarry Smith 36595fce210SBarry Smith Collective on PetscSF 36695fce210SBarry Smith 36795fce210SBarry Smith Input Arguments: 36895fce210SBarry Smith + sf - star forest 36995fce210SBarry Smith . unit - data type 37095fce210SBarry Smith . array - array to be sent 371*5b0d146aSStefano Zampini . sync - type of synchronization PetscSFWindowSyncType 37295fce210SBarry Smith . epoch - PETSC_TRUE to acquire the window and start an epoch, PETSC_FALSE to just acquire the window 373*5b0d146aSStefano Zampini . fenceassert - assert parameter for call to MPI_Win_fence(), if sync == PETSCSF_WINDOW_SYNC_FENCE 374*5b0d146aSStefano Zampini . postassert - assert parameter for call to MPI_Win_post(), if sync == PETSCSF_WINDOW_SYNC_ACTIVE 375*5b0d146aSStefano Zampini . startassert - assert parameter for call to MPI_Win_start(), if sync == PETSCSF_WINDOW_SYNC_ACTIVE 376*5b0d146aSStefano Zampini - target_disp - target_disp argument to RMA calls (significative for PETSCSF_WINDOW_FLAVOR_DYNAMIC flavor only) 37795fce210SBarry Smith 37895fce210SBarry Smith Output Arguments: 37995fce210SBarry Smith . win - window 38095fce210SBarry Smith 38195fce210SBarry Smith Level: developer 382dec1416fSJunchao Zhang .seealso: PetscSFGetRootRanks(), PetscSFWindowGetDataTypes() 383*5b0d146aSStefano Zampini */ 384*5b0d146aSStefano Zampini static PetscErrorCode PetscSFGetWindow(PetscSF sf,MPI_Datatype unit,void *array,PetscSFWindowSyncType sync,PetscBool epoch,PetscMPIInt fenceassert,PetscMPIInt postassert,PetscMPIInt startassert,const MPI_Aint **target_disp, MPI_Win *win) 38595fce210SBarry Smith { 38695fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 38795fce210SBarry Smith PetscErrorCode ierr; 38895fce210SBarry Smith MPI_Aint lb,lb_true,bytes,bytes_true; 38995fce210SBarry Smith PetscSFWinLink link; 390*5b0d146aSStefano Zampini MPI_Aint winaddr; 391*5b0d146aSStefano Zampini PetscInt nranks; 392*5b0d146aSStefano Zampini PetscBool reuse = PETSC_FALSE, update = PETSC_FALSE; 393*5b0d146aSStefano Zampini #if defined(PETSC_USE_DEBUG) 394*5b0d146aSStefano Zampini PetscBool dummy[2]; 395*5b0d146aSStefano Zampini #endif 396*5b0d146aSStefano Zampini MPI_Aint wsize; 39795fce210SBarry Smith 39895fce210SBarry Smith PetscFunctionBegin; 39995fce210SBarry Smith ierr = MPI_Type_get_extent(unit,&lb,&bytes);CHKERRQ(ierr); 40095fce210SBarry Smith ierr = MPI_Type_get_true_extent(unit,&lb_true,&bytes_true);CHKERRQ(ierr); 40195fce210SBarry Smith if (lb != 0 || lb_true != 0) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"No support for unit type with nonzero lower bound, write petsc-maint@mcs.anl.gov if you want this feature"); 40295fce210SBarry Smith if (bytes != bytes_true) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"No support for unit type with modified extent, write petsc-maint@mcs.anl.gov if you want this feature"); 403*5b0d146aSStefano Zampini if (w->flavor != PETSCSF_WINDOW_FLAVOR_CREATE) reuse = PETSC_TRUE; 404*5b0d146aSStefano Zampini for (link=w->wins; reuse && link; link=link->next) { 405*5b0d146aSStefano Zampini PetscBool winok = PETSC_FALSE; 406*5b0d146aSStefano Zampini if (w->flavor != link->flavor) continue; 407*5b0d146aSStefano Zampini switch (w->flavor) { 408*5b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_DYNAMIC: /* check available matching array, error if in use (we additionally check that the matching condition is the same across processes) */ 409*5b0d146aSStefano Zampini if (array == link->addr) { 410*5b0d146aSStefano Zampini #if defined(PETSC_USE_DEBUG) 411*5b0d146aSStefano Zampini dummy[0] = PETSC_TRUE; 412*5b0d146aSStefano Zampini dummy[1] = PETSC_TRUE; 413*5b0d146aSStefano Zampini ierr = MPI_Allreduce(MPI_IN_PLACE,dummy ,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 414*5b0d146aSStefano Zampini ierr = MPI_Allreduce(MPI_IN_PLACE,dummy+1,1,MPIU_BOOL,MPI_LOR ,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 415*5b0d146aSStefano Zampini if (dummy[0] != dummy[1]) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"PETSCSF_WINDOW_FLAVOR_DYNAMIC requires root pointers to be consistently used across the comm. Use PETSCSF_WINDOW_FLAVOR_CREATE or PETSCSF_WINDOW_FLAVOR_ALLOCATE instead"); 416*5b0d146aSStefano Zampini #endif 417*5b0d146aSStefano Zampini if (link->inuse) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_PLIB,"Window in use"); 418*5b0d146aSStefano Zampini if (epoch && link->epoch) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_PLIB,"Window epoch not finished"); 419*5b0d146aSStefano Zampini winok = PETSC_TRUE; 420*5b0d146aSStefano Zampini link->paddr = array; 421*5b0d146aSStefano Zampini #if defined(PETSC_USE_DEBUG) 422*5b0d146aSStefano Zampini } else { 423*5b0d146aSStefano Zampini dummy[0] = PETSC_FALSE; 424*5b0d146aSStefano Zampini dummy[1] = PETSC_FALSE; 425*5b0d146aSStefano Zampini ierr = MPI_Allreduce(MPI_IN_PLACE,dummy ,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 426*5b0d146aSStefano Zampini ierr = MPI_Allreduce(MPI_IN_PLACE,dummy+1,1,MPIU_BOOL,MPI_LOR ,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 427*5b0d146aSStefano Zampini if (dummy[0] != dummy[1]) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"PETSCSF_WINDOW_FLAVOR_DYNAMIC requires root pointers to be consistently used across the comm. Use PETSCSF_WINDOW_FLAVOR_CREATE or PETSCSF_WINDOW_FLAVOR_ALLOCATE instead"); 428*5b0d146aSStefano Zampini #endif 429*5b0d146aSStefano Zampini } 430*5b0d146aSStefano Zampini break; 431*5b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_ALLOCATE: /* check available by matching size, allocate if in use */ 432*5b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_SHARED: 433*5b0d146aSStefano Zampini if (!link->inuse && bytes == (MPI_Aint)link->bytes) { 434*5b0d146aSStefano Zampini update = PETSC_TRUE; 435*5b0d146aSStefano Zampini link->paddr = array; 436*5b0d146aSStefano Zampini winok = PETSC_TRUE; 437*5b0d146aSStefano Zampini } 438*5b0d146aSStefano Zampini break; 439*5b0d146aSStefano Zampini default: SETERRQ1(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"No support for flavor %s",PetscSFWindowFlavorTypes[w->flavor]); 440*5b0d146aSStefano Zampini } 441*5b0d146aSStefano Zampini if (winok) { 442*5b0d146aSStefano Zampini *win = link->win; 443*5b0d146aSStefano Zampini ierr = PetscInfo3(sf,"Reusing window %d of flavor %d for comm %d\n",link->win,link->flavor,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 444*5b0d146aSStefano Zampini goto found; 445*5b0d146aSStefano Zampini } 446*5b0d146aSStefano Zampini } 447*5b0d146aSStefano Zampini 448*5b0d146aSStefano Zampini wsize = (MPI_Aint)bytes*sf->nroots; 44995dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 45095fce210SBarry Smith link->bytes = bytes; 45195fce210SBarry Smith link->next = w->wins; 452*5b0d146aSStefano Zampini link->flavor = w->flavor; 453*5b0d146aSStefano Zampini link->dyn_target_addr = NULL; 45495fce210SBarry Smith w->wins = link; 455*5b0d146aSStefano Zampini switch (w->flavor) { 456*5b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_CREATE: 457*5b0d146aSStefano Zampini ierr = MPI_Win_create(array,wsize,(PetscMPIInt)bytes,w->info,PetscObjectComm((PetscObject)sf),&link->win);CHKERRQ(ierr); 458*5b0d146aSStefano Zampini link->addr = array; 459*5b0d146aSStefano Zampini link->paddr = array; 460*5b0d146aSStefano Zampini break; 461*5b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_DYNAMIC: 462*5b0d146aSStefano Zampini ierr = MPI_Win_create_dynamic(w->info,PetscObjectComm((PetscObject)sf),&link->win);CHKERRQ(ierr); 463*5b0d146aSStefano Zampini #if defined(PETSC_HAVE_OMPI_MAJOR_VERSION) /* some OpenMPI versions do not support MPI_Win_attach(win,NULL,0); */ 464*5b0d146aSStefano Zampini ierr = MPI_Win_attach(link->win,wsize ? array : &ierr,wsize);CHKERRQ(ierr); 465*5b0d146aSStefano Zampini #else 466*5b0d146aSStefano Zampini ierr = MPI_Win_attach(link->win,array,wsize);CHKERRQ(ierr); 467*5b0d146aSStefano Zampini #endif 468*5b0d146aSStefano Zampini link->addr = array; 469*5b0d146aSStefano Zampini link->paddr = array; 470*5b0d146aSStefano Zampini if (!w->dynsf) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_ORDER,"Must call PetscSFSetUp()"); 471*5b0d146aSStefano Zampini ierr = PetscSFSetUp(w->dynsf);CHKERRQ(ierr); 472*5b0d146aSStefano Zampini ierr = PetscSFGetRootRanks(w->dynsf,&nranks,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 473*5b0d146aSStefano Zampini ierr = PetscMalloc1(nranks,&link->dyn_target_addr);CHKERRQ(ierr); 474*5b0d146aSStefano Zampini ierr = MPI_Get_address(array,&winaddr);CHKERRQ(ierr); 475*5b0d146aSStefano Zampini ierr = PetscSFBcastBegin(w->dynsf,MPI_AINT,&winaddr,link->dyn_target_addr);CHKERRQ(ierr); 476*5b0d146aSStefano Zampini ierr = PetscSFBcastEnd(w->dynsf,MPI_AINT,&winaddr,link->dyn_target_addr);CHKERRQ(ierr); 477*5b0d146aSStefano Zampini break; 478*5b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_ALLOCATE: 479*5b0d146aSStefano Zampini ierr = MPI_Win_allocate(wsize,(PetscMPIInt)bytes,w->info,PetscObjectComm((PetscObject)sf),&link->addr,&link->win);CHKERRQ(ierr); 480*5b0d146aSStefano Zampini update = PETSC_TRUE; 481*5b0d146aSStefano Zampini link->paddr = array; 482*5b0d146aSStefano Zampini break; 483*5b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 484*5b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_SHARED: 485*5b0d146aSStefano Zampini ierr = MPI_Win_allocate_shared(wsize,(PetscMPIInt)bytes,w->info,PetscObjectComm((PetscObject)sf),&link->addr,&link->win);CHKERRQ(ierr); 486*5b0d146aSStefano Zampini update = PETSC_TRUE; 487*5b0d146aSStefano Zampini link->paddr = array; 488*5b0d146aSStefano Zampini break; 489*5b0d146aSStefano Zampini #endif 490*5b0d146aSStefano Zampini default: SETERRQ1(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"No support for flavor %s",PetscSFWindowFlavorTypes[w->flavor]); 491*5b0d146aSStefano Zampini } 492*5b0d146aSStefano Zampini ierr = PetscInfo3(sf,"New window %d of flavor %d for comm %d\n",link->win,link->flavor,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 49395fce210SBarry Smith *win = link->win; 49495fce210SBarry Smith 495*5b0d146aSStefano Zampini found: 496*5b0d146aSStefano Zampini 497*5b0d146aSStefano Zampini if (update) { 498*5b0d146aSStefano Zampini ierr = PetscMemcpy(link->addr,array,sf->nroots*bytes);CHKERRQ(ierr); 499*5b0d146aSStefano Zampini if (sync == PETSCSF_WINDOW_SYNC_LOCK) { 500*5b0d146aSStefano Zampini ierr = MPI_Win_fence(0,*win);CHKERRQ(ierr); 501*5b0d146aSStefano Zampini } 502*5b0d146aSStefano Zampini } 503*5b0d146aSStefano Zampini link->inuse = PETSC_TRUE; 504*5b0d146aSStefano Zampini link->epoch = epoch; 505*5b0d146aSStefano Zampini *target_disp = link->dyn_target_addr; 50695fce210SBarry Smith if (epoch) { 507*5b0d146aSStefano Zampini switch (sync) { 50895fce210SBarry Smith case PETSCSF_WINDOW_SYNC_FENCE: 50995fce210SBarry Smith ierr = MPI_Win_fence(fenceassert,*win);CHKERRQ(ierr); 51095fce210SBarry Smith break; 51195fce210SBarry Smith case PETSCSF_WINDOW_SYNC_LOCK: /* Handled outside */ 51295fce210SBarry Smith break; 51395fce210SBarry Smith case PETSCSF_WINDOW_SYNC_ACTIVE: { 51495fce210SBarry Smith MPI_Group ingroup,outgroup; 515*5b0d146aSStefano Zampini PetscMPIInt isize,osize; 516*5b0d146aSStefano Zampini 517*5b0d146aSStefano Zampini /* OpenMPI 4.0.2 with btl=vader does not like calling 518*5b0d146aSStefano Zampini - MPI_Win_complete when ogroup is empty 519*5b0d146aSStefano Zampini - MPI_Win_wait when igroup is empty 520*5b0d146aSStefano Zampini So, we do not even issue the corresponding start and post calls 521*5b0d146aSStefano Zampini The MPI standard (Sec. 11.5.2 of MPI 3.1) only requires that 522*5b0d146aSStefano Zampini start(outgroup) has a matching post(ingroup) 523*5b0d146aSStefano Zampini and this is guaranteed by PetscSF 524*5b0d146aSStefano Zampini */ 52595fce210SBarry Smith ierr = PetscSFGetGroups(sf,&ingroup,&outgroup);CHKERRQ(ierr); 526*5b0d146aSStefano Zampini ierr = MPI_Group_size(ingroup,&isize);CHKERRQ(ierr); 527*5b0d146aSStefano Zampini ierr = MPI_Group_size(outgroup,&osize);CHKERRQ(ierr); 528*5b0d146aSStefano Zampini if (isize) { ierr = MPI_Win_post(ingroup,postassert,*win);CHKERRQ(ierr); } 529*5b0d146aSStefano Zampini if (osize) { ierr = MPI_Win_start(outgroup,startassert,*win);CHKERRQ(ierr); } 53095fce210SBarry Smith } break; 53195fce210SBarry Smith default: SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_PLIB,"Unknown synchronization type"); 53295fce210SBarry Smith } 53395fce210SBarry Smith } 53495fce210SBarry Smith PetscFunctionReturn(0); 53595fce210SBarry Smith } 53695fce210SBarry Smith 537*5b0d146aSStefano Zampini /* 53895fce210SBarry Smith PetscSFFindWindow - Finds a window that is already in use 53995fce210SBarry Smith 54095fce210SBarry Smith Not Collective 54195fce210SBarry Smith 54295fce210SBarry Smith Input Arguments: 54395fce210SBarry Smith + sf - star forest 54495fce210SBarry Smith . unit - data type 54595fce210SBarry Smith - array - array with which the window is associated 54695fce210SBarry Smith 54795fce210SBarry Smith Output Arguments: 54895fce210SBarry Smith . win - window 54995fce210SBarry Smith 55095fce210SBarry Smith Level: developer 55195fce210SBarry Smith 55295fce210SBarry Smith .seealso: PetscSFGetWindow(), PetscSFRestoreWindow() 553*5b0d146aSStefano Zampini */ 55495fce210SBarry Smith static PetscErrorCode PetscSFFindWindow(PetscSF sf,MPI_Datatype unit,const void *array,MPI_Win *win) 55595fce210SBarry Smith { 55695fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 55795fce210SBarry Smith PetscSFWinLink link; 558*5b0d146aSStefano Zampini PetscErrorCode ierr; 55995fce210SBarry Smith 56095fce210SBarry Smith PetscFunctionBegin; 561c0cd0301SJed Brown *win = MPI_WIN_NULL; 56295fce210SBarry Smith for (link=w->wins; link; link=link->next) { 563*5b0d146aSStefano Zampini if (array == link->paddr) { 564*5b0d146aSStefano Zampini ierr = PetscInfo3(sf,"Window %d of flavor %d for comm %d\n",link->win,link->flavor,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 56595fce210SBarry Smith *win = link->win; 56695fce210SBarry Smith PetscFunctionReturn(0); 56795fce210SBarry Smith } 56895fce210SBarry Smith } 56995fce210SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Requested window not in use"); 57095fce210SBarry Smith PetscFunctionReturn(0); 57195fce210SBarry Smith } 57295fce210SBarry Smith 573*5b0d146aSStefano Zampini /* 57495fce210SBarry Smith PetscSFRestoreWindow - Restores a window obtained with PetscSFGetWindow() 57595fce210SBarry Smith 57695fce210SBarry Smith Collective 57795fce210SBarry Smith 57895fce210SBarry Smith Input Arguments: 57995fce210SBarry Smith + sf - star forest 58095fce210SBarry Smith . unit - data type 58195fce210SBarry Smith . array - array associated with window 582*5b0d146aSStefano Zampini . sync - type of synchronization PetscSFWindowSyncType 58395fce210SBarry Smith . epoch - close an epoch, must match argument to PetscSFGetWindow() 584*5b0d146aSStefano Zampini . update - if we have to update the local window array 58595fce210SBarry Smith - win - window 58695fce210SBarry Smith 58795fce210SBarry Smith Level: developer 58895fce210SBarry Smith 58995fce210SBarry Smith .seealso: PetscSFFindWindow() 590*5b0d146aSStefano Zampini */ 591*5b0d146aSStefano Zampini static PetscErrorCode PetscSFRestoreWindow(PetscSF sf,MPI_Datatype unit,void *array,PetscSFWindowSyncType sync,PetscBool epoch,PetscMPIInt fenceassert,PetscBool update,MPI_Win *win) 59295fce210SBarry Smith { 59395fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 59495fce210SBarry Smith PetscErrorCode ierr; 59595fce210SBarry Smith PetscSFWinLink *p,link; 596*5b0d146aSStefano Zampini PetscBool reuse = PETSC_FALSE; 597*5b0d146aSStefano Zampini PetscSFWindowFlavorType flavor; 598*5b0d146aSStefano Zampini void* laddr; 599*5b0d146aSStefano Zampini size_t bytes; 60095fce210SBarry Smith 60195fce210SBarry Smith PetscFunctionBegin; 60295fce210SBarry Smith for (p=&w->wins; *p; p=&(*p)->next) { 60395fce210SBarry Smith link = *p; 60495fce210SBarry Smith if (*win == link->win) { 605*5b0d146aSStefano Zampini if (array != link->paddr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Matched window, but not array"); 60695fce210SBarry Smith if (epoch != link->epoch) { 60795fce210SBarry Smith if (epoch) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"No epoch to end"); 60895fce210SBarry Smith else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Restoring window without ending epoch"); 60995fce210SBarry Smith } 610*5b0d146aSStefano Zampini laddr = link->addr; 611*5b0d146aSStefano Zampini flavor = link->flavor; 612*5b0d146aSStefano Zampini bytes = link->bytes; 613*5b0d146aSStefano Zampini if (flavor != PETSCSF_WINDOW_FLAVOR_CREATE) reuse = PETSC_TRUE; 614*5b0d146aSStefano Zampini else { *p = link->next; update = PETSC_FALSE; } /* remove from list */ 61595fce210SBarry Smith goto found; 61695fce210SBarry Smith } 61795fce210SBarry Smith } 61895fce210SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Requested window not in use"); 61995fce210SBarry Smith 62095fce210SBarry Smith found: 621*5b0d146aSStefano Zampini ierr = PetscInfo3(sf,"Window %d of flavor %d for comm %d\n",link->win,link->flavor,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 62295fce210SBarry Smith if (epoch) { 623*5b0d146aSStefano Zampini switch (sync) { 62495fce210SBarry Smith case PETSCSF_WINDOW_SYNC_FENCE: 62595fce210SBarry Smith ierr = MPI_Win_fence(fenceassert,*win);CHKERRQ(ierr); 62695fce210SBarry Smith break; 627*5b0d146aSStefano Zampini case PETSCSF_WINDOW_SYNC_LOCK: /* Handled outside */ 628*5b0d146aSStefano Zampini break; 62995fce210SBarry Smith case PETSCSF_WINDOW_SYNC_ACTIVE: { 630*5b0d146aSStefano Zampini MPI_Group ingroup,outgroup; 631*5b0d146aSStefano Zampini PetscMPIInt isize,osize; 632*5b0d146aSStefano Zampini 633*5b0d146aSStefano Zampini /* OpenMPI 4.0.2 with btl=wader does not like calling 634*5b0d146aSStefano Zampini - MPI_Win_complete when ogroup is empty 635*5b0d146aSStefano Zampini - MPI_Win_wait when igroup is empty 636*5b0d146aSStefano Zampini The MPI standard (Sec. 11.5.2 of MPI 3.1) only requires that 637*5b0d146aSStefano Zampini - each process who issues a call to MPI_Win_start issues a call to MPI_Win_Complete 638*5b0d146aSStefano Zampini - each process who issues a call to MPI_Win_post issues a call to MPI_Win_Wait 639*5b0d146aSStefano Zampini */ 640*5b0d146aSStefano Zampini ierr = PetscSFGetGroups(sf,&ingroup,&outgroup);CHKERRQ(ierr); 641*5b0d146aSStefano Zampini ierr = MPI_Group_size(ingroup,&isize);CHKERRQ(ierr); 642*5b0d146aSStefano Zampini ierr = MPI_Group_size(outgroup,&osize);CHKERRQ(ierr); 643*5b0d146aSStefano Zampini if (osize) { ierr = MPI_Win_complete(*win);CHKERRQ(ierr); } 644*5b0d146aSStefano Zampini if (isize) { ierr = MPI_Win_wait(*win);CHKERRQ(ierr); } 64595fce210SBarry Smith } break; 64695fce210SBarry Smith default: SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_PLIB,"Unknown synchronization type"); 64795fce210SBarry Smith } 64895fce210SBarry Smith } 649*5b0d146aSStefano Zampini if (update) { 650*5b0d146aSStefano Zampini if (sync == PETSCSF_WINDOW_SYNC_LOCK) { 651*5b0d146aSStefano Zampini ierr = MPI_Win_fence(MPI_MODE_NOPUT|MPI_MODE_NOSUCCEED,*win);CHKERRQ(ierr); 652*5b0d146aSStefano Zampini } 653*5b0d146aSStefano Zampini ierr = PetscMemcpy(array,laddr,sf->nroots*bytes);CHKERRQ(ierr); 654*5b0d146aSStefano Zampini } 655*5b0d146aSStefano Zampini link->epoch = PETSC_FALSE; 656*5b0d146aSStefano Zampini link->inuse = PETSC_FALSE; 657*5b0d146aSStefano Zampini link->paddr = NULL; 658*5b0d146aSStefano Zampini if (!reuse) { 65995fce210SBarry Smith ierr = MPI_Win_free(&link->win);CHKERRQ(ierr); 66095fce210SBarry Smith ierr = PetscFree(link);CHKERRQ(ierr); 66195fce210SBarry Smith *win = MPI_WIN_NULL; 662*5b0d146aSStefano Zampini } 66395fce210SBarry Smith PetscFunctionReturn(0); 66495fce210SBarry Smith } 66595fce210SBarry Smith 66695fce210SBarry Smith static PetscErrorCode PetscSFSetUp_Window(PetscSF sf) 66795fce210SBarry Smith { 66895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 66995fce210SBarry Smith PetscErrorCode ierr; 67095fce210SBarry Smith MPI_Group ingroup,outgroup; 67195fce210SBarry Smith 67295fce210SBarry Smith PetscFunctionBegin; 673b5a8e515SJed Brown ierr = PetscSFSetUpRanks(sf,MPI_GROUP_EMPTY);CHKERRQ(ierr); 674*5b0d146aSStefano Zampini if (!w->dynsf) { 675*5b0d146aSStefano Zampini PetscInt i; 676*5b0d146aSStefano Zampini PetscSFNode *remotes; 677*5b0d146aSStefano Zampini 678*5b0d146aSStefano Zampini ierr = PetscMalloc1(sf->nranks,&remotes);CHKERRQ(ierr); 679*5b0d146aSStefano Zampini for (i=0;i<sf->nranks;i++) { 680*5b0d146aSStefano Zampini remotes[i].rank = sf->ranks[i]; 681*5b0d146aSStefano Zampini remotes[i].index = 0; 682*5b0d146aSStefano Zampini } 683*5b0d146aSStefano Zampini ierr = PetscSFDuplicate(sf,PETSCSF_DUPLICATE_RANKS,&w->dynsf);CHKERRQ(ierr); 684*5b0d146aSStefano Zampini ierr = PetscSFWindowSetFlavorType(w->dynsf,PETSCSF_WINDOW_FLAVOR_CREATE);CHKERRQ(ierr); /* break recursion */ 685*5b0d146aSStefano Zampini ierr = PetscSFSetGraph(w->dynsf,1,sf->nranks,NULL,PETSC_OWN_POINTER,remotes,PETSC_OWN_POINTER);CHKERRQ(ierr); 686*5b0d146aSStefano Zampini ierr = PetscLogObjectParent((PetscObject)sf,(PetscObject)w->dynsf);CHKERRQ(ierr); 687*5b0d146aSStefano Zampini } 68895fce210SBarry Smith switch (w->sync) { 68995fce210SBarry Smith case PETSCSF_WINDOW_SYNC_ACTIVE: 69095fce210SBarry Smith ierr = PetscSFGetGroups(sf,&ingroup,&outgroup);CHKERRQ(ierr); 69195fce210SBarry Smith default: 69295fce210SBarry Smith break; 69395fce210SBarry Smith } 69495fce210SBarry Smith PetscFunctionReturn(0); 69595fce210SBarry Smith } 69695fce210SBarry Smith 6974416b707SBarry Smith static PetscErrorCode PetscSFSetFromOptions_Window(PetscOptionItems *PetscOptionsObject,PetscSF sf) 69895fce210SBarry Smith { 69995fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 70095fce210SBarry Smith PetscErrorCode ierr; 701*5b0d146aSStefano Zampini PetscSFWindowFlavorType flavor = w->flavor; 70295fce210SBarry Smith 70395fce210SBarry Smith PetscFunctionBegin; 704e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"PetscSF Window options");CHKERRQ(ierr); 70595fce210SBarry Smith ierr = PetscOptionsEnum("-sf_window_sync","synchronization type to use for PetscSF Window communication","PetscSFWindowSetSyncType",PetscSFWindowSyncTypes,(PetscEnum)w->sync,(PetscEnum*)&w->sync,NULL);CHKERRQ(ierr); 706*5b0d146aSStefano Zampini ierr = PetscOptionsEnum("-sf_window_flavor","flavor to use for PetscSF Window creation","PetscSFWindowSetFlavorType",PetscSFWindowFlavorTypes,(PetscEnum)flavor,(PetscEnum*)&flavor,NULL);CHKERRQ(ierr); 707*5b0d146aSStefano Zampini ierr = PetscSFWindowSetFlavorType(sf,flavor);CHKERRQ(ierr); 70895fce210SBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 70995fce210SBarry Smith PetscFunctionReturn(0); 71095fce210SBarry Smith } 71195fce210SBarry Smith 71295fce210SBarry Smith static PetscErrorCode PetscSFReset_Window(PetscSF sf) 71395fce210SBarry Smith { 71495fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 71595fce210SBarry Smith PetscErrorCode ierr; 71695fce210SBarry Smith PetscSFDataLink link,next; 71795fce210SBarry Smith PetscSFWinLink wlink,wnext; 71895fce210SBarry Smith PetscInt i; 71995fce210SBarry Smith 72095fce210SBarry Smith PetscFunctionBegin; 72195fce210SBarry Smith for (link=w->link; link; link=next) { 72295fce210SBarry Smith next = link->next; 72395fce210SBarry Smith ierr = MPI_Type_free(&link->unit);CHKERRQ(ierr); 72495fce210SBarry Smith for (i=0; i<sf->nranks; i++) { 72595fce210SBarry Smith ierr = MPI_Type_free(&link->mine[i]);CHKERRQ(ierr); 72695fce210SBarry Smith ierr = MPI_Type_free(&link->remote[i]);CHKERRQ(ierr); 72795fce210SBarry Smith } 72895fce210SBarry Smith ierr = PetscFree2(link->mine,link->remote);CHKERRQ(ierr); 72995fce210SBarry Smith ierr = PetscFree(link);CHKERRQ(ierr); 73095fce210SBarry Smith } 73195fce210SBarry Smith w->link = NULL; 73295fce210SBarry Smith for (wlink=w->wins; wlink; wlink=wnext) { 73395fce210SBarry Smith wnext = wlink->next; 73495fce210SBarry Smith if (wlink->inuse) SETERRQ1(PetscObjectComm((PetscObject)sf),PETSC_ERR_ARG_WRONGSTATE,"Window still in use with address %p",(void*)wlink->addr); 735*5b0d146aSStefano Zampini ierr = PetscFree(wlink->dyn_target_addr);CHKERRQ(ierr); 73695fce210SBarry Smith ierr = MPI_Win_free(&wlink->win);CHKERRQ(ierr); 73795fce210SBarry Smith ierr = PetscFree(wlink);CHKERRQ(ierr); 73895fce210SBarry Smith } 73995fce210SBarry Smith w->wins = NULL; 740*5b0d146aSStefano Zampini ierr = PetscSFDestroy(&w->dynsf);CHKERRQ(ierr); 741*5b0d146aSStefano Zampini if (w->info != MPI_INFO_NULL) { 742*5b0d146aSStefano Zampini ierr = MPI_Info_free(&w->info);CHKERRQ(ierr); 743*5b0d146aSStefano Zampini } 74495fce210SBarry Smith PetscFunctionReturn(0); 74595fce210SBarry Smith } 74695fce210SBarry Smith 74795fce210SBarry Smith static PetscErrorCode PetscSFDestroy_Window(PetscSF sf) 74895fce210SBarry Smith { 74995fce210SBarry Smith PetscErrorCode ierr; 75095fce210SBarry Smith 75195fce210SBarry Smith PetscFunctionBegin; 75229046d53SLisandro Dalcin ierr = PetscSFReset_Window(sf);CHKERRQ(ierr); 75395fce210SBarry Smith ierr = PetscFree(sf->data);CHKERRQ(ierr); 754bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetSyncType_C",NULL);CHKERRQ(ierr); 755bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetSyncType_C",NULL);CHKERRQ(ierr); 756*5b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetFlavorType_C",NULL);CHKERRQ(ierr); 757*5b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetFlavorType_C",NULL);CHKERRQ(ierr); 758*5b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetInfo_C",NULL);CHKERRQ(ierr); 759*5b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetInfo_C",NULL);CHKERRQ(ierr); 76095fce210SBarry Smith PetscFunctionReturn(0); 76195fce210SBarry Smith } 76295fce210SBarry Smith 76395fce210SBarry Smith static PetscErrorCode PetscSFView_Window(PetscSF sf,PetscViewer viewer) 76495fce210SBarry Smith { 76595fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 76695fce210SBarry Smith PetscErrorCode ierr; 76795fce210SBarry Smith PetscBool iascii; 768*5b0d146aSStefano Zampini PetscViewerFormat format; 76995fce210SBarry Smith 77095fce210SBarry Smith PetscFunctionBegin; 771*5b0d146aSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 77295fce210SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 77395fce210SBarry Smith if (iascii) { 774*5b0d146aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," current flavor=%s synchronization=%s sort=%s\n",PetscSFWindowFlavorTypes[w->flavor],PetscSFWindowSyncTypes[w->sync],sf->rankorder ? "rank-order" : "unordered");CHKERRQ(ierr); 775*5b0d146aSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 776*5b0d146aSStefano Zampini if (w->info != MPI_INFO_NULL) { 777*5b0d146aSStefano Zampini PetscMPIInt k,nkeys; 778*5b0d146aSStefano Zampini char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL]; 779*5b0d146aSStefano Zampini 780*5b0d146aSStefano Zampini ierr = MPI_Info_get_nkeys(w->info,&nkeys);CHKERRQ(ierr); 781*5b0d146aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," current info with %d keys. Ordered key-value pairs follow:\n",nkeys);CHKERRQ(ierr); 782*5b0d146aSStefano Zampini for (k = 0; k < nkeys; k++) { 783*5b0d146aSStefano Zampini PetscMPIInt flag; 784*5b0d146aSStefano Zampini 785*5b0d146aSStefano Zampini ierr = MPI_Info_get_nthkey(w->info,k,key);CHKERRQ(ierr); 786*5b0d146aSStefano Zampini ierr = MPI_Info_get(w->info,key,MPI_MAX_INFO_VAL,value,&flag);CHKERRQ(ierr); 787*5b0d146aSStefano Zampini if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing key %s",key); 788*5b0d146aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," %s = %s\n",key,value);CHKERRQ(ierr); 789*5b0d146aSStefano Zampini } 790*5b0d146aSStefano Zampini } else { 791*5b0d146aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," current info=MPI_INFO_NULL\n");CHKERRQ(ierr); 792*5b0d146aSStefano Zampini } 793*5b0d146aSStefano Zampini } 79495fce210SBarry Smith } 79595fce210SBarry Smith PetscFunctionReturn(0); 79695fce210SBarry Smith } 79795fce210SBarry Smith 79895fce210SBarry Smith static PetscErrorCode PetscSFDuplicate_Window(PetscSF sf,PetscSFDuplicateOption opt,PetscSF newsf) 79995fce210SBarry Smith { 80095fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 80195fce210SBarry Smith PetscErrorCode ierr; 80295fce210SBarry Smith PetscSFWindowSyncType synctype; 80395fce210SBarry Smith 80495fce210SBarry Smith PetscFunctionBegin; 80595fce210SBarry Smith synctype = w->sync; 80695fce210SBarry Smith /* HACK: Must use FENCE or LOCK when called from PetscSFGetGroups() because ACTIVE here would cause recursion. */ 807*5b0d146aSStefano Zampini if (!sf->setupcalled) synctype = PETSCSF_WINDOW_SYNC_LOCK; 80895fce210SBarry Smith ierr = PetscSFWindowSetSyncType(newsf,synctype);CHKERRQ(ierr); 809*5b0d146aSStefano Zampini ierr = PetscSFWindowSetFlavorType(newsf,w->flavor);CHKERRQ(ierr); 810*5b0d146aSStefano Zampini ierr = PetscSFWindowSetInfo(newsf,w->info);CHKERRQ(ierr); 81195fce210SBarry Smith PetscFunctionReturn(0); 81295fce210SBarry Smith } 81395fce210SBarry Smith 814eb02082bSJunchao Zhang static PetscErrorCode PetscSFBcastAndOpBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,const void *rootdata,PetscMemType leafmtype,void *leafdata,MPI_Op op) 81595fce210SBarry Smith { 81695fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 81795fce210SBarry Smith PetscErrorCode ierr; 81895fce210SBarry Smith PetscInt i,nranks; 81995fce210SBarry Smith const PetscMPIInt *ranks; 820*5b0d146aSStefano Zampini const MPI_Aint *target_disp; 82195fce210SBarry Smith const MPI_Datatype *mine,*remote; 82295fce210SBarry Smith MPI_Win win; 82395fce210SBarry Smith 82495fce210SBarry Smith PetscFunctionBegin; 825*5b0d146aSStefano Zampini if (op != MPI_REPLACE || op != MPIU_REPLACE) SETERRQ(PetscObjectComm((PetscObject)sf), PETSC_ERR_SUP, "PetscSFBcastAndOpBegin_Window with op!=MPI_REPLACE has not been implemented"); 826dec1416fSJunchao Zhang ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,NULL,NULL,NULL);CHKERRQ(ierr); 82795fce210SBarry Smith ierr = PetscSFWindowGetDataTypes(sf,unit,&mine,&remote);CHKERRQ(ierr); 828*5b0d146aSStefano Zampini ierr = PetscSFGetWindow(sf,unit,(void*)rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOPUT|MPI_MODE_NOPRECEDE,MPI_MODE_NOPUT,0,&target_disp,&win);CHKERRQ(ierr); 82995fce210SBarry Smith for (i=0; i<nranks; i++) { 830*5b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 831*5b0d146aSStefano Zampini 83295fce210SBarry Smith if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) {ierr = MPI_Win_lock(MPI_LOCK_SHARED,ranks[i],MPI_MODE_NOCHECK,win);CHKERRQ(ierr);} 833*5b0d146aSStefano Zampini ierr = MPI_Get(leafdata,1,mine[i],ranks[i],tdp,1,remote[i],win);CHKERRQ(ierr); 83495fce210SBarry Smith if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) {ierr = MPI_Win_unlock(ranks[i],win);CHKERRQ(ierr);} 83595fce210SBarry Smith } 83695fce210SBarry Smith PetscFunctionReturn(0); 83795fce210SBarry Smith } 83895fce210SBarry Smith 839eb02082bSJunchao Zhang PetscErrorCode PetscSFBcastAndOpEnd_Window(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,const void *rootdata,PetscMemType leafmtype,void *leafdata,MPI_Op op) 84095fce210SBarry Smith { 841*5b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 84295fce210SBarry Smith PetscErrorCode ierr; 84395fce210SBarry Smith MPI_Win win; 84495fce210SBarry Smith 84595fce210SBarry Smith PetscFunctionBegin; 84695fce210SBarry Smith ierr = PetscSFFindWindow(sf,unit,rootdata,&win);CHKERRQ(ierr); 847*5b0d146aSStefano Zampini ierr = PetscSFRestoreWindow(sf,unit,(void*)rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOSTORE|MPI_MODE_NOSUCCEED,PETSC_FALSE,&win);CHKERRQ(ierr); 84895fce210SBarry Smith PetscFunctionReturn(0); 84995fce210SBarry Smith } 85095fce210SBarry Smith 851eb02082bSJunchao Zhang PetscErrorCode PetscSFReduceBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType leafmtype,const void *leafdata,PetscMemType rootmtype,void *rootdata,MPI_Op op) 85295fce210SBarry Smith { 85395fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 85495fce210SBarry Smith PetscErrorCode ierr; 85595fce210SBarry Smith PetscInt i,nranks; 85695fce210SBarry Smith const PetscMPIInt *ranks; 857*5b0d146aSStefano Zampini const MPI_Aint *target_disp; 85895fce210SBarry Smith const MPI_Datatype *mine,*remote; 85995fce210SBarry Smith MPI_Win win; 86095fce210SBarry Smith 86195fce210SBarry Smith PetscFunctionBegin; 862dec1416fSJunchao Zhang ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,NULL,NULL,NULL);CHKERRQ(ierr); 86395fce210SBarry Smith ierr = PetscSFWindowGetDataTypes(sf,unit,&mine,&remote);CHKERRQ(ierr); 86495fce210SBarry Smith ierr = PetscSFWindowOpTranslate(&op);CHKERRQ(ierr); 865*5b0d146aSStefano Zampini ierr = PetscSFGetWindow(sf,unit,rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOPRECEDE,0,0,&target_disp,&win);CHKERRQ(ierr); 86695fce210SBarry Smith for (i=0; i<nranks; i++) { 867*5b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 868*5b0d146aSStefano Zampini 86995fce210SBarry Smith if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) {ierr = MPI_Win_lock(MPI_LOCK_SHARED,ranks[i],MPI_MODE_NOCHECK,win);CHKERRQ(ierr);} 870*5b0d146aSStefano Zampini ierr = MPI_Accumulate((void*)leafdata,1,mine[i],ranks[i],tdp,1,remote[i],op,win); 871*5b0d146aSStefano Zampini if (ierr) { /* intercept the MPI error since the combination of unit and op is not supported */ 872*5b0d146aSStefano Zampini PetscMPIInt len; 873*5b0d146aSStefano Zampini char errstring[MPI_MAX_ERROR_STRING]; 874*5b0d146aSStefano Zampini 875*5b0d146aSStefano Zampini MPI_Error_string(ierr,errstring,&len); 876*5b0d146aSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Internal error in MPI: %s",errstring); 877*5b0d146aSStefano Zampini } 87895fce210SBarry Smith if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) {ierr = MPI_Win_unlock(ranks[i],win);CHKERRQ(ierr);} 87995fce210SBarry Smith } 88095fce210SBarry Smith PetscFunctionReturn(0); 88195fce210SBarry Smith } 88295fce210SBarry Smith 883eb02082bSJunchao Zhang static PetscErrorCode PetscSFReduceEnd_Window(PetscSF sf,MPI_Datatype unit,PetscMemType leafmtype,const void *leafdata,PetscMemType rootmtype,void *rootdata,MPI_Op op) 88495fce210SBarry Smith { 88595fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 88695fce210SBarry Smith PetscErrorCode ierr; 88795fce210SBarry Smith MPI_Win win; 88895fce210SBarry Smith 88995fce210SBarry Smith PetscFunctionBegin; 89095fce210SBarry Smith if (!w->wins) PetscFunctionReturn(0); 89195fce210SBarry Smith ierr = PetscSFFindWindow(sf,unit,rootdata,&win);CHKERRQ(ierr); 892*5b0d146aSStefano Zampini ierr = PetscSFRestoreWindow(sf,unit,rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOSUCCEED,PETSC_TRUE,&win);CHKERRQ(ierr); 89395fce210SBarry Smith PetscFunctionReturn(0); 89495fce210SBarry Smith } 895*5b0d146aSStefano Zampini 896eb02082bSJunchao Zhang static PetscErrorCode PetscSFFetchAndOpBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,void *rootdata,PetscMemType leafmtype,const void *leafdata,void *leafupdate,MPI_Op op) 89795fce210SBarry Smith { 89895fce210SBarry Smith PetscErrorCode ierr; 89995fce210SBarry Smith PetscInt i,nranks; 90095fce210SBarry Smith const PetscMPIInt *ranks; 90195fce210SBarry Smith const MPI_Datatype *mine,*remote; 902*5b0d146aSStefano Zampini const MPI_Aint *target_disp; 90395fce210SBarry Smith MPI_Win win; 904*5b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 905*5b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 906*5b0d146aSStefano Zampini PetscSFWindowFlavorType oldf; 907*5b0d146aSStefano Zampini #endif 90895fce210SBarry Smith 90995fce210SBarry Smith PetscFunctionBegin; 910dec1416fSJunchao Zhang ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,NULL,NULL,NULL);CHKERRQ(ierr); 91195fce210SBarry Smith ierr = PetscSFWindowGetDataTypes(sf,unit,&mine,&remote);CHKERRQ(ierr); 91295fce210SBarry Smith ierr = PetscSFWindowOpTranslate(&op);CHKERRQ(ierr); 913*5b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 914*5b0d146aSStefano Zampini /* FetchAndOp without MPI_Get_Accumulate requires locking. 915*5b0d146aSStefano Zampini we create a new window every time to not interfere with user-defined MPI_Info which may have used "no_locks"="true" */ 916*5b0d146aSStefano Zampini oldf = w->flavor; 917*5b0d146aSStefano Zampini w->flavor = PETSCSF_WINDOW_FLAVOR_CREATE; 918*5b0d146aSStefano Zampini ierr = PetscSFGetWindow(sf,unit,rootdata,PETSCSF_WINDOW_SYNC_LOCK,PETSC_FALSE,0,0,0,&target_disp,&win);CHKERRQ(ierr); 919*5b0d146aSStefano Zampini #else 920*5b0d146aSStefano Zampini ierr = PetscSFGetWindow(sf,unit,rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOPRECEDE,0,0,&target_disp,&win);CHKERRQ(ierr); 921*5b0d146aSStefano Zampini #endif 922*5b0d146aSStefano Zampini for (i=0; i<nranks; i++) { 923*5b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 924*5b0d146aSStefano Zampini 925*5b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 926*5b0d146aSStefano Zampini ierr = MPI_Win_lock(MPI_LOCK_EXCLUSIVE,ranks[i],0,win);CHKERRQ(ierr); 927*5b0d146aSStefano Zampini ierr = MPI_Get(leafupdate,1,mine[i],ranks[i],tdp,1,remote[i],win);CHKERRQ(ierr); 928*5b0d146aSStefano Zampini ierr = MPI_Accumulate((void*)leafdata,1,mine[i],ranks[i],tdp,1,remote[i],op,win); 929*5b0d146aSStefano Zampini if (ierr) { /* intercept the MPI error since the combination of unit and op is not supported */ 930*5b0d146aSStefano Zampini PetscMPIInt len; 931*5b0d146aSStefano Zampini char errstring[MPI_MAX_ERROR_STRING]; 932*5b0d146aSStefano Zampini 933*5b0d146aSStefano Zampini MPI_Error_string(ierr,errstring,&len); 934*5b0d146aSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Internal error in MPI: %s",errstring); 93595fce210SBarry Smith } 936*5b0d146aSStefano Zampini ierr = MPI_Win_unlock(ranks[i],win);CHKERRQ(ierr); 937*5b0d146aSStefano Zampini #else 938*5b0d146aSStefano Zampini if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { ierr = MPI_Win_lock(MPI_LOCK_SHARED,ranks[i],0,win);CHKERRQ(ierr); } 939*5b0d146aSStefano Zampini ierr = MPI_Get_accumulate((void*)leafdata,1,mine[i],leafupdate,1,mine[i],ranks[i],tdp,1,remote[i],op,win); 940*5b0d146aSStefano Zampini if (ierr) { /* intercept the MPI error since the combination of unit and op is not supported */ 941*5b0d146aSStefano Zampini PetscMPIInt len; 942*5b0d146aSStefano Zampini char errstring[MPI_MAX_ERROR_STRING]; 943*5b0d146aSStefano Zampini 944*5b0d146aSStefano Zampini MPI_Error_string(ierr,errstring,&len); 945*5b0d146aSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Internal error in MPI: %s",errstring); 946*5b0d146aSStefano Zampini } 947*5b0d146aSStefano Zampini if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { ierr = MPI_Win_unlock(ranks[i],win);CHKERRQ(ierr); } 948*5b0d146aSStefano Zampini #endif 949*5b0d146aSStefano Zampini } 950*5b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 951*5b0d146aSStefano Zampini w->flavor = oldf; 952*5b0d146aSStefano Zampini #endif 95395fce210SBarry Smith PetscFunctionReturn(0); 95495fce210SBarry Smith } 95595fce210SBarry Smith 956eb02082bSJunchao Zhang static PetscErrorCode PetscSFFetchAndOpEnd_Window(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,void *rootdata,PetscMemType leafmtype,const void *leafdata,void *leafupdate,MPI_Op op) 95795fce210SBarry Smith { 95895fce210SBarry Smith PetscErrorCode ierr; 95995fce210SBarry Smith MPI_Win win; 960*5b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 961*5b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 962*5b0d146aSStefano Zampini #endif 96395fce210SBarry Smith 96495fce210SBarry Smith PetscFunctionBegin; 96595fce210SBarry Smith ierr = PetscSFFindWindow(sf,unit,rootdata,&win);CHKERRQ(ierr); 966*5b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 967*5b0d146aSStefano Zampini ierr = PetscSFRestoreWindow(sf,unit,rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOSUCCEED,PETSC_TRUE,&win);CHKERRQ(ierr); 968*5b0d146aSStefano Zampini #else 969*5b0d146aSStefano Zampini ierr = PetscSFRestoreWindow(sf,unit,rootdata,PETSCSF_WINDOW_SYNC_LOCK,PETSC_FALSE,0,PETSC_TRUE,&win);CHKERRQ(ierr); 970*5b0d146aSStefano Zampini #endif 97195fce210SBarry Smith PetscFunctionReturn(0); 97295fce210SBarry Smith } 97395fce210SBarry Smith 974dec1416fSJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFCreate_Window(PetscSF sf) 97595fce210SBarry Smith { 97695fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 97795fce210SBarry Smith PetscErrorCode ierr; 97895fce210SBarry Smith 97995fce210SBarry Smith PetscFunctionBegin; 98095fce210SBarry Smith sf->ops->SetUp = PetscSFSetUp_Window; 98195fce210SBarry Smith sf->ops->SetFromOptions = PetscSFSetFromOptions_Window; 98295fce210SBarry Smith sf->ops->Reset = PetscSFReset_Window; 98395fce210SBarry Smith sf->ops->Destroy = PetscSFDestroy_Window; 98495fce210SBarry Smith sf->ops->View = PetscSFView_Window; 98595fce210SBarry Smith sf->ops->Duplicate = PetscSFDuplicate_Window; 986de49d1a2SJunchao Zhang sf->ops->BcastAndOpBegin = PetscSFBcastAndOpBegin_Window; 987de49d1a2SJunchao Zhang sf->ops->BcastAndOpEnd = PetscSFBcastAndOpEnd_Window; 98895fce210SBarry Smith sf->ops->ReduceBegin = PetscSFReduceBegin_Window; 98995fce210SBarry Smith sf->ops->ReduceEnd = PetscSFReduceEnd_Window; 99095fce210SBarry Smith sf->ops->FetchAndOpBegin = PetscSFFetchAndOpBegin_Window; 99195fce210SBarry Smith sf->ops->FetchAndOpEnd = PetscSFFetchAndOpEnd_Window; 99295fce210SBarry Smith 993b00a9115SJed Brown ierr = PetscNewLog(sf,&w);CHKERRQ(ierr); 99495fce210SBarry Smith sf->data = (void*)w; 99595fce210SBarry Smith w->sync = PETSCSF_WINDOW_SYNC_FENCE; 996*5b0d146aSStefano Zampini w->flavor = PETSCSF_WINDOW_FLAVOR_CREATE; 997*5b0d146aSStefano Zampini w->info = MPI_INFO_NULL; 99895fce210SBarry Smith 999bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetSyncType_C",PetscSFWindowSetSyncType_Window);CHKERRQ(ierr); 1000bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetSyncType_C",PetscSFWindowGetSyncType_Window);CHKERRQ(ierr); 1001*5b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetFlavorType_C",PetscSFWindowSetFlavorType_Window);CHKERRQ(ierr); 1002*5b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetFlavorType_C",PetscSFWindowGetFlavorType_Window);CHKERRQ(ierr); 1003*5b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetInfo_C",PetscSFWindowSetInfo_Window);CHKERRQ(ierr); 1004*5b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetInfo_C",PetscSFWindowGetInfo_Window);CHKERRQ(ierr); 100595fce210SBarry Smith 100695fce210SBarry Smith #if defined(OMPI_MAJOR_VERSION) && (OMPI_MAJOR_VERSION < 1 || (OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION <= 6)) 100795fce210SBarry Smith { 100895fce210SBarry Smith PetscBool ackbug = PETSC_FALSE; 1009c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-acknowledge_ompi_onesided_bug",&ackbug,NULL);CHKERRQ(ierr); 101095fce210SBarry Smith if (ackbug) { 1011955c1f14SBarry Smith ierr = PetscInfo(sf,"Acknowledged Open MPI bug, proceeding anyway. Expect memory corruption.\n");CHKERRQ(ierr); 101295fce210SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_LIB,"Open MPI is known to be buggy (https://svn.open-mpi.org/trac/ompi/ticket/1905 and 2656), use -acknowledge_ompi_onesided_bug to proceed"); 101395fce210SBarry Smith } 101495fce210SBarry Smith #endif 101595fce210SBarry Smith PetscFunctionReturn(0); 101695fce210SBarry Smith } 1017