1fd697ae2SVaclav Hapla 2fd697ae2SVaclav Hapla static char help[]= "Test leaf sorting in PetscSFSetGraph()\n\n"; 3fd697ae2SVaclav Hapla 4fd697ae2SVaclav Hapla #include <petscsf.h> 5fd697ae2SVaclav Hapla 6fd697ae2SVaclav Hapla typedef struct { 7fd697ae2SVaclav Hapla MPI_Comm comm; 8fd697ae2SVaclav Hapla PetscMPIInt rank, size; 9fd697ae2SVaclav Hapla PetscInt leaveStep, nLeavesPerRank; 10fd697ae2SVaclav Hapla PetscBool contiguousLeaves; 11fd697ae2SVaclav Hapla PetscCopyMode localmode, remotemode; 12fd697ae2SVaclav Hapla PetscInt *ilocal; 13fd697ae2SVaclav Hapla PetscSFNode *iremote; 14fd697ae2SVaclav Hapla } AppCtx; 15fd697ae2SVaclav Hapla 16fd697ae2SVaclav Hapla static PetscErrorCode GetOptions(MPI_Comm comm, AppCtx *ctx) 17fd697ae2SVaclav Hapla { 18fd697ae2SVaclav Hapla PetscFunctionBegin; 19fd697ae2SVaclav Hapla ctx->comm = comm; 20fd697ae2SVaclav Hapla ctx->nLeavesPerRank = 4; 21fd697ae2SVaclav Hapla ctx->leaveStep = 1; 22fd697ae2SVaclav Hapla ctx->contiguousLeaves = PETSC_FALSE; 23fd697ae2SVaclav Hapla ctx->localmode = PETSC_OWN_POINTER; 24fd697ae2SVaclav Hapla ctx->remotemode = PETSC_OWN_POINTER; 25fd697ae2SVaclav Hapla ctx->ilocal = NULL; 26fd697ae2SVaclav Hapla ctx->iremote = NULL; 27*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL, NULL, "-n_leaves_per_rank", &ctx->nLeavesPerRank, NULL)); 28*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL, NULL, "-leave_step", &ctx->leaveStep, NULL)); 29*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetEnum(NULL, NULL, "-localmode", PetscCopyModes, (PetscEnum*) &ctx->localmode, NULL)); 30*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetEnum(NULL, NULL, "-remotemode", PetscCopyModes, (PetscEnum*) &ctx->remotemode, NULL)); 31fd697ae2SVaclav Hapla ctx->contiguousLeaves = (PetscBool) (ctx->leaveStep == 1); 32*5f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_size(comm, &ctx->size)); 33*5f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_rank(comm, &ctx->rank)); 34fd697ae2SVaclav Hapla PetscFunctionReturn(0); 35fd697ae2SVaclav Hapla } 36fd697ae2SVaclav Hapla 37fd697ae2SVaclav Hapla static PetscErrorCode PetscSFCheckEqual_Private(PetscSF sf0, PetscSF sf1) 38fd697ae2SVaclav Hapla { 39fd697ae2SVaclav Hapla PetscInt nRoot, nLeave; 40fd697ae2SVaclav Hapla Vec vecRoot0, vecLeave0, vecRoot1, vecLeave1; 41fd697ae2SVaclav Hapla MPI_Comm comm; 42fd697ae2SVaclav Hapla PetscBool flg; 43fd697ae2SVaclav Hapla 44fd697ae2SVaclav Hapla PetscFunctionBegin; 45*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetComm((PetscObject)sf0, &comm)); 46*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFGetGraph(sf0, &nRoot, NULL, NULL, NULL)); 47*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFGetLeafRange(sf0, NULL, &nLeave)); 48fd697ae2SVaclav Hapla nLeave++; 49*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreateMPI(comm, nRoot, PETSC_DECIDE, &vecRoot0)); 50*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreateMPI(comm, nLeave, PETSC_DECIDE, &vecLeave0)); 51*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(vecRoot0, &vecRoot1)); 52*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(vecLeave0, &vecLeave1)); 53fd697ae2SVaclav Hapla { 54fd697ae2SVaclav Hapla PetscRandom rand; 55fd697ae2SVaclav Hapla 56*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomCreate(comm, &rand)); 57*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomSetFromOptions(rand)); 58*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetRandom(vecRoot0, rand)); 59*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetRandom(vecLeave0, rand)); 60*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(vecRoot0, vecRoot1)); 61*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecCopy(vecLeave0, vecLeave1)); 62*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomDestroy(&rand)); 63fd697ae2SVaclav Hapla } 64fd697ae2SVaclav Hapla 65*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(sf0, vecRoot0, vecLeave0, ADD_VALUES, SCATTER_FORWARD)); 66*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd( sf0, vecRoot0, vecLeave0, ADD_VALUES, SCATTER_FORWARD)); 67*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(sf1, vecRoot1, vecLeave1, ADD_VALUES, SCATTER_FORWARD)); 68*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd( sf1, vecRoot1, vecLeave1, ADD_VALUES, SCATTER_FORWARD)); 69*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecEqual(vecLeave0, vecLeave1, &flg)); 70fd697ae2SVaclav Hapla PetscCheck(flg, comm, PETSC_ERR_PLIB, "leave vectors differ"); 71fd697ae2SVaclav Hapla 72*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(sf0, vecLeave0, vecRoot0, ADD_VALUES, SCATTER_REVERSE)); 73*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd( sf0, vecLeave0, vecRoot0, ADD_VALUES, SCATTER_REVERSE)); 74*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(sf1, vecLeave1, vecRoot1, ADD_VALUES, SCATTER_REVERSE)); 75*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd( sf1, vecLeave1, vecRoot1, ADD_VALUES, SCATTER_REVERSE)); 76*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecEqual(vecRoot0, vecRoot1, &flg)); 77fd697ae2SVaclav Hapla PetscCheck(flg, comm, PETSC_ERR_PLIB, "root vectors differ"); 78fd697ae2SVaclav Hapla 79*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&vecRoot0)); 80*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&vecRoot1)); 81*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&vecLeave0)); 82*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&vecLeave1)); 83fd697ae2SVaclav Hapla PetscFunctionReturn(0); 84fd697ae2SVaclav Hapla } 85fd697ae2SVaclav Hapla 86fd697ae2SVaclav Hapla PetscErrorCode CreateSF0(AppCtx *ctx, PetscSF *sf0) 87fd697ae2SVaclav Hapla { 88fd697ae2SVaclav Hapla PetscInt j, k, r; 89fd697ae2SVaclav Hapla PetscInt nLeaves = ctx->nLeavesPerRank * ctx->size; 90fd697ae2SVaclav Hapla PetscInt nroots = ctx->nLeavesPerRank; 91fd697ae2SVaclav Hapla PetscSF sf; 92fd697ae2SVaclav Hapla PetscInt *ilocal; 93fd697ae2SVaclav Hapla PetscSFNode *iremote; 94fd697ae2SVaclav Hapla 95fd697ae2SVaclav Hapla PetscFunctionBegin; 96*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nLeaves+1, &ctx->ilocal)); 97*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nLeaves, &ctx->iremote)); 98fd697ae2SVaclav Hapla ilocal = ctx->ilocal; 99fd697ae2SVaclav Hapla iremote = ctx->iremote; 100fd697ae2SVaclav Hapla ilocal[nLeaves] = -ctx->leaveStep; 101*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFCreate(ctx->comm, &sf)); 102fd697ae2SVaclav Hapla for (r=0, j=nLeaves-1; r<ctx->size; r++) { 103fd697ae2SVaclav Hapla for (k=0; k<ctx->nLeavesPerRank; k++, j--) { 104fd697ae2SVaclav Hapla ilocal[j] = ilocal[j+1] + ctx->leaveStep; 105fd697ae2SVaclav Hapla iremote[j].rank = r; 106fd697ae2SVaclav Hapla iremote[j].index = k; 107fd697ae2SVaclav Hapla } 108fd697ae2SVaclav Hapla } 109*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFSetGraph(sf, nroots, nLeaves, ilocal, ctx->localmode, iremote, ctx->remotemode)); 110fd697ae2SVaclav Hapla { 111fd697ae2SVaclav Hapla const PetscInt *tlocal; 112fd697ae2SVaclav Hapla PetscBool sorted; 113fd697ae2SVaclav Hapla 114*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFGetGraph(sf, NULL, NULL, &tlocal, NULL)); 115fd697ae2SVaclav Hapla PetscCheckFalse(ctx->contiguousLeaves && tlocal,PETSC_COMM_SELF,PETSC_ERR_PLIB,"ilocal=NULL expected for contiguous case"); 116fd697ae2SVaclav Hapla if (tlocal) { 117*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSortedInt(nLeaves, tlocal, &sorted)); 118fd697ae2SVaclav Hapla PetscCheck(sorted,PETSC_COMM_SELF,PETSC_ERR_PLIB,"ilocal expected to be sorted"); 119fd697ae2SVaclav Hapla } 120fd697ae2SVaclav Hapla } 121fd697ae2SVaclav Hapla *sf0 = sf; 122fd697ae2SVaclav Hapla PetscFunctionReturn(0); 123fd697ae2SVaclav Hapla } 124fd697ae2SVaclav Hapla 125fd697ae2SVaclav Hapla PetscErrorCode CreateSF1(AppCtx *ctx, PetscSF *sf1) 126fd697ae2SVaclav Hapla { 127fd697ae2SVaclav Hapla PetscInt j, k, r; 128fd697ae2SVaclav Hapla PetscInt *ilocal = NULL; 129fd697ae2SVaclav Hapla PetscSFNode *iremote; 130fd697ae2SVaclav Hapla PetscInt nLeaves = ctx->nLeavesPerRank * ctx->size; 131fd697ae2SVaclav Hapla PetscInt nroots = ctx->nLeavesPerRank; 132fd697ae2SVaclav Hapla PetscSF sf; 133fd697ae2SVaclav Hapla 134fd697ae2SVaclav Hapla PetscFunctionBegin; 135fd697ae2SVaclav Hapla ilocal = NULL; 136fd697ae2SVaclav Hapla if (!ctx->contiguousLeaves) { 137*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(nLeaves+1, &ilocal)); 138fd697ae2SVaclav Hapla } 139*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nLeaves, &iremote)); 140*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFCreate(ctx->comm, &sf)); 141fd697ae2SVaclav Hapla for (r=0, j=0; r<ctx->size; r++) { 142fd697ae2SVaclav Hapla for (k=0; k<ctx->nLeavesPerRank; k++, j++) { 143fd697ae2SVaclav Hapla if (!ctx->contiguousLeaves) { 144fd697ae2SVaclav Hapla ilocal[j+1] = ilocal[j] + ctx->leaveStep; 145fd697ae2SVaclav Hapla } 146fd697ae2SVaclav Hapla iremote[j].rank = r; 147fd697ae2SVaclav Hapla iremote[j].index = k; 148fd697ae2SVaclav Hapla } 149fd697ae2SVaclav Hapla } 150fd697ae2SVaclav Hapla PetscCheck(j == nLeaves,PETSC_COMM_SELF,PETSC_ERR_PLIB,"j != nLeaves"); 151*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFSetGraph(sf, nroots, nLeaves, ilocal, PETSC_OWN_POINTER, iremote, PETSC_OWN_POINTER)); 152fd697ae2SVaclav Hapla if (ctx->contiguousLeaves) { 153fd697ae2SVaclav Hapla const PetscInt *tlocal; 154fd697ae2SVaclav Hapla 155*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFGetGraph(sf, NULL, NULL, &tlocal, NULL)); 156fd697ae2SVaclav Hapla PetscCheckFalse(tlocal,PETSC_COMM_SELF,PETSC_ERR_PLIB,"ilocal=NULL expected for contiguous case"); 157fd697ae2SVaclav Hapla } 158fd697ae2SVaclav Hapla *sf1 = sf; 159fd697ae2SVaclav Hapla PetscFunctionReturn(0); 160fd697ae2SVaclav Hapla } 161fd697ae2SVaclav Hapla 162fd697ae2SVaclav Hapla int main(int argc, char **argv) 163fd697ae2SVaclav Hapla { 164fd697ae2SVaclav Hapla AppCtx ctx; 165fd697ae2SVaclav Hapla PetscSF sf0, sf1; 166fd697ae2SVaclav Hapla MPI_Comm comm; 167fd697ae2SVaclav Hapla PetscErrorCode ierr; 168fd697ae2SVaclav Hapla 169fd697ae2SVaclav Hapla ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr; 170fd697ae2SVaclav Hapla comm = PETSC_COMM_WORLD; 171*5f80ce2aSJacob Faibussowitsch CHKERRQ(GetOptions(comm, &ctx)); 172fd697ae2SVaclav Hapla 173*5f80ce2aSJacob Faibussowitsch CHKERRQ(CreateSF0(&ctx, &sf0)); 174*5f80ce2aSJacob Faibussowitsch CHKERRQ(CreateSF1(&ctx, &sf1)); 175fd697ae2SVaclav Hapla ierr = PetscSFViewFromOptions(sf0, NULL, "-sf0_view"); 176fd697ae2SVaclav Hapla ierr = PetscSFViewFromOptions(sf1, NULL, "-sf1_view"); 177*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFCheckEqual_Private(sf0, sf1)); 178fd697ae2SVaclav Hapla 179fd697ae2SVaclav Hapla if (ctx.localmode != PETSC_OWN_POINTER) { 180*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(ctx.ilocal)); 181fd697ae2SVaclav Hapla } 182fd697ae2SVaclav Hapla if (ctx.remotemode != PETSC_OWN_POINTER) { 183*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(ctx.iremote)); 184fd697ae2SVaclav Hapla } 185*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDestroy(&sf0)); 186*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSFDestroy(&sf1)); 187fd697ae2SVaclav Hapla ierr = PetscFinalize(); 188fd697ae2SVaclav Hapla return ierr; 189fd697ae2SVaclav Hapla } 190fd697ae2SVaclav Hapla 191fd697ae2SVaclav Hapla /*TEST 192fd697ae2SVaclav Hapla testset: 193fd697ae2SVaclav Hapla suffix: 1 194fd697ae2SVaclav Hapla nsize: {{1 3}} 195fd697ae2SVaclav Hapla args: -n_leaves_per_rank {{0 5}} -leave_step {{1 3}} 196fd697ae2SVaclav Hapla test: 197fd697ae2SVaclav Hapla suffix: a 198fd697ae2SVaclav Hapla args: -localmode {{COPY_VALUES OWN_POINTER}} -remotemode {{COPY_VALUES OWN_POINTER}} 199fd697ae2SVaclav Hapla test: 200fd697ae2SVaclav Hapla suffix: b 201fd697ae2SVaclav Hapla args: -localmode USE_POINTER -remotemode {{COPY_VALUES OWN_POINTER USE_POINTER}} 202fd697ae2SVaclav Hapla TEST*/ 203