Actual source code: ex72.c


  2: static char help[] = "Reads a PETSc matrix and vector from a file and solves a linear system.\n\
  3: This version first preloads and solves a small system, then loads \n\
  4: another (larger) system and solves it as well.  This example illustrates\n\
  5: preloading of instructions with the smaller system so that more accurate\n\
  6: performance monitoring can be done with the larger one (that actually\n\
  7: is the system of interest).  See the 'Performance Hints' chapter of the\n\
  8: users manual for a discussion of preloading.  Input parameters include\n\
  9:   -f0 <input_file> : first file to load (small system)\n\
 10:   -f1 <input_file> : second file to load (larger system)\n\n\
 11:   -nearnulldim <0> : number of vectors in the near-null space immediately following matrix\n\n\
 12:   -trans  : solve transpose system instead\n\n";
 13: /*
 14:   This code can be used to test PETSc interface to other packages.\n\
 15:   Examples of command line options:       \n\
 16:    ./ex72 -f0 <datafile> -ksp_type preonly  \n\
 17:         -help -ksp_view                  \n\
 18:         -num_numfac <num_numfac> -num_rhs <num_rhs> \n\
 19:         -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type superlu or superlu_dist or mumps \n\
 20:         -ksp_type preonly -pc_type cholesky -pc_factor_mat_solver_type mumps \n\
 21:    mpiexec -n <np> ./ex72 -f0 <datafile> -ksp_type cg -pc_type asm -pc_asm_type basic -sub_pc_type icc -mat_type sbaij
 22:  \n\n";
 23: */

 25: /*
 26:   Include "petscksp.h" so that we can use KSP solvers.  Note that this file
 27:   automatically includes:
 28:      petscsys.h       - base PETSc routines   petscvec.h - vectors
 29:      petscmat.h - matrices
 30:      petscis.h     - index sets            petscksp.h - Krylov subspace methods
 31:      petscviewer.h - viewers               petscpc.h  - preconditioners
 32: */
 33: #include <petscksp.h>

 35: int main(int argc, char **args)
 36: {
 37:   KSP         ksp;                         /* linear solver context */
 38:   Mat         A;                           /* matrix */
 39:   Vec         x, b, u;                     /* approx solution, RHS, exact solution */
 40:   PetscViewer viewer;                      /* viewer */
 41:   char        file[4][PETSC_MAX_PATH_LEN]; /* input file name */
 42:   PetscBool   table = PETSC_FALSE, flg, trans = PETSC_FALSE, initialguess = PETSC_FALSE;
 43:   PetscBool   outputSoln = PETSC_FALSE, constantnullspace = PETSC_FALSE;
 44:   PetscInt    its, num_numfac, m, n, M, p, nearnulldim = 0;
 45:   PetscReal   norm;
 46:   PetscBool   preload = PETSC_TRUE, isSymmetric, cknorm = PETSC_FALSE, initialguessfile = PETSC_FALSE;
 47:   PetscMPIInt rank;
 48:   char        initialguessfilename[PETSC_MAX_PATH_LEN];
 49:   char        mtype[PETSC_MAX_PATH_LEN];

 51:   PetscFunctionBeginUser;
 52:   PetscCall(PetscInitialize(&argc, &args, (char *)0, help));
 53:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
 54:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-table", &table, NULL));
 55:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-constantnullspace", &constantnullspace, NULL));
 56:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-trans", &trans, NULL));
 57:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-initialguess", &initialguess, NULL));
 58:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-output_solution", &outputSoln, NULL));
 59:   PetscCall(PetscOptionsGetString(NULL, NULL, "-initialguessfilename", initialguessfilename, sizeof(initialguessfilename), &initialguessfile));
 60:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-nearnulldim", &nearnulldim, NULL));

 62:   /*
 63:      Determine files from which we read the two linear systems
 64:      (matrix and right-hand-side vector).
 65:   */
 66:   PetscCall(PetscOptionsGetString(NULL, NULL, "-f", file[0], sizeof(file[0]), &flg));
 67:   if (flg) {
 68:     PetscCall(PetscStrncpy(file[1], file[0], sizeof(file[1])));
 69:     preload = PETSC_FALSE;
 70:   } else {
 71:     PetscCall(PetscOptionsGetString(NULL, NULL, "-f0", file[0], sizeof(file[0]), &flg));
 72:     PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Must indicate binary file with the -f0 or -f option");
 73:     PetscCall(PetscOptionsGetString(NULL, NULL, "-f1", file[1], sizeof(file[1]), &flg));
 74:     if (!flg) preload = PETSC_FALSE; /* don't bother with second system */
 75:   }

 77:   /* -----------------------------------------------------------
 78:                   Beginning of linear solver loop
 79:      ----------------------------------------------------------- */
 80:   /*
 81:      Loop through the linear solve 2 times.
 82:       - The intention here is to preload and solve a small system;
 83:         then load another (larger) system and solve it as well.
 84:         This process preloads the instructions with the smaller
 85:         system so that more accurate performance monitoring (via
 86:         -log_view) can be done with the larger one (that actually
 87:         is the system of interest).
 88:   */
 89:   PetscPreLoadBegin(preload, "Load system");

 91:   /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
 92:                          Load system
 93:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

 95:   /*
 96:      Open binary file.  Note that we use FILE_MODE_READ to indicate
 97:      reading from this file.
 98:   */
 99:   PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[PetscPreLoadIt], FILE_MODE_READ, &viewer));

