Actual source code: arrayview.c

  1: #include <petsc/private/petscimpl.h>
  2: #include <petscviewer.h>

  4: /*@
  5:   PetscIntViewNumColumns - Prints an array of integers; useful for debugging.

  7:   Collective

  9:   Input Parameters:
 10: + N      - number of integers in array
 11: . Ncol   - number of integers to print per row
 12: . idx    - array of integers
 13: - viewer - an optional `PetscViewer` visualization context

 15:   Level: intermediate

 17:   Note:
 18:   This may be called from within the debugger, passing 0 as the viewer

 20:   This API may be removed in the future.

 22:   Developer Note:
 23:   `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done

 25: .seealso: `PetscViewer`, `PetscIntView()`, `PetscRealView()`
 26: @*/
 27: PetscErrorCode PetscIntViewNumColumns(PetscInt N, PetscInt Ncol, const PetscInt idx[], PetscViewer viewer)
 28: {
 29:   PetscMPIInt rank, size;
 30:   PetscInt    j, i, n = N / Ncol, p = N % Ncol;
 31:   PetscBool   isascii, isbinary;
 32:   MPI_Comm    comm;

 34:   PetscFunctionBegin;
 35:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
 36:   if (N) PetscAssertPointer(idx, 3);
 38:   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
 39:   PetscCallMPI(MPI_Comm_size(comm, &size));
 40:   PetscCallMPI(MPI_Comm_rank(comm, &rank));

 42:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
 43:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
 44:   if (isascii) {
 45:     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
 46:     for (i = 0; i < n; i++) {
 47:       if (size > 1) {
 48:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, Ncol * i));
 49:       } else {
 50:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", Ncol * i));
 51:       }
 52:       for (j = 0; j < Ncol; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[i * Ncol + j]));
 53:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
 54:     }
 55:     if (p) {
 56:       if (size > 1) {
 57:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %" PetscInt_FMT ":", rank, Ncol * n));
 58:       } else {
 59:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT ":", Ncol * n));
 60:       }
 61:       for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %" PetscInt_FMT, idx[Ncol * n + i]));
 62:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
 63:     }
 64:     PetscCall(PetscViewerFlush(viewer));
 65:     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
 66:   } else if (isbinary) {
 67:     PetscMPIInt *sizes, Ntotal, *displs, NN;
 68:     PetscInt    *array;

 70:     PetscCall(PetscMPIIntCast(N, &NN));

 72:     if (size > 1) {
 73:       if (rank) {
 74:         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
 75:         PetscCallMPI(MPI_Gatherv(idx, NN, MPIU_INT, NULL, NULL, NULL, MPIU_INT, 0, comm));
 76:       } else {
 77:         PetscCall(PetscMalloc1(size, &sizes));
 78:         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
 79:         Ntotal = sizes[0];
 80:         PetscCall(PetscMalloc1(size, &displs));
 81:         displs[0] = 0;
 82:         for (i = 1; i < size; i++) {
 83:           Ntotal += sizes[i];
 84:           displs[i] = displs[i - 1] + sizes[i - 1];
 85:         }
 86:         PetscCall(PetscMalloc1(Ntotal, &array));
 87:         PetscCallMPI(MPI_Gatherv(idx, NN, MPIU_INT, array, sizes, displs, MPIU_INT, 0, comm));
 88:         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_INT));
 89:         PetscCall(PetscFree(sizes));
 90:         PetscCall(PetscFree(displs));
 91:         PetscCall(PetscFree(array));
 92:       }
 93:     } else {
 94:       PetscCall(PetscViewerBinaryWrite(viewer, idx, N, PETSC_INT));
 95:     }
 96:   } else {
 97:     const char *tname;
 98:     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
 99:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
100:   }
101:   PetscFunctionReturn(PETSC_SUCCESS);
102: }

