140e23c03SJunchao Zhang #if !defined(__SFBASIC_H) 240e23c03SJunchao Zhang #define __SFBASIC_H 340e23c03SJunchao Zhang 440e23c03SJunchao Zhang #include <../src/vec/is/sf/impls/basic/sfpack.h> 540e23c03SJunchao Zhang 640e23c03SJunchao Zhang typedef enum {PETSCSF_LEAF2ROOT_REDUCE=0, PETSCSF_ROOT2LEAF_BCAST=1} PetscSFDirection; 740e23c03SJunchao Zhang 840e23c03SJunchao Zhang typedef struct _n_PetscSFPack_Basic *PetscSFPack_Basic; 940e23c03SJunchao Zhang 1040e23c03SJunchao Zhang #define SPPACKBASICHEADER \ 1140e23c03SJunchao Zhang SFPACKHEADER; \ 1240e23c03SJunchao Zhang char **root; /* Packed root data, indexed by leaf rank */ \ 1340e23c03SJunchao Zhang char **leaf; /* Packed leaf data, indexed by root rank */ \ 1440e23c03SJunchao Zhang PetscMPIInt half; /* Number of MPI_Requests used for either leaf2root or root2leaf communication */ \ 1540e23c03SJunchao Zhang MPI_Request *requests /* [2*half] requests arranged in this order: leaf2root root/leaf reqs, root2leaf root/leaf reqs */ 1640e23c03SJunchao Zhang 1740e23c03SJunchao Zhang struct _n_PetscSFPack_Basic { 1840e23c03SJunchao Zhang SPPACKBASICHEADER; 1940e23c03SJunchao Zhang PetscBool initialized[2]; /* Is the communcation pattern in each direction initialized? [0] for leaf2root, [1] for root2leaf */ 2040e23c03SJunchao Zhang }; 2140e23c03SJunchao Zhang 2240e23c03SJunchao Zhang #define SFBASICHEADER \ 2340e23c03SJunchao Zhang PetscMPIInt niranks; /* Number of incoming ranks (ranks accessing my roots) */ \ 2440e23c03SJunchao Zhang PetscMPIInt ndiranks; /* Number of incoming ranks (ranks accessing my roots) in distinguished set */ \ 2540e23c03SJunchao Zhang PetscMPIInt *iranks; /* Array of ranks that reference my roots */ \ 2640e23c03SJunchao Zhang PetscInt itotal; /* Total number of graph edges referencing my roots */ \ 2740e23c03SJunchao Zhang PetscInt *ioffset; /* Array of length niranks+1 holding offset in irootloc[] for each rank */ \ 2840e23c03SJunchao Zhang PetscInt *irootloc; /* Incoming roots referenced by ranks starting at ioffset[rank] */ \ 2940e23c03SJunchao Zhang PetscSFPackOpt rootpackopt; /* Optimization plans to (un)pack roots based on patterns in irootloc[]. NULL for no plans */ \ 3040e23c03SJunchao Zhang PetscSFPack avail; /* One or more entries per MPI Datatype, lazily constructed */ \ 3140e23c03SJunchao Zhang PetscSFPack inuse /* Buffers being used for transactions that have not yet completed */ 3240e23c03SJunchao Zhang 3340e23c03SJunchao Zhang typedef struct { 3440e23c03SJunchao Zhang SFBASICHEADER; 3540e23c03SJunchao Zhang } PetscSF_Basic; 3640e23c03SJunchao Zhang 3740e23c03SJunchao Zhang PETSC_STATIC_INLINE PetscErrorCode PetscSFGetRootInfo_Basic(PetscSF sf,PetscInt *nrootranks,PetscInt *ndrootranks,const PetscMPIInt **rootranks,const PetscInt **rootoffset,const PetscInt **rootloc) 3840e23c03SJunchao Zhang { 3940e23c03SJunchao Zhang PetscSF_Basic *bas = (PetscSF_Basic*)sf->data; 4040e23c03SJunchao Zhang 4140e23c03SJunchao Zhang PetscFunctionBegin; 4240e23c03SJunchao Zhang if (nrootranks) *nrootranks = bas->niranks; 4340e23c03SJunchao Zhang if (ndrootranks) *ndrootranks = bas->ndiranks; 4440e23c03SJunchao Zhang if (rootranks) *rootranks = bas->iranks; 4540e23c03SJunchao Zhang if (rootoffset) *rootoffset = bas->ioffset; 4640e23c03SJunchao Zhang if (rootloc) *rootloc = bas->irootloc; 4740e23c03SJunchao Zhang PetscFunctionReturn(0); 4840e23c03SJunchao Zhang } 4940e23c03SJunchao Zhang 5040e23c03SJunchao Zhang PETSC_STATIC_INLINE PetscErrorCode PetscSFGetLeafInfo_Basic(PetscSF sf,PetscInt *nleafranks,PetscInt *ndleafranks,const PetscMPIInt **leafranks,const PetscInt **leafoffset,const PetscInt **leafloc,const PetscInt **leafrremote) 5140e23c03SJunchao Zhang { 5240e23c03SJunchao Zhang PetscFunctionBegin; 5340e23c03SJunchao Zhang if (nleafranks) *nleafranks = sf->nranks; 5440e23c03SJunchao Zhang if (ndleafranks) *ndleafranks = sf->ndranks; 5540e23c03SJunchao Zhang if (leafranks) *leafranks = sf->ranks; 5640e23c03SJunchao Zhang if (leafoffset) *leafoffset = sf->roffset; 5740e23c03SJunchao Zhang if (leafloc) *leafloc = sf->rmine; 5840e23c03SJunchao Zhang if (leafrremote) *leafrremote = sf->rremote; 5940e23c03SJunchao Zhang PetscFunctionReturn(0); 6040e23c03SJunchao Zhang } 6140e23c03SJunchao Zhang 6240e23c03SJunchao Zhang PETSC_STATIC_INLINE PetscErrorCode PetscSFPackWaitall_Basic(PetscSFPack_Basic link,PetscSFDirection direction) 6340e23c03SJunchao Zhang { 6440e23c03SJunchao Zhang PetscErrorCode ierr; 6540e23c03SJunchao Zhang MPI_Request *requests = (direction == PETSCSF_LEAF2ROOT_REDUCE) ? link->requests : link->requests + link->half; 6640e23c03SJunchao Zhang 6740e23c03SJunchao Zhang PetscFunctionBegin; 6840e23c03SJunchao Zhang ierr = MPI_Waitall(link->half,requests,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6940e23c03SJunchao Zhang PetscFunctionReturn(0); 7040e23c03SJunchao Zhang } 7140e23c03SJunchao Zhang 7240e23c03SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFSetUp_Basic(PetscSF); 7340e23c03SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFView_Basic(PetscSF,PetscViewer); 7440e23c03SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFReset_Basic(PetscSF); 7540e23c03SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFDestroy_Basic(PetscSF); 7640e23c03SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFBcastAndOpEnd_Basic(PetscSF,MPI_Datatype,const void*,void*,MPI_Op); 7740e23c03SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFReduceEnd_Basic(PetscSF,MPI_Datatype,const void*,void*,MPI_Op); 7840e23c03SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFFetchAndOpBegin_Basic(PetscSF,MPI_Datatype,void*,const void*,void*,MPI_Op); 79*f659e5c7SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFCreateEmbeddedSF_Basic(PetscSF,PetscInt,const PetscInt*,PetscSF*); 80*f659e5c7SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFCreateEmbeddedLeafSF_Basic(PetscSF,PetscInt,const PetscInt*,PetscSF*); 8140e23c03SJunchao Zhang PETSC_INTERN PetscErrorCode PetscSFGetLeafRanks_Basic(PetscSF,PetscInt*,const PetscMPIInt**,const PetscInt**,const PetscInt**); 8240e23c03SJunchao Zhang #endif 83