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) */
PetscSFWindowOpTranslate(MPI_Op * op)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 @*/
PetscSFWindowGetDataTypes(PetscSF sf,MPI_Datatype unit,const MPI_Datatype ** localtypes,const MPI_Datatype ** remotetypes)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 @*/
PetscSFWindowSetFlavorType(PetscSF sf,PetscSFWindowFlavorType flavor)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
PetscSFWindowSetFlavorType_Window(PetscSF sf,PetscSFWindowFlavorType flavor)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 @*/
PetscSFWindowGetFlavorType(PetscSF sf,PetscSFWindowFlavorType * flavor)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
PetscSFWindowGetFlavorType_Window(PetscSF sf,PetscSFWindowFlavorType * flavor)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 @*/
PetscSFWindowSetSyncType(PetscSF sf,PetscSFWindowSyncType sync)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
PetscSFWindowSetSyncType_Window(PetscSF sf,PetscSFWindowSyncType sync)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 @*/
PetscSFWindowGetSyncType(PetscSF sf,PetscSFWindowSyncType * sync)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
PetscSFWindowGetSyncType_Window(PetscSF sf,PetscSFWindowSyncType * sync)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 @*/
PetscSFWindowSetInfo(PetscSF sf,MPI_Info info)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
PetscSFWindowSetInfo_Window(PetscSF sf,MPI_Info info)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 @*/
PetscSFWindowGetInfo(PetscSF sf,MPI_Info * info)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
PetscSFWindowGetInfo_Window(PetscSF sf,MPI_Info * info)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
PetscSFWindowCreateDynamicSF(PetscSF sf,PetscSF * dynsf)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
PetscSFWindowAttach(PetscSF sf,PetscSFWinLink link,void * rootdata,size_t wsize)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
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)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 */
PetscSFFindWindow(PetscSF sf,MPI_Datatype unit,const void * rootdata,const void * leafdata,MPI_Win * win,MPI_Request ** reqs)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 */
PetscSFRestoreWindow(PetscSF sf,MPI_Datatype unit,void * array,PetscSFWindowSyncType sync,PetscBool epoch,PetscMPIInt fenceassert,PetscBool update,MPI_Win * win)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
PetscSFSetUp_Window(PetscSF sf)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
PetscSFSetFromOptions_Window(PetscSF sf,PetscOptionItems PetscOptionsObject)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
PetscSFReset_Window(PetscSF sf)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
PetscSFRegisterPersistent_Window(PetscSF sf,MPI_Datatype unit,const void * rootdata,const void * leafdata)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
PetscSFDeregisterPersistent_Window(PetscSF sf,MPI_Datatype unit,const void * rootdata,const void * leafdata)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
PetscSFDestroy_Window(PetscSF sf)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
PetscSFView_Window(PetscSF sf,PetscViewer viewer)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
PetscSFDuplicate_Window(PetscSF sf,PetscSFDuplicateOption opt,PetscSF newsf)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
PetscSFBcastBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,const void * rootdata,PetscMemType leafmtype,void * leafdata,MPI_Op op)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
PetscSFBcastEnd_Window(PetscSF sf,MPI_Datatype unit,const void * rootdata,void * leafdata,MPI_Op op)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
PetscSFReduceBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType leafmtype,const void * leafdata,PetscMemType rootmtype,void * rootdata,MPI_Op op)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
PetscSFReduceEnd_Window(PetscSF sf,MPI_Datatype unit,const void * leafdata,void * rootdata,MPI_Op op)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
PetscSFFetchAndOpBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,void * rootdata,PetscMemType leafmtype,const void * leafdata,void * leafupdate,MPI_Op op)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
PetscSFFetchAndOpEnd_Window(PetscSF sf,MPI_Datatype unit,void * rootdata,const void * leafdata,void * leafupdate,MPI_Op op)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
PetscSFCreate_Window(PetscSF sf)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