104: /*@
105:   PetscRealViewNumColumns - Prints an array of doubles; useful for debugging.

107:   Collective

109:   Input Parameters:
110: + N      - number of `PetscReal` in array
111: . Ncol   - number of `PetscReal` to print per row
112: . idx    - array of `PetscReal`
113: - viewer - an optional `PetscViewer` visualization context

115:   Level: intermediate

117:   Note:
118:   This may be called from within the debugger, passing 0 as the viewer

120:   This API may be removed in the future.

122:   Developer Note:
123:   `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done

125: .seealso: `PetscViewer`, `PetscRealView()`, `PetscIntView()`
126: @*/
127: PetscErrorCode PetscRealViewNumColumns(PetscInt N, PetscInt Ncol, const PetscReal idx[], PetscViewer viewer)
128: {
129:   PetscMPIInt rank, size;
130:   PetscInt    j, i, n = N / Ncol, p = N % Ncol;
131:   PetscBool   isascii, isbinary;
132:   MPI_Comm    comm;

134:   PetscFunctionBegin;
135:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
136:   if (N) PetscAssertPointer(idx, 3);
138:   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
139:   PetscCallMPI(MPI_Comm_size(comm, &size));
140:   PetscCallMPI(MPI_Comm_rank(comm, &rank));

142:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
143:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
144:   if (isascii) {
145:     PetscInt tab;

147:     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
148:     PetscCall(PetscViewerASCIIGetTab(viewer, &tab));
149:     for (i = 0; i < n; i++) {
150:       PetscCall(PetscViewerASCIISetTab(viewer, tab));
151:       if (size > 1) {
152:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, Ncol * i));
153:       } else {
154:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", Ncol * i));
155:       }
156:       PetscCall(PetscViewerASCIISetTab(viewer, 0));
157:       for (j = 0; j < Ncol; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * Ncol + j]));
158:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
159:     }
160:     if (p) {
161:       PetscCall(PetscViewerASCIISetTab(viewer, tab));
162:       if (size > 1) {
163:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, Ncol * n));
164:       } else {
165:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", Ncol * n));
166:       }
167:       PetscCall(PetscViewerASCIISetTab(viewer, 0));
168:       for (i = 0; i < p; i++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[Ncol * n + i]));
169:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
170:     }
171:     PetscCall(PetscViewerFlush(viewer));
172:     PetscCall(PetscViewerASCIISetTab(viewer, tab));
173:     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
174:   } else if (isbinary) {
175:     PetscMPIInt *sizes, *displs, Ntotal, NN;
176:     PetscReal   *array;

178:     PetscCall(PetscMPIIntCast(N, &NN));

180:     if (size > 1) {
181:       if (rank) {
182:         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
183:         PetscCallMPI(MPI_Gatherv(idx, NN, MPIU_REAL, NULL, NULL, NULL, MPIU_REAL, 0, comm));
184:       } else {
185:         PetscCall(PetscMalloc1(size, &sizes));
186:         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
187:         Ntotal = sizes[0];
188:         PetscCall(PetscMalloc1(size, &displs));
189:         displs[0] = 0;
190:         for (i = 1; i < size; i++) {
191:           Ntotal += sizes[i];
192:           displs[i] = displs[i - 1] + sizes[i - 1];
193:         }
194:         PetscCall(PetscMalloc1(Ntotal, &array));
195:         PetscCallMPI(MPI_Gatherv(idx, NN, MPIU_REAL, array, sizes, displs, MPIU_REAL, 0, comm));
196:         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_REAL));
197:         PetscCall(PetscFree(sizes));
198:         PetscCall(PetscFree(displs));
199:         PetscCall(PetscFree(array));
200:       }
201:     } else {
202:       PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_REAL));
203:     }
204:   } else {
205:     const char *tname;
206:     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
207:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
208:   }
209:   PetscFunctionReturn(PETSC_SUCCESS);
210: }

