Actual source code: ex16.c

  1: static char help[] = "Test PetscSFCreateByMatchingIndices\n\n";

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

  6: /* Test PetscSFCreateByMatchingIndices.

  8: testnum 0:

 10:   rank             : 0            1            2
 11:   numRootIndices   : 3            1            1
 12:   rootIndices      : [1 0 2]      [3]          [3]
 13:   rootLocalOffset  : 100          200          300
 14:   layout           : [0 1]        [2]          [3]
 15:   numLeafIndices   : 1            1            2
 16:   leafIndices      : [0]          [2]          [0 3]
 17:   leafLocalOffset  : 400          500          600

 19: would build the following SF:

 21:   [0] 400 <- (0,101)
 22:   [1] 500 <- (0,102)
 23:   [2] 600 <- (0,101)
 24:   [2] 601 <- (2,300)

 26: testnum 1:

 28:   rank             : 0               1               2
 29:   numRootIndices   : 3               1               1
 30:   rootIndices      : [1 0 2]         [3]             [3]
 31:   rootLocalOffset  : 100             200             300
 32:   layout           : [0 1]           [2]             [3]
 33:   numLeafIndices   : numRootIndices  numRootIndices  numRootIndices
 34:   leafIndices      : rootIndices     rootIndices     rootIndices
 35:   leafLocalOffset  : rootLocalOffset rootLocalOffset rootLocalOffset

 37: would build the following SF:

 39:   [1] 200 <- (2,300)

 41: testnum 2:

 43:   No one claims ownership of global index 1, but no one needs it.

 45:   rank             : 0            1            2
 46:   numRootIndices   : 2            1            1
 47:   rootIndices      : [0 2]        [3]          [3]
 48:   rootLocalOffset  : 100          200          300
 49:   layout           : [0 1]        [2]          [3]
 50:   numLeafIndices   : 1            1            2
 51:   leafIndices      : [0]          [2]          [0 3]
 52:   leafLocalOffset  : 400          500          600

 54: would build the following SF:

 56:   [0] 400 <- (0,100)
 57:   [1] 500 <- (0,101)
 58:   [2] 600 <- (0,100)
 59:   [2] 601 <- (2,300)

 61: */

 63: int main(int argc, char **argv)
 64: {
 65:   PetscSF     sf;
 66:   PetscLayout layout;
 67:   PetscInt    N, n;
 68:   PetscInt    nA = -1, *A, offsetA = -1;
 69:   PetscInt    nB = -1, *B, offsetB = -1;
 70:   PetscMPIInt size, rank;
 71:   PetscInt    testnum;

 73:   PetscFunctionBeginUser;
 74:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
 75:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-testnum", &testnum, NULL));
 76:   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
 77:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
 78:   PetscCheck(size == 3, PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");

 80:   switch (testnum) {
 81:   case 0:
 82:     N = 4;
 83:     n = PETSC_DECIDE;
 84:     switch (rank) {
 85:     case 0:
 86:       nA      = 3;
 87:       offsetA = 100;
 88:       nB      = 1;
 89:       offsetB = 400;
 90:       break;
 91:     case 1:
 92:       nA      = 1;
 93:       offsetA = 200;
 94:       nB      = 1;
 95:       offsetB = 500;
 96:       break;
 97:     case 2:
 98:       nA      = 1;
 99:       offsetA = 300;
100:       nB      = 2;
101:       offsetB = 600;
102:       break;
103:     default:
104:       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
105:     }
106:     PetscCall(PetscMalloc1(nA, &A));
107:     PetscCall(PetscMalloc1(nB, &B));
108:     switch (rank) {
109:     case 0:
110:       A[0] = 1;
111:       A[1] = 0;
112:       A[2] = 2;
113:       B[0] = 0;
114:       break;
115:     case 1:
116:       A[0] = 3;
117:       B[0] = 2;
118:       break;
119:     case 2:
120:       A[0] = 3;
121:       B[0] = 0;
122:       B[1] = 3;
123:       break;
124:     default:
125:       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
126:     }
127:     break;
128:   case 1:
129:     N = 4;
130:     n = PETSC_DECIDE;
131:     switch (rank) {
132:     case 0:
133:       nA      = 3;
134:       offsetA = 100;
135:       break;
136:     case 1:
137:       nA      = 1;
138:       offsetA = 200;
139:       break;
140:     case 2:
141:       nA      = 1;
142:       offsetA = 300;
143:       break;
144:     default:
145:       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
146:     }
147:     PetscCall(PetscMalloc1(nA, &A));
148:     switch (rank) {
149:     case 0:
150:       A[0] = 1;
151:       A[1] = 0;
152:       A[2] = 2;
153:       break;
154:     case 1:
155:       A[0] = 3;
156:       break;
157:     case 2:
158:       A[0] = 3;
159:       break;
160:     default:
161:       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
162:     }
163:     nB      = nA;
164:     B       = A;
165:     offsetB = offsetA;
166:     break;
167:   case 2:
168:     N = 4;
169:     n = PETSC_DECIDE;
170:     switch (rank) {
171:     case 0:
172:       nA      = 2;
173:       offsetA = 100;
174:       nB      = 1;
175:       offsetB = 400;
176:       break;
177:     case 1:
178:       nA      = 1;
179:       offsetA = 200;
180:       nB      = 1;
181:       offsetB = 500;
182:       break;
183:     case 2:
184:       nA      = 1;
185:       offsetA = 300;
186:       nB      = 2;
187:       offsetB = 600;
188:       break;
189:     default:
190:       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
191:     }
192:     PetscCall(PetscMalloc1(nA, &A));
193:     PetscCall(PetscMalloc1(nB, &B));
194:     switch (rank) {
195:     case 0:
196:       A[0] = 0;
197:       A[1] = 2;
198:       B[0] = 0;
199:       break;
200:     case 1:
201:       A[0] = 3;
202:       B[0] = 2;
203:       break;
204:     case 2:
205:       A[0] = 3;
206:       B[0] = 0;
207:       B[1] = 3;
208:       break;
209:     default:
210:       SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 3 MPI processes");
211:     }
212:     break;
213:   }
214:   PetscCall(PetscLayoutCreate(PETSC_COMM_WORLD, &layout));
215:   PetscCall(PetscLayoutSetSize(layout, N));
216:   PetscCall(PetscLayoutSetLocalSize(layout, n));
217:   PetscCall(PetscLayoutSetBlockSize(layout, 1));
218:   PetscCall(PetscSFCreateByMatchingIndices(layout, nA, A, NULL, offsetA, nB, B, NULL, offsetB, NULL, &sf));
219:   PetscCall(PetscLayoutDestroy(&layout));
220:   PetscCall(PetscFree(A));
221:   if (testnum != 1) PetscCall(PetscFree(B));
222:   PetscCall(PetscObjectSetName((PetscObject)sf, "sf"));
223:   PetscCall(PetscSFView(sf, NULL));
224:   PetscCall(PetscSFDestroy(&sf));

226:   PetscCall(PetscFinalize());
227:   return 0;
228: }

230: /*TEST

232:   test:
233:     suffix: 0
234:     nsize: 3
235:     args: -testnum 0

237:   test:
238:     suffix: 1
239:     nsize: 3
240:     args: -testnum 1

242:   test:
243:     suffix: 2
244:     nsize: 3
245:     args: -testnum 2

247: TEST*/