Actual source code: ex5.c

petsc-3.13.4 2020-08-01
Report Typos and Errors
  1: static char help[]= "Test PetscSFFCompose when the ilocal arrays are not identity nor dense\n\n";

  3:  #include <petsc.h>
  4:  #include <petscsf.h>

  6: int main(int argc, char **argv)
  7: {
  9:   PetscSF        sfA, sfB, sfBA, sfAAm, sfBBm, sfAm, sfBm;
 10:   PetscInt       nrootsA, nleavesA, nrootsB, nleavesB;
 11:   PetscInt       *ilocalA, *ilocalB;
 12:   PetscSFNode    *iremoteA, *iremoteB;
 13:   PetscMPIInt    rank,size;
 14:   PetscInt       i,m,n,k,nl = 2,mA,mB,nldataA,nldataB;
 15:   PetscInt       *rdA,*rdB,*ldA,*ldB;
 16:   PetscBool      inverse = PETSC_FALSE;

 18:   PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr;
 19:   PetscOptionsGetInt(NULL,NULL,"-nl",&nl,NULL);
 20:   PetscOptionsGetBool(NULL,NULL,"-explicit_inverse",&inverse,NULL);
 21:   MPI_Comm_size(PETSC_COMM_WORLD,&size);
 22:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);

 24:   PetscSFCreate(PETSC_COMM_WORLD, &sfA);
 25:   PetscSFCreate(PETSC_COMM_WORLD, &sfB);
 26:   PetscSFSetFromOptions(sfA);
 27:   PetscSFSetFromOptions(sfB);

 29:   n = 4*nl*size;
 30:   m = 2*nl;
 31:   k = nl;

 33:   nldataA = !rank ? n : 0;
 34:   nldataB = 3*nl;

 36:   nrootsA  = m;
 37:   nleavesA = !rank ? size*m : 0;
 38:   nrootsB  = !rank ? n : 0;
 39:   nleavesB = k;

 41:   PetscMalloc1(nleavesA, &ilocalA);
 42:   PetscMalloc1(nleavesA, &iremoteA);
 43:   PetscMalloc1(nleavesB, &ilocalB);
 44:   PetscMalloc1(nleavesB, &iremoteB);

 46:   /* sf A bcast is equivalent to a sparse gather on process 0
 47:      process 0 receives data in the middle [nl,3*nl] of the leaf data array for A */
 48:   for (i = 0; i < nleavesA; i++) {
 49:     iremoteA[i].rank = i/m;
 50:     iremoteA[i].index = i%m;
 51:     ilocalA[i] = nl + i/m * 4*nl + i%m;
 52:   }

 54:   /* sf B bcast is equivalent to a sparse scatter from process 0
 55:      process 0 sends data from [nl,2*nl] of the leaf data array for A
 56:      each process receives, in reverse order, in the middle [nl,2*nl] of the leaf data array for B */
 57:   for (i = 0; i < nleavesB; i++) {
 58:     iremoteB[i].rank = 0;
 59:     iremoteB[i].index = rank * 4*nl + nl + i%m;
 60:     ilocalB[i] = 2*nl - i - 1;
 61:   }
 62:   PetscSFSetGraph(sfA, nrootsA, nleavesA, ilocalA, PETSC_OWN_POINTER, iremoteA, PETSC_OWN_POINTER);
 63:   PetscSFSetGraph(sfB, nrootsB, nleavesB, ilocalB, PETSC_OWN_POINTER, iremoteB, PETSC_OWN_POINTER);
 64:   PetscSFSetUp(sfA);
 65:   PetscSFSetUp(sfB);
 66:   PetscObjectSetName((PetscObject)sfA, "sfA");
 67:   PetscObjectSetName((PetscObject)sfB, "sfB");
 68:   PetscSFViewFromOptions(sfA, NULL, "-view");
 69:   PetscSFViewFromOptions(sfB, NULL, "-view");

 71:   PetscSFGetLeafRange(sfA, NULL, &mA);
 72:   PetscSFGetLeafRange(sfB, NULL, &mB);
 73:   PetscMalloc2(nrootsA, &rdA, nldataA, &ldA);
 74:   PetscMalloc2(nrootsB, &rdB, nldataB, &ldB);
 75:   for (i = 0; i < nrootsA; i++) rdA[i] = m*rank + i;
 76:   for (i = 0; i < nldataA; i++) ldA[i] = -1;
 77:   for (i = 0; i < nldataB; i++) ldB[i] = -1;

 79:   PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "BcastB(BcastA)\n");
 80:   PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "A: root data\n");
 81:   PetscIntView(nrootsA, rdA, PETSC_VIEWER_STDOUT_WORLD);
 82:   PetscSFBcastBegin(sfA, MPIU_INT, rdA, ldA);
 83:   PetscSFBcastEnd(sfA, MPIU_INT, rdA, ldA);
 84:   PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "A: leaf data (all)\n");
 85:   PetscIntView(nldataA, ldA, PETSC_VIEWER_STDOUT_WORLD);
 86:   PetscSFBcastBegin(sfB, MPIU_INT, ldA, ldB);
 87:   PetscSFBcastEnd(sfB, MPIU_INT, ldA, ldB);
 88:   PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "B: leaf data (all)\n");
 89:   PetscIntView(nldataB, ldB, PETSC_VIEWER_STDOUT_WORLD);

 91:   PetscSFCompose(sfA, sfB, &sfBA);
 92:   PetscSFSetFromOptions(sfBA);
 93:   PetscSFSetUp(sfBA);
 94:   PetscObjectSetName((PetscObject)sfBA, "sfBA");
 95:   PetscSFViewFromOptions(sfBA, NULL, "-view");

 97:   for (i = 0; i < nldataB; i++) ldB[i] = -1;
 98:   PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "BcastBA\n");
 99:   PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "BA: root data\n");