101:   /*
102:      Load the matrix and vector; then destroy the viewer.
103:   */
104:   PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
105:   PetscCall(MatSetFromOptions(A));
106:   PetscCall(MatLoad(A, viewer));

108:   PetscCall(PetscOptionsGetString(NULL, NULL, "-mat_convert_type", mtype, sizeof(mtype), &flg));
109:   if (flg) PetscCall(MatConvert(A, mtype, MAT_INPLACE_MATRIX, &A));

111:   if (nearnulldim) {
112:     MatNullSpace nullsp;
113:     Vec         *nullvecs;
114:     PetscInt     i;
115:     PetscCall(PetscMalloc1(nearnulldim, &nullvecs));
116:     for (i = 0; i < nearnulldim; i++) {
117:       PetscCall(VecCreate(PETSC_COMM_WORLD, &nullvecs[i]));
118:       PetscCall(VecLoad(nullvecs[i], viewer));
119:     }
120:     PetscCall(MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_FALSE, nearnulldim, nullvecs, &nullsp));
121:     PetscCall(MatSetNearNullSpace(A, nullsp));
122:     for (i = 0; i < nearnulldim; i++) PetscCall(VecDestroy(&nullvecs[i]));
123:     PetscCall(PetscFree(nullvecs));
124:     PetscCall(MatNullSpaceDestroy(&nullsp));
125:   }
126:   if (constantnullspace) {
127:     MatNullSpace constant;
128:     PetscCall(MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_TRUE, 0, NULL, &constant));
129:     PetscCall(MatSetNullSpace(A, constant));
130:     PetscCall(MatNullSpaceDestroy(&constant));
131:   }
132:   flg = PETSC_FALSE;
133:   PetscCall(PetscOptionsGetString(NULL, NULL, "-rhs", file[2], sizeof(file[2]), &flg));
134:   PetscCall(VecCreate(PETSC_COMM_WORLD, &b));
135:   if (flg) { /* rhs is stored in a separate file */
136:     if (file[2][0] == '0' || file[2][0] == 0) {
137:       PetscInt    m;
138:       PetscScalar one = 1.0;
139:       PetscCall(PetscInfo(0, "Using vector of ones for RHS\n"));
140:       PetscCall(MatGetLocalSize(A, &m, NULL));
141:       PetscCall(VecSetSizes(b, m, PETSC_DECIDE));
142:       PetscCall(VecSetFromOptions(b));
143:       PetscCall(VecSet(b, one));
144:     } else {
145:       PetscCall(PetscViewerDestroy(&viewer));
146:       PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[2], FILE_MODE_READ, &viewer));
147:       PetscCall(VecSetFromOptions(b));
148:       PetscCall(VecLoad(b, viewer));
149:     }
150:   } else { /* rhs is stored in the same file as matrix */
151:     PetscCall(VecSetFromOptions(b));
152:     PetscCall(VecLoad(b, viewer));
153:   }
154:   PetscCall(PetscViewerDestroy(&viewer));

156:   /* Make A singular for testing zero-pivot of ilu factorization */
157:   /* Example: ./ex72 -f0 <datafile> -test_zeropivot -pc_factor_shift_type <shift_type> */
158:   flg = PETSC_FALSE;
159:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_zeropivot", &flg, NULL));
160:   if (flg) { /* set a row as zeros */
161:     PetscInt row = 0;
162:     PetscCall(MatSetOption(A, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE));
163:     PetscCall(MatZeroRows(A, 1, &row, 0.0, NULL, NULL));
164:   }

166:   /* Check whether A is symmetric, then set A->symmetric option */
167:   flg = PETSC_FALSE;
168:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-check_symmetry", &flg, NULL));
169:   if (flg) {
170:     PetscCall(MatIsSymmetric(A, 0.0, &isSymmetric));
171:     if (!isSymmetric) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Warning: A is non-symmetric \n"));
172:   }

174:   /*
175:      If the loaded matrix is larger than the vector (due to being padded
176:      to match the block size of the system), then create a new padded vector.
177:   */

179:   PetscCall(MatGetLocalSize(A, NULL, &n));
180:   PetscCall(MatGetSize(A, &M, NULL));
181:   PetscCall(VecGetSize(b, &m));
182:   PetscCall(VecGetLocalSize(b, &p));
183:   preload = (PetscBool)(M != m || p != n); /* Global or local dimension mismatch */
184:   PetscCall(MPIU_Allreduce(&preload, &flg, 1, MPIU_BOOL, MPI_LOR, PetscObjectComm((PetscObject)A)));
185:   if (flg) { /* Create a new vector b by padding the old one */
186:     PetscInt     j, mvec, start, end, indx;
187:     Vec          tmp;
188:     PetscScalar *bold;

190:     PetscCall(VecCreate(PETSC_COMM_WORLD, &tmp));
191:     PetscCall(VecSetSizes(tmp, n, PETSC_DECIDE));
192:     PetscCall(VecSetFromOptions(tmp));
193:     PetscCall(VecGetOwnershipRange(b, &start, &end));
194:     PetscCall(VecGetLocalSize(b, &mvec));
195:     PetscCall(VecGetArray(b, &bold));
196:     for (j = 0; j < mvec; j++) {
197:       indx = start + j;
198:       PetscCall(VecSetValues(tmp, 1, &indx, bold + j, INSERT_VALUES));
199:     }
200:     PetscCall(VecRestoreArray(b, &bold));
201:     PetscCall(VecDestroy(&b));
202:     PetscCall(VecAssemblyBegin(tmp));
203:     PetscCall(VecAssemblyEnd(tmp));
204:     b = tmp;
205:   }

