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 */ 85b0d146aSStefano Zampini PetscSFDataLink link; /* List of MPI data types, lazily constructed for each data type */ 995fce210SBarry Smith PetscSFWinLink wins; /* List of active windows */ 105b0d146aSStefano Zampini PetscSFWindowFlavorType flavor; /* Current PETSCSF_WINDOW_FLAVOR_ */ 115b0d146aSStefano Zampini PetscSF dynsf; 125b0d146aSStefano Zampini MPI_Info info; 1397a85fb4SToby Isaac MPI_Comm window_comm; 1497a85fb4SToby Isaac PetscBool is_empty; 1597a85fb4SToby Isaac PetscMPIInt *wcommranks; 1695fce210SBarry Smith } PetscSF_Window; 1795fce210SBarry Smith 1895fce210SBarry Smith struct _n_PetscSFDataLink { 1995fce210SBarry Smith MPI_Datatype unit; 2095fce210SBarry Smith MPI_Datatype *mine; 2195fce210SBarry Smith MPI_Datatype *remote; 2295fce210SBarry Smith PetscSFDataLink next; 2395fce210SBarry Smith }; 2495fce210SBarry Smith 2595fce210SBarry Smith struct _n_PetscSFWinLink { 2695fce210SBarry Smith PetscBool inuse; 2797a85fb4SToby Isaac MPI_Aint bytes; 2895fce210SBarry Smith void *addr; 2997a85fb4SToby Isaac void *rootdata; 3097a85fb4SToby Isaac void *leafdata; 3195fce210SBarry Smith MPI_Win win; 32684a874aSStefano Zampini MPI_Request *reqs; 335b0d146aSStefano Zampini PetscSFWindowFlavorType flavor; 345b0d146aSStefano Zampini MPI_Aint *dyn_target_addr; 3595fce210SBarry Smith PetscBool epoch; 3697a85fb4SToby Isaac PetscBool persistent; 3795fce210SBarry Smith PetscSFWinLink next; 3895fce210SBarry Smith }; 3995fce210SBarry Smith 404c8fdceaSLisandro Dalcin const char *const PetscSFWindowSyncTypes[] = {"FENCE", "LOCK", "ACTIVE", "PetscSFWindowSyncType", "PETSCSF_WINDOW_SYNC_", NULL}; 414c8fdceaSLisandro Dalcin const char *const PetscSFWindowFlavorTypes[] = {"CREATE", "DYNAMIC", "ALLOCATE", "SHARED", "PetscSFWindowFlavorType", "PETSCSF_WINDOW_FLAVOR_", NULL}; 4295fce210SBarry Smith 43820f2d46SBarry Smith /* Built-in MPI_Ops act elementwise inside MPI_Accumulate, but cannot be used with composite types inside collectives (MPI_Allreduce) */ 44d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFWindowOpTranslate(MPI_Op *op) 45d71ae5a4SJacob Faibussowitsch { 4695fce210SBarry Smith PetscFunctionBegin; 4795fce210SBarry Smith if (*op == MPIU_SUM) *op = MPI_SUM; 4895fce210SBarry Smith else if (*op == MPIU_MAX) *op = MPI_MAX; 4995fce210SBarry Smith else if (*op == MPIU_MIN) *op = MPI_MIN; 503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5195fce210SBarry Smith } 5295fce210SBarry Smith 53e33f79d8SJacob Faibussowitsch /* 5495fce210SBarry Smith PetscSFWindowGetDataTypes - gets composite local and remote data types for each rank 5595fce210SBarry Smith 5695fce210SBarry Smith Not Collective 5795fce210SBarry Smith 584165533cSJose E. Roman Input Parameters: 59cab54364SBarry Smith + sf - star forest of type `PETSCSFWINDOW` 6095fce210SBarry Smith - unit - data type for each node 6195fce210SBarry Smith 624165533cSJose E. Roman Output Parameters: 6395fce210SBarry Smith + localtypes - types describing part of local leaf buffer referencing each remote rank 6495fce210SBarry Smith - remotetypes - types describing part of remote root buffer referenced for each remote rank 6595fce210SBarry Smith 6695fce210SBarry Smith Level: developer 6795fce210SBarry Smith 68cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFSetGraph()`, `PetscSFView()` 6995fce210SBarry Smith @*/ 70d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFWindowGetDataTypes(PetscSF sf, MPI_Datatype unit, const MPI_Datatype **localtypes, const MPI_Datatype **remotetypes) 71d71ae5a4SJacob Faibussowitsch { 7295fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 7395fce210SBarry Smith PetscSFDataLink link; 746497c311SBarry Smith PetscMPIInt nranks; 756497c311SBarry Smith const PetscInt *roffset; 7695fce210SBarry Smith 7795fce210SBarry Smith PetscFunctionBegin; 7895fce210SBarry Smith /* Look for types in cache */ 7995fce210SBarry Smith for (link = w->link; link; link = link->next) { 8095fce210SBarry Smith PetscBool match; 816497c311SBarry Smith 829566063dSJacob Faibussowitsch PetscCall(MPIPetsc_Type_compare(unit, link->unit, &match)); 8395fce210SBarry Smith if (match) { 8495fce210SBarry Smith *localtypes = link->mine; 8595fce210SBarry Smith *remotetypes = link->remote; 863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8795fce210SBarry Smith } 8895fce210SBarry Smith } 8995fce210SBarry Smith 9095fce210SBarry Smith /* Create new composite types for each send rank */ 916497c311SBarry Smith PetscCall(PetscSFGetRootRanks(sf, &nranks, NULL, &roffset, NULL, NULL)); 929566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 939566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_dup(unit, &link->unit)); 949566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nranks, &link->mine, nranks, &link->remote)); 956497c311SBarry Smith for (PetscMPIInt i = 0; i < nranks; i++) { 966497c311SBarry Smith PetscMPIInt rcount; 9795fce210SBarry Smith PetscMPIInt *rmine, *rremote; 986497c311SBarry Smith 996497c311SBarry Smith PetscCall(PetscMPIIntCast(roffset[i + 1] - roffset[i], &rcount)); 10095fce210SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 10195fce210SBarry Smith rmine = sf->rmine + sf->roffset[i]; 10295fce210SBarry Smith rremote = sf->rremote + sf->roffset[i]; 10395fce210SBarry Smith #else 1049566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(rcount, &rmine, rcount, &rremote)); 1056497c311SBarry Smith for (PetscInt j = 0; j < rcount; j++) { 1066497c311SBarry Smith PetscCall(PetscMPIIntCast(sf->rmine[sf->roffset[i] + j], &rmine[j])); 1076497c311SBarry Smith PetscCall(PetscMPIIntCast(sf->rremote[sf->roffset[i] + j], &rremote[j])); 10895fce210SBarry Smith } 10995fce210SBarry Smith #endif 1105b0d146aSStefano Zampini 1119566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_create_indexed_block(rcount, 1, rmine, link->unit, &link->mine[i])); 1129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_create_indexed_block(rcount, 1, rremote, link->unit, &link->remote[i])); 11395fce210SBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 1149566063dSJacob Faibussowitsch PetscCall(PetscFree2(rmine, rremote)); 11595fce210SBarry Smith #endif 1169566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_commit(&link->mine[i])); 1179566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_commit(&link->remote[i])); 11895fce210SBarry Smith } 11995fce210SBarry Smith link->next = w->link; 12095fce210SBarry Smith w->link = link; 12195fce210SBarry Smith 12295fce210SBarry Smith *localtypes = link->mine; 12395fce210SBarry Smith *remotetypes = link->remote; 1243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12595fce210SBarry Smith } 12695fce210SBarry Smith 127cc4c1da9SBarry Smith /*@ 128cab54364SBarry Smith PetscSFWindowSetFlavorType - Set flavor type for `MPI_Win` creation 1295b0d146aSStefano Zampini 1305b0d146aSStefano Zampini Logically Collective 1315b0d146aSStefano Zampini 1324165533cSJose E. Roman Input Parameters: 133cab54364SBarry Smith + sf - star forest for communication of type `PETSCSFWINDOW` 1345b0d146aSStefano Zampini - flavor - flavor type 1355b0d146aSStefano Zampini 1365b0d146aSStefano Zampini Options Database Key: 137cab54364SBarry Smith . -sf_window_flavor <flavor> - sets the flavor type CREATE, DYNAMIC, ALLOCATE or SHARED (see `PetscSFWindowFlavorType`) 1385b0d146aSStefano Zampini 1395b0d146aSStefano Zampini Level: advanced 1405b0d146aSStefano Zampini 141cab54364SBarry Smith Notes: 142e33f79d8SJacob Faibussowitsch Windows reuse follows these rules\: 143cab54364SBarry Smith .vb 1445b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_CREATE: creates a new window every time, uses MPI_Win_create 1455b0d146aSStefano Zampini 1465b0d146aSStefano 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. 14797a85fb4SToby Isaac PetscSFRegisterPersistent(sf,rootdata1,leafdata); 1485b0d146aSStefano Zampini for i=1 to K 14997a85fb4SToby Isaac PetscSFOperationBegin(sf,rootdata1,leafdata); 15097a85fb4SToby Isaac PetscSFOperationEnd(sf,rootdata1,leafdata); 1515b0d146aSStefano Zampini ... 15297a85fb4SToby Isaac PetscSFOperationBegin(sf,rootdata1,leafdata); 15397a85fb4SToby Isaac PetscSFOperationEnd(sf,rootdata1,leafdata); 1545b0d146aSStefano Zampini endfor 15597a85fb4SToby Isaac PetscSFDeregisterPersistent(sf,rootdata1,leafdata); 15697a85fb4SToby Isaac 1575b0d146aSStefano Zampini The following pattern will instead raise an error 15897a85fb4SToby Isaac PetscSFOperationBegin(sf,rootdata1,leafdata); 15997a85fb4SToby Isaac PetscSFOperationEnd(sf,rootdata1,leafdata); 16097a85fb4SToby Isaac PetscSFOperationBegin(sf,rank ? rootdata1 : rootdata2,leafdata); 16197a85fb4SToby Isaac PetscSFOperationEnd(sf,rank ? rootdata1 : rootdata2,leafdata); 1625b0d146aSStefano Zampini 1635b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_ALLOCATE: uses MPI_Win_allocate, reuses any pre-existing window which fits the data and it is not in use 1645b0d146aSStefano Zampini 1655b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_SHARED: uses MPI_Win_allocate_shared, reusage policy as for PETSCSF_WINDOW_FLAVOR_ALLOCATE 166cab54364SBarry Smith .ve 1675b0d146aSStefano Zampini 168cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFSetFromOptions()`, `PetscSFWindowGetFlavorType()` 1695b0d146aSStefano Zampini @*/ 170d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSFWindowSetFlavorType(PetscSF sf, PetscSFWindowFlavorType flavor) 171d71ae5a4SJacob Faibussowitsch { 1725b0d146aSStefano Zampini PetscFunctionBegin; 1735b0d146aSStefano Zampini PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 1745b0d146aSStefano Zampini PetscValidLogicalCollectiveEnum(sf, flavor, 2); 175cac4c232SBarry Smith PetscTryMethod(sf, "PetscSFWindowSetFlavorType_C", (PetscSF, PetscSFWindowFlavorType), (sf, flavor)); 1763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1775b0d146aSStefano Zampini } 1785b0d146aSStefano Zampini 179d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFWindowSetFlavorType_Window(PetscSF sf, PetscSFWindowFlavorType flavor) 180d71ae5a4SJacob Faibussowitsch { 1815b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window *)sf->data; 1825b0d146aSStefano Zampini 1835b0d146aSStefano Zampini PetscFunctionBegin; 1845b0d146aSStefano Zampini w->flavor = flavor; 1853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1865b0d146aSStefano Zampini } 1875b0d146aSStefano Zampini 188cc4c1da9SBarry Smith /*@ 189cab54364SBarry Smith PetscSFWindowGetFlavorType - Get `PETSCSFWINDOW` flavor type for `PetscSF` communication 1905b0d146aSStefano Zampini 1915b0d146aSStefano Zampini Logically Collective 1925b0d146aSStefano Zampini 1934165533cSJose E. Roman Input Parameter: 194cab54364SBarry Smith . sf - star forest for communication of type `PETSCSFWINDOW` 1955b0d146aSStefano Zampini 1964165533cSJose E. Roman Output Parameter: 1975b0d146aSStefano Zampini . flavor - flavor type 1985b0d146aSStefano Zampini 1995b0d146aSStefano Zampini Level: advanced 2005b0d146aSStefano Zampini 201cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFSetFromOptions()`, `PetscSFWindowSetFlavorType()` 2025b0d146aSStefano Zampini @*/ 203d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSFWindowGetFlavorType(PetscSF sf, PetscSFWindowFlavorType *flavor) 204d71ae5a4SJacob Faibussowitsch { 2055b0d146aSStefano Zampini PetscFunctionBegin; 2065b0d146aSStefano Zampini PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 2074f572ea9SToby Isaac PetscAssertPointer(flavor, 2); 208cac4c232SBarry Smith PetscUseMethod(sf, "PetscSFWindowGetFlavorType_C", (PetscSF, PetscSFWindowFlavorType *), (sf, flavor)); 2093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2105b0d146aSStefano Zampini } 2115b0d146aSStefano Zampini 212d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFWindowGetFlavorType_Window(PetscSF sf, PetscSFWindowFlavorType *flavor) 213d71ae5a4SJacob Faibussowitsch { 2145b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window *)sf->data; 2155b0d146aSStefano Zampini 2165b0d146aSStefano Zampini PetscFunctionBegin; 2175b0d146aSStefano Zampini *flavor = w->flavor; 2183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2195b0d146aSStefano Zampini } 2205b0d146aSStefano Zampini 221cc4c1da9SBarry Smith /*@ 222cab54364SBarry Smith PetscSFWindowSetSyncType - Set synchronization type for `PetscSF` communication of type `PETSCSFWINDOW` 22395fce210SBarry Smith 22495fce210SBarry Smith Logically Collective 22595fce210SBarry Smith 2264165533cSJose E. Roman Input Parameters: 22795fce210SBarry Smith + sf - star forest for communication 22895fce210SBarry Smith - sync - synchronization type 22995fce210SBarry Smith 23095fce210SBarry Smith Options Database Key: 231cab54364SBarry Smith . -sf_window_sync <sync> - sets the synchronization type FENCE, LOCK, or ACTIVE (see `PetscSFWindowSyncType`) 23295fce210SBarry Smith 23395fce210SBarry Smith Level: advanced 23495fce210SBarry Smith 235cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFSetFromOptions()`, `PetscSFWindowGetSyncType()`, `PetscSFWindowSyncType` 23695fce210SBarry Smith @*/ 237d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSFWindowSetSyncType(PetscSF sf, PetscSFWindowSyncType sync) 238d71ae5a4SJacob Faibussowitsch { 23995fce210SBarry Smith PetscFunctionBegin; 24095fce210SBarry Smith PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 24195fce210SBarry Smith PetscValidLogicalCollectiveEnum(sf, sync, 2); 242cac4c232SBarry Smith PetscTryMethod(sf, "PetscSFWindowSetSyncType_C", (PetscSF, PetscSFWindowSyncType), (sf, sync)); 2433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24495fce210SBarry Smith } 24595fce210SBarry Smith 246d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFWindowSetSyncType_Window(PetscSF sf, PetscSFWindowSyncType sync) 247d71ae5a4SJacob Faibussowitsch { 24895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 24995fce210SBarry Smith 25095fce210SBarry Smith PetscFunctionBegin; 25195fce210SBarry Smith w->sync = sync; 2523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25395fce210SBarry Smith } 25495fce210SBarry Smith 255cc4c1da9SBarry Smith /*@ 256cab54364SBarry Smith PetscSFWindowGetSyncType - Get synchronization type for `PetscSF` communication of type `PETSCSFWINDOW` 25795fce210SBarry Smith 25895fce210SBarry Smith Logically Collective 25995fce210SBarry Smith 2604165533cSJose E. Roman Input Parameter: 26195fce210SBarry Smith . sf - star forest for communication 26295fce210SBarry Smith 2634165533cSJose E. Roman Output Parameter: 26495fce210SBarry Smith . sync - synchronization type 26595fce210SBarry Smith 26695fce210SBarry Smith Level: advanced 26795fce210SBarry Smith 268cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFSetFromOptions()`, `PetscSFWindowSetSyncType()`, `PetscSFWindowSyncType` 26995fce210SBarry Smith @*/ 270d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSFWindowGetSyncType(PetscSF sf, PetscSFWindowSyncType *sync) 271d71ae5a4SJacob Faibussowitsch { 27295fce210SBarry Smith PetscFunctionBegin; 27395fce210SBarry Smith PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 2744f572ea9SToby Isaac PetscAssertPointer(sync, 2); 275cac4c232SBarry Smith PetscUseMethod(sf, "PetscSFWindowGetSyncType_C", (PetscSF, PetscSFWindowSyncType *), (sf, sync)); 2763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27795fce210SBarry Smith } 27895fce210SBarry Smith 279d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFWindowGetSyncType_Window(PetscSF sf, PetscSFWindowSyncType *sync) 280d71ae5a4SJacob Faibussowitsch { 28195fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 28295fce210SBarry Smith 28395fce210SBarry Smith PetscFunctionBegin; 28495fce210SBarry Smith *sync = w->sync; 2853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28695fce210SBarry Smith } 28795fce210SBarry Smith 28895fce210SBarry Smith /*@C 289cab54364SBarry Smith PetscSFWindowSetInfo - Set the `MPI_Info` handle that will be used for subsequent windows allocation 2905b0d146aSStefano Zampini 2915b0d146aSStefano Zampini Logically Collective 2925b0d146aSStefano Zampini 2934165533cSJose E. Roman Input Parameters: 2945b0d146aSStefano Zampini + sf - star forest for communication 295cab54364SBarry Smith - info - `MPI_Info` handle 2965b0d146aSStefano Zampini 2975b0d146aSStefano Zampini Level: advanced 2985b0d146aSStefano Zampini 299cab54364SBarry Smith Note: 300cab54364SBarry Smith The info handle is duplicated with a call to `MPI_Info_dup()` unless info = `MPI_INFO_NULL`. 3015b0d146aSStefano Zampini 302cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFSetFromOptions()`, `PetscSFWindowGetInfo()` 3035b0d146aSStefano Zampini @*/ 304d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSFWindowSetInfo(PetscSF sf, MPI_Info info) 305d71ae5a4SJacob Faibussowitsch { 3065b0d146aSStefano Zampini PetscFunctionBegin; 3075b0d146aSStefano Zampini PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 308cac4c232SBarry Smith PetscTryMethod(sf, "PetscSFWindowSetInfo_C", (PetscSF, MPI_Info), (sf, info)); 3093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3105b0d146aSStefano Zampini } 3115b0d146aSStefano Zampini 312d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFWindowSetInfo_Window(PetscSF sf, MPI_Info info) 313d71ae5a4SJacob Faibussowitsch { 3145b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window *)sf->data; 3155b0d146aSStefano Zampini 3165b0d146aSStefano Zampini PetscFunctionBegin; 31748a46eb9SPierre Jolivet if (w->info != MPI_INFO_NULL) PetscCallMPI(MPI_Info_free(&w->info)); 31848a46eb9SPierre Jolivet if (info != MPI_INFO_NULL) PetscCallMPI(MPI_Info_dup(info, &w->info)); 3193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3205b0d146aSStefano Zampini } 3215b0d146aSStefano Zampini 3225b0d146aSStefano Zampini /*@C 323cab54364SBarry Smith PetscSFWindowGetInfo - Get the `MPI_Info` handle used for windows allocation 3245b0d146aSStefano Zampini 3255b0d146aSStefano Zampini Logically Collective 3265b0d146aSStefano Zampini 3274165533cSJose E. Roman Input Parameter: 3285b0d146aSStefano Zampini . sf - star forest for communication 3295b0d146aSStefano Zampini 3304165533cSJose E. Roman Output Parameter: 331cab54364SBarry Smith . info - `MPI_Info` handle 3325b0d146aSStefano Zampini 3335b0d146aSStefano Zampini Level: advanced 3345b0d146aSStefano Zampini 335cab54364SBarry Smith Note: 336cab54364SBarry Smith If `PetscSFWindowSetInfo()` has not be called, this returns `MPI_INFO_NULL` 3375b0d146aSStefano Zampini 338cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFSetFromOptions()`, `PetscSFWindowSetInfo()` 3395b0d146aSStefano Zampini @*/ 340d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSFWindowGetInfo(PetscSF sf, MPI_Info *info) 341d71ae5a4SJacob Faibussowitsch { 3425b0d146aSStefano Zampini PetscFunctionBegin; 3435b0d146aSStefano Zampini PetscValidHeaderSpecific(sf, PETSCSF_CLASSID, 1); 3444f572ea9SToby Isaac PetscAssertPointer(info, 2); 345cac4c232SBarry Smith PetscUseMethod(sf, "PetscSFWindowGetInfo_C", (PetscSF, MPI_Info *), (sf, info)); 3463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3475b0d146aSStefano Zampini } 3485b0d146aSStefano Zampini 349d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFWindowGetInfo_Window(PetscSF sf, MPI_Info *info) 350d71ae5a4SJacob Faibussowitsch { 3515b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window *)sf->data; 3525b0d146aSStefano Zampini 3535b0d146aSStefano Zampini PetscFunctionBegin; 3545b0d146aSStefano Zampini *info = w->info; 3553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3565b0d146aSStefano Zampini } 3575b0d146aSStefano Zampini 35897a85fb4SToby Isaac static PetscErrorCode PetscSFWindowCreateDynamicSF(PetscSF sf, PetscSF *dynsf) 35997a85fb4SToby Isaac { 36097a85fb4SToby Isaac PetscSFNode *remotes; 36197a85fb4SToby Isaac 36297a85fb4SToby Isaac PetscFunctionBegin; 36397a85fb4SToby Isaac PetscCall(PetscMalloc1(sf->nranks, &remotes)); 36497a85fb4SToby Isaac for (PetscInt i = 0; i < sf->nranks; i++) { 36597a85fb4SToby Isaac remotes[i].rank = sf->ranks[i]; 36697a85fb4SToby Isaac remotes[i].index = 0; 36797a85fb4SToby Isaac } 36897a85fb4SToby Isaac PetscCall(PetscSFDuplicate(sf, PETSCSF_DUPLICATE_RANKS, dynsf)); 36997a85fb4SToby Isaac PetscCall(PetscSFSetType(*dynsf, PETSCSFBASIC)); /* break recursion */ 37097a85fb4SToby Isaac PetscCall(PetscSFSetGraph(*dynsf, 1, sf->nranks, NULL, PETSC_OWN_POINTER, remotes, PETSC_OWN_POINTER)); 37197a85fb4SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 37297a85fb4SToby Isaac } 37397a85fb4SToby Isaac 37497a85fb4SToby Isaac static PetscErrorCode PetscSFWindowAttach(PetscSF sf, PetscSFWinLink link, void *rootdata, size_t wsize) 37597a85fb4SToby Isaac { 37697a85fb4SToby Isaac PetscFunctionBegin; 37797a85fb4SToby Isaac #if defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW) 37897a85fb4SToby Isaac { 37997a85fb4SToby Isaac PetscSF_Window *w = (PetscSF_Window *)sf->data; 38097a85fb4SToby Isaac MPI_Comm wcomm; 38197a85fb4SToby Isaac MPI_Aint winaddr; 38297a85fb4SToby Isaac void *addr = rootdata; 3836497c311SBarry Smith PetscMPIInt nranks; 38497a85fb4SToby Isaac // some Open MPI versions do not support MPI_Win_attach(win,NULL,0); 38597a85fb4SToby Isaac wcomm = w->window_comm; 38697a85fb4SToby Isaac if (addr != NULL) PetscCallMPI(MPI_Win_attach(link->win, addr, wsize)); 38797a85fb4SToby Isaac link->addr = addr; 38897a85fb4SToby Isaac PetscCheck(w->dynsf, wcomm, PETSC_ERR_ORDER, "Must call PetscSFSetUp()"); 38997a85fb4SToby Isaac PetscCall(PetscSFGetRootRanks(w->dynsf, &nranks, NULL, NULL, NULL, NULL)); 39097a85fb4SToby Isaac PetscCallMPI(MPI_Get_address(addr, &winaddr)); 39197a85fb4SToby Isaac if (!link->dyn_target_addr) PetscCall(PetscMalloc1(nranks, &link->dyn_target_addr)); 39297a85fb4SToby Isaac PetscCall(PetscSFBcastBegin(w->dynsf, MPI_AINT, &winaddr, link->dyn_target_addr, MPI_REPLACE)); 39397a85fb4SToby Isaac PetscCall(PetscSFBcastEnd(w->dynsf, MPI_AINT, &winaddr, link->dyn_target_addr, MPI_REPLACE)); 39497a85fb4SToby Isaac } 39597a85fb4SToby Isaac #else 39697a85fb4SToby Isaac SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "dynamic windows not supported"); 39797a85fb4SToby Isaac #endif 39897a85fb4SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 39997a85fb4SToby Isaac } 40097a85fb4SToby Isaac 4015b0d146aSStefano Zampini /* 40295fce210SBarry Smith PetscSFGetWindow - Get a window for use with a given data type 40395fce210SBarry Smith 404c3339decSBarry Smith Collective 40595fce210SBarry Smith 4064165533cSJose E. Roman Input Parameters: 40795fce210SBarry Smith + sf - star forest 40895fce210SBarry Smith . unit - data type 40997a85fb4SToby Isaac . rootdata - array to be sent 41097a85fb4SToby Isaac . leafdata - only used to help uniquely identify windows 411cab54364SBarry Smith . sync - type of synchronization `PetscSFWindowSyncType` 412cab54364SBarry Smith . epoch - `PETSC_TRUE` to acquire the window and start an epoch, `PETSC_FALSE` to just acquire the window 413cab54364SBarry Smith . fenceassert - assert parameter for call to `MPI_Win_fence()`, if sync == `PETSCSF_WINDOW_SYNC_FENCE` 414cab54364SBarry Smith . postassert - assert parameter for call to `MPI_Win_post()`, if sync == `PETSCSF_WINDOW_SYNC_ACTIVE` 415cab54364SBarry Smith - startassert - assert parameter for call to `MPI_Win_start()`, if sync == `PETSCSF_WINDOW_SYNC_ACTIVE` 41695fce210SBarry Smith 4174165533cSJose E. Roman Output Parameters: 418cab54364SBarry Smith + target_disp - target_disp argument for RMA calls (significative for `PETSCSF_WINDOW_FLAVOR_DYNAMIC` only) 419cab54364SBarry Smith + reqs - array of requests (significative for sync == `PETSCSF_WINDOW_SYNC_LOCK` only) 420684a874aSStefano Zampini - win - window 42195fce210SBarry Smith 42295fce210SBarry Smith Level: developer 423cab54364SBarry Smith 424cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFGetRootRanks()`, `PetscSFWindowGetDataTypes()` 4255b0d146aSStefano Zampini */ 42697a85fb4SToby Isaac 42797a85fb4SToby Isaac static PetscErrorCode PetscSFGetWindow(PetscSF sf, MPI_Datatype unit, void *rootdata, void *leafdata, PetscSFWindowSyncType sync, PetscBool epoch, PetscMPIInt fenceassert, PetscMPIInt postassert, PetscMPIInt startassert, const MPI_Aint **target_disp, MPI_Request **reqs, MPI_Win *win) 428d71ae5a4SJacob Faibussowitsch { 42995fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 43097a85fb4SToby Isaac MPI_Aint bytes; 43195fce210SBarry Smith PetscSFWinLink link; 4325b0d146aSStefano Zampini PetscBool reuse = PETSC_FALSE, update = PETSC_FALSE; 4335b0d146aSStefano Zampini MPI_Aint wsize; 43497a85fb4SToby Isaac MPI_Comm wcomm; 43597a85fb4SToby Isaac PetscBool is_empty; 43695fce210SBarry Smith 43795fce210SBarry Smith PetscFunctionBegin; 43897a85fb4SToby Isaac PetscCall(PetscSFGetDatatypeSize_Internal(PetscObjectComm((PetscObject)sf), unit, &bytes)); 43997a85fb4SToby Isaac wsize = (MPI_Aint)(bytes * sf->nroots); 44097a85fb4SToby Isaac wcomm = w->window_comm; 44197a85fb4SToby Isaac is_empty = w->is_empty; 44297a85fb4SToby Isaac if (is_empty) { 44397a85fb4SToby Isaac if (target_disp) *target_disp = NULL; 44497a85fb4SToby Isaac if (reqs) *reqs = NULL; 44597a85fb4SToby Isaac *win = MPI_WIN_NULL; 44697a85fb4SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 44797a85fb4SToby Isaac } 4485b0d146aSStefano Zampini if (w->flavor != PETSCSF_WINDOW_FLAVOR_CREATE) reuse = PETSC_TRUE; 44997a85fb4SToby Isaac if (PetscDefined(HAVE_MPI_FEATURE_DYNAMIC_WINDOW) && w->flavor == PETSCSF_WINDOW_FLAVOR_DYNAMIC) { 45097a85fb4SToby Isaac // first search for a persistent window 4515b0d146aSStefano Zampini for (link = w->wins; reuse && link; link = link->next) { 45297a85fb4SToby Isaac PetscBool match; 45397a85fb4SToby Isaac 45497a85fb4SToby Isaac if (!link->persistent) continue; 45597a85fb4SToby Isaac match = (link->flavor == w->flavor && link->rootdata == rootdata && link->leafdata == leafdata) ? PETSC_TRUE : PETSC_FALSE; 45676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 45797a85fb4SToby Isaac PetscInt matches[2]; 45897a85fb4SToby Isaac PetscInt all_matches[2]; 45997a85fb4SToby Isaac 46097a85fb4SToby Isaac matches[0] = match ? 1 : 0; 46197a85fb4SToby Isaac matches[1] = match ? -1 : 0; 46297a85fb4SToby Isaac PetscCallMPI(MPIU_Allreduce(matches, all_matches, 2, MPIU_INT, MPI_MAX, wcomm)); 46397a85fb4SToby Isaac all_matches[1] = -all_matches[1]; 46497a85fb4SToby Isaac PetscCheck(all_matches[0] == all_matches[1], wcomm, PETSC_ERR_ARG_INCOMP, 46597a85fb4SToby Isaac "Inconsistent use across MPI processes of persistent leaf and root data registered with PetscSFRegisterPersistent().\n" 46697a85fb4SToby Isaac "Either the persistent data was changed on a subset of processes (which is not allowed),\n" 46797a85fb4SToby Isaac "or persistent data was not deregistered with PetscSFDeregisterPersistent() before being deallocated"); 46876bd3646SJed Brown } 46997a85fb4SToby Isaac if (match) { 47097a85fb4SToby Isaac PetscCheck(!link->inuse, wcomm, PETSC_ERR_ARG_WRONGSTATE, "Communication already in progress on persistent root and leaf data"); 47197a85fb4SToby Isaac PetscCheck(!epoch || !link->epoch, wcomm, PETSC_ERR_ARG_WRONGSTATE, "Communication epoch already open for window"); 47297a85fb4SToby Isaac PetscCheck(bytes == link->bytes, wcomm, PETSC_ERR_ARG_WRONGSTATE, "Wrong data type for persistent root and leaf data"); 4735b0d146aSStefano Zampini *win = link->win; 47497a85fb4SToby Isaac goto found; 47597a85fb4SToby Isaac } 47697a85fb4SToby Isaac } 47797a85fb4SToby Isaac } 47897a85fb4SToby Isaac for (link = w->wins; reuse && link; link = link->next) { 47997a85fb4SToby Isaac if (w->flavor != link->flavor) continue; 48097a85fb4SToby Isaac /* an existing window can be used (1) if it is not in use, (2) if we are 48197a85fb4SToby Isaac not asking to start an epoch or it does not have an already started 48297a85fb4SToby Isaac epoch, and (3) if it is the right size */ 48397a85fb4SToby Isaac if (!link->inuse && (!epoch || !link->epoch) && bytes == (MPI_Aint)link->bytes) { 48497a85fb4SToby Isaac if (w->flavor == PETSCSF_WINDOW_FLAVOR_DYNAMIC) { 48597a85fb4SToby Isaac PetscCall(PetscSFWindowAttach(sf, link, rootdata, wsize)); 48697a85fb4SToby Isaac } else { 48797a85fb4SToby Isaac update = PETSC_TRUE; 48897a85fb4SToby Isaac } 48997a85fb4SToby Isaac link->rootdata = rootdata; 49097a85fb4SToby Isaac link->leafdata = leafdata; 49197a85fb4SToby Isaac PetscCall(PetscInfo(sf, "Reusing window %" PETSC_INTPTR_T_FMT " of flavor %d for comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)link->win, link->flavor, (PETSC_INTPTR_T)wcomm)); 49297a85fb4SToby Isaac *win = link->win; 4935b0d146aSStefano Zampini goto found; 4945b0d146aSStefano Zampini } 4955b0d146aSStefano Zampini } 4965b0d146aSStefano Zampini 4979566063dSJacob Faibussowitsch PetscCall(PetscNew(&link)); 49895fce210SBarry Smith link->bytes = bytes; 49995fce210SBarry Smith link->next = w->wins; 5005b0d146aSStefano Zampini link->flavor = w->flavor; 5015b0d146aSStefano Zampini link->dyn_target_addr = NULL; 502684a874aSStefano Zampini link->reqs = NULL; 50395fce210SBarry Smith w->wins = link; 50497a85fb4SToby Isaac link->rootdata = rootdata; 50597a85fb4SToby Isaac link->leafdata = leafdata; 506684a874aSStefano Zampini if (sync == PETSCSF_WINDOW_SYNC_LOCK) { 5079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(sf->nranks, &link->reqs)); 5086497c311SBarry Smith for (PetscMPIInt i = 0; i < sf->nranks; i++) link->reqs[i] = MPI_REQUEST_NULL; 509684a874aSStefano Zampini } 5105b0d146aSStefano Zampini switch (w->flavor) { 5115b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_CREATE: 51297a85fb4SToby Isaac PetscCallMPI(MPI_Win_create(rootdata, wsize, (PetscMPIInt)bytes, w->info, wcomm, &link->win)); 51397a85fb4SToby Isaac link->addr = rootdata; 5145b0d146aSStefano Zampini break; 515d547623eSJunchao Zhang #if defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW) 516d71ae5a4SJacob Faibussowitsch case PETSCSF_WINDOW_FLAVOR_DYNAMIC: 51797a85fb4SToby Isaac PetscCallMPI(MPI_Win_create_dynamic(w->info, wcomm, &link->win)); 51897a85fb4SToby Isaac PetscCall(PetscSFWindowAttach(sf, link, rootdata, wsize)); 5195b0d146aSStefano Zampini break; 5205b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_ALLOCATE: 52197a85fb4SToby Isaac PetscCallMPI(MPI_Win_allocate(wsize, (PetscMPIInt)bytes, w->info, wcomm, &link->addr, &link->win)); 5225b0d146aSStefano Zampini update = PETSC_TRUE; 5235b0d146aSStefano Zampini break; 524d547623eSJunchao Zhang #endif 5255b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 5265b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_SHARED: 52797a85fb4SToby Isaac PetscCallMPI(MPI_Win_allocate_shared(wsize, (PetscMPIInt)bytes, w->info, wcomm, &link->addr, &link->win)); 5285b0d146aSStefano Zampini update = PETSC_TRUE; 5295b0d146aSStefano Zampini break; 5305b0d146aSStefano Zampini #endif 531d71ae5a4SJacob Faibussowitsch default: 53297a85fb4SToby Isaac SETERRQ(wcomm, PETSC_ERR_SUP, "No support for flavor %s", PetscSFWindowFlavorTypes[w->flavor]); 5335b0d146aSStefano Zampini } 53497a85fb4SToby Isaac PetscCall(PetscInfo(sf, "New window %" PETSC_INTPTR_T_FMT " of flavor %d for comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)link->win, link->flavor, (PETSC_INTPTR_T)wcomm)); 53595fce210SBarry Smith *win = link->win; 53695fce210SBarry Smith 5375b0d146aSStefano Zampini found: 5385b0d146aSStefano Zampini 539684a874aSStefano Zampini if (target_disp) *target_disp = link->dyn_target_addr; 540684a874aSStefano Zampini if (reqs) *reqs = link->reqs; 54197a85fb4SToby Isaac if (update) { /* locks are needed for the "separate" memory model only, the fence guarantees memory-synchronization */ 542684a874aSStefano Zampini PetscMPIInt rank; 543684a874aSStefano Zampini 54497a85fb4SToby Isaac PetscCallMPI(MPI_Comm_rank(wcomm, &rank)); 5459566063dSJacob Faibussowitsch if (sync == PETSCSF_WINDOW_SYNC_LOCK) PetscCallMPI(MPI_Win_lock(MPI_LOCK_EXCLUSIVE, rank, MPI_MODE_NOCHECK, *win)); 54697a85fb4SToby Isaac PetscCall(PetscMemcpy(link->addr, rootdata, sf->nroots * bytes)); 5475b0d146aSStefano Zampini if (sync == PETSCSF_WINDOW_SYNC_LOCK) { 5489566063dSJacob Faibussowitsch PetscCallMPI(MPI_Win_unlock(rank, *win)); 5499566063dSJacob Faibussowitsch PetscCallMPI(MPI_Win_fence(0, *win)); 5505b0d146aSStefano Zampini } 5515b0d146aSStefano Zampini } 5525b0d146aSStefano Zampini link->inuse = PETSC_TRUE; 5535b0d146aSStefano Zampini link->epoch = epoch; 55495fce210SBarry Smith if (epoch) { 5555b0d146aSStefano Zampini switch (sync) { 556d71ae5a4SJacob Faibussowitsch case PETSCSF_WINDOW_SYNC_FENCE: 557d71ae5a4SJacob Faibussowitsch PetscCallMPI(MPI_Win_fence(fenceassert, *win)); 558d71ae5a4SJacob Faibussowitsch break; 559d71ae5a4SJacob Faibussowitsch case PETSCSF_WINDOW_SYNC_LOCK: /* Handled outside */ 560d71ae5a4SJacob Faibussowitsch break; 56195fce210SBarry Smith case PETSCSF_WINDOW_SYNC_ACTIVE: { 56295fce210SBarry Smith MPI_Group ingroup, outgroup; 5635b0d146aSStefano Zampini PetscMPIInt isize, osize; 5645b0d146aSStefano Zampini 5655b0d146aSStefano Zampini /* Open MPI 4.0.2 with btl=vader does not like calling 5665b0d146aSStefano Zampini - MPI_Win_complete when ogroup is empty 5675b0d146aSStefano Zampini - MPI_Win_wait when igroup is empty 5685b0d146aSStefano Zampini So, we do not even issue the corresponding start and post calls 5695b0d146aSStefano Zampini The MPI standard (Sec. 11.5.2 of MPI 3.1) only requires that 5705b0d146aSStefano Zampini start(outgroup) has a matching post(ingroup) 5715b0d146aSStefano Zampini and this is guaranteed by PetscSF 5725b0d146aSStefano Zampini */ 5739566063dSJacob Faibussowitsch PetscCall(PetscSFGetGroups(sf, &ingroup, &outgroup)); 5749566063dSJacob Faibussowitsch PetscCallMPI(MPI_Group_size(ingroup, &isize)); 5759566063dSJacob Faibussowitsch PetscCallMPI(MPI_Group_size(outgroup, &osize)); 5769566063dSJacob Faibussowitsch if (isize) PetscCallMPI(MPI_Win_post(ingroup, postassert, *win)); 5779566063dSJacob Faibussowitsch if (osize) PetscCallMPI(MPI_Win_start(outgroup, startassert, *win)); 57895fce210SBarry Smith } break; 579d71ae5a4SJacob Faibussowitsch default: 58097a85fb4SToby Isaac SETERRQ(wcomm, PETSC_ERR_PLIB, "Unknown synchronization type"); 58195fce210SBarry Smith } 58295fce210SBarry Smith } 5833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 58495fce210SBarry Smith } 58595fce210SBarry Smith 5865b0d146aSStefano Zampini /* 58795fce210SBarry Smith PetscSFFindWindow - Finds a window that is already in use 58895fce210SBarry Smith 58995fce210SBarry Smith Not Collective 59095fce210SBarry Smith 5914165533cSJose E. Roman Input Parameters: 59295fce210SBarry Smith + sf - star forest 59395fce210SBarry Smith . unit - data type 59497a85fb4SToby Isaac . rootdata - array with which the window is associated 59597a85fb4SToby Isaac - leafdata - only used to help uniquely identify windows 59695fce210SBarry Smith 5974165533cSJose E. Roman Output Parameters: 598684a874aSStefano Zampini + win - window 599684a874aSStefano Zampini - reqs - outstanding requests associated to the window 60095fce210SBarry Smith 60195fce210SBarry Smith Level: developer 60295fce210SBarry Smith 603cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFGetWindow()`, `PetscSFRestoreWindow()` 6045b0d146aSStefano Zampini */ 60597a85fb4SToby Isaac static PetscErrorCode PetscSFFindWindow(PetscSF sf, MPI_Datatype unit, const void *rootdata, const void *leafdata, MPI_Win *win, MPI_Request **reqs) 606d71ae5a4SJacob Faibussowitsch { 60795fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 60895fce210SBarry Smith PetscSFWinLink link; 60997a85fb4SToby Isaac PetscBool is_empty; 61097a85fb4SToby Isaac MPI_Aint bytes; 61195fce210SBarry Smith 61295fce210SBarry Smith PetscFunctionBegin; 61397a85fb4SToby Isaac PetscCall(PetscSFGetDatatypeSize_Internal(PetscObjectComm((PetscObject)sf), unit, &bytes)); 614c0cd0301SJed Brown *win = MPI_WIN_NULL; 61597a85fb4SToby Isaac is_empty = w->is_empty; 61697a85fb4SToby Isaac if (is_empty) { 61797a85fb4SToby Isaac *reqs = NULL; 61897a85fb4SToby Isaac *win = MPI_WIN_NULL; 61997a85fb4SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 62097a85fb4SToby Isaac } 62195fce210SBarry Smith for (link = w->wins; link; link = link->next) { 62297a85fb4SToby Isaac if (rootdata == link->rootdata && leafdata == link->leafdata && bytes == link->bytes) { 62397a85fb4SToby Isaac PetscCall(PetscInfo(sf, "Window %" PETSC_INTPTR_T_FMT " of flavor %d for comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)link->win, link->flavor, (PETSC_INTPTR_T)w->window_comm)); 62495fce210SBarry Smith *win = link->win; 625684a874aSStefano Zampini *reqs = link->reqs; 6263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62795fce210SBarry Smith } 62895fce210SBarry Smith } 62995fce210SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Requested window not in use"); 63095fce210SBarry Smith } 63195fce210SBarry Smith 6325b0d146aSStefano Zampini /* 633cab54364SBarry Smith PetscSFRestoreWindow - Restores a window obtained with `PetscSFGetWindow()` 63495fce210SBarry Smith 63595fce210SBarry Smith Collective 63695fce210SBarry Smith 6374165533cSJose E. Roman Input Parameters: 63895fce210SBarry Smith + sf - star forest 63995fce210SBarry Smith . unit - data type 64095fce210SBarry Smith . array - array associated with window 641cab54364SBarry Smith . sync - type of synchronization `PetscSFWindowSyncType` 642cab54364SBarry Smith . epoch - close an epoch, must match argument to `PetscSFGetWindow()` 6435b0d146aSStefano Zampini . update - if we have to update the local window array 64495fce210SBarry Smith - win - window 64595fce210SBarry Smith 64695fce210SBarry Smith Level: developer 64795fce210SBarry Smith 648cab54364SBarry Smith .seealso: `PetscSF`, `PETSCSFWINDOW`, `PetscSFFindWindow()` 6495b0d146aSStefano Zampini */ 650d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFRestoreWindow(PetscSF sf, MPI_Datatype unit, void *array, PetscSFWindowSyncType sync, PetscBool epoch, PetscMPIInt fenceassert, PetscBool update, MPI_Win *win) 651d71ae5a4SJacob Faibussowitsch { 65295fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 65395fce210SBarry Smith PetscSFWinLink *p, link; 6545b0d146aSStefano Zampini PetscBool reuse = PETSC_FALSE; 6555b0d146aSStefano Zampini PetscSFWindowFlavorType flavor; 6565b0d146aSStefano Zampini void *laddr; 65797a85fb4SToby Isaac MPI_Aint bytes; 65897a85fb4SToby Isaac MPI_Comm wcomm; 65995fce210SBarry Smith 66095fce210SBarry Smith PetscFunctionBegin; 66197a85fb4SToby Isaac if (*win == MPI_WIN_NULL) PetscFunctionReturn(PETSC_SUCCESS); 66297a85fb4SToby Isaac wcomm = w->window_comm; 66395fce210SBarry Smith for (p = &w->wins; *p; p = &(*p)->next) { 66495fce210SBarry Smith link = *p; 66595fce210SBarry Smith if (*win == link->win) { 66697a85fb4SToby Isaac PetscCheck(array == link->rootdata, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Matched window, but not array"); 66795fce210SBarry Smith if (epoch != link->epoch) { 66828b400f6SJacob Faibussowitsch PetscCheck(!epoch, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "No epoch to end"); 669f7d195e4SLawrence Mitchell SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Restoring window without ending epoch"); 67095fce210SBarry Smith } 6715b0d146aSStefano Zampini laddr = link->addr; 6725b0d146aSStefano Zampini flavor = link->flavor; 6735b0d146aSStefano Zampini bytes = link->bytes; 6745b0d146aSStefano Zampini if (flavor != PETSCSF_WINDOW_FLAVOR_CREATE) reuse = PETSC_TRUE; 6759371c9d4SSatish Balay else { 6769371c9d4SSatish Balay *p = link->next; 6779371c9d4SSatish Balay update = PETSC_FALSE; 6789371c9d4SSatish Balay } /* remove from list */ 67995fce210SBarry Smith goto found; 68095fce210SBarry Smith } 68195fce210SBarry Smith } 68295fce210SBarry Smith SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Requested window not in use"); 68395fce210SBarry Smith 68495fce210SBarry Smith found: 68597a85fb4SToby Isaac PetscCall(PetscInfo(sf, "Window %" PETSC_INTPTR_T_FMT " of flavor %d for comm %" PETSC_INTPTR_T_FMT "\n", (PETSC_INTPTR_T)link->win, link->flavor, (PETSC_INTPTR_T)wcomm)); 68695fce210SBarry Smith if (epoch) { 6875b0d146aSStefano Zampini switch (sync) { 688d71ae5a4SJacob Faibussowitsch case PETSCSF_WINDOW_SYNC_FENCE: 689d71ae5a4SJacob Faibussowitsch PetscCallMPI(MPI_Win_fence(fenceassert, *win)); 690d71ae5a4SJacob Faibussowitsch break; 691d71ae5a4SJacob Faibussowitsch case PETSCSF_WINDOW_SYNC_LOCK: /* Handled outside */ 692d71ae5a4SJacob Faibussowitsch break; 69395fce210SBarry Smith case PETSCSF_WINDOW_SYNC_ACTIVE: { 6945b0d146aSStefano Zampini MPI_Group ingroup, outgroup; 6955b0d146aSStefano Zampini PetscMPIInt isize, osize; 6965b0d146aSStefano Zampini 6975b0d146aSStefano Zampini /* Open MPI 4.0.2 with btl=wader does not like calling 6985b0d146aSStefano Zampini - MPI_Win_complete when ogroup is empty 6995b0d146aSStefano Zampini - MPI_Win_wait when igroup is empty 7005b0d146aSStefano Zampini The MPI standard (Sec. 11.5.2 of MPI 3.1) only requires that 7015b0d146aSStefano Zampini - each process who issues a call to MPI_Win_start issues a call to MPI_Win_Complete 7025b0d146aSStefano Zampini - each process who issues a call to MPI_Win_post issues a call to MPI_Win_Wait 7035b0d146aSStefano Zampini */ 7049566063dSJacob Faibussowitsch PetscCall(PetscSFGetGroups(sf, &ingroup, &outgroup)); 7059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Group_size(ingroup, &isize)); 7069566063dSJacob Faibussowitsch PetscCallMPI(MPI_Group_size(outgroup, &osize)); 7079566063dSJacob Faibussowitsch if (osize) PetscCallMPI(MPI_Win_complete(*win)); 7089566063dSJacob Faibussowitsch if (isize) PetscCallMPI(MPI_Win_wait(*win)); 70995fce210SBarry Smith } break; 710d71ae5a4SJacob Faibussowitsch default: 71197a85fb4SToby Isaac SETERRQ(wcomm, PETSC_ERR_PLIB, "Unknown synchronization type"); 71295fce210SBarry Smith } 71395fce210SBarry Smith } 71497a85fb4SToby Isaac #if defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW) 71597a85fb4SToby Isaac if (link->flavor == PETSCSF_WINDOW_FLAVOR_DYNAMIC && !link->persistent) { 71697a85fb4SToby Isaac if (link->addr != NULL) PetscCallMPI(MPI_Win_detach(link->win, link->addr)); 71797a85fb4SToby Isaac link->addr = NULL; 71897a85fb4SToby Isaac } 71997a85fb4SToby Isaac #endif 7205b0d146aSStefano Zampini if (update) { 72148a46eb9SPierre Jolivet if (sync == PETSCSF_WINDOW_SYNC_LOCK) PetscCallMPI(MPI_Win_fence(MPI_MODE_NOPUT | MPI_MODE_NOSUCCEED, *win)); 7229566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(array, laddr, sf->nroots * bytes)); 7235b0d146aSStefano Zampini } 7245b0d146aSStefano Zampini link->epoch = PETSC_FALSE; 7255b0d146aSStefano Zampini link->inuse = PETSC_FALSE; 72697a85fb4SToby Isaac if (!link->persistent) { 72797a85fb4SToby Isaac link->rootdata = NULL; 72897a85fb4SToby Isaac link->leafdata = NULL; 72997a85fb4SToby Isaac } 7305b0d146aSStefano Zampini if (!reuse) { 7319566063dSJacob Faibussowitsch PetscCall(PetscFree(link->dyn_target_addr)); 7329566063dSJacob Faibussowitsch PetscCall(PetscFree(link->reqs)); 7339566063dSJacob Faibussowitsch PetscCallMPI(MPI_Win_free(&link->win)); 7349566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 73595fce210SBarry Smith *win = MPI_WIN_NULL; 7365b0d146aSStefano Zampini } 7373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 73895fce210SBarry Smith } 73995fce210SBarry Smith 740d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFSetUp_Window(PetscSF sf) 741d71ae5a4SJacob Faibussowitsch { 74295fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 74395fce210SBarry Smith MPI_Group ingroup, outgroup; 74497a85fb4SToby Isaac MPI_Comm comm; 74595fce210SBarry Smith 74695fce210SBarry Smith PetscFunctionBegin; 7479566063dSJacob Faibussowitsch PetscCall(PetscSFSetUpRanks(sf, MPI_GROUP_EMPTY)); 74897a85fb4SToby Isaac PetscCall(PetscObjectGetComm((PetscObject)sf, &comm)); 74997a85fb4SToby Isaac if (w->window_comm == MPI_COMM_NULL) { 75097a85fb4SToby Isaac PetscInt nroots, nleaves, nranks; 75197a85fb4SToby Isaac PetscBool has_empty; 75297a85fb4SToby Isaac PetscMPIInt wcommrank; 75397a85fb4SToby Isaac PetscSF dynsf_full = NULL; 75497a85fb4SToby Isaac 75597a85fb4SToby Isaac if (w->flavor == PETSCSF_WINDOW_FLAVOR_DYNAMIC) PetscCall(PetscSFWindowCreateDynamicSF(sf, &dynsf_full)); 75697a85fb4SToby Isaac 75797a85fb4SToby Isaac PetscCall(PetscSFGetGraph(sf, &nroots, &nleaves, NULL, NULL)); 75897a85fb4SToby Isaac has_empty = (nroots == 0 && nleaves == 0) ? PETSC_TRUE : PETSC_FALSE; 75997a85fb4SToby Isaac nranks = sf->nranks; 76097a85fb4SToby Isaac PetscCall(PetscMalloc1(nranks, &w->wcommranks)); 76197a85fb4SToby Isaac w->is_empty = has_empty; 762*5440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &has_empty, 1, MPI_C_BOOL, MPI_LOR, comm)); 76397a85fb4SToby Isaac if (has_empty) { 76497a85fb4SToby Isaac PetscMPIInt rank; 76597a85fb4SToby Isaac MPI_Comm raw_comm; 7665b0d146aSStefano Zampini PetscSFNode *remotes; 7675b0d146aSStefano Zampini 76897a85fb4SToby Isaac PetscCallMPI(MPI_Comm_rank(comm, &rank)); 76997a85fb4SToby Isaac PetscCallMPI(MPI_Comm_split(comm, w->is_empty ? 1 : 0, rank, &raw_comm)); 77097a85fb4SToby Isaac PetscCall(PetscCommDuplicate(raw_comm, &w->window_comm, NULL)); 77197a85fb4SToby Isaac PetscCallMPI(MPI_Comm_free(&raw_comm)); 77297a85fb4SToby Isaac 77397a85fb4SToby Isaac PetscCallMPI(MPI_Comm_rank(w->window_comm, &wcommrank)); 77497a85fb4SToby Isaac if (!dynsf_full) PetscCall(PetscSFWindowCreateDynamicSF(sf, &dynsf_full)); 77597a85fb4SToby Isaac PetscCall(PetscSFBcastBegin(dynsf_full, MPI_INT, &wcommrank, w->wcommranks, MPI_REPLACE)); 77697a85fb4SToby Isaac PetscCall(PetscSFBcastEnd(dynsf_full, MPI_INT, &wcommrank, w->wcommranks, MPI_REPLACE)); 77797a85fb4SToby Isaac 77897a85fb4SToby Isaac if (w->flavor == PETSCSF_WINDOW_FLAVOR_DYNAMIC) { 77997a85fb4SToby Isaac PetscCall(PetscSFCreate(w->window_comm, &w->dynsf)); 78097a85fb4SToby Isaac PetscCall(PetscSFSetType(w->dynsf, PETSCSFBASIC)); /* break recursion */ 7819566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(sf->nranks, &remotes)); 78297a85fb4SToby Isaac for (PetscInt i = 0; i < sf->nranks; i++) { 78397a85fb4SToby Isaac remotes[i].rank = w->wcommranks[i]; 7845b0d146aSStefano Zampini remotes[i].index = 0; 7855b0d146aSStefano Zampini } 7869566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(w->dynsf, 1, sf->nranks, NULL, PETSC_OWN_POINTER, remotes, PETSC_OWN_POINTER)); 7875b0d146aSStefano Zampini } 78897a85fb4SToby Isaac } else { 78997a85fb4SToby Isaac PetscCall(PetscCommDuplicate(PetscObjectComm((PetscObject)sf), &w->window_comm, NULL)); 79097a85fb4SToby Isaac PetscCall(PetscArraycpy(w->wcommranks, sf->ranks, nranks)); 79197a85fb4SToby Isaac PetscCall(PetscObjectReference((PetscObject)dynsf_full)); 79297a85fb4SToby Isaac w->dynsf = dynsf_full; 79397a85fb4SToby Isaac } 79497a85fb4SToby Isaac if (w->dynsf) PetscCall(PetscSFSetUp(w->dynsf)); 79597a85fb4SToby Isaac PetscCall(PetscSFDestroy(&dynsf_full)); 79697a85fb4SToby Isaac } 79795fce210SBarry Smith switch (w->sync) { 798d71ae5a4SJacob Faibussowitsch case PETSCSF_WINDOW_SYNC_ACTIVE: 799d71ae5a4SJacob Faibussowitsch PetscCall(PetscSFGetGroups(sf, &ingroup, &outgroup)); 800d71ae5a4SJacob Faibussowitsch default: 801d71ae5a4SJacob Faibussowitsch break; 80295fce210SBarry Smith } 8033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80495fce210SBarry Smith } 80595fce210SBarry Smith 806ce78bad3SBarry Smith static PetscErrorCode PetscSFSetFromOptions_Window(PetscSF sf, PetscOptionItems PetscOptionsObject) 807d71ae5a4SJacob Faibussowitsch { 80895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 8095b0d146aSStefano Zampini PetscSFWindowFlavorType flavor = w->flavor; 81095fce210SBarry Smith 81195fce210SBarry Smith PetscFunctionBegin; 812d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "PetscSF Window options"); 8139566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-sf_window_sync", "synchronization type to use for PetscSF Window communication", "PetscSFWindowSetSyncType", PetscSFWindowSyncTypes, (PetscEnum)w->sync, (PetscEnum *)&w->sync, NULL)); 8149566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-sf_window_flavor", "flavor to use for PetscSF Window creation", "PetscSFWindowSetFlavorType", PetscSFWindowFlavorTypes, (PetscEnum)flavor, (PetscEnum *)&flavor, NULL)); 8159566063dSJacob Faibussowitsch PetscCall(PetscSFWindowSetFlavorType(sf, flavor)); 816d0609cedSBarry Smith PetscOptionsHeadEnd(); 8173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81895fce210SBarry Smith } 81995fce210SBarry Smith 820d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFReset_Window(PetscSF sf) 821d71ae5a4SJacob Faibussowitsch { 82295fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 82395fce210SBarry Smith PetscSFDataLink link, next; 82495fce210SBarry Smith PetscSFWinLink wlink, wnext; 82595fce210SBarry Smith PetscInt i; 82697a85fb4SToby Isaac MPI_Comm wcomm; 82797a85fb4SToby Isaac PetscBool is_empty; 82895fce210SBarry Smith 82995fce210SBarry Smith PetscFunctionBegin; 83095fce210SBarry Smith for (link = w->link; link; link = next) { 83195fce210SBarry Smith next = link->next; 8329566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_free(&link->unit)); 83395fce210SBarry Smith for (i = 0; i < sf->nranks; i++) { 8349566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_free(&link->mine[i])); 8359566063dSJacob Faibussowitsch PetscCallMPI(MPI_Type_free(&link->remote[i])); 83695fce210SBarry Smith } 8379566063dSJacob Faibussowitsch PetscCall(PetscFree2(link->mine, link->remote)); 8389566063dSJacob Faibussowitsch PetscCall(PetscFree(link)); 83995fce210SBarry Smith } 84095fce210SBarry Smith w->link = NULL; 84197a85fb4SToby Isaac wcomm = w->window_comm; 84297a85fb4SToby Isaac is_empty = w->is_empty; 84397a85fb4SToby Isaac if (!is_empty) { 84495fce210SBarry Smith for (wlink = w->wins; wlink; wlink = wnext) { 84595fce210SBarry Smith wnext = wlink->next; 84697a85fb4SToby Isaac PetscCheck(!wlink->inuse, wcomm, PETSC_ERR_ARG_WRONGSTATE, "Window still in use with address %p", (void *)wlink->addr); 8479566063dSJacob Faibussowitsch PetscCall(PetscFree(wlink->dyn_target_addr)); 8489566063dSJacob Faibussowitsch PetscCall(PetscFree(wlink->reqs)); 8499566063dSJacob Faibussowitsch PetscCallMPI(MPI_Win_free(&wlink->win)); 8509566063dSJacob Faibussowitsch PetscCall(PetscFree(wlink)); 85195fce210SBarry Smith } 85297a85fb4SToby Isaac } 85395fce210SBarry Smith w->wins = NULL; 8549566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&w->dynsf)); 85548a46eb9SPierre Jolivet if (w->info != MPI_INFO_NULL) PetscCallMPI(MPI_Info_free(&w->info)); 85697a85fb4SToby Isaac PetscCall(PetscCommDestroy(&w->window_comm)); 85797a85fb4SToby Isaac PetscCall(PetscFree(w->wcommranks)); 85897a85fb4SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 85997a85fb4SToby Isaac } 86097a85fb4SToby Isaac 86197a85fb4SToby Isaac static PetscErrorCode PetscSFRegisterPersistent_Window(PetscSF sf, MPI_Datatype unit, const void *rootdata, const void *leafdata) 86297a85fb4SToby Isaac { 86397a85fb4SToby Isaac PetscSF_Window *w = (PetscSF_Window *)sf->data; 86497a85fb4SToby Isaac MPI_Aint bytes, wsize; 86597a85fb4SToby Isaac PetscBool is_empty; 86697a85fb4SToby Isaac PetscSFWinLink link; 86797a85fb4SToby Isaac 86897a85fb4SToby Isaac PetscFunctionBegin; 86997a85fb4SToby Isaac PetscCall(PetscSFSetUp(sf)); 87097a85fb4SToby Isaac if (w->flavor != PETSCSF_WINDOW_FLAVOR_DYNAMIC) PetscFunctionReturn(PETSC_SUCCESS); 87197a85fb4SToby Isaac PetscCall(PetscSFGetDatatypeSize_Internal(PetscObjectComm((PetscObject)sf), unit, &bytes)); 87297a85fb4SToby Isaac wsize = (MPI_Aint)(bytes * sf->nroots); 87397a85fb4SToby Isaac is_empty = w->is_empty; 87497a85fb4SToby Isaac if (is_empty) PetscFunctionReturn(PETSC_SUCCESS); 87597a85fb4SToby Isaac PetscCall(PetscNew(&link)); 87697a85fb4SToby Isaac link->flavor = w->flavor; 87797a85fb4SToby Isaac link->next = w->wins; 87897a85fb4SToby Isaac #if defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW) 87997a85fb4SToby Isaac { 88097a85fb4SToby Isaac MPI_Comm wcomm = w->window_comm; 88197a85fb4SToby Isaac PetscCallMPI(MPI_Win_create_dynamic(w->info, wcomm, &link->win)); 88297a85fb4SToby Isaac } 88397a85fb4SToby Isaac #endif 88497a85fb4SToby Isaac PetscCall(PetscSFWindowAttach(sf, link, (void *)rootdata, wsize)); 88597a85fb4SToby Isaac link->rootdata = (void *)rootdata; 88697a85fb4SToby Isaac link->leafdata = (void *)leafdata; 88797a85fb4SToby Isaac link->bytes = bytes; 88897a85fb4SToby Isaac link->epoch = PETSC_FALSE; 88997a85fb4SToby Isaac link->inuse = PETSC_FALSE; 89097a85fb4SToby Isaac link->persistent = PETSC_TRUE; 89197a85fb4SToby Isaac w->wins = link; 89297a85fb4SToby Isaac if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { 89397a85fb4SToby Isaac PetscInt i; 89497a85fb4SToby Isaac 89597a85fb4SToby Isaac PetscCall(PetscMalloc1(sf->nranks, &link->reqs)); 89697a85fb4SToby Isaac for (i = 0; i < sf->nranks; i++) link->reqs[i] = MPI_REQUEST_NULL; 89797a85fb4SToby Isaac } 89897a85fb4SToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 89997a85fb4SToby Isaac } 90097a85fb4SToby Isaac 90197a85fb4SToby Isaac static PetscErrorCode PetscSFDeregisterPersistent_Window(PetscSF sf, MPI_Datatype unit, const void *rootdata, const void *leafdata) 90297a85fb4SToby Isaac { 90397a85fb4SToby Isaac PetscSF_Window *w = (PetscSF_Window *)sf->data; 90497a85fb4SToby Isaac MPI_Aint bytes; 90597a85fb4SToby Isaac MPI_Comm wcomm; 90697a85fb4SToby Isaac PetscBool is_empty; 90797a85fb4SToby Isaac PetscSFWinLink *p; 90897a85fb4SToby Isaac 90997a85fb4SToby Isaac PetscFunctionBegin; 91097a85fb4SToby Isaac PetscCall(PetscSFSetUp(sf)); 91197a85fb4SToby Isaac if (w->flavor != PETSCSF_WINDOW_FLAVOR_DYNAMIC) PetscFunctionReturn(PETSC_SUCCESS); 91297a85fb4SToby Isaac PetscCall(PetscSFGetDatatypeSize_Internal(PetscObjectComm((PetscObject)sf), unit, &bytes)); 91397a85fb4SToby Isaac wcomm = w->window_comm; 91497a85fb4SToby Isaac is_empty = w->is_empty; 91597a85fb4SToby Isaac if (is_empty) PetscFunctionReturn(PETSC_SUCCESS); 91697a85fb4SToby Isaac for (p = &w->wins; *p; p = &(*p)->next) { 91797a85fb4SToby Isaac PetscSFWinLink link = *p; 91897a85fb4SToby Isaac if (link->flavor == w->flavor && link->persistent && link->rootdata == rootdata && link->leafdata == leafdata && link->bytes == bytes) { 91997a85fb4SToby Isaac PetscCheck(!link->inuse, wcomm, PETSC_ERR_ARG_WRONGSTATE, "Deregistering a window when communication is still in progress"); 92097a85fb4SToby Isaac PetscCheck(!link->epoch, wcomm, PETSC_ERR_ARG_WRONGSTATE, "Deregistering a window with an unconcluded epoch"); 92197a85fb4SToby Isaac #if defined(PETSC_HAVE_MPI_FEATURE_DYNAMIC_WINDOW) 92297a85fb4SToby Isaac PetscCallMPI(MPI_Win_detach(link->win, link->addr)); 92397a85fb4SToby Isaac link->addr = NULL; 92497a85fb4SToby Isaac #endif 92597a85fb4SToby Isaac PetscCall(PetscFree(link->dyn_target_addr)); 92697a85fb4SToby Isaac PetscCall(PetscFree(link->reqs)); 92797a85fb4SToby Isaac PetscCallMPI(MPI_Win_free(&link->win)); 92897a85fb4SToby Isaac *p = link->next; 92997a85fb4SToby Isaac PetscCall(PetscFree(link)); 93097a85fb4SToby Isaac break; 93197a85fb4SToby Isaac } 93297a85fb4SToby Isaac } 9333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 93495fce210SBarry Smith } 93595fce210SBarry Smith 936d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFDestroy_Window(PetscSF sf) 937d71ae5a4SJacob Faibussowitsch { 93895fce210SBarry Smith PetscFunctionBegin; 9399566063dSJacob Faibussowitsch PetscCall(PetscSFReset_Window(sf)); 9409566063dSJacob Faibussowitsch PetscCall(PetscFree(sf->data)); 9419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowSetSyncType_C", NULL)); 9429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowGetSyncType_C", NULL)); 9439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowSetFlavorType_C", NULL)); 9449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowGetFlavorType_C", NULL)); 9459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowSetInfo_C", NULL)); 9469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowGetInfo_C", NULL)); 94797a85fb4SToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFRegisterPersistent_C", NULL)); 94897a85fb4SToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFDeregisterPersistent_C", NULL)); 9493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 95095fce210SBarry Smith } 95195fce210SBarry Smith 952d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFView_Window(PetscSF sf, PetscViewer viewer) 953d71ae5a4SJacob Faibussowitsch { 95495fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 9559f196a02SMartin Diehl PetscBool isascii; 9565b0d146aSStefano Zampini PetscViewerFormat format; 95795fce210SBarry Smith 95895fce210SBarry Smith PetscFunctionBegin; 9599566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 9609f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 9619f196a02SMartin Diehl if (isascii) { 9629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " current flavor=%s synchronization=%s MultiSF sort=%s\n", PetscSFWindowFlavorTypes[w->flavor], PetscSFWindowSyncTypes[w->sync], sf->rankorder ? "rank-order" : "unordered")); 9635b0d146aSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 9645b0d146aSStefano Zampini if (w->info != MPI_INFO_NULL) { 9655b0d146aSStefano Zampini PetscMPIInt k, nkeys; 9665b0d146aSStefano Zampini char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL]; 9675b0d146aSStefano Zampini 9689566063dSJacob Faibussowitsch PetscCallMPI(MPI_Info_get_nkeys(w->info, &nkeys)); 9699566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " current info with %d keys. Ordered key-value pairs follow:\n", nkeys)); 9705b0d146aSStefano Zampini for (k = 0; k < nkeys; k++) { 9715b0d146aSStefano Zampini PetscMPIInt flag; 9725b0d146aSStefano Zampini 9739566063dSJacob Faibussowitsch PetscCallMPI(MPI_Info_get_nthkey(w->info, k, key)); 9749566063dSJacob Faibussowitsch PetscCallMPI(MPI_Info_get(w->info, key, MPI_MAX_INFO_VAL, value, &flag)); 97528b400f6SJacob Faibussowitsch PetscCheck(flag, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing key %s", key); 9769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s = %s\n", key, value)); 9775b0d146aSStefano Zampini } 9785b0d146aSStefano Zampini } else { 9799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " current info=MPI_INFO_NULL\n")); 9805b0d146aSStefano Zampini } 9815b0d146aSStefano Zampini } 98295fce210SBarry Smith } 9833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 98495fce210SBarry Smith } 98595fce210SBarry Smith 986d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFDuplicate_Window(PetscSF sf, PetscSFDuplicateOption opt, PetscSF newsf) 987d71ae5a4SJacob Faibussowitsch { 98895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 98995fce210SBarry Smith PetscSFWindowSyncType synctype; 99095fce210SBarry Smith 99195fce210SBarry Smith PetscFunctionBegin; 99295fce210SBarry Smith synctype = w->sync; 99395fce210SBarry Smith /* HACK: Must use FENCE or LOCK when called from PetscSFGetGroups() because ACTIVE here would cause recursion. */ 9945b0d146aSStefano Zampini if (!sf->setupcalled) synctype = PETSCSF_WINDOW_SYNC_LOCK; 9959566063dSJacob Faibussowitsch PetscCall(PetscSFWindowSetSyncType(newsf, synctype)); 9969566063dSJacob Faibussowitsch PetscCall(PetscSFWindowSetFlavorType(newsf, w->flavor)); 9979566063dSJacob Faibussowitsch PetscCall(PetscSFWindowSetInfo(newsf, w->info)); 9983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99995fce210SBarry Smith } 100095fce210SBarry Smith 1001d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFBcastBegin_Window(PetscSF sf, MPI_Datatype unit, PetscMemType rootmtype, const void *rootdata, PetscMemType leafmtype, void *leafdata, MPI_Op op) 1002d71ae5a4SJacob Faibussowitsch { 100395fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 10046497c311SBarry Smith PetscMPIInt nranks; 100595fce210SBarry Smith const PetscMPIInt *ranks; 10065b0d146aSStefano Zampini const MPI_Aint *target_disp; 100795fce210SBarry Smith const MPI_Datatype *mine, *remote; 1008684a874aSStefano Zampini MPI_Request *reqs; 100995fce210SBarry Smith MPI_Win win; 101095fce210SBarry Smith 101195fce210SBarry Smith PetscFunctionBegin; 101208401ef6SPierre Jolivet PetscCheck(op == MPI_REPLACE, PetscObjectComm((PetscObject)sf), PETSC_ERR_SUP, "PetscSFBcastBegin_Window with op!=MPI_REPLACE has not been implemented"); 101397a85fb4SToby Isaac PetscCall(PetscSFGetRootRanks(sf, &nranks, NULL, NULL, NULL, NULL)); 10149566063dSJacob Faibussowitsch PetscCall(PetscSFWindowGetDataTypes(sf, unit, &mine, &remote)); 101597a85fb4SToby Isaac PetscCall(PetscSFGetWindow(sf, unit, (void *)rootdata, leafdata, w->sync, PETSC_TRUE, MPI_MODE_NOPUT | MPI_MODE_NOPRECEDE, MPI_MODE_NOPUT, 0, &target_disp, &reqs, &win)); 101697a85fb4SToby Isaac ranks = w->wcommranks; 10176497c311SBarry Smith for (PetscMPIInt i = 0; i < nranks; i++) { 10185b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 1019684a874aSStefano Zampini if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { 10209566063dSJacob Faibussowitsch PetscCallMPI(MPI_Win_lock(MPI_LOCK_SHARED, ranks[i], MPI_MODE_NOCHECK, win)); 1021684a874aSStefano Zampini #if defined(PETSC_HAVE_MPI_RGET) 10229566063dSJacob Faibussowitsch PetscCallMPI(MPI_Rget(leafdata, 1, mine[i], ranks[i], tdp, 1, remote[i], win, &reqs[i])); 1023684a874aSStefano Zampini #else 10249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Get(leafdata, 1, mine[i], ranks[i], tdp, 1, remote[i], win)); 1025684a874aSStefano Zampini #endif 1026684a874aSStefano Zampini } else { 10276497c311SBarry Smith CHKMEMQ; 10289566063dSJacob Faibussowitsch PetscCallMPI(MPI_Get(leafdata, 1, mine[i], ranks[i], tdp, 1, remote[i], win)); 10296497c311SBarry Smith CHKMEMQ; 1030684a874aSStefano Zampini } 103195fce210SBarry Smith } 10323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 103395fce210SBarry Smith } 103495fce210SBarry Smith 103566976f2fSJacob Faibussowitsch static PetscErrorCode PetscSFBcastEnd_Window(PetscSF sf, MPI_Datatype unit, const void *rootdata, void *leafdata, MPI_Op op) 1036d71ae5a4SJacob Faibussowitsch { 10375b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window *)sf->data; 103895fce210SBarry Smith MPI_Win win; 10394b9acda6SJunchao Zhang MPI_Request *reqs = NULL; 104095fce210SBarry Smith 104195fce210SBarry Smith PetscFunctionBegin; 104297a85fb4SToby Isaac PetscCall(PetscSFFindWindow(sf, unit, rootdata, leafdata, &win, &reqs)); 10439566063dSJacob Faibussowitsch if (reqs) PetscCallMPI(MPI_Waitall(sf->nranks, reqs, MPI_STATUSES_IGNORE)); 1044684a874aSStefano Zampini if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { 10456497c311SBarry Smith PetscMPIInt nranks; 1046684a874aSStefano Zampini const PetscMPIInt *ranks; 1047684a874aSStefano Zampini 104897a85fb4SToby Isaac PetscCall(PetscSFGetRootRanks(sf, &nranks, NULL, NULL, NULL, NULL)); 104997a85fb4SToby Isaac ranks = w->wcommranks; 10506497c311SBarry Smith for (PetscMPIInt i = 0; i < nranks; i++) PetscCallMPI(MPI_Win_unlock(ranks[i], win)); 1051684a874aSStefano Zampini } 10529566063dSJacob Faibussowitsch PetscCall(PetscSFRestoreWindow(sf, unit, (void *)rootdata, w->sync, PETSC_TRUE, MPI_MODE_NOSTORE | MPI_MODE_NOSUCCEED, PETSC_FALSE, &win)); 10533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 105495fce210SBarry Smith } 105595fce210SBarry Smith 105666976f2fSJacob Faibussowitsch static PetscErrorCode PetscSFReduceBegin_Window(PetscSF sf, MPI_Datatype unit, PetscMemType leafmtype, const void *leafdata, PetscMemType rootmtype, void *rootdata, MPI_Op op) 1057d71ae5a4SJacob Faibussowitsch { 105895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 10596497c311SBarry Smith PetscMPIInt nranks; 106095fce210SBarry Smith const PetscMPIInt *ranks; 10615b0d146aSStefano Zampini const MPI_Aint *target_disp; 106295fce210SBarry Smith const MPI_Datatype *mine, *remote; 106395fce210SBarry Smith MPI_Win win; 106495fce210SBarry Smith 106595fce210SBarry Smith PetscFunctionBegin; 106697a85fb4SToby Isaac PetscCall(PetscSFGetRootRanks(sf, &nranks, NULL, NULL, NULL, NULL)); 10679566063dSJacob Faibussowitsch PetscCall(PetscSFWindowGetDataTypes(sf, unit, &mine, &remote)); 10689566063dSJacob Faibussowitsch PetscCall(PetscSFWindowOpTranslate(&op)); 106997a85fb4SToby Isaac PetscCall(PetscSFGetWindow(sf, unit, rootdata, (void *)leafdata, w->sync, PETSC_TRUE, MPI_MODE_NOPRECEDE, 0, 0, &target_disp, NULL, &win)); 107097a85fb4SToby Isaac ranks = w->wcommranks; 10716497c311SBarry Smith for (PetscMPIInt i = 0; i < nranks; i++) { 10725b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 10735b0d146aSStefano Zampini 10749566063dSJacob Faibussowitsch if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) PetscCallMPI(MPI_Win_lock(MPI_LOCK_SHARED, ranks[i], MPI_MODE_NOCHECK, win)); 10759566063dSJacob Faibussowitsch PetscCallMPI(MPI_Accumulate((void *)leafdata, 1, mine[i], ranks[i], tdp, 1, remote[i], op, win)); 10769566063dSJacob Faibussowitsch if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) PetscCallMPI(MPI_Win_unlock(ranks[i], win)); 107795fce210SBarry Smith } 10783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 107995fce210SBarry Smith } 108095fce210SBarry Smith 1081d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFReduceEnd_Window(PetscSF sf, MPI_Datatype unit, const void *leafdata, void *rootdata, MPI_Op op) 1082d71ae5a4SJacob Faibussowitsch { 108395fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 108495fce210SBarry Smith MPI_Win win; 10854b9acda6SJunchao Zhang MPI_Request *reqs = NULL; 108695fce210SBarry Smith 108795fce210SBarry Smith PetscFunctionBegin; 108897a85fb4SToby Isaac PetscCall(PetscSFFindWindow(sf, unit, rootdata, leafdata, &win, &reqs)); 10899566063dSJacob Faibussowitsch if (reqs) PetscCallMPI(MPI_Waitall(sf->nranks, reqs, MPI_STATUSES_IGNORE)); 10909566063dSJacob Faibussowitsch PetscCall(PetscSFRestoreWindow(sf, unit, rootdata, w->sync, PETSC_TRUE, MPI_MODE_NOSUCCEED, PETSC_TRUE, &win)); 10913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 109295fce210SBarry Smith } 10935b0d146aSStefano Zampini 1094d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFFetchAndOpBegin_Window(PetscSF sf, MPI_Datatype unit, PetscMemType rootmtype, void *rootdata, PetscMemType leafmtype, const void *leafdata, void *leafupdate, MPI_Op op) 1095d71ae5a4SJacob Faibussowitsch { 10966497c311SBarry Smith PetscMPIInt nranks; 109795fce210SBarry Smith const PetscMPIInt *ranks; 109895fce210SBarry Smith const MPI_Datatype *mine, *remote; 10995b0d146aSStefano Zampini const MPI_Aint *target_disp; 110095fce210SBarry Smith MPI_Win win; 11015b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window *)sf->data; 11025b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 11035b0d146aSStefano Zampini PetscSFWindowFlavorType oldf; 11045b0d146aSStefano Zampini #endif 110595fce210SBarry Smith 110695fce210SBarry Smith PetscFunctionBegin; 110797a85fb4SToby Isaac PetscCall(PetscSFGetRootRanks(sf, &nranks, NULL, NULL, NULL, NULL)); 11089566063dSJacob Faibussowitsch PetscCall(PetscSFWindowGetDataTypes(sf, unit, &mine, &remote)); 11099566063dSJacob Faibussowitsch PetscCall(PetscSFWindowOpTranslate(&op)); 11105b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 11115b0d146aSStefano Zampini /* FetchAndOp without MPI_Get_Accumulate requires locking. 11125b0d146aSStefano Zampini we create a new window every time to not interfere with user-defined MPI_Info which may have used "no_locks"="true" */ 11135b0d146aSStefano Zampini oldf = w->flavor; 11145b0d146aSStefano Zampini w->flavor = PETSCSF_WINDOW_FLAVOR_CREATE; 111597a85fb4SToby Isaac PetscCall(PetscSFGetWindow(sf, unit, rootdata, (void *)leafdata, PETSCSF_WINDOW_SYNC_LOCK, PETSC_FALSE, 0, 0, 0, &target_disp, NULL, &win)); 11165b0d146aSStefano Zampini #else 111797a85fb4SToby Isaac PetscCall(PetscSFGetWindow(sf, unit, rootdata, (void *)leafdata, w->sync, PETSC_TRUE, MPI_MODE_NOPRECEDE, 0, 0, &target_disp, NULL, &win)); 11185b0d146aSStefano Zampini #endif 111997a85fb4SToby Isaac ranks = w->wcommranks; 11206497c311SBarry Smith for (PetscMPIInt i = 0; i < nranks; i++) { 11215b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 11225b0d146aSStefano Zampini 11235b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 11249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Win_lock(MPI_LOCK_EXCLUSIVE, ranks[i], 0, win)); 11259566063dSJacob Faibussowitsch PetscCallMPI(MPI_Get(leafupdate, 1, mine[i], ranks[i], tdp, 1, remote[i], win)); 11269566063dSJacob Faibussowitsch PetscCallMPI(MPI_Accumulate((void *)leafdata, 1, mine[i], ranks[i], tdp, 1, remote[i], op, win)); 11279566063dSJacob Faibussowitsch PetscCallMPI(MPI_Win_unlock(ranks[i], win)); 11285b0d146aSStefano Zampini #else 11299566063dSJacob Faibussowitsch if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) PetscCallMPI(MPI_Win_lock(MPI_LOCK_SHARED, ranks[i], 0, win)); 11309566063dSJacob Faibussowitsch PetscCallMPI(MPI_Get_accumulate((void *)leafdata, 1, mine[i], leafupdate, 1, mine[i], ranks[i], tdp, 1, remote[i], op, win)); 11319566063dSJacob Faibussowitsch if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) PetscCallMPI(MPI_Win_unlock(ranks[i], win)); 11325b0d146aSStefano Zampini #endif 11335b0d146aSStefano Zampini } 11345b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 11355b0d146aSStefano Zampini w->flavor = oldf; 11365b0d146aSStefano Zampini #endif 11373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 113895fce210SBarry Smith } 113995fce210SBarry Smith 1140d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscSFFetchAndOpEnd_Window(PetscSF sf, MPI_Datatype unit, void *rootdata, const void *leafdata, void *leafupdate, MPI_Op op) 1141d71ae5a4SJacob Faibussowitsch { 114295fce210SBarry Smith MPI_Win win; 11435b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 11445b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window *)sf->data; 11455b0d146aSStefano Zampini #endif 11464b9acda6SJunchao Zhang MPI_Request *reqs = NULL; 114795fce210SBarry Smith 114895fce210SBarry Smith PetscFunctionBegin; 114997a85fb4SToby Isaac PetscCall(PetscSFFindWindow(sf, unit, rootdata, leafdata, &win, &reqs)); 11509566063dSJacob Faibussowitsch if (reqs) PetscCallMPI(MPI_Waitall(sf->nranks, reqs, MPI_STATUSES_IGNORE)); 11515b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 11529566063dSJacob Faibussowitsch PetscCall(PetscSFRestoreWindow(sf, unit, rootdata, w->sync, PETSC_TRUE, MPI_MODE_NOSUCCEED, PETSC_TRUE, &win)); 11535b0d146aSStefano Zampini #else 11549566063dSJacob Faibussowitsch PetscCall(PetscSFRestoreWindow(sf, unit, rootdata, PETSCSF_WINDOW_SYNC_LOCK, PETSC_FALSE, 0, PETSC_TRUE, &win)); 11555b0d146aSStefano Zampini #endif 11563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 115795fce210SBarry Smith } 115895fce210SBarry Smith 1159d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscSFCreate_Window(PetscSF sf) 1160d71ae5a4SJacob Faibussowitsch { 116195fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window *)sf->data; 116295fce210SBarry Smith 116395fce210SBarry Smith PetscFunctionBegin; 116495fce210SBarry Smith sf->ops->SetUp = PetscSFSetUp_Window; 116595fce210SBarry Smith sf->ops->SetFromOptions = PetscSFSetFromOptions_Window; 116695fce210SBarry Smith sf->ops->Reset = PetscSFReset_Window; 116795fce210SBarry Smith sf->ops->Destroy = PetscSFDestroy_Window; 116895fce210SBarry Smith sf->ops->View = PetscSFView_Window; 116995fce210SBarry Smith sf->ops->Duplicate = PetscSFDuplicate_Window; 1170ad227feaSJunchao Zhang sf->ops->BcastBegin = PetscSFBcastBegin_Window; 1171ad227feaSJunchao Zhang sf->ops->BcastEnd = PetscSFBcastEnd_Window; 117295fce210SBarry Smith sf->ops->ReduceBegin = PetscSFReduceBegin_Window; 117395fce210SBarry Smith sf->ops->ReduceEnd = PetscSFReduceEnd_Window; 117495fce210SBarry Smith sf->ops->FetchAndOpBegin = PetscSFFetchAndOpBegin_Window; 117595fce210SBarry Smith sf->ops->FetchAndOpEnd = PetscSFFetchAndOpEnd_Window; 117695fce210SBarry Smith 11774dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&w)); 117895fce210SBarry Smith sf->data = (void *)w; 117995fce210SBarry Smith w->sync = PETSCSF_WINDOW_SYNC_FENCE; 11805b0d146aSStefano Zampini w->flavor = PETSCSF_WINDOW_FLAVOR_CREATE; 11815b0d146aSStefano Zampini w->info = MPI_INFO_NULL; 118297a85fb4SToby Isaac w->window_comm = MPI_COMM_NULL; 118395fce210SBarry Smith 11849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowSetSyncType_C", PetscSFWindowSetSyncType_Window)); 11859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowGetSyncType_C", PetscSFWindowGetSyncType_Window)); 11869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowSetFlavorType_C", PetscSFWindowSetFlavorType_Window)); 11879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowGetFlavorType_C", PetscSFWindowGetFlavorType_Window)); 11889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowSetInfo_C", PetscSFWindowSetInfo_Window)); 11899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFWindowGetInfo_C", PetscSFWindowGetInfo_Window)); 119097a85fb4SToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFRegisterPersistent_C", PetscSFRegisterPersistent_Window)); 119197a85fb4SToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)sf, "PetscSFDeregisterPersistent_C", PetscSFDeregisterPersistent_Window)); 119295fce210SBarry Smith 1193100ffedbSJunchao Zhang #if defined(PETSC_HAVE_OPENMPI) 1194100ffedbSJunchao Zhang #if PETSC_PKG_OPENMPI_VERSION_LE(1, 6, 0) 119595fce210SBarry Smith { 119695fce210SBarry Smith PetscBool ackbug = PETSC_FALSE; 1197966bd95aSPierre Jolivet 11989566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-acknowledge_ompi_onesided_bug", &ackbug, NULL)); 1199966bd95aSPierre Jolivet PetscCheck(ackbug, 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"); 12009566063dSJacob Faibussowitsch PetscCall(PetscInfo(sf, "Acknowledged Open MPI bug, proceeding anyway. Expect memory corruption.\n")); 120195fce210SBarry Smith } 120295fce210SBarry Smith #endif 1203100ffedbSJunchao Zhang #endif 12043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 120595fce210SBarry Smith } 1206