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; 1395fce210SBarry Smith } PetscSF_Window; 1495fce210SBarry Smith 1595fce210SBarry Smith struct _n_PetscSFDataLink { 1695fce210SBarry Smith MPI_Datatype unit; 1795fce210SBarry Smith MPI_Datatype *mine; 1895fce210SBarry Smith MPI_Datatype *remote; 1995fce210SBarry Smith PetscSFDataLink next; 2095fce210SBarry Smith }; 2195fce210SBarry Smith 2295fce210SBarry Smith struct _n_PetscSFWinLink { 2395fce210SBarry Smith PetscBool inuse; 2495fce210SBarry Smith size_t bytes; 2595fce210SBarry Smith void *addr; 265b0d146aSStefano Zampini void *paddr; 2795fce210SBarry Smith MPI_Win win; 28684a874aSStefano Zampini MPI_Request *reqs; 295b0d146aSStefano Zampini PetscSFWindowFlavorType flavor; 305b0d146aSStefano Zampini MPI_Aint *dyn_target_addr; 3195fce210SBarry Smith PetscBool epoch; 3295fce210SBarry Smith PetscSFWinLink next; 3395fce210SBarry Smith }; 3495fce210SBarry Smith 35*4c8fdceaSLisandro Dalcin const char *const PetscSFWindowSyncTypes[] = {"FENCE","LOCK","ACTIVE","PetscSFWindowSyncType","PETSCSF_WINDOW_SYNC_",NULL}; 36*4c8fdceaSLisandro Dalcin const char *const PetscSFWindowFlavorTypes[] = {"CREATE","DYNAMIC","ALLOCATE","SHARED","PetscSFWindowFlavorType","PETSCSF_WINDOW_FLAVOR_",NULL}; 3795fce210SBarry Smith 38b2566f29SBarry Smith /* Built-in MPI_Ops act elementwise inside MPI_Accumulate, but cannot be used with composite types inside collectives (MPIU_Allreduce) */ 3995fce210SBarry Smith static PetscErrorCode PetscSFWindowOpTranslate(MPI_Op *op) 4095fce210SBarry Smith { 4195fce210SBarry Smith PetscFunctionBegin; 4295fce210SBarry Smith if (*op == MPIU_SUM) *op = MPI_SUM; 4395fce210SBarry Smith else if (*op == MPIU_MAX) *op = MPI_MAX; 4495fce210SBarry Smith else if (*op == MPIU_MIN) *op = MPI_MIN; 4595fce210SBarry Smith PetscFunctionReturn(0); 4695fce210SBarry Smith } 4795fce210SBarry Smith 4895fce210SBarry Smith /*@C 4995fce210SBarry Smith PetscSFWindowGetDataTypes - gets composite local and remote data types for each rank 5095fce210SBarry Smith 5195fce210SBarry Smith Not Collective 5295fce210SBarry Smith 5395fce210SBarry Smith Input Arguments: 5495fce210SBarry Smith + sf - star forest 5595fce210SBarry Smith - unit - data type for each node 5695fce210SBarry Smith 5795fce210SBarry Smith Output Arguments: 5895fce210SBarry Smith + localtypes - types describing part of local leaf buffer referencing each remote rank 5995fce210SBarry Smith - remotetypes - types describing part of remote root buffer referenced for each remote rank 6095fce210SBarry Smith 6195fce210SBarry Smith Level: developer 6295fce210SBarry Smith 6395fce210SBarry Smith .seealso: PetscSFSetGraph(), PetscSFView() 6495fce210SBarry Smith @*/ 6595fce210SBarry Smith static PetscErrorCode PetscSFWindowGetDataTypes(PetscSF sf,MPI_Datatype unit,const MPI_Datatype **localtypes,const MPI_Datatype **remotetypes) 6695fce210SBarry Smith { 6795fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 6895fce210SBarry Smith PetscErrorCode ierr; 6995fce210SBarry Smith PetscSFDataLink link; 7095fce210SBarry Smith PetscInt i,nranks; 7195fce210SBarry Smith const PetscInt *roffset,*rmine,*rremote; 7295fce210SBarry Smith const PetscMPIInt *ranks; 7395fce210SBarry Smith 7495fce210SBarry Smith PetscFunctionBegin; 7595fce210SBarry Smith /* Look for types in cache */ 7695fce210SBarry Smith for (link=w->link; link; link=link->next) { 7795fce210SBarry Smith PetscBool match; 7895fce210SBarry Smith ierr = MPIPetsc_Type_compare(unit,link->unit,&match);CHKERRQ(ierr); 7995fce210SBarry Smith if (match) { 8095fce210SBarry Smith *localtypes = link->mine; 8195fce210SBarry Smith *remotetypes = link->remote; 8295fce210SBarry Smith PetscFunctionReturn(0); 8395fce210SBarry Smith } 8495fce210SBarry Smith } 8595fce210SBarry Smith 8695fce210SBarry Smith /* Create new composite types for each send rank */ 87dec1416fSJunchao Zhang ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,&roffset,&rmine,&rremote);CHKERRQ(ierr); 8895dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 8995fce210SBarry Smith ierr = MPI_Type_dup(unit,&link->unit);CHKERRQ(ierr); 90dcca6d9dSJed Brown ierr = PetscMalloc2(nranks,&link->mine,nranks,&link->remote);CHKERRQ(ierr); 9195fce210SBarry Smith for (i=0; i<nranks; i++) { 925b0d146aSStefano Zampini PetscInt rcount = roffset[i+1] - roffset[i]; 9395fce210SBarry Smith PetscMPIInt *rmine,*rremote; 9495fce210SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES) 9595fce210SBarry Smith rmine = sf->rmine + sf->roffset[i]; 9695fce210SBarry Smith rremote = sf->rremote + sf->roffset[i]; 9795fce210SBarry Smith #else 9895fce210SBarry Smith PetscInt j; 99dcca6d9dSJed Brown ierr = PetscMalloc2(rcount,&rmine,rcount,&rremote);CHKERRQ(ierr); 10095fce210SBarry Smith for (j=0; j<rcount; j++) { 10195fce210SBarry Smith ierr = PetscMPIIntCast(sf->rmine[sf->roffset[i]+j],rmine+j);CHKERRQ(ierr); 10295fce210SBarry Smith ierr = PetscMPIIntCast(sf->rremote[sf->roffset[i]+j],rremote+j);CHKERRQ(ierr); 10395fce210SBarry Smith } 10495fce210SBarry Smith #endif 1055b0d146aSStefano Zampini 10695fce210SBarry Smith ierr = MPI_Type_create_indexed_block(rcount,1,rmine,link->unit,&link->mine[i]);CHKERRQ(ierr); 10795fce210SBarry Smith ierr = MPI_Type_create_indexed_block(rcount,1,rremote,link->unit,&link->remote[i]);CHKERRQ(ierr); 10895fce210SBarry Smith #if defined(PETSC_USE_64BIT_INDICES) 10995fce210SBarry Smith ierr = PetscFree2(rmine,rremote);CHKERRQ(ierr); 11095fce210SBarry Smith #endif 11195fce210SBarry Smith ierr = MPI_Type_commit(&link->mine[i]);CHKERRQ(ierr); 11295fce210SBarry Smith ierr = MPI_Type_commit(&link->remote[i]);CHKERRQ(ierr); 11395fce210SBarry Smith } 11495fce210SBarry Smith link->next = w->link; 11595fce210SBarry Smith w->link = link; 11695fce210SBarry Smith 11795fce210SBarry Smith *localtypes = link->mine; 11895fce210SBarry Smith *remotetypes = link->remote; 11995fce210SBarry Smith PetscFunctionReturn(0); 12095fce210SBarry Smith } 12195fce210SBarry Smith 12295fce210SBarry Smith /*@C 1235b0d146aSStefano Zampini PetscSFWindowSetFlavorType - Set flavor type for MPI_Win creation 1245b0d146aSStefano Zampini 1255b0d146aSStefano Zampini Logically Collective 1265b0d146aSStefano Zampini 1275b0d146aSStefano Zampini Input Arguments: 1285b0d146aSStefano Zampini + sf - star forest for communication 1295b0d146aSStefano Zampini - flavor - flavor type 1305b0d146aSStefano Zampini 1315b0d146aSStefano Zampini Options Database Key: 1325b0d146aSStefano Zampini . -sf_window_flavor <flavor> - sets the flavor type CREATE, DYNAMIC, ALLOCATE or SHARED (see PetscSFWindowFlavorType) 1335b0d146aSStefano Zampini 1345b0d146aSStefano Zampini Level: advanced 1355b0d146aSStefano Zampini 1365b0d146aSStefano Zampini Notes: Windows reusage follow this rules: 1375b0d146aSStefano Zampini 1385b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_CREATE: creates a new window every time, uses MPI_Win_create 1395b0d146aSStefano Zampini 1405b0d146aSStefano 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. 1415b0d146aSStefano Zampini for i=1 to K 1425b0d146aSStefano Zampini PetscSFOperationBegin(rootdata1,leafdata_whatever); 1435b0d146aSStefano Zampini PetscSFOperationEnd(rootdata1,leafdata_whatever); 1445b0d146aSStefano Zampini ... 1455b0d146aSStefano Zampini PetscSFOperationBegin(rootdataN,leafdata_whatever); 1465b0d146aSStefano Zampini PetscSFOperationEnd(rootdataN,leafdata_whatever); 1475b0d146aSStefano Zampini endfor 1485b0d146aSStefano Zampini The following pattern will instead raise an error 1495b0d146aSStefano Zampini PetscSFOperationBegin(rootdata1,leafdata_whatever); 1505b0d146aSStefano Zampini PetscSFOperationEnd(rootdata1,leafdata_whatever); 1515b0d146aSStefano Zampini PetscSFOperationBegin(rank ? rootdata1 : rootdata2,leafdata_whatever); 1525b0d146aSStefano Zampini PetscSFOperationEnd(rank ? rootdata1 : rootdata2,leafdata_whatever); 1535b0d146aSStefano Zampini 1545b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_ALLOCATE: uses MPI_Win_allocate, reuses any pre-existing window which fits the data and it is not in use 1555b0d146aSStefano Zampini 1565b0d146aSStefano Zampini PETSCSF_WINDOW_FLAVOR_SHARED: uses MPI_Win_allocate_shared, reusage policy as for PETSCSF_WINDOW_FLAVOR_ALLOCATE 1575b0d146aSStefano Zampini 1585b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowGetFlavorType() 1595b0d146aSStefano Zampini @*/ 1605b0d146aSStefano Zampini PetscErrorCode PetscSFWindowSetFlavorType(PetscSF sf,PetscSFWindowFlavorType flavor) 1615b0d146aSStefano Zampini { 1625b0d146aSStefano Zampini PetscErrorCode ierr; 1635b0d146aSStefano Zampini 1645b0d146aSStefano Zampini PetscFunctionBegin; 1655b0d146aSStefano Zampini PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 1665b0d146aSStefano Zampini PetscValidLogicalCollectiveEnum(sf,flavor,2); 1675b0d146aSStefano Zampini ierr = PetscTryMethod(sf,"PetscSFWindowSetFlavorType_C",(PetscSF,PetscSFWindowFlavorType),(sf,flavor));CHKERRQ(ierr); 1685b0d146aSStefano Zampini PetscFunctionReturn(0); 1695b0d146aSStefano Zampini } 1705b0d146aSStefano Zampini 1715b0d146aSStefano Zampini static PetscErrorCode PetscSFWindowSetFlavorType_Window(PetscSF sf,PetscSFWindowFlavorType flavor) 1725b0d146aSStefano Zampini { 1735b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 1745b0d146aSStefano Zampini 1755b0d146aSStefano Zampini PetscFunctionBegin; 1765b0d146aSStefano Zampini w->flavor = flavor; 1775b0d146aSStefano Zampini PetscFunctionReturn(0); 1785b0d146aSStefano Zampini } 1795b0d146aSStefano Zampini 1805b0d146aSStefano Zampini /*@C 1815b0d146aSStefano Zampini PetscSFWindowGetFlavorType - Get flavor type for PetscSF communication 1825b0d146aSStefano Zampini 1835b0d146aSStefano Zampini Logically Collective 1845b0d146aSStefano Zampini 1855b0d146aSStefano Zampini Input Argument: 1865b0d146aSStefano Zampini . sf - star forest for communication 1875b0d146aSStefano Zampini 1885b0d146aSStefano Zampini Output Argument: 1895b0d146aSStefano Zampini . flavor - flavor type 1905b0d146aSStefano Zampini 1915b0d146aSStefano Zampini Level: advanced 1925b0d146aSStefano Zampini 1935b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowSetFlavorType() 1945b0d146aSStefano Zampini @*/ 1955b0d146aSStefano Zampini PetscErrorCode PetscSFWindowGetFlavorType(PetscSF sf,PetscSFWindowFlavorType *flavor) 1965b0d146aSStefano Zampini { 1975b0d146aSStefano Zampini PetscErrorCode ierr; 1985b0d146aSStefano Zampini 1995b0d146aSStefano Zampini PetscFunctionBegin; 2005b0d146aSStefano Zampini PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 2015b0d146aSStefano Zampini PetscValidPointer(flavor,2); 2025b0d146aSStefano Zampini ierr = PetscUseMethod(sf,"PetscSFWindowGetFlavorType_C",(PetscSF,PetscSFWindowFlavorType*),(sf,flavor));CHKERRQ(ierr); 2035b0d146aSStefano Zampini PetscFunctionReturn(0); 2045b0d146aSStefano Zampini } 2055b0d146aSStefano Zampini 2065b0d146aSStefano Zampini static PetscErrorCode PetscSFWindowGetFlavorType_Window(PetscSF sf,PetscSFWindowFlavorType *flavor) 2075b0d146aSStefano Zampini { 2085b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 2095b0d146aSStefano Zampini 2105b0d146aSStefano Zampini PetscFunctionBegin; 2115b0d146aSStefano Zampini *flavor = w->flavor; 2125b0d146aSStefano Zampini PetscFunctionReturn(0); 2135b0d146aSStefano Zampini } 2145b0d146aSStefano Zampini 2155b0d146aSStefano Zampini /*@C 2165b0d146aSStefano Zampini PetscSFWindowSetSyncType - Set synchronization type for PetscSF communication 21795fce210SBarry Smith 21895fce210SBarry Smith Logically Collective 21995fce210SBarry Smith 22095fce210SBarry Smith Input Arguments: 22195fce210SBarry Smith + sf - star forest for communication 22295fce210SBarry Smith - sync - synchronization type 22395fce210SBarry Smith 22495fce210SBarry Smith Options Database Key: 22560263706SJed Brown . -sf_window_sync <sync> - sets the synchronization type FENCE, LOCK, or ACTIVE (see PetscSFWindowSyncType) 22695fce210SBarry Smith 22795fce210SBarry Smith Level: advanced 22895fce210SBarry Smith 22995fce210SBarry Smith .seealso: PetscSFSetFromOptions(), PetscSFWindowGetSyncType() 23095fce210SBarry Smith @*/ 23195fce210SBarry Smith PetscErrorCode PetscSFWindowSetSyncType(PetscSF sf,PetscSFWindowSyncType sync) 23295fce210SBarry Smith { 23395fce210SBarry Smith PetscErrorCode ierr; 23495fce210SBarry Smith 23595fce210SBarry Smith PetscFunctionBegin; 23695fce210SBarry Smith PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 23795fce210SBarry Smith PetscValidLogicalCollectiveEnum(sf,sync,2); 2385b0d146aSStefano Zampini ierr = PetscTryMethod(sf,"PetscSFWindowSetSyncType_C",(PetscSF,PetscSFWindowSyncType),(sf,sync));CHKERRQ(ierr); 23995fce210SBarry Smith PetscFunctionReturn(0); 24095fce210SBarry Smith } 24195fce210SBarry Smith 242f7a08781SBarry Smith static PetscErrorCode PetscSFWindowSetSyncType_Window(PetscSF sf,PetscSFWindowSyncType sync) 24395fce210SBarry Smith { 24495fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 24595fce210SBarry Smith 24695fce210SBarry Smith PetscFunctionBegin; 24795fce210SBarry Smith w->sync = sync; 24895fce210SBarry Smith PetscFunctionReturn(0); 24995fce210SBarry Smith } 25095fce210SBarry Smith 25195fce210SBarry Smith /*@C 2525b0d146aSStefano Zampini PetscSFWindowGetSyncType - Get synchronization type for PetscSF communication 25395fce210SBarry Smith 25495fce210SBarry Smith Logically Collective 25595fce210SBarry Smith 25695fce210SBarry Smith Input Argument: 25795fce210SBarry Smith . sf - star forest for communication 25895fce210SBarry Smith 25995fce210SBarry Smith Output Argument: 26095fce210SBarry Smith . sync - synchronization type 26195fce210SBarry Smith 26295fce210SBarry Smith Level: advanced 26395fce210SBarry Smith 2645b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowSetSyncType() 26595fce210SBarry Smith @*/ 26695fce210SBarry Smith PetscErrorCode PetscSFWindowGetSyncType(PetscSF sf,PetscSFWindowSyncType *sync) 26795fce210SBarry Smith { 26895fce210SBarry Smith PetscErrorCode ierr; 26995fce210SBarry Smith 27095fce210SBarry Smith PetscFunctionBegin; 27195fce210SBarry Smith PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 27295fce210SBarry Smith PetscValidPointer(sync,2); 273163d334eSBarry Smith ierr = PetscUseMethod(sf,"PetscSFWindowGetSyncType_C",(PetscSF,PetscSFWindowSyncType*),(sf,sync));CHKERRQ(ierr); 27495fce210SBarry Smith PetscFunctionReturn(0); 27595fce210SBarry Smith } 27695fce210SBarry Smith 277f7a08781SBarry Smith static PetscErrorCode PetscSFWindowGetSyncType_Window(PetscSF sf,PetscSFWindowSyncType *sync) 27895fce210SBarry Smith { 27995fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 28095fce210SBarry Smith 28195fce210SBarry Smith PetscFunctionBegin; 28295fce210SBarry Smith *sync = w->sync; 28395fce210SBarry Smith PetscFunctionReturn(0); 28495fce210SBarry Smith } 28595fce210SBarry Smith 28695fce210SBarry Smith /*@C 2875b0d146aSStefano Zampini PetscSFWindowSetInfo - Set the MPI_Info handle that will be used for subsequent windows allocation 2885b0d146aSStefano Zampini 2895b0d146aSStefano Zampini Logically Collective 2905b0d146aSStefano Zampini 2915b0d146aSStefano Zampini Input Argument: 2925b0d146aSStefano Zampini + sf - star forest for communication 2935b0d146aSStefano Zampini - info - MPI_Info handle 2945b0d146aSStefano Zampini 2955b0d146aSStefano Zampini Level: advanced 2965b0d146aSStefano Zampini 2975b0d146aSStefano Zampini Notes: the info handle is duplicated with a call to MPI_Info_dup unless info = MPI_INFO_NULL. 2985b0d146aSStefano Zampini 2995b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowGetInfo() 3005b0d146aSStefano Zampini @*/ 3015b0d146aSStefano Zampini PetscErrorCode PetscSFWindowSetInfo(PetscSF sf,MPI_Info info) 3025b0d146aSStefano Zampini { 3035b0d146aSStefano Zampini PetscErrorCode ierr; 3045b0d146aSStefano Zampini 3055b0d146aSStefano Zampini PetscFunctionBegin; 3065b0d146aSStefano Zampini PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 3075b0d146aSStefano Zampini ierr = PetscTryMethod(sf,"PetscSFWindowSetInfo_C",(PetscSF,MPI_Info),(sf,info));CHKERRQ(ierr); 3085b0d146aSStefano Zampini PetscFunctionReturn(0); 3095b0d146aSStefano Zampini } 3105b0d146aSStefano Zampini 3115b0d146aSStefano Zampini static PetscErrorCode PetscSFWindowSetInfo_Window(PetscSF sf,MPI_Info info) 3125b0d146aSStefano Zampini { 3135b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 3145b0d146aSStefano Zampini PetscErrorCode ierr; 3155b0d146aSStefano Zampini 3165b0d146aSStefano Zampini PetscFunctionBegin; 3175b0d146aSStefano Zampini if (w->info != MPI_INFO_NULL) { 3185b0d146aSStefano Zampini ierr = MPI_Info_free(&w->info);CHKERRQ(ierr); 3195b0d146aSStefano Zampini } 3205b0d146aSStefano Zampini if (info != MPI_INFO_NULL) { 3215b0d146aSStefano Zampini ierr = MPI_Info_dup(info,&w->info);CHKERRQ(ierr); 3225b0d146aSStefano Zampini } 3235b0d146aSStefano Zampini PetscFunctionReturn(0); 3245b0d146aSStefano Zampini } 3255b0d146aSStefano Zampini 3265b0d146aSStefano Zampini /*@C 3275b0d146aSStefano Zampini PetscSFWindowGetInfo - Get the MPI_Info handle used for windows allocation 3285b0d146aSStefano Zampini 3295b0d146aSStefano Zampini Logically Collective 3305b0d146aSStefano Zampini 3315b0d146aSStefano Zampini Input Argument: 3325b0d146aSStefano Zampini . sf - star forest for communication 3335b0d146aSStefano Zampini 3345b0d146aSStefano Zampini Output Argument: 3355b0d146aSStefano Zampini . info - MPI_Info handle 3365b0d146aSStefano Zampini 3375b0d146aSStefano Zampini Level: advanced 3385b0d146aSStefano Zampini 3395b0d146aSStefano Zampini Notes: if PetscSFWindowSetInfo() has not be called, this returns MPI_INFO_NULL 3405b0d146aSStefano Zampini 3415b0d146aSStefano Zampini .seealso: PetscSFSetFromOptions(), PetscSFWindowSetInfo() 3425b0d146aSStefano Zampini @*/ 3435b0d146aSStefano Zampini PetscErrorCode PetscSFWindowGetInfo(PetscSF sf,MPI_Info *info) 3445b0d146aSStefano Zampini { 3455b0d146aSStefano Zampini PetscErrorCode ierr; 3465b0d146aSStefano Zampini 3475b0d146aSStefano Zampini PetscFunctionBegin; 3485b0d146aSStefano Zampini PetscValidHeaderSpecific(sf,PETSCSF_CLASSID,1); 3495b0d146aSStefano Zampini PetscValidPointer(info,2); 3505b0d146aSStefano Zampini ierr = PetscUseMethod(sf,"PetscSFWindowGetInfo_C",(PetscSF,MPI_Info*),(sf,info));CHKERRQ(ierr); 3515b0d146aSStefano Zampini PetscFunctionReturn(0); 3525b0d146aSStefano Zampini } 3535b0d146aSStefano Zampini 3545b0d146aSStefano Zampini static PetscErrorCode PetscSFWindowGetInfo_Window(PetscSF sf,MPI_Info *info) 3555b0d146aSStefano Zampini { 3565b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 3575b0d146aSStefano Zampini 3585b0d146aSStefano Zampini PetscFunctionBegin; 3595b0d146aSStefano Zampini *info = w->info; 3605b0d146aSStefano Zampini PetscFunctionReturn(0); 3615b0d146aSStefano Zampini } 3625b0d146aSStefano Zampini 3635b0d146aSStefano Zampini /* 36495fce210SBarry Smith PetscSFGetWindow - Get a window for use with a given data type 36595fce210SBarry Smith 36695fce210SBarry Smith Collective on PetscSF 36795fce210SBarry Smith 36895fce210SBarry Smith Input Arguments: 36995fce210SBarry Smith + sf - star forest 37095fce210SBarry Smith . unit - data type 37195fce210SBarry Smith . array - array to be sent 3725b0d146aSStefano Zampini . sync - type of synchronization PetscSFWindowSyncType 37395fce210SBarry Smith . epoch - PETSC_TRUE to acquire the window and start an epoch, PETSC_FALSE to just acquire the window 3745b0d146aSStefano Zampini . fenceassert - assert parameter for call to MPI_Win_fence(), if sync == PETSCSF_WINDOW_SYNC_FENCE 3755b0d146aSStefano Zampini . postassert - assert parameter for call to MPI_Win_post(), if sync == PETSCSF_WINDOW_SYNC_ACTIVE 376684a874aSStefano Zampini - startassert - assert parameter for call to MPI_Win_start(), if sync == PETSCSF_WINDOW_SYNC_ACTIVE 37795fce210SBarry Smith 37895fce210SBarry Smith Output Arguments: 379684a874aSStefano Zampini + target_disp - target_disp argument for RMA calls (significative for PETSCSF_WINDOW_FLAVOR_DYNAMIC only) 380684a874aSStefano Zampini + reqs - array of requests (significative for sync == PETSCSF_WINDOW_SYNC_LOCK only) 381684a874aSStefano Zampini - win - window 38295fce210SBarry Smith 38395fce210SBarry Smith Level: developer 384dec1416fSJunchao Zhang .seealso: PetscSFGetRootRanks(), PetscSFWindowGetDataTypes() 3855b0d146aSStefano Zampini */ 386684a874aSStefano Zampini static PetscErrorCode PetscSFGetWindow(PetscSF sf,MPI_Datatype unit,void *array,PetscSFWindowSyncType sync,PetscBool epoch,PetscMPIInt fenceassert,PetscMPIInt postassert,PetscMPIInt startassert,const MPI_Aint **target_disp, MPI_Request **reqs, MPI_Win *win) 38795fce210SBarry Smith { 38895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 38995fce210SBarry Smith PetscErrorCode ierr; 39095fce210SBarry Smith MPI_Aint lb,lb_true,bytes,bytes_true; 39195fce210SBarry Smith PetscSFWinLink link; 3925b0d146aSStefano Zampini MPI_Aint winaddr; 3935b0d146aSStefano Zampini PetscInt nranks; 3945b0d146aSStefano Zampini PetscBool reuse = PETSC_FALSE, update = PETSC_FALSE; 3955b0d146aSStefano Zampini PetscBool dummy[2]; 3965b0d146aSStefano Zampini MPI_Aint wsize; 39795fce210SBarry Smith 39895fce210SBarry Smith PetscFunctionBegin; 39995fce210SBarry Smith ierr = MPI_Type_get_extent(unit,&lb,&bytes);CHKERRQ(ierr); 40095fce210SBarry Smith ierr = MPI_Type_get_true_extent(unit,&lb_true,&bytes_true);CHKERRQ(ierr); 40195fce210SBarry Smith if (lb != 0 || lb_true != 0) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"No support for unit type with nonzero lower bound, write petsc-maint@mcs.anl.gov if you want this feature"); 40295fce210SBarry Smith if (bytes != bytes_true) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"No support for unit type with modified extent, write petsc-maint@mcs.anl.gov if you want this feature"); 4035b0d146aSStefano Zampini if (w->flavor != PETSCSF_WINDOW_FLAVOR_CREATE) reuse = PETSC_TRUE; 4045b0d146aSStefano Zampini for (link=w->wins; reuse && link; link=link->next) { 4055b0d146aSStefano Zampini PetscBool winok = PETSC_FALSE; 4065b0d146aSStefano Zampini if (w->flavor != link->flavor) continue; 4075b0d146aSStefano Zampini switch (w->flavor) { 4085b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_DYNAMIC: /* check available matching array, error if in use (we additionally check that the matching condition is the same across processes) */ 4095b0d146aSStefano Zampini if (array == link->addr) { 41076bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 4115b0d146aSStefano Zampini dummy[0] = PETSC_TRUE; 4125b0d146aSStefano Zampini dummy[1] = PETSC_TRUE; 4135b0d146aSStefano Zampini ierr = MPI_Allreduce(MPI_IN_PLACE,dummy ,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 4145b0d146aSStefano Zampini ierr = MPI_Allreduce(MPI_IN_PLACE,dummy+1,1,MPIU_BOOL,MPI_LOR ,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 4155b0d146aSStefano Zampini if (dummy[0] != dummy[1]) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"PETSCSF_WINDOW_FLAVOR_DYNAMIC requires root pointers to be consistently used across the comm. Use PETSCSF_WINDOW_FLAVOR_CREATE or PETSCSF_WINDOW_FLAVOR_ALLOCATE instead"); 41676bd3646SJed Brown } 4175b0d146aSStefano Zampini if (link->inuse) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_PLIB,"Window in use"); 4185b0d146aSStefano Zampini if (epoch && link->epoch) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_PLIB,"Window epoch not finished"); 4195b0d146aSStefano Zampini winok = PETSC_TRUE; 4205b0d146aSStefano Zampini link->paddr = array; 42176bd3646SJed Brown } else if (PetscDefined(USE_DEBUG)) { 4225b0d146aSStefano Zampini dummy[0] = PETSC_FALSE; 4235b0d146aSStefano Zampini dummy[1] = PETSC_FALSE; 4245b0d146aSStefano Zampini ierr = MPI_Allreduce(MPI_IN_PLACE,dummy ,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 4255b0d146aSStefano Zampini ierr = MPI_Allreduce(MPI_IN_PLACE,dummy+1,1,MPIU_BOOL,MPI_LOR ,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 4265b0d146aSStefano Zampini if (dummy[0] != dummy[1]) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"PETSCSF_WINDOW_FLAVOR_DYNAMIC requires root pointers to be consistently used across the comm. Use PETSCSF_WINDOW_FLAVOR_CREATE or PETSCSF_WINDOW_FLAVOR_ALLOCATE instead"); 4275b0d146aSStefano Zampini } 4285b0d146aSStefano Zampini break; 4295b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_ALLOCATE: /* check available by matching size, allocate if in use */ 4305b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_SHARED: 4315b0d146aSStefano Zampini if (!link->inuse && bytes == (MPI_Aint)link->bytes) { 4325b0d146aSStefano Zampini update = PETSC_TRUE; 4335b0d146aSStefano Zampini link->paddr = array; 4345b0d146aSStefano Zampini winok = PETSC_TRUE; 4355b0d146aSStefano Zampini } 4365b0d146aSStefano Zampini break; 4375b0d146aSStefano Zampini default: SETERRQ1(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"No support for flavor %s",PetscSFWindowFlavorTypes[w->flavor]); 4385b0d146aSStefano Zampini } 4395b0d146aSStefano Zampini if (winok) { 4405b0d146aSStefano Zampini *win = link->win; 4415b0d146aSStefano Zampini ierr = PetscInfo3(sf,"Reusing window %d of flavor %d for comm %d\n",link->win,link->flavor,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 4425b0d146aSStefano Zampini goto found; 4435b0d146aSStefano Zampini } 4445b0d146aSStefano Zampini } 4455b0d146aSStefano Zampini 4465b0d146aSStefano Zampini wsize = (MPI_Aint)bytes*sf->nroots; 44795dccacaSBarry Smith ierr = PetscNew(&link);CHKERRQ(ierr); 44895fce210SBarry Smith link->bytes = bytes; 44995fce210SBarry Smith link->next = w->wins; 4505b0d146aSStefano Zampini link->flavor = w->flavor; 4515b0d146aSStefano Zampini link->dyn_target_addr = NULL; 452684a874aSStefano Zampini link->reqs = NULL; 45395fce210SBarry Smith w->wins = link; 454684a874aSStefano Zampini if (sync == PETSCSF_WINDOW_SYNC_LOCK) { 455684a874aSStefano Zampini PetscInt i; 456684a874aSStefano Zampini 457684a874aSStefano Zampini ierr = PetscMalloc1(sf->nranks,&link->reqs);CHKERRQ(ierr); 458684a874aSStefano Zampini for (i = 0; i < sf->nranks; i++) link->reqs[i] = MPI_REQUEST_NULL; 459684a874aSStefano Zampini } 4605b0d146aSStefano Zampini switch (w->flavor) { 4615b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_CREATE: 4625b0d146aSStefano Zampini ierr = MPI_Win_create(array,wsize,(PetscMPIInt)bytes,w->info,PetscObjectComm((PetscObject)sf),&link->win);CHKERRQ(ierr); 4635b0d146aSStefano Zampini link->addr = array; 4645b0d146aSStefano Zampini link->paddr = array; 4655b0d146aSStefano Zampini break; 4665b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_DYNAMIC: 4675b0d146aSStefano Zampini ierr = MPI_Win_create_dynamic(w->info,PetscObjectComm((PetscObject)sf),&link->win);CHKERRQ(ierr); 4685b0d146aSStefano Zampini #if defined(PETSC_HAVE_OMPI_MAJOR_VERSION) /* some OpenMPI versions do not support MPI_Win_attach(win,NULL,0); */ 4695b0d146aSStefano Zampini ierr = MPI_Win_attach(link->win,wsize ? array : &ierr,wsize);CHKERRQ(ierr); 4705b0d146aSStefano Zampini #else 4715b0d146aSStefano Zampini ierr = MPI_Win_attach(link->win,array,wsize);CHKERRQ(ierr); 4725b0d146aSStefano Zampini #endif 4735b0d146aSStefano Zampini link->addr = array; 4745b0d146aSStefano Zampini link->paddr = array; 4755b0d146aSStefano Zampini if (!w->dynsf) SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_ORDER,"Must call PetscSFSetUp()"); 4765b0d146aSStefano Zampini ierr = PetscSFSetUp(w->dynsf);CHKERRQ(ierr); 4775b0d146aSStefano Zampini ierr = PetscSFGetRootRanks(w->dynsf,&nranks,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 4785b0d146aSStefano Zampini ierr = PetscMalloc1(nranks,&link->dyn_target_addr);CHKERRQ(ierr); 4795b0d146aSStefano Zampini ierr = MPI_Get_address(array,&winaddr);CHKERRQ(ierr); 4805b0d146aSStefano Zampini ierr = PetscSFBcastBegin(w->dynsf,MPI_AINT,&winaddr,link->dyn_target_addr);CHKERRQ(ierr); 4815b0d146aSStefano Zampini ierr = PetscSFBcastEnd(w->dynsf,MPI_AINT,&winaddr,link->dyn_target_addr);CHKERRQ(ierr); 4825b0d146aSStefano Zampini break; 4835b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_ALLOCATE: 4845b0d146aSStefano Zampini ierr = MPI_Win_allocate(wsize,(PetscMPIInt)bytes,w->info,PetscObjectComm((PetscObject)sf),&link->addr,&link->win);CHKERRQ(ierr); 4855b0d146aSStefano Zampini update = PETSC_TRUE; 4865b0d146aSStefano Zampini link->paddr = array; 4875b0d146aSStefano Zampini break; 4885b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) 4895b0d146aSStefano Zampini case PETSCSF_WINDOW_FLAVOR_SHARED: 4905b0d146aSStefano Zampini ierr = MPI_Win_allocate_shared(wsize,(PetscMPIInt)bytes,w->info,PetscObjectComm((PetscObject)sf),&link->addr,&link->win);CHKERRQ(ierr); 4915b0d146aSStefano Zampini update = PETSC_TRUE; 4925b0d146aSStefano Zampini link->paddr = array; 4935b0d146aSStefano Zampini break; 4945b0d146aSStefano Zampini #endif 4955b0d146aSStefano Zampini default: SETERRQ1(PetscObjectComm((PetscObject)sf),PETSC_ERR_SUP,"No support for flavor %s",PetscSFWindowFlavorTypes[w->flavor]); 4965b0d146aSStefano Zampini } 4975b0d146aSStefano Zampini ierr = PetscInfo3(sf,"New window %d of flavor %d for comm %d\n",link->win,link->flavor,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 49895fce210SBarry Smith *win = link->win; 49995fce210SBarry Smith 5005b0d146aSStefano Zampini found: 5015b0d146aSStefano Zampini 502684a874aSStefano Zampini if (target_disp) *target_disp = link->dyn_target_addr; 503684a874aSStefano Zampini if (reqs) *reqs = link->reqs; 504684a874aSStefano Zampini if (update) { /* locks are needed for the "separate" memory model only, the fence guaranties memory-synchronization */ 505684a874aSStefano Zampini PetscMPIInt rank; 506684a874aSStefano Zampini 507684a874aSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)sf),&rank);CHKERRQ(ierr); 508684a874aSStefano Zampini if (sync == PETSCSF_WINDOW_SYNC_LOCK) { ierr = MPI_Win_lock(MPI_LOCK_EXCLUSIVE,rank,MPI_MODE_NOCHECK,*win);CHKERRQ(ierr); } 5095b0d146aSStefano Zampini ierr = PetscMemcpy(link->addr,array,sf->nroots*bytes);CHKERRQ(ierr); 5105b0d146aSStefano Zampini if (sync == PETSCSF_WINDOW_SYNC_LOCK) { 511684a874aSStefano Zampini ierr = MPI_Win_unlock(rank,*win);CHKERRQ(ierr); 5125b0d146aSStefano Zampini ierr = MPI_Win_fence(0,*win);CHKERRQ(ierr); 5135b0d146aSStefano Zampini } 5145b0d146aSStefano Zampini } 5155b0d146aSStefano Zampini link->inuse = PETSC_TRUE; 5165b0d146aSStefano Zampini link->epoch = epoch; 51795fce210SBarry Smith if (epoch) { 5185b0d146aSStefano Zampini switch (sync) { 51995fce210SBarry Smith case PETSCSF_WINDOW_SYNC_FENCE: 52095fce210SBarry Smith ierr = MPI_Win_fence(fenceassert,*win);CHKERRQ(ierr); 52195fce210SBarry Smith break; 52295fce210SBarry Smith case PETSCSF_WINDOW_SYNC_LOCK: /* Handled outside */ 52395fce210SBarry Smith break; 52495fce210SBarry Smith case PETSCSF_WINDOW_SYNC_ACTIVE: { 52595fce210SBarry Smith MPI_Group ingroup,outgroup; 5265b0d146aSStefano Zampini PetscMPIInt isize,osize; 5275b0d146aSStefano Zampini 5285b0d146aSStefano Zampini /* OpenMPI 4.0.2 with btl=vader does not like calling 5295b0d146aSStefano Zampini - MPI_Win_complete when ogroup is empty 5305b0d146aSStefano Zampini - MPI_Win_wait when igroup is empty 5315b0d146aSStefano Zampini So, we do not even issue the corresponding start and post calls 5325b0d146aSStefano Zampini The MPI standard (Sec. 11.5.2 of MPI 3.1) only requires that 5335b0d146aSStefano Zampini start(outgroup) has a matching post(ingroup) 5345b0d146aSStefano Zampini and this is guaranteed by PetscSF 5355b0d146aSStefano Zampini */ 53695fce210SBarry Smith ierr = PetscSFGetGroups(sf,&ingroup,&outgroup);CHKERRQ(ierr); 5375b0d146aSStefano Zampini ierr = MPI_Group_size(ingroup,&isize);CHKERRQ(ierr); 5385b0d146aSStefano Zampini ierr = MPI_Group_size(outgroup,&osize);CHKERRQ(ierr); 5395b0d146aSStefano Zampini if (isize) { ierr = MPI_Win_post(ingroup,postassert,*win);CHKERRQ(ierr); } 5405b0d146aSStefano Zampini if (osize) { ierr = MPI_Win_start(outgroup,startassert,*win);CHKERRQ(ierr); } 54195fce210SBarry Smith } break; 54295fce210SBarry Smith default: SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_PLIB,"Unknown synchronization type"); 54395fce210SBarry Smith } 54495fce210SBarry Smith } 54595fce210SBarry Smith PetscFunctionReturn(0); 54695fce210SBarry Smith } 54795fce210SBarry Smith 5485b0d146aSStefano Zampini /* 54995fce210SBarry Smith PetscSFFindWindow - Finds a window that is already in use 55095fce210SBarry Smith 55195fce210SBarry Smith Not Collective 55295fce210SBarry Smith 55395fce210SBarry Smith Input Arguments: 55495fce210SBarry Smith + sf - star forest 55595fce210SBarry Smith . unit - data type 55695fce210SBarry Smith - array - array with which the window is associated 55795fce210SBarry Smith 55895fce210SBarry Smith Output Arguments: 559684a874aSStefano Zampini + win - window 560684a874aSStefano Zampini - reqs - outstanding requests associated to the window 56195fce210SBarry Smith 56295fce210SBarry Smith Level: developer 56395fce210SBarry Smith 56495fce210SBarry Smith .seealso: PetscSFGetWindow(), PetscSFRestoreWindow() 5655b0d146aSStefano Zampini */ 566684a874aSStefano Zampini static PetscErrorCode PetscSFFindWindow(PetscSF sf,MPI_Datatype unit,const void *array,MPI_Win *win,MPI_Request **reqs) 56795fce210SBarry Smith { 56895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 56995fce210SBarry Smith PetscSFWinLink link; 5705b0d146aSStefano Zampini PetscErrorCode ierr; 57195fce210SBarry Smith 57295fce210SBarry Smith PetscFunctionBegin; 573c0cd0301SJed Brown *win = MPI_WIN_NULL; 57495fce210SBarry Smith for (link=w->wins; link; link=link->next) { 5755b0d146aSStefano Zampini if (array == link->paddr) { 5765b0d146aSStefano Zampini ierr = PetscInfo3(sf,"Window %d of flavor %d for comm %d\n",link->win,link->flavor,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 57795fce210SBarry Smith *win = link->win; 578684a874aSStefano Zampini *reqs = link->reqs; 57995fce210SBarry Smith PetscFunctionReturn(0); 58095fce210SBarry Smith } 58195fce210SBarry Smith } 58295fce210SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Requested window not in use"); 58395fce210SBarry Smith PetscFunctionReturn(0); 58495fce210SBarry Smith } 58595fce210SBarry Smith 5865b0d146aSStefano Zampini /* 58795fce210SBarry Smith PetscSFRestoreWindow - Restores a window obtained with PetscSFGetWindow() 58895fce210SBarry Smith 58995fce210SBarry Smith Collective 59095fce210SBarry Smith 59195fce210SBarry Smith Input Arguments: 59295fce210SBarry Smith + sf - star forest 59395fce210SBarry Smith . unit - data type 59495fce210SBarry Smith . array - array associated with window 5955b0d146aSStefano Zampini . sync - type of synchronization PetscSFWindowSyncType 59695fce210SBarry Smith . epoch - close an epoch, must match argument to PetscSFGetWindow() 5975b0d146aSStefano Zampini . update - if we have to update the local window array 59895fce210SBarry Smith - win - window 59995fce210SBarry Smith 60095fce210SBarry Smith Level: developer 60195fce210SBarry Smith 60295fce210SBarry Smith .seealso: PetscSFFindWindow() 6035b0d146aSStefano Zampini */ 6045b0d146aSStefano Zampini static PetscErrorCode PetscSFRestoreWindow(PetscSF sf,MPI_Datatype unit,void *array,PetscSFWindowSyncType sync,PetscBool epoch,PetscMPIInt fenceassert,PetscBool update,MPI_Win *win) 60595fce210SBarry Smith { 60695fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 60795fce210SBarry Smith PetscErrorCode ierr; 60895fce210SBarry Smith PetscSFWinLink *p,link; 6095b0d146aSStefano Zampini PetscBool reuse = PETSC_FALSE; 6105b0d146aSStefano Zampini PetscSFWindowFlavorType flavor; 6115b0d146aSStefano Zampini void* laddr; 6125b0d146aSStefano Zampini size_t bytes; 61395fce210SBarry Smith 61495fce210SBarry Smith PetscFunctionBegin; 61595fce210SBarry Smith for (p=&w->wins; *p; p=&(*p)->next) { 61695fce210SBarry Smith link = *p; 61795fce210SBarry Smith if (*win == link->win) { 6185b0d146aSStefano Zampini if (array != link->paddr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Matched window, but not array"); 61995fce210SBarry Smith if (epoch != link->epoch) { 62095fce210SBarry Smith if (epoch) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"No epoch to end"); 62195fce210SBarry Smith else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Restoring window without ending epoch"); 62295fce210SBarry Smith } 6235b0d146aSStefano Zampini laddr = link->addr; 6245b0d146aSStefano Zampini flavor = link->flavor; 6255b0d146aSStefano Zampini bytes = link->bytes; 6265b0d146aSStefano Zampini if (flavor != PETSCSF_WINDOW_FLAVOR_CREATE) reuse = PETSC_TRUE; 6275b0d146aSStefano Zampini else { *p = link->next; update = PETSC_FALSE; } /* remove from list */ 62895fce210SBarry Smith goto found; 62995fce210SBarry Smith } 63095fce210SBarry Smith } 63195fce210SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Requested window not in use"); 63295fce210SBarry Smith 63395fce210SBarry Smith found: 6345b0d146aSStefano Zampini ierr = PetscInfo3(sf,"Window %d of flavor %d for comm %d\n",link->win,link->flavor,PetscObjectComm((PetscObject)sf));CHKERRQ(ierr); 63595fce210SBarry Smith if (epoch) { 6365b0d146aSStefano Zampini switch (sync) { 63795fce210SBarry Smith case PETSCSF_WINDOW_SYNC_FENCE: 63895fce210SBarry Smith ierr = MPI_Win_fence(fenceassert,*win);CHKERRQ(ierr); 63995fce210SBarry Smith break; 6405b0d146aSStefano Zampini case PETSCSF_WINDOW_SYNC_LOCK: /* Handled outside */ 6415b0d146aSStefano Zampini break; 64295fce210SBarry Smith case PETSCSF_WINDOW_SYNC_ACTIVE: { 6435b0d146aSStefano Zampini MPI_Group ingroup,outgroup; 6445b0d146aSStefano Zampini PetscMPIInt isize,osize; 6455b0d146aSStefano Zampini 6465b0d146aSStefano Zampini /* OpenMPI 4.0.2 with btl=wader does not like calling 6475b0d146aSStefano Zampini - MPI_Win_complete when ogroup is empty 6485b0d146aSStefano Zampini - MPI_Win_wait when igroup is empty 6495b0d146aSStefano Zampini The MPI standard (Sec. 11.5.2 of MPI 3.1) only requires that 6505b0d146aSStefano Zampini - each process who issues a call to MPI_Win_start issues a call to MPI_Win_Complete 6515b0d146aSStefano Zampini - each process who issues a call to MPI_Win_post issues a call to MPI_Win_Wait 6525b0d146aSStefano Zampini */ 6535b0d146aSStefano Zampini ierr = PetscSFGetGroups(sf,&ingroup,&outgroup);CHKERRQ(ierr); 6545b0d146aSStefano Zampini ierr = MPI_Group_size(ingroup,&isize);CHKERRQ(ierr); 6555b0d146aSStefano Zampini ierr = MPI_Group_size(outgroup,&osize);CHKERRQ(ierr); 6565b0d146aSStefano Zampini if (osize) { ierr = MPI_Win_complete(*win);CHKERRQ(ierr); } 6575b0d146aSStefano Zampini if (isize) { ierr = MPI_Win_wait(*win);CHKERRQ(ierr); } 65895fce210SBarry Smith } break; 65995fce210SBarry Smith default: SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_PLIB,"Unknown synchronization type"); 66095fce210SBarry Smith } 66195fce210SBarry Smith } 6625b0d146aSStefano Zampini if (update) { 6635b0d146aSStefano Zampini if (sync == PETSCSF_WINDOW_SYNC_LOCK) { 6645b0d146aSStefano Zampini ierr = MPI_Win_fence(MPI_MODE_NOPUT|MPI_MODE_NOSUCCEED,*win);CHKERRQ(ierr); 6655b0d146aSStefano Zampini } 6665b0d146aSStefano Zampini ierr = PetscMemcpy(array,laddr,sf->nroots*bytes);CHKERRQ(ierr); 6675b0d146aSStefano Zampini } 6685b0d146aSStefano Zampini link->epoch = PETSC_FALSE; 6695b0d146aSStefano Zampini link->inuse = PETSC_FALSE; 6705b0d146aSStefano Zampini link->paddr = NULL; 6715b0d146aSStefano Zampini if (!reuse) { 672684a874aSStefano Zampini ierr = PetscFree(link->dyn_target_addr);CHKERRQ(ierr); 673684a874aSStefano Zampini ierr = PetscFree(link->reqs);CHKERRQ(ierr); 67495fce210SBarry Smith ierr = MPI_Win_free(&link->win);CHKERRQ(ierr); 67595fce210SBarry Smith ierr = PetscFree(link);CHKERRQ(ierr); 67695fce210SBarry Smith *win = MPI_WIN_NULL; 6775b0d146aSStefano Zampini } 67895fce210SBarry Smith PetscFunctionReturn(0); 67995fce210SBarry Smith } 68095fce210SBarry Smith 68195fce210SBarry Smith static PetscErrorCode PetscSFSetUp_Window(PetscSF sf) 68295fce210SBarry Smith { 68395fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 68495fce210SBarry Smith PetscErrorCode ierr; 68595fce210SBarry Smith MPI_Group ingroup,outgroup; 68695fce210SBarry Smith 68795fce210SBarry Smith PetscFunctionBegin; 688b5a8e515SJed Brown ierr = PetscSFSetUpRanks(sf,MPI_GROUP_EMPTY);CHKERRQ(ierr); 6895b0d146aSStefano Zampini if (!w->dynsf) { 6905b0d146aSStefano Zampini PetscInt i; 6915b0d146aSStefano Zampini PetscSFNode *remotes; 6925b0d146aSStefano Zampini 6935b0d146aSStefano Zampini ierr = PetscMalloc1(sf->nranks,&remotes);CHKERRQ(ierr); 6945b0d146aSStefano Zampini for (i=0;i<sf->nranks;i++) { 6955b0d146aSStefano Zampini remotes[i].rank = sf->ranks[i]; 6965b0d146aSStefano Zampini remotes[i].index = 0; 6975b0d146aSStefano Zampini } 6985b0d146aSStefano Zampini ierr = PetscSFDuplicate(sf,PETSCSF_DUPLICATE_RANKS,&w->dynsf);CHKERRQ(ierr); 6995b0d146aSStefano Zampini ierr = PetscSFWindowSetFlavorType(w->dynsf,PETSCSF_WINDOW_FLAVOR_CREATE);CHKERRQ(ierr); /* break recursion */ 7005b0d146aSStefano Zampini ierr = PetscSFSetGraph(w->dynsf,1,sf->nranks,NULL,PETSC_OWN_POINTER,remotes,PETSC_OWN_POINTER);CHKERRQ(ierr); 7015b0d146aSStefano Zampini ierr = PetscLogObjectParent((PetscObject)sf,(PetscObject)w->dynsf);CHKERRQ(ierr); 7025b0d146aSStefano Zampini } 70395fce210SBarry Smith switch (w->sync) { 70495fce210SBarry Smith case PETSCSF_WINDOW_SYNC_ACTIVE: 70595fce210SBarry Smith ierr = PetscSFGetGroups(sf,&ingroup,&outgroup);CHKERRQ(ierr); 70695fce210SBarry Smith default: 70795fce210SBarry Smith break; 70895fce210SBarry Smith } 70995fce210SBarry Smith PetscFunctionReturn(0); 71095fce210SBarry Smith } 71195fce210SBarry Smith 7124416b707SBarry Smith static PetscErrorCode PetscSFSetFromOptions_Window(PetscOptionItems *PetscOptionsObject,PetscSF sf) 71395fce210SBarry Smith { 71495fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 71595fce210SBarry Smith PetscErrorCode ierr; 7165b0d146aSStefano Zampini PetscSFWindowFlavorType flavor = w->flavor; 71795fce210SBarry Smith 71895fce210SBarry Smith PetscFunctionBegin; 719e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"PetscSF Window options");CHKERRQ(ierr); 72095fce210SBarry Smith ierr = PetscOptionsEnum("-sf_window_sync","synchronization type to use for PetscSF Window communication","PetscSFWindowSetSyncType",PetscSFWindowSyncTypes,(PetscEnum)w->sync,(PetscEnum*)&w->sync,NULL);CHKERRQ(ierr); 7215b0d146aSStefano Zampini ierr = PetscOptionsEnum("-sf_window_flavor","flavor to use for PetscSF Window creation","PetscSFWindowSetFlavorType",PetscSFWindowFlavorTypes,(PetscEnum)flavor,(PetscEnum*)&flavor,NULL);CHKERRQ(ierr); 7225b0d146aSStefano Zampini ierr = PetscSFWindowSetFlavorType(sf,flavor);CHKERRQ(ierr); 72395fce210SBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 72495fce210SBarry Smith PetscFunctionReturn(0); 72595fce210SBarry Smith } 72695fce210SBarry Smith 72795fce210SBarry Smith static PetscErrorCode PetscSFReset_Window(PetscSF sf) 72895fce210SBarry Smith { 72995fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 73095fce210SBarry Smith PetscErrorCode ierr; 73195fce210SBarry Smith PetscSFDataLink link,next; 73295fce210SBarry Smith PetscSFWinLink wlink,wnext; 73395fce210SBarry Smith PetscInt i; 73495fce210SBarry Smith 73595fce210SBarry Smith PetscFunctionBegin; 73695fce210SBarry Smith for (link=w->link; link; link=next) { 73795fce210SBarry Smith next = link->next; 73895fce210SBarry Smith ierr = MPI_Type_free(&link->unit);CHKERRQ(ierr); 73995fce210SBarry Smith for (i=0; i<sf->nranks; i++) { 74095fce210SBarry Smith ierr = MPI_Type_free(&link->mine[i]);CHKERRQ(ierr); 74195fce210SBarry Smith ierr = MPI_Type_free(&link->remote[i]);CHKERRQ(ierr); 74295fce210SBarry Smith } 74395fce210SBarry Smith ierr = PetscFree2(link->mine,link->remote);CHKERRQ(ierr); 74495fce210SBarry Smith ierr = PetscFree(link);CHKERRQ(ierr); 74595fce210SBarry Smith } 74695fce210SBarry Smith w->link = NULL; 74795fce210SBarry Smith for (wlink=w->wins; wlink; wlink=wnext) { 74895fce210SBarry Smith wnext = wlink->next; 74995fce210SBarry Smith if (wlink->inuse) SETERRQ1(PetscObjectComm((PetscObject)sf),PETSC_ERR_ARG_WRONGSTATE,"Window still in use with address %p",(void*)wlink->addr); 7505b0d146aSStefano Zampini ierr = PetscFree(wlink->dyn_target_addr);CHKERRQ(ierr); 751684a874aSStefano Zampini ierr = PetscFree(wlink->reqs);CHKERRQ(ierr); 75295fce210SBarry Smith ierr = MPI_Win_free(&wlink->win);CHKERRQ(ierr); 75395fce210SBarry Smith ierr = PetscFree(wlink);CHKERRQ(ierr); 75495fce210SBarry Smith } 75595fce210SBarry Smith w->wins = NULL; 7565b0d146aSStefano Zampini ierr = PetscSFDestroy(&w->dynsf);CHKERRQ(ierr); 7575b0d146aSStefano Zampini if (w->info != MPI_INFO_NULL) { 7585b0d146aSStefano Zampini ierr = MPI_Info_free(&w->info);CHKERRQ(ierr); 7595b0d146aSStefano Zampini } 76095fce210SBarry Smith PetscFunctionReturn(0); 76195fce210SBarry Smith } 76295fce210SBarry Smith 76395fce210SBarry Smith static PetscErrorCode PetscSFDestroy_Window(PetscSF sf) 76495fce210SBarry Smith { 76595fce210SBarry Smith PetscErrorCode ierr; 76695fce210SBarry Smith 76795fce210SBarry Smith PetscFunctionBegin; 76829046d53SLisandro Dalcin ierr = PetscSFReset_Window(sf);CHKERRQ(ierr); 76995fce210SBarry Smith ierr = PetscFree(sf->data);CHKERRQ(ierr); 770bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetSyncType_C",NULL);CHKERRQ(ierr); 771bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetSyncType_C",NULL);CHKERRQ(ierr); 7725b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetFlavorType_C",NULL);CHKERRQ(ierr); 7735b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetFlavorType_C",NULL);CHKERRQ(ierr); 7745b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetInfo_C",NULL);CHKERRQ(ierr); 7755b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetInfo_C",NULL);CHKERRQ(ierr); 77695fce210SBarry Smith PetscFunctionReturn(0); 77795fce210SBarry Smith } 77895fce210SBarry Smith 77995fce210SBarry Smith static PetscErrorCode PetscSFView_Window(PetscSF sf,PetscViewer viewer) 78095fce210SBarry Smith { 78195fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 78295fce210SBarry Smith PetscErrorCode ierr; 78395fce210SBarry Smith PetscBool iascii; 7845b0d146aSStefano Zampini PetscViewerFormat format; 78595fce210SBarry Smith 78695fce210SBarry Smith PetscFunctionBegin; 7875b0d146aSStefano Zampini ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 78895fce210SBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 78995fce210SBarry Smith if (iascii) { 7905b0d146aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," current flavor=%s synchronization=%s sort=%s\n",PetscSFWindowFlavorTypes[w->flavor],PetscSFWindowSyncTypes[w->sync],sf->rankorder ? "rank-order" : "unordered");CHKERRQ(ierr); 7915b0d146aSStefano Zampini if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 7925b0d146aSStefano Zampini if (w->info != MPI_INFO_NULL) { 7935b0d146aSStefano Zampini PetscMPIInt k,nkeys; 7945b0d146aSStefano Zampini char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL]; 7955b0d146aSStefano Zampini 7965b0d146aSStefano Zampini ierr = MPI_Info_get_nkeys(w->info,&nkeys);CHKERRQ(ierr); 7975b0d146aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," current info with %d keys. Ordered key-value pairs follow:\n",nkeys);CHKERRQ(ierr); 7985b0d146aSStefano Zampini for (k = 0; k < nkeys; k++) { 7995b0d146aSStefano Zampini PetscMPIInt flag; 8005b0d146aSStefano Zampini 8015b0d146aSStefano Zampini ierr = MPI_Info_get_nthkey(w->info,k,key);CHKERRQ(ierr); 8025b0d146aSStefano Zampini ierr = MPI_Info_get(w->info,key,MPI_MAX_INFO_VAL,value,&flag);CHKERRQ(ierr); 8035b0d146aSStefano Zampini if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing key %s",key); 8045b0d146aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," %s = %s\n",key,value);CHKERRQ(ierr); 8055b0d146aSStefano Zampini } 8065b0d146aSStefano Zampini } else { 8075b0d146aSStefano Zampini ierr = PetscViewerASCIIPrintf(viewer," current info=MPI_INFO_NULL\n");CHKERRQ(ierr); 8085b0d146aSStefano Zampini } 8095b0d146aSStefano Zampini } 81095fce210SBarry Smith } 81195fce210SBarry Smith PetscFunctionReturn(0); 81295fce210SBarry Smith } 81395fce210SBarry Smith 81495fce210SBarry Smith static PetscErrorCode PetscSFDuplicate_Window(PetscSF sf,PetscSFDuplicateOption opt,PetscSF newsf) 81595fce210SBarry Smith { 81695fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 81795fce210SBarry Smith PetscErrorCode ierr; 81895fce210SBarry Smith PetscSFWindowSyncType synctype; 81995fce210SBarry Smith 82095fce210SBarry Smith PetscFunctionBegin; 82195fce210SBarry Smith synctype = w->sync; 82295fce210SBarry Smith /* HACK: Must use FENCE or LOCK when called from PetscSFGetGroups() because ACTIVE here would cause recursion. */ 8235b0d146aSStefano Zampini if (!sf->setupcalled) synctype = PETSCSF_WINDOW_SYNC_LOCK; 82495fce210SBarry Smith ierr = PetscSFWindowSetSyncType(newsf,synctype);CHKERRQ(ierr); 8255b0d146aSStefano Zampini ierr = PetscSFWindowSetFlavorType(newsf,w->flavor);CHKERRQ(ierr); 8265b0d146aSStefano Zampini ierr = PetscSFWindowSetInfo(newsf,w->info);CHKERRQ(ierr); 82795fce210SBarry Smith PetscFunctionReturn(0); 82895fce210SBarry Smith } 82995fce210SBarry Smith 830eb02082bSJunchao Zhang static PetscErrorCode PetscSFBcastAndOpBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,const void *rootdata,PetscMemType leafmtype,void *leafdata,MPI_Op op) 83195fce210SBarry Smith { 83295fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 83395fce210SBarry Smith PetscErrorCode ierr; 83495fce210SBarry Smith PetscInt i,nranks; 83595fce210SBarry Smith const PetscMPIInt *ranks; 8365b0d146aSStefano Zampini const MPI_Aint *target_disp; 83795fce210SBarry Smith const MPI_Datatype *mine,*remote; 838684a874aSStefano Zampini MPI_Request *reqs; 83995fce210SBarry Smith MPI_Win win; 84095fce210SBarry Smith 84195fce210SBarry Smith PetscFunctionBegin; 8425b0d146aSStefano Zampini if (op != MPI_REPLACE || op != MPIU_REPLACE) SETERRQ(PetscObjectComm((PetscObject)sf), PETSC_ERR_SUP, "PetscSFBcastAndOpBegin_Window with op!=MPI_REPLACE has not been implemented"); 843dec1416fSJunchao Zhang ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,NULL,NULL,NULL);CHKERRQ(ierr); 84495fce210SBarry Smith ierr = PetscSFWindowGetDataTypes(sf,unit,&mine,&remote);CHKERRQ(ierr); 845684a874aSStefano Zampini ierr = PetscSFGetWindow(sf,unit,(void*)rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOPUT|MPI_MODE_NOPRECEDE,MPI_MODE_NOPUT,0,&target_disp,&reqs,&win);CHKERRQ(ierr); 84695fce210SBarry Smith for (i=0; i<nranks; i++) { 8475b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 8485b0d146aSStefano Zampini 849684a874aSStefano Zampini if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { 850684a874aSStefano Zampini ierr = MPI_Win_lock(MPI_LOCK_SHARED,ranks[i],MPI_MODE_NOCHECK,win);CHKERRQ(ierr); 851684a874aSStefano Zampini #if defined(PETSC_HAVE_MPI_RGET) 852684a874aSStefano Zampini ierr = MPI_Rget(leafdata,1,mine[i],ranks[i],tdp,1,remote[i],win,&reqs[i]);CHKERRQ(ierr); 853684a874aSStefano Zampini #else 8545b0d146aSStefano Zampini ierr = MPI_Get(leafdata,1,mine[i],ranks[i],tdp,1,remote[i],win);CHKERRQ(ierr); 855684a874aSStefano Zampini #endif 856684a874aSStefano Zampini } else { 857684a874aSStefano Zampini ierr = MPI_Get(leafdata,1,mine[i],ranks[i],tdp,1,remote[i],win);CHKERRQ(ierr); 858684a874aSStefano Zampini } 85995fce210SBarry Smith } 86095fce210SBarry Smith PetscFunctionReturn(0); 86195fce210SBarry Smith } 86295fce210SBarry Smith 86300816365SJunchao Zhang PetscErrorCode PetscSFBcastAndOpEnd_Window(PetscSF sf,MPI_Datatype unit,const void *rootdata,void *leafdata,MPI_Op op) 86495fce210SBarry Smith { 8655b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 86695fce210SBarry Smith PetscErrorCode ierr; 86795fce210SBarry Smith MPI_Win win; 8684b9acda6SJunchao Zhang MPI_Request *reqs = NULL; 86995fce210SBarry Smith 87095fce210SBarry Smith PetscFunctionBegin; 871684a874aSStefano Zampini ierr = PetscSFFindWindow(sf,unit,rootdata,&win,&reqs);CHKERRQ(ierr); 872684a874aSStefano Zampini if (reqs) { ierr = MPI_Waitall(sf->nranks,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); } 873684a874aSStefano Zampini if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { 874684a874aSStefano Zampini PetscInt i,nranks; 875684a874aSStefano Zampini const PetscMPIInt *ranks; 876684a874aSStefano Zampini 877684a874aSStefano Zampini ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,NULL,NULL,NULL);CHKERRQ(ierr); 878684a874aSStefano Zampini for (i=0; i<nranks; i++) { 879684a874aSStefano Zampini ierr = MPI_Win_unlock(ranks[i],win);CHKERRQ(ierr); 880684a874aSStefano Zampini } 881684a874aSStefano Zampini } 8825b0d146aSStefano Zampini ierr = PetscSFRestoreWindow(sf,unit,(void*)rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOSTORE|MPI_MODE_NOSUCCEED,PETSC_FALSE,&win);CHKERRQ(ierr); 88395fce210SBarry Smith PetscFunctionReturn(0); 88495fce210SBarry Smith } 88595fce210SBarry Smith 886eb02082bSJunchao Zhang PetscErrorCode PetscSFReduceBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType leafmtype,const void *leafdata,PetscMemType rootmtype,void *rootdata,MPI_Op op) 88795fce210SBarry Smith { 88895fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 88995fce210SBarry Smith PetscErrorCode ierr; 89095fce210SBarry Smith PetscInt i,nranks; 89195fce210SBarry Smith const PetscMPIInt *ranks; 8925b0d146aSStefano Zampini const MPI_Aint *target_disp; 89395fce210SBarry Smith const MPI_Datatype *mine,*remote; 89495fce210SBarry Smith MPI_Win win; 89595fce210SBarry Smith 89695fce210SBarry Smith PetscFunctionBegin; 897dec1416fSJunchao Zhang ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,NULL,NULL,NULL);CHKERRQ(ierr); 89895fce210SBarry Smith ierr = PetscSFWindowGetDataTypes(sf,unit,&mine,&remote);CHKERRQ(ierr); 89995fce210SBarry Smith ierr = PetscSFWindowOpTranslate(&op);CHKERRQ(ierr); 900684a874aSStefano Zampini ierr = PetscSFGetWindow(sf,unit,rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOPRECEDE,0,0,&target_disp,NULL,&win);CHKERRQ(ierr); 90195fce210SBarry Smith for (i=0; i<nranks; i++) { 9025b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 9035b0d146aSStefano Zampini 90495fce210SBarry Smith if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) {ierr = MPI_Win_lock(MPI_LOCK_SHARED,ranks[i],MPI_MODE_NOCHECK,win);CHKERRQ(ierr);} 9055b0d146aSStefano Zampini ierr = MPI_Accumulate((void*)leafdata,1,mine[i],ranks[i],tdp,1,remote[i],op,win); 9065b0d146aSStefano Zampini if (ierr) { /* intercept the MPI error since the combination of unit and op is not supported */ 9075b0d146aSStefano Zampini PetscMPIInt len; 9085b0d146aSStefano Zampini char errstring[MPI_MAX_ERROR_STRING]; 9095b0d146aSStefano Zampini 9105b0d146aSStefano Zampini MPI_Error_string(ierr,errstring,&len); 9115b0d146aSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Internal error in MPI: %s",errstring); 9125b0d146aSStefano Zampini } 91395fce210SBarry Smith if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) {ierr = MPI_Win_unlock(ranks[i],win);CHKERRQ(ierr);} 91495fce210SBarry Smith } 91595fce210SBarry Smith PetscFunctionReturn(0); 91695fce210SBarry Smith } 91795fce210SBarry Smith 91800816365SJunchao Zhang static PetscErrorCode PetscSFReduceEnd_Window(PetscSF sf,MPI_Datatype unit,const void *leafdata,void *rootdata,MPI_Op op) 91995fce210SBarry Smith { 92095fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 92195fce210SBarry Smith PetscErrorCode ierr; 92295fce210SBarry Smith MPI_Win win; 9234b9acda6SJunchao Zhang MPI_Request *reqs = NULL; 92495fce210SBarry Smith 92595fce210SBarry Smith PetscFunctionBegin; 926684a874aSStefano Zampini ierr = PetscSFFindWindow(sf,unit,rootdata,&win,&reqs);CHKERRQ(ierr); 927684a874aSStefano Zampini if (reqs) { ierr = MPI_Waitall(sf->nranks,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); } 9285b0d146aSStefano Zampini ierr = PetscSFRestoreWindow(sf,unit,rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOSUCCEED,PETSC_TRUE,&win);CHKERRQ(ierr); 92995fce210SBarry Smith PetscFunctionReturn(0); 93095fce210SBarry Smith } 9315b0d146aSStefano Zampini 932eb02082bSJunchao Zhang static PetscErrorCode PetscSFFetchAndOpBegin_Window(PetscSF sf,MPI_Datatype unit,PetscMemType rootmtype,void *rootdata,PetscMemType leafmtype,const void *leafdata,void *leafupdate,MPI_Op op) 93395fce210SBarry Smith { 93495fce210SBarry Smith PetscErrorCode ierr; 93595fce210SBarry Smith PetscInt i,nranks; 93695fce210SBarry Smith const PetscMPIInt *ranks; 93795fce210SBarry Smith const MPI_Datatype *mine,*remote; 9385b0d146aSStefano Zampini const MPI_Aint *target_disp; 93995fce210SBarry Smith MPI_Win win; 9405b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 9415b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 9425b0d146aSStefano Zampini PetscSFWindowFlavorType oldf; 9435b0d146aSStefano Zampini #endif 94495fce210SBarry Smith 94595fce210SBarry Smith PetscFunctionBegin; 946dec1416fSJunchao Zhang ierr = PetscSFGetRootRanks(sf,&nranks,&ranks,NULL,NULL,NULL);CHKERRQ(ierr); 94795fce210SBarry Smith ierr = PetscSFWindowGetDataTypes(sf,unit,&mine,&remote);CHKERRQ(ierr); 94895fce210SBarry Smith ierr = PetscSFWindowOpTranslate(&op);CHKERRQ(ierr); 9495b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 9505b0d146aSStefano Zampini /* FetchAndOp without MPI_Get_Accumulate requires locking. 9515b0d146aSStefano Zampini we create a new window every time to not interfere with user-defined MPI_Info which may have used "no_locks"="true" */ 9525b0d146aSStefano Zampini oldf = w->flavor; 9535b0d146aSStefano Zampini w->flavor = PETSCSF_WINDOW_FLAVOR_CREATE; 954684a874aSStefano Zampini ierr = PetscSFGetWindow(sf,unit,rootdata,PETSCSF_WINDOW_SYNC_LOCK,PETSC_FALSE,0,0,0,&target_disp,NULL,&win);CHKERRQ(ierr); 9555b0d146aSStefano Zampini #else 956684a874aSStefano Zampini ierr = PetscSFGetWindow(sf,unit,rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOPRECEDE,0,0,&target_disp,NULL,&win);CHKERRQ(ierr); 9575b0d146aSStefano Zampini #endif 9585b0d146aSStefano Zampini for (i=0; i<nranks; i++) { 9595b0d146aSStefano Zampini MPI_Aint tdp = target_disp ? target_disp[i] : 0; 9605b0d146aSStefano Zampini 9615b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 9625b0d146aSStefano Zampini ierr = MPI_Win_lock(MPI_LOCK_EXCLUSIVE,ranks[i],0,win);CHKERRQ(ierr); 9635b0d146aSStefano Zampini ierr = MPI_Get(leafupdate,1,mine[i],ranks[i],tdp,1,remote[i],win);CHKERRQ(ierr); 9645b0d146aSStefano Zampini ierr = MPI_Accumulate((void*)leafdata,1,mine[i],ranks[i],tdp,1,remote[i],op,win); 9655b0d146aSStefano Zampini if (ierr) { /* intercept the MPI error since the combination of unit and op is not supported */ 9665b0d146aSStefano Zampini PetscMPIInt len; 9675b0d146aSStefano Zampini char errstring[MPI_MAX_ERROR_STRING]; 9685b0d146aSStefano Zampini 9695b0d146aSStefano Zampini MPI_Error_string(ierr,errstring,&len); 9705b0d146aSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Internal error in MPI: %s",errstring); 97195fce210SBarry Smith } 9725b0d146aSStefano Zampini ierr = MPI_Win_unlock(ranks[i],win);CHKERRQ(ierr); 9735b0d146aSStefano Zampini #else 9745b0d146aSStefano Zampini if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { ierr = MPI_Win_lock(MPI_LOCK_SHARED,ranks[i],0,win);CHKERRQ(ierr); } 9755b0d146aSStefano Zampini ierr = MPI_Get_accumulate((void*)leafdata,1,mine[i],leafupdate,1,mine[i],ranks[i],tdp,1,remote[i],op,win); 9765b0d146aSStefano Zampini if (ierr) { /* intercept the MPI error since the combination of unit and op is not supported */ 9775b0d146aSStefano Zampini PetscMPIInt len; 9785b0d146aSStefano Zampini char errstring[MPI_MAX_ERROR_STRING]; 9795b0d146aSStefano Zampini 9805b0d146aSStefano Zampini MPI_Error_string(ierr,errstring,&len); 9815b0d146aSStefano Zampini SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Internal error in MPI: %s",errstring); 9825b0d146aSStefano Zampini } 9835b0d146aSStefano Zampini if (w->sync == PETSCSF_WINDOW_SYNC_LOCK) { ierr = MPI_Win_unlock(ranks[i],win);CHKERRQ(ierr); } 9845b0d146aSStefano Zampini #endif 9855b0d146aSStefano Zampini } 9865b0d146aSStefano Zampini #if !defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 9875b0d146aSStefano Zampini w->flavor = oldf; 9885b0d146aSStefano Zampini #endif 98995fce210SBarry Smith PetscFunctionReturn(0); 99095fce210SBarry Smith } 99195fce210SBarry Smith 99200816365SJunchao Zhang static PetscErrorCode PetscSFFetchAndOpEnd_Window(PetscSF sf,MPI_Datatype unit,void *rootdata,const void *leafdata,void *leafupdate,MPI_Op op) 99395fce210SBarry Smith { 99495fce210SBarry Smith PetscErrorCode ierr; 99595fce210SBarry Smith MPI_Win win; 9965b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 9975b0d146aSStefano Zampini PetscSF_Window *w = (PetscSF_Window*)sf->data; 9985b0d146aSStefano Zampini #endif 9994b9acda6SJunchao Zhang MPI_Request *reqs = NULL; 100095fce210SBarry Smith 100195fce210SBarry Smith PetscFunctionBegin; 1002684a874aSStefano Zampini ierr = PetscSFFindWindow(sf,unit,rootdata,&win,&reqs);CHKERRQ(ierr); 1003684a874aSStefano Zampini if (reqs) { ierr = MPI_Waitall(sf->nranks,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); } 10045b0d146aSStefano Zampini #if defined(PETSC_HAVE_MPI_GET_ACCUMULATE) 10055b0d146aSStefano Zampini ierr = PetscSFRestoreWindow(sf,unit,rootdata,w->sync,PETSC_TRUE,MPI_MODE_NOSUCCEED,PETSC_TRUE,&win);CHKERRQ(ierr); 10065b0d146aSStefano Zampini #else 10075b0d146aSStefano Zampini ierr = PetscSFRestoreWindow(sf,unit,rootdata,PETSCSF_WINDOW_SYNC_LOCK,PETSC_FALSE,0,PETSC_TRUE,&win);CHKERRQ(ierr); 10085b0d146aSStefano Zampini #endif 100995fce210SBarry Smith PetscFunctionReturn(0); 101095fce210SBarry Smith } 101195fce210SBarry Smith 1012dec1416fSJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFCreate_Window(PetscSF sf) 101395fce210SBarry Smith { 101495fce210SBarry Smith PetscSF_Window *w = (PetscSF_Window*)sf->data; 101595fce210SBarry Smith PetscErrorCode ierr; 101695fce210SBarry Smith 101795fce210SBarry Smith PetscFunctionBegin; 101895fce210SBarry Smith sf->ops->SetUp = PetscSFSetUp_Window; 101995fce210SBarry Smith sf->ops->SetFromOptions = PetscSFSetFromOptions_Window; 102095fce210SBarry Smith sf->ops->Reset = PetscSFReset_Window; 102195fce210SBarry Smith sf->ops->Destroy = PetscSFDestroy_Window; 102295fce210SBarry Smith sf->ops->View = PetscSFView_Window; 102395fce210SBarry Smith sf->ops->Duplicate = PetscSFDuplicate_Window; 1024de49d1a2SJunchao Zhang sf->ops->BcastAndOpBegin = PetscSFBcastAndOpBegin_Window; 1025de49d1a2SJunchao Zhang sf->ops->BcastAndOpEnd = PetscSFBcastAndOpEnd_Window; 102695fce210SBarry Smith sf->ops->ReduceBegin = PetscSFReduceBegin_Window; 102795fce210SBarry Smith sf->ops->ReduceEnd = PetscSFReduceEnd_Window; 102895fce210SBarry Smith sf->ops->FetchAndOpBegin = PetscSFFetchAndOpBegin_Window; 102995fce210SBarry Smith sf->ops->FetchAndOpEnd = PetscSFFetchAndOpEnd_Window; 103095fce210SBarry Smith 1031b00a9115SJed Brown ierr = PetscNewLog(sf,&w);CHKERRQ(ierr); 103295fce210SBarry Smith sf->data = (void*)w; 103395fce210SBarry Smith w->sync = PETSCSF_WINDOW_SYNC_FENCE; 10345b0d146aSStefano Zampini w->flavor = PETSCSF_WINDOW_FLAVOR_CREATE; 10355b0d146aSStefano Zampini w->info = MPI_INFO_NULL; 103695fce210SBarry Smith 1037bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetSyncType_C",PetscSFWindowSetSyncType_Window);CHKERRQ(ierr); 1038bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetSyncType_C",PetscSFWindowGetSyncType_Window);CHKERRQ(ierr); 10395b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetFlavorType_C",PetscSFWindowSetFlavorType_Window);CHKERRQ(ierr); 10405b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetFlavorType_C",PetscSFWindowGetFlavorType_Window);CHKERRQ(ierr); 10415b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowSetInfo_C",PetscSFWindowSetInfo_Window);CHKERRQ(ierr); 10425b0d146aSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)sf,"PetscSFWindowGetInfo_C",PetscSFWindowGetInfo_Window);CHKERRQ(ierr); 104395fce210SBarry Smith 104495fce210SBarry Smith #if defined(OMPI_MAJOR_VERSION) && (OMPI_MAJOR_VERSION < 1 || (OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION <= 6)) 104595fce210SBarry Smith { 104695fce210SBarry Smith PetscBool ackbug = PETSC_FALSE; 1047c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-acknowledge_ompi_onesided_bug",&ackbug,NULL);CHKERRQ(ierr); 104895fce210SBarry Smith if (ackbug) { 1049955c1f14SBarry Smith ierr = PetscInfo(sf,"Acknowledged Open MPI bug, proceeding anyway. Expect memory corruption.\n");CHKERRQ(ierr); 105095fce210SBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)sf),PETSC_ERR_LIB,"Open MPI is known to be buggy (https://svn.open-mpi.org/trac/ompi/ticket/1905 and 2656), use -acknowledge_ompi_onesided_bug to proceed"); 105195fce210SBarry Smith } 105295fce210SBarry Smith #endif 105395fce210SBarry Smith PetscFunctionReturn(0); 105495fce210SBarry Smith } 1055