207:   PetscCall(MatCreateVecs(A, &x, NULL));
208:   PetscCall(VecDuplicate(b, &u));
209:   if (initialguessfile) {
210:     PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, initialguessfilename, FILE_MODE_READ, &viewer));
211:     PetscCall(VecLoad(x, viewer));
212:     PetscCall(PetscViewerDestroy(&viewer));
213:     initialguess = PETSC_TRUE;
214:   } else if (initialguess) {
215:     PetscCall(VecSet(x, 1.0));
216:   } else {
217:     PetscCall(VecSet(x, 0.0));
218:   }

220:   /* Check scaling in A */
221:   flg = PETSC_FALSE;
222:   PetscCall(PetscOptionsGetBool(NULL, NULL, "-check_scaling", &flg, NULL));
223:   if (flg) {
224:     Vec       max, min;
225:     PetscInt  idx;
226:     PetscReal val;

228:     PetscCall(VecDuplicate(x, &max));
229:     PetscCall(VecDuplicate(x, &min));
230:     PetscCall(MatGetRowMaxAbs(A, max, NULL));
231:     PetscCall(MatGetRowMinAbs(A, min, NULL));
232:     {
233:       PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "max.data", &viewer));
234:       PetscCall(VecView(max, viewer));
235:       PetscCall(PetscViewerDestroy(&viewer));
236:       PetscCall(PetscViewerASCIIOpen(PETSC_COMM_WORLD, "min.data", &viewer));
237:       PetscCall(VecView(min, viewer));
238:       PetscCall(PetscViewerDestroy(&viewer));
239:     }
240:     PetscCall(VecView(max, PETSC_VIEWER_DRAW_WORLD));
241:     PetscCall(VecMax(max, &idx, &val));
242:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Largest max row element %g at row %" PetscInt_FMT "\n", (double)val, idx));
243:     PetscCall(VecView(min, PETSC_VIEWER_DRAW_WORLD));
244:     PetscCall(VecMin(min, &idx, &val));
245:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Smallest min row element %g at row %" PetscInt_FMT "\n", (double)val, idx));
246:     PetscCall(VecMin(max, &idx, &val));
247:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Smallest max row element %g at row %" PetscInt_FMT "\n", (double)val, idx));
248:     PetscCall(VecPointwiseDivide(max, max, min));
249:     PetscCall(VecMax(max, &idx, &val));
250:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Largest row ratio %g at row %" PetscInt_FMT "\n", (double)val, idx));
251:     PetscCall(VecView(max, PETSC_VIEWER_DRAW_WORLD));
252:     PetscCall(VecDestroy(&max));
253:     PetscCall(VecDestroy(&min));
254:   }

256:   /*  PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); */
257:   /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
258:                     Setup solve for system
259:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
260:   /*
261:      Conclude profiling last stage; begin profiling next stage.
262:   */
263:   PetscPreLoadStage("KSPSetUpSolve");

265:   /*
266:      Create linear solver; set operators; set runtime options.
267:   */
268:   PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
269:   PetscCall(KSPSetInitialGuessNonzero(ksp, initialguess));
270:   num_numfac = 1;
271:   PetscCall(PetscOptionsGetInt(NULL, NULL, "-num_numfac", &num_numfac, NULL));
272:   while (num_numfac--) {
273:     PC        pc;
274:     PetscBool lsqr, isbddc, ismatis;
275:     char      str[32];

277:     PetscCall(PetscOptionsGetString(NULL, NULL, "-ksp_type", str, sizeof(str), &lsqr));
278:     if (lsqr) PetscCall(PetscStrcmp("lsqr", str, &lsqr));
279:     if (lsqr) {
280:       Mat BtB;
281:       PetscCall(MatTransposeMatMult(A, A, MAT_INITIAL_MATRIX, 4, &BtB));
282:       PetscCall(KSPSetOperators(ksp, A, BtB));
283:       PetscCall(MatDestroy(&BtB));
284:     } else {
285:       PetscCall(KSPSetOperators(ksp, A, A));
286:     }
287:     PetscCall(KSPSetFromOptions(ksp));

289:     /* if we test BDDC, make sure pmat is of type MATIS */
290:     PetscCall(KSPGetPC(ksp, &pc));
291:     PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCBDDC, &isbddc));
292:     PetscCall(PetscObjectTypeCompare((PetscObject)A, MATIS, &ismatis));
293:     if (isbddc && !ismatis) {
294:       Mat J;

296:       PetscCall(MatConvert(A, MATIS, MAT_INITIAL_MATRIX, &J));
297:       PetscCall(KSPSetOperators(ksp, A, J));
298:       PetscCall(MatDestroy(&J));
299:     }