100:   PetscIntView(nrootsA, rdA, PETSC_VIEWER_STDOUT_WORLD);
101:   PetscSFBcastBegin(sfBA, MPIU_INT, rdA, ldB);
102:   PetscSFBcastEnd(sfBA, MPIU_INT, rdA, ldB);
103:   PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "BA: leaf data (all)\n");
104:   PetscIntView(nldataB, ldB, PETSC_VIEWER_STDOUT_WORLD);

106:   PetscSFCreateInverseSF(sfA, &sfAm);
107:   PetscSFSetFromOptions(sfAm);
108:   PetscObjectSetName((PetscObject)sfAm, "sfAm");
109:   PetscSFViewFromOptions(sfAm, NULL, "-view");

111:   if (!inverse) {
112:     PetscSFComposeInverse(sfA, sfA, &sfAAm);
113:   } else {
114:     PetscSFCompose(sfA, sfAm, &sfAAm);
115:   }
116:   PetscSFSetFromOptions(sfAAm);
117:   PetscSFSetUp(sfAAm);
118:   PetscObjectSetName((PetscObject)sfAAm, "sfAAm");
119:   PetscSFViewFromOptions(sfAAm, NULL, "-view");

121:   PetscSFCreateInverseSF(sfB, &sfBm);
122:   PetscSFSetFromOptions(sfBm);
123:   PetscObjectSetName((PetscObject)sfBm, "sfBm");
124:   PetscSFViewFromOptions(sfBm, NULL, "-view");

126:   if (!inverse) {
127:     PetscSFComposeInverse(sfB, sfB, &sfBBm);
128:   } else {
129:     PetscSFCompose(sfB, sfBm, &sfBBm);
130:   }
131:   PetscSFSetFromOptions(sfBBm);
132:   PetscSFSetUp(sfBBm);
133:   PetscObjectSetName((PetscObject)sfBBm, "sfBBm");
134:   PetscSFViewFromOptions(sfBBm, NULL, "-view");

136:   PetscFree2(rdA, ldA);
137:   PetscFree2(rdB, ldB);

139:   PetscSFDestroy(&sfA);
140:   PetscSFDestroy(&sfB);
141:   PetscSFDestroy(&sfBA);
142:   PetscSFDestroy(&sfAm);
143:   PetscSFDestroy(&sfBm);
144:   PetscSFDestroy(&sfAAm);
145:   PetscSFDestroy(&sfBBm);

147:   PetscFinalize();

149:   return ierr;
150: }

152: /*TEST

154:    test:
155:      suffix: 1
156:      args: -view -explicit_inverse {{0 1}}

158:    test:
159:      nsize: 7
160:      filter: grep -v "type" | grep -v "sort"
161:      suffix: 2
162:      args: -view -nl 5 -explicit_inverse {{0 1}}

164:    # we cannot test for -sf_window_flavor dynamic because SFCompose with sparse leaves may change the root data pointer only locally, and this is not supported by the dynamic case
165:    test:
166:      nsize: 7
167:      suffix: 2_window
168:      filter: grep -v "type" | grep -v "sort"
169:      output_file: output/ex5_2.out
170:      args: -view -nl 5 -explicit_inverse {{0 1}} -sf_type window -sf_window_sync {{fence lock active}} -sf_window_flavor {{create allocate}}
171:      requires: define(PETSC_HAVE_MPI_ONE_SIDED)

173:    # The nightly test suite with MPICH uses ch3:sock, which is broken when winsize == 0 in some of the processes
174:    test:
175:      nsize: 7
176:      suffix: 2_window_shared
177:      filter: grep -v "type" | grep -v "sort"
178:      output_file: output/ex5_2.out
179:      args: -view -nl 5 -explicit_inverse {{0 1}} -sf_type window -sf_window_sync {{fence lock active}} -sf_window_flavor shared
180:      requires: define(PETSC_HAVE_MPI_PROCESS_SHARED_MEMORY) !define(PETSC_HAVE_MPICH_NUMVERSION) define(PETSC_HAVE_MPI_ONE_SIDED)

182: TEST*/