212: /*@
213:   PetscScalarViewNumColumns - Prints an array of doubles; useful for debugging.

215:   Collective

217:   Input Parameters:
218: + N      - number of `PetscScalar` in array
219: . Ncol   - number of `PetscScalar` to print per row
220: . idx    - array of `PetscScalar`
221: - viewer - an optional `PetscViewer` visualization context

223:   Level: intermediate

225:   Note:
226:   This may be called from within the debugger, passing 0 as the viewer

228:   This API may be removed in the future.

230:   Developer Note:
231:   `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done

233: .seealso: `PetscViewer`, `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`
234: @*/
235: PetscErrorCode PetscScalarViewNumColumns(PetscInt N, PetscInt Ncol, const PetscScalar idx[], PetscViewer viewer)
236: {
237:   PetscMPIInt rank, size;
238:   PetscInt    j, i, n = N / Ncol, p = N % Ncol;
239:   PetscBool   isascii, isbinary;
240:   MPI_Comm    comm;

242:   PetscFunctionBegin;
243:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
244:   if (N) PetscAssertPointer(idx, 3);
246:   PetscCall(PetscObjectGetComm((PetscObject)viewer, &comm));
247:   PetscCallMPI(MPI_Comm_size(comm, &size));
248:   PetscCallMPI(MPI_Comm_rank(comm, &rank));

250:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
251:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
252:   if (isascii) {
253:     PetscCall(PetscViewerASCIIPushSynchronized(viewer));
254:     for (i = 0; i < n; i++) {
255:       if (size > 1) {
256:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, Ncol * i));
257:       } else {
258:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", Ncol * i));
259:       }
260:       for (j = 0; j < Ncol; j++) {
261: #if PetscDefined(USE_COMPLEX)
262:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[i * Ncol + j]), (double)PetscImaginaryPart(idx[i * Ncol + j])));
263: #else
264:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[i * Ncol + j]));
265: #endif
266:       }
267:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
268:     }
269:     if (p) {
270:       if (size > 1) {
271:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] %2" PetscInt_FMT ":", rank, Ncol * n));
272:       } else {
273:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%2" PetscInt_FMT ":", Ncol * n));
274:       }
275:       for (i = 0; i < p; i++) {
276: #if PetscDefined(USE_COMPLEX)
277:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " (%12.4e,%12.4e)", (double)PetscRealPart(idx[n * Ncol + i]), (double)PetscImaginaryPart(idx[n * Ncol + i])));
278: #else
279:         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " %12.4e", (double)idx[Ncol * n + i]));
280: #endif
281:       }
282:       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
283:     }
284:     PetscCall(PetscViewerFlush(viewer));
285:     PetscCall(PetscViewerASCIIPopSynchronized(viewer));
286:   } else if (isbinary) {
287:     PetscMPIInt *sizes, Ntotal, *displs, NN;
288:     PetscScalar *array;

290:     PetscCall(PetscMPIIntCast(N, &NN));

292:     if (size > 1) {
293:       if (rank) {
294:         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, NULL, 0, MPI_INT, 0, comm));
295:         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, NULL, NULL, NULL, MPIU_SCALAR, 0, comm));
296:       } else {
297:         PetscCall(PetscMalloc1(size, &sizes));
298:         PetscCallMPI(MPI_Gather(&NN, 1, MPI_INT, sizes, 1, MPI_INT, 0, comm));
299:         Ntotal = sizes[0];
300:         PetscCall(PetscMalloc1(size, &displs));
301:         displs[0] = 0;
302:         for (i = 1; i < size; i++) {
303:           Ntotal += sizes[i];
304:           displs[i] = displs[i - 1] + sizes[i - 1];
305:         }
306:         PetscCall(PetscMalloc1(Ntotal, &array));
307:         PetscCallMPI(MPI_Gatherv((void *)idx, NN, MPIU_SCALAR, array, sizes, displs, MPIU_SCALAR, 0, comm));
308:         PetscCall(PetscViewerBinaryWrite(viewer, array, Ntotal, PETSC_SCALAR));
309:         PetscCall(PetscFree(sizes));
310:         PetscCall(PetscFree(displs));
311:         PetscCall(PetscFree(array));
312:       }
313:     } else {
314:       PetscCall(PetscViewerBinaryWrite(viewer, (void *)idx, N, PETSC_SCALAR));
315:     }
316:   } else {
317:     const char *tname;
318:     PetscCall(PetscObjectGetName((PetscObject)viewer, &tname));
319:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot handle that PetscViewer of type %s", tname);
320:   }
321:   PetscFunctionReturn(PETSC_SUCCESS);
322: }

324: /*@
325:   PetscIntView - Prints an array of integers; useful for debugging.

327:   Collective

329:   Input Parameters:
330: + N      - number of integers in array
331: . idx    - array of integers
332: - viewer - an optional `PetscViewer` visualization context

334:   Level: intermediate

336:   Note:
337:   This may be called from within the debugger, passing 0 as the viewer

339:   This API may be removed in the future.

341:   Same as `PetscIntViewNumColumns()` with 20 values per row

343:   Developer Note:
344:   `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done

346: .seealso: `PetscViewer`, `PetscIntViewNumColumns()`, `PetscIntCSRView()`, `PetscRealView()`
347: @*/
348: PetscErrorCode PetscIntView(PetscInt N, const PetscInt idx[], PetscViewer viewer)
349: {
350:   PetscFunctionBegin;
351:   PetscCall(PetscIntViewNumColumns(N, 20, idx, viewer));
352:   PetscFunctionReturn(PETSC_SUCCESS);
353: }