301:     /*
302:      Here we explicitly call KSPSetUp() and KSPSetUpOnBlocks() to
303:      enable more precise profiling of setting up the preconditioner.
304:      These calls are optional, since both will be called within
305:      KSPSolve() if they haven't been called already.
306:     */
307:     PetscCall(KSPSetUp(ksp));
308:     PetscCall(KSPSetUpOnBlocks(ksp));

310:     /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
311:                          Solve system
312:       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

314:     /*
315:      Solve linear system;
316:     */
317:     if (trans) {
318:       PetscCall(KSPSolveTranspose(ksp, b, x));
319:       PetscCall(KSPGetIterationNumber(ksp, &its));
320:     } else {
321:       PetscInt num_rhs = 1;
322:       PetscCall(PetscOptionsGetInt(NULL, NULL, "-num_rhs", &num_rhs, NULL));
323:       cknorm = PETSC_FALSE;
324:       PetscCall(PetscOptionsGetBool(NULL, NULL, "-cknorm", &cknorm, NULL));
325:       while (num_rhs--) {
326:         if (num_rhs == 1) PetscCall(VecSet(x, 0.0));
327:         PetscCall(KSPSolve(ksp, b, x));
328:       }
329:       PetscCall(KSPGetIterationNumber(ksp, &its));
330:       if (cknorm) { /* Check error for each rhs */
331:         if (trans) {
332:           PetscCall(MatMultTranspose(A, x, u));
333:         } else {
334:           PetscCall(MatMult(A, x, u));
335:         }
336:         PetscCall(VecAXPY(u, -1.0, b));
337:         PetscCall(VecNorm(u, NORM_2, &norm));
338:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Number of iterations = %3" PetscInt_FMT "\n", its));
339:         if (!PetscIsNanScalar(norm)) {
340:           if (norm < 1.e-12) {
341:             PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Residual norm < 1.e-12\n"));
342:           } else {
343:             PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Residual norm %g\n", (double)norm));
344:           }
345:         }
346:       }
347:     } /* while (num_rhs--) */

349:     /* - - - - - - - - - - - New Stage - - - - - - - - - - - - -
350:           Check error, print output, free data structures.
351:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

353:     /*
354:        Check error
355:     */
356:     if (trans) {
357:       PetscCall(MatMultTranspose(A, x, u));
358:     } else {
359:       PetscCall(MatMult(A, x, u));
360:     }
361:     PetscCall(VecAXPY(u, -1.0, b));
362:     PetscCall(VecNorm(u, NORM_2, &norm));
363:     /*
364:      Write output (optionally using table for solver details).
365:       - PetscPrintf() handles output for multiprocessor jobs
366:         by printing from only one processor in the communicator.
367:       - KSPView() prints information about the linear solver.
368:     */
369:     if (table) {
370:       char *matrixname = NULL, kspinfo[120];

372:       /*
373:        Open a string viewer; then write info to it.
374:       */
375:       PetscCall(PetscViewerStringOpen(PETSC_COMM_WORLD, kspinfo, sizeof(kspinfo), &viewer));
376:       PetscCall(KSPView(ksp, viewer));
377:       PetscCall(PetscStrrchr(file[PetscPreLoadIt], '/', &matrixname));
378:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%-8.8s %3" PetscInt_FMT " %2.0e %s \n", matrixname, its, (double)norm, kspinfo));

380:       /*
381:         Destroy the viewer
382:       */
383:       PetscCall(PetscViewerDestroy(&viewer));
384:     } else {
385:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Number of iterations = %3" PetscInt_FMT "\n", its));
386:       if (!PetscIsNanScalar(norm)) {
387:         if (norm < 1.e-12 && !PetscIsNanScalar((PetscScalar)norm)) {
388:           PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Residual norm < 1.e-12\n"));
389:         } else {
390:           PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Residual norm %g\n", (double)norm));
391:         }
392:       }
393:     }
394:     PetscCall(PetscOptionsGetString(NULL, NULL, "-solution", file[3], sizeof(file[3]), &flg));
395:     if (flg) {
396:       Vec       xstar;
397:       PetscReal norm;

399:       PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[3], FILE_MODE_READ, &viewer));
400:       PetscCall(VecCreate(PETSC_COMM_WORLD, &xstar));
401:       PetscCall(VecLoad(xstar, viewer));
402:       PetscCall(VecAXPY(xstar, -1.0, x));
403:       PetscCall(VecNorm(xstar, NORM_2, &norm));
404:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error norm %g\n", (double)norm));
405:       PetscCall(VecDestroy(&xstar));
406:       PetscCall(PetscViewerDestroy(&viewer));
407:     }
408:     if (outputSoln) {
409:       PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, "solution.petsc", FILE_MODE_WRITE, &viewer));
410:       PetscCall(VecView(x, viewer));
411:       PetscCall(PetscViewerDestroy(&viewer));
412:     }

414:     flg = PETSC_FALSE;
415:     PetscCall(PetscOptionsGetBool(NULL, NULL, "-ksp_reason", &flg, NULL));
416:     if (flg) {
417:       KSPConvergedReason reason;
418:       PetscCall(KSPGetConvergedReason(ksp, &reason));
419:       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "KSPConvergedReason: %s\n", KSPConvergedReasons[reason]));
420:     }

422:   } /* while (num_numfac--) */

424:   /*
425:      Free work space.  All PETSc objects should be destroyed when they
426:      are no longer needed.
427:   */
428:   PetscCall(MatDestroy(&A));
429:   PetscCall(VecDestroy(&b));
430:   PetscCall(VecDestroy(&u));
431:   PetscCall(VecDestroy(&x));
432:   PetscCall(KSPDestroy(&ksp));
433:   PetscPreLoadEnd();
434:   /* -----------------------------------------------------------
435:                       End of linear solver loop
436:      ----------------------------------------------------------- */

438:   PetscCall(PetscFinalize());
439:   return 0;
440: }

442: /*TEST

444:    build:
445:       requires: !complex

447:    testset:
448:       suffix: 1
449:       nsize: 2
450:       args: -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int@PETSC_INDEX_SIZE@-float@PETSC_SCALAR_SIZE@
451:       requires: !__float128

453:    testset:
454:       suffix: 1a
455:       args: -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int@PETSC_INDEX_SIZE@-float@PETSC_SCALAR_SIZE@
456:       requires: !__float128

458:    testset:
459:       nsize: 2
460:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
461:       args: -f0 ${DATAFILESPATH}/matrices/medium
462:       args:  -ksp_type bicg
463:       test:
464:          suffix: 2

466:    testset:
467:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
468:       args: -f0 ${DATAFILESPATH}/matrices/medium
469:       args: -ksp_type bicg
470:       test:
471:          suffix: 4
472:          args: -pc_type lu
473:       test:
474:          suffix: 5

476:    testset:
477:       suffix: 6
478:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
479:       args: -f0 ${DATAFILESPATH}/matrices/fem1
480:       args: -pc_factor_levels 2 -pc_factor_fill 1.73 -ksp_gmres_cgs_refinement_type refine_always

482:    testset:
483:       TODO: Matrix row/column sizes are not compatible with block size
484:       suffix: 7
485:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
486:       args: -f0 ${DATAFILESPATH}/matrices/medium
487:       args: -viewer_binary_skip_info -mat_type seqbaij
488:       args: -matload_block_size {{2 3 4 5 6 7 8}separate output}
489:       args: -ksp_max_it 100 -ksp_gmres_cgs_refinement_type refine_always
490:       args: -ksp_rtol 1.0e-15 -ksp_monitor_short
491:       test:
492:          suffix: a
493:       test:
494:          suffix: b
495:          args: -pc_factor_mat_ordering_type nd
496:       test:
497:          suffix: c
498:          args: -pc_factor_levels 1
499:       test:
500:          requires: metis
501:          suffix: d
502:          args: -pc_factor_mat_ordering_type metisnd

504:    testset:
505:       TODO: Matrix row/column sizes are not compatible with block size
506:       suffix: 7_d
507:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
508:       args: -f0 ${DATAFILESPATH}/matrices/medium
509:       args: -viewer_binary_skip_info -mat_type seqbaij
510:       args: -matload_block_size {{2 3 4 5 6 7 8}shared output}
511:       args: -ksp_type preonly -pc_type lu

513:    testset:
514:       suffix: 8
515:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
516:       args: -f0 ${DATAFILESPATH}/matrices/medium
517:       args: -ksp_diagonal_scale -pc_type eisenstat -ksp_monitor_short -ksp_diagonal_scale_fix -ksp_gmres_cgs_refinement_type refine_always -mat_no_inode

519:    testset:
520:       TODO: Matrix row/column sizes are not compatible with block size
521:       suffix: 9
522:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
523:       args: -f0 ${DATAFILESPATH}/matrices/medium
524:       args: -viewer_binary_skip_info  -matload_block_size {{1 2 3 4 5 6 7}separate output} -ksp_max_it 100 -ksp_gmres_cgs_refinement_type refine_always -ksp_rtol 1.0e-15 -ksp_monitor_short
525:       test:
526:          suffix: a
527:          args: -mat_type seqbaij
528:       test:
529:          suffix: b
530:          args: -mat_type seqbaij -trans
531:       test:
532:          suffix: c
533:          nsize: 2
534:          args: -mat_type mpibaij
535:       test:
536:          suffix: d
537:          nsize: 2
538:          args: -mat_type mpibaij -trans
539:       test:
540:          suffix: e
541:          nsize: 3
542:          args: -mat_type mpibaij
543:       test:
544:          suffix: f
545:          nsize: 3
546:          args: -mat_type mpibaij -trans

548:    testset:
549:       suffix: 10
550:       nsize: 2
551:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
552:       args: -ksp_type fgmres -pc_type ksp -f0 ${DATAFILESPATH}/matrices/medium -ksp_fgmres_modifypcksp -ksp_monitor_short

554:    testset:
555:       suffix: 12
556:       requires: datafilespath matlab
557:       args: -pc_type lu -pc_factor_mat_solver_type matlab -f0 ${DATAFILESPATH}/matrices/arco1

559:    testset:
560:       suffix: 13
561:       requires: datafilespath lusol
562:       args: -f0 ${DATAFILESPATH}/matrices/arco1
563:       args: -mat_type lusol -pc_type lu

565:    testset:
566:       nsize: 3
567:       args: -f0 ${DATAFILESPATH}/matrices/medium
568:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
569:       test:
570:          suffix: 14
571:          requires: spai
572:          args: -pc_type spai
573:       test:
574:          suffix: 15
575:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
576:          args: -pc_type hypre -pc_hypre_type pilut
577:       test:
578:          suffix: 16
579:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
580:          args: -pc_type hypre -pc_hypre_type parasails
581:       test:
582:          suffix: 17
583:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
584:          args: -pc_type hypre -pc_hypre_type boomeramg
585:       test:
586:          suffix: 18
587:          requires: hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
588:          args: -pc_type hypre -pc_hypre_type euclid

590:    testset:
591:       suffix: 19
592:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
593:       args: -f0 ${DATAFILESPATH}/matrices/poisson1
594:       args: -ksp_type cg -pc_type icc
595:       args: -pc_factor_levels {{0 2 4}separate output}
596:       test:
597:       test:
598:          args: -mat_type seqsbaij

600:    testset:
601:       suffix: ILU
602:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
603:       args: -f0 ${DATAFILESPATH}/matrices/small
604:       args: -pc_factor_levels 1
605:       test:
606:       test:
607:          # This is tested against regular ILU (used to be denoted ILUBAIJ)
608:          args: -mat_type baij

610:    testset:
611:       suffix: aijcusparse
612:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) cuda
613:       args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_monitor_short -ksp_view -mat_view ascii::ascii_info -mat_type aijcusparse -pc_factor_mat_solver_type cusparse -pc_type ilu -vec_type cuda

615:    testset:
616:       TODO: No output file. Need to determine if deprecated
617:       suffix: asm_viennacl
618:       nsize: 2
619:       requires: viennacl
620:       args: -pc_type asm -pc_asm_sub_mat_type aijviennacl -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int${PETSC_INDEX_SIZE}-float${PETSC_SCALAR_SIZE}

622:    testset:
623:       nsize: 2
624:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) hypre !defined(PETSC_HAVE_HYPRE_DEVICE)
625:       args: -f0 ${DATAFILESPATH}/matrices/poisson2.gz -ksp_monitor_short -ksp_rtol 1.E-9 -pc_type hypre -pc_hypre_type boomeramg
626:       test:
627:          suffix: boomeramg_euclid
628:          args: -pc_hypre_boomeramg_smooth_type Euclid -pc_hypre_boomeramg_smooth_num_levels 2 -pc_hypre_boomeramg_eu_level 1 -pc_hypre_boomeramg_eu_droptolerance 0.01
629:          TODO: Need to determine if deprecated
630:       test:
631:          suffix: boomeramg_euclid_bj
632:          args: -pc_hypre_boomeramg_smooth_type Euclid -pc_hypre_boomeramg_smooth_num_levels 2 -pc_hypre_boomeramg_eu_level 1 -pc_hypre_boomeramg_eu_droptolerance 0.01 -pc_hypre_boomeramg_eu_bj
633:          TODO: Need to determine if deprecated
634:       test:
635:          suffix: boomeramg_parasails
636:          args: -pc_hypre_boomeramg_smooth_type ParaSails -pc_hypre_boomeramg_smooth_num_levels 2
637:       test:
638:          suffix: boomeramg_pilut
639:          args: -pc_hypre_boomeramg_smooth_type Pilut -pc_hypre_boomeramg_smooth_num_levels 2
640:       test:
641:          suffix: boomeramg_schwarz
642:          args: -pc_hypre_boomeramg_smooth_type Schwarz-smoothers

644:    testset:
645:       suffix: cg_singlereduction
646:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
647:       args: -f0 ${DATAFILESPATH}/matrices/small
648:       args: -mat_type mpisbaij -ksp_type cg -pc_type eisenstat -ksp_monitor_short -ksp_converged_reason
649:       test:
650:       test:
651:          args: -ksp_cg_single_reduction

653:    testset:
654:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
655:       args: -f0 ${DATAFILESPATH}/matrices/poisson2.gz
656:       args: -ksp_monitor_short -pc_type icc
657:       test:
658:          suffix: cr
659:          args: -ksp_type cr
660:       test:
661:          suffix: lcd
662:          args: -ksp_type lcd

664:    testset:
665:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
666:       args: -f0 ${DATAFILESPATH}/matrices/small
667:       args: -ksp_monitor_short -ksp_view -mat_view ascii::ascii_info
668:       test:
669:          suffix: seqaijcrl
670:          args: -mat_type seqaijcrl
671:       test:
672:          suffix: seqaijperm
673:          args: -mat_type seqaijperm

675:    testset:
676:       nsize: 2
677:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
678:       args: -f0 ${DATAFILESPATH}/matrices/small
679:       args: -ksp_monitor_short -ksp_view
680:       # Different output files
681:       test:
682:          suffix: mpiaijcrl
683:          args: -mat_type mpiaijcrl
684:       test:
685:          suffix: mpiaijperm
686:          args: -mat_type mpiaijperm

688:    testset:
689:       nsize: 4
690:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) !defined(PETSC_HAVE_I_MPI_NUMVERSION)
691:       args: -ksp_monitor_short -ksp_view
692:       test:
693:          suffix: xxt
694:          args: -f0 ${DATAFILESPATH}/matrices/poisson1 -check_symmetry -ksp_type cg -pc_type tfs
695:       test:
696:          suffix: xyt
697:          args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_type gmres -pc_type tfs

699:    testset:
700:       # The output file here is the same as mumps
701:       suffix: mumps_cholesky
702:       output_file: output/ex72_mumps.out
703:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps
704:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type cholesky -pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2
705:       nsize: {{1 2}}
706:       test:
707:          args: -mat_type sbaij -mat_ignore_lower_triangular
708:       test:
709:          args: -mat_type aij
710:       test:
711:          args: -mat_type aij -matload_spd

713:    testset:
714:       # The output file here is the same as mumps
715:       suffix: mumps_lu
716:       output_file: output/ex72_mumps.out
717:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps
718:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2
719:       test:
720:          args: -mat_type seqaij
721:       test:
722:          nsize: 2
723:          args: -mat_type mpiaij
724:       test:
725:          args: -mat_type seqbaij -matload_block_size 2
726:       test:
727:          nsize: 2
728:          args: -mat_type mpibaij -matload_block_size 2
729:       test:
730:          args: -mat_type aij -mat_mumps_icntl_7 5
731:          TODO: Need to determine if deprecated

733:    test:
734:       suffix: mumps_lu_parmetis
735:       output_file: output/ex72_mumps.out
736:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps parmetis
737:       nsize: 2
738:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2 -mat_type mpiaij -mat_mumps_icntl_28 2 -mat_mumps_icntl_29 2

740:    test:
741:       suffix: mumps_lu_ptscotch
742:       output_file: output/ex72_mumps.out
743:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps ptscotch
744:       nsize: 2
745:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2 -mat_type mpiaij -mat_mumps_icntl_28 2 -mat_mumps_icntl_29 1

747:    testset:
748:       # The output file here is the same as mumps
749:       suffix: mumps_redundant
750:       output_file: output/ex72_mumps_redundant.out
751:       nsize: 8
752:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps
753:       args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_type preonly -pc_type redundant -pc_redundant_number {{8 7 6 5 4 3 2 1}} -redundant_pc_factor_mat_solver_type mumps -num_numfac 2 -num_rhs 2

755:    testset:
756:       suffix: pastix_cholesky
757:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) pastix
758:       output_file: output/ex72_mumps.out
759:       nsize: {{1 2}}
760:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_factor_mat_solver_type pastix -num_numfac 2 -num_rhs 2 -pc_type cholesky -mat_type sbaij -mat_ignore_lower_triangular

762:    testset:
763:       suffix: pastix_lu
764:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) pastix
765:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type pastix -num_numfac 2 -num_rhs 2
766:       output_file: output/ex72_mumps.out
767:       test:
768:          args: -mat_type seqaij
769:       test:
770:          nsize: 2
771:          args: -mat_type mpiaij

773:    testset:
774:       suffix: pastix_redundant
775:       output_file: output/ex72_mumps_redundant.out
776:       nsize: 8
777:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) pastix
778:       args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_type preonly -pc_type redundant -pc_redundant_number {{8 7 6 5 4 3 2 1}} -redundant_pc_factor_mat_solver_type pastix -num_numfac 2 -num_rhs 2

780:    testset:
781:       suffix: superlu_dist_lu
782:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) superlu_dist
783:       output_file: output/ex72_mumps.out
784:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type superlu_dist -num_numfac 2 -num_rhs 2
785:       nsize: {{1 2}}

787:    testset:
788:       suffix: superlu_dist_redundant
789:       nsize: 8
790:       output_file: output/ex72_mumps_redundant.out
791:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) superlu_dist
792:       args: -f0 ${DATAFILESPATH}/matrices/medium -ksp_type preonly -pc_type redundant -pc_redundant_number {{8 7 6 5 4 3 2 1}} -redundant_pc_factor_mat_solver_type superlu_dist -num_numfac 2 -num_rhs 2

794:    testset:
795:       suffix: superlu_lu
796:       output_file: output/ex72_mumps.out
797:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) superlu
798:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -pc_factor_mat_solver_type superlu -num_numfac 2 -num_rhs 2

800:    testset:
801:       suffix: umfpack
802:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) suitesparse
803:       args: -f0 ${DATAFILESPATH}/matrices/small -ksp_type preonly -pc_type lu -mat_type seqaij -pc_factor_mat_solver_type umfpack -num_numfac 2 -num_rhs 2

805:    testset:
806:       suffix: zeropivot
807:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
808:       args: -f0 ${DATAFILESPATH}/matrices/small -test_zeropivot -ksp_converged_reason -ksp_type fgmres -pc_type ksp -fp_trap 0
809:       test:
810:          nsize: 3
811:          args: -ksp_pc_type bjacobi
812:       test:
813:          nsize: 2
814:          args: -ksp_ksp_type cg -ksp_pc_type bjacobi -ksp_pc_bjacobi_blocks 1
815:       #test:
816:          #nsize: 3
817:          #args: -ksp_ksp_converged_reason -ksp_pc_type bjacobi -ksp_sub_ksp_converged_reason
818:          #TODO: Need to determine if deprecated

820:    testset:
821:       requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
822:       args: -mat_convert_type is -f0 ${DATAFILESPATH}/matrices/medium -ksp_type fgmres
823:       test:
824:          suffix: aij_gdsw
825:          nsize: 4
826:          args: -mat_convert_type aij -pc_type mg -pc_mg_levels 2 -pc_mg_adapt_interp_coarse_space gdsw -pc_mg_galerkin -mg_levels_pc_type asm
827:       test:
828:          output_file: output/ex72_aij_gdsw.out
829:          suffix: is_gdsw
830:          nsize: 4
831:          args: -pc_type mg -pc_mg_levels 2  -pc_mg_adapt_interp_coarse_space gdsw -pc_mg_galerkin -mg_levels_pc_type asm
832:       test:
833:          suffix: is_asm
834:          nsize: {{1 2}separate output}
835:          args: -pc_type asm
836:       test:
837:          suffix: bddc_seq
838:          nsize: 1
839:          args: -pc_type bddc
840:       test:
841:          suffix: bddc_par
842:          nsize: 2
843:          args: -pc_type bddc
844:       test:
845:          requires: parmetis
846:          suffix: bddc_par_nd_parmetis
847:          filter: sed -e "s/Number of iterations =   [0-9]/Number of iterations = 9/g"
848:          nsize: 4
849:          args: -ksp_error_if_not_converged -pc_type bddc -mat_is_disassemble_l2g_type nd -mat_partitioning_type parmetis
850:       test:
851:          requires: ptscotch defined(PETSC_HAVE_SCOTCH_PARMETIS_V3_NODEND)
852:          suffix: bddc_par_nd_ptscotch
853:          filter: sed -e "s/Number of iterations =   [0-9]/Number of iterations = 9/g"
854:          nsize: 4
855:          args: -ksp_error_if_not_converged -pc_type bddc -mat_is_disassemble_l2g_type nd -mat_partitioning_type ptscotch

857:    testset:
858:       requires: !__float128 hpddm slepc defined(PETSC_HAVE_DYNAMIC_LIBRARIES) defined(PETSC_USE_SHARED_LIBRARIES)
859:       test:
860:          suffix: hpddm_mat
861:          output_file: output/ex72_bddc_seq.out
862:          filter: sed -e "s/Number of iterations =   2/Number of iterations =   1/g"
863:          nsize: 2
864:          args: -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/spd-real-int@PETSC_INDEX_SIZE@-float@PETSC_SCALAR_SIZE@ -pc_type hpddm -pc_hpddm_define_subdomains -pc_hpddm_levels_1_sub_pc_type cholesky -pc_hpddm_levels_1_eps_nev 5 -pc_hpddm_levels_1_st_pc_type mat
865:       test:
866:          requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES)
867:          suffix: hpddm_gen_non_hermitian
868:          output_file: output/ex72_2.out
869:          nsize: 4
870:          args: -f0 ${DATAFILESPATH}/matrices/arco1 -pc_type hpddm -pc_hpddm_define_subdomains -pc_hpddm_levels_1_sub_pc_type lu -pc_hpddm_levels_1_eps_nev 10 -pc_hpddm_levels_1_st_share_sub_ksp -pc_hpddm_levels_1_eps_gen_non_hermitian -pc_hpddm_coarse_mat_type baij -pc_hpddm_block_splitting -pc_hpddm_levels_1_eps_threshold 0.7 -pc_hpddm_coarse_pc_type lu -ksp_pc_side right
871:       test:
872:          requires: datafilespath double !defined(PETSC_USE_64BIT_INDICES) mumps !defined(PETSCTEST_VALGRIND)
873:          suffix: hpddm_gen_non_hermitian_baij
874:          output_file: output/ex72_5.out
875:          nsize: 4
876:          timeoutfactor: 2
877:          args: -f0 ${DATAFILESPATH}/matrices/arco6 -pc_type hpddm -pc_hpddm_define_subdomains -pc_hpddm_levels_1_sub_pc_type lu -pc_hpddm_levels_1_eps_nev 30 -pc_hpddm_levels_1_st_share_sub_ksp -pc_hpddm_levels_1_eps_gen_non_hermitian -pc_hpddm_coarse_mat_type baij -pc_hpddm_block_splitting -pc_hpddm_levels_1_eps_threshold 0.8 -pc_hpddm_coarse_pc_type lu -ksp_pc_side right -mat_type baij -pc_hpddm_levels_1_sub_pc_factor_mat_solver_type mumps -pc_hpddm_levels_1_eps_tol 1.0e-2
878: TEST*/