355: /*@
356:   PetscIntCSRView - Prints a graph represented in compressed sparse row (CSR) format; useful for debugging.

358:   Collective

360:   Input Parameters:
361: + N      - number of local vertices
362: . ia     - row pointers of length `N + 1`
363: . ja     - adjacency list of length `ia[N]`
364: - viewer - an optional `PetscViewer` visualization context

366:   Level: intermediate

368:   Notes:
369:   This may be called from within the debugger, passing `NULL` as the viewer.

371:   `ia[0]` must be zero and the row pointers must be nondecreasing.

373:   Only ASCII viewers are supported.

375: .seealso: `PetscViewer`, `PetscIntView()`, `PetscPartitionerPartition()`
376: @*/
377: PetscErrorCode PetscIntCSRView(PetscInt N, const PetscInt ia[], const PetscInt ja[], PetscViewer viewer)
378: {
379:   PetscMPIInt rank;
380:   PetscBool   isascii;

382:   PetscFunctionBegin;
383:   PetscCheck(N >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of rows must be non-negative");
384:   if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
385:   if (N) {
386:     PetscAssertPointer(ia, 2);
387:     PetscCheck(!ia[0], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "First row offset must be zero, got %" PetscInt_FMT, ia[0]);
388:     for (PetscInt i = 0; i < N; i++)
389:       PetscCheck(ia[i] <= ia[i + 1], PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row offsets must be nondecreasing, got ia[%" PetscInt_FMT "] = %" PetscInt_FMT " > ia[%" PetscInt_FMT "] = %" PetscInt_FMT, i, ia[i], i + 1, ia[i + 1]);
390:     if (ia[N]) PetscAssertPointer(ja, 3);
391:   }
393:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
394:   PetscCheck(isascii, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Only ASCII viewers are supported");
395:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer), &rank));
396:   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
397:   PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Nv: %" PetscInt_FMT "\n", rank, N));
398:   for (PetscInt i = 0; i < N; i++) {
399:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]  ", rank));
400:     for (PetscInt j = ia[i]; j < ia[i + 1]; j++) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT " ", ja[j]));
401:     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%" PetscInt_FMT "-%" PetscInt_FMT ")\n", ia[i], ia[i + 1]));
402:   }
403:   PetscCall(PetscViewerFlush(viewer));
404:   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
405:   PetscFunctionReturn(PETSC_SUCCESS);
406: }

408: /*@
409:   PetscRealView - Prints an array of doubles; useful for debugging.

411:   Collective

413:   Input Parameters:
414: + N      - number of `PetscReal` in array
415: . idx    - array of `PetscReal`
416: - viewer - an optional `PetscViewer` visualization context

418:   Level: intermediate

420:   Note:
421:   This may be called from within the debugger, passing 0 as the viewer

423:   This API may be removed in the future.

425:   Same as `PetscRealViewNumColumns()` with 5 values per row

427:   Developer Note:
428:   `idx` cannot be const because may be passed to binary viewer where temporary byte swapping may be done

430: .seealso: `PetscViewer`, `PetscIntView()`
431: @*/
432: PetscErrorCode PetscRealView(PetscInt N, const PetscReal idx[], PetscViewer viewer)
433: {
434:   PetscFunctionBegin;
435:   PetscCall(PetscRealViewNumColumns(N, 5, idx, viewer));
436:   PetscFunctionReturn(PETSC_SUCCESS);
437: }

439: /*@
440:   PetscScalarView - Prints an array of `PetscScalar`; useful for debugging.

442:   Collective

444:   Input Parameters:
445: + N      - number of scalars in array
446: . idx    - array of scalars
447: - viewer - an optional `PetscViewer` visualization context

449:   Level: intermediate

451:   Note:
452:   This may be called from within the debugger, passing 0 as the viewer

454:   This API may be removed in the future.

456:   Same as `PetscScalarViewNumColumns()` with 3 values per row

458:   Developer Note:
459:   `idx` cannot be const because may be passed to binary viewer where byte swapping may be done

461: .seealso: `PetscViewer`, `PetscIntView()`, `PetscRealView()`
462: @*/
463: PetscErrorCode PetscScalarView(PetscInt N, const PetscScalar idx[], PetscViewer viewer)
464: {
465:   PetscFunctionBegin;
466:   PetscCall(PetscScalarViewNumColumns(N, 3, idx, viewer));
467:   PetscFunctionReturn(PETSC_SUCCESS);
468: }