Actual source code: ex94.c


  2: static char help[] = "Tests sequential and parallel MatMatMult() and MatPtAP(), MatTransposeMatMult(), sequential MatMatTransposeMult(), MatRARt()\n\
  3: Input arguments are:\n\
  4:   -f0 <input_file> -f1 <input_file> -f2 <input_file> -f3 <input_file> : file to load\n\n";
  5: /* Example of usage:
  6:    ./ex94 -f0 <A_binary> -f1 <B_binary> -matmatmult_mat_view ascii::ascii_info -matmatmulttr_mat_view
  7:    mpiexec -n 3 ./ex94 -f0 medium -f1 medium -f2 arco1 -f3 arco1 -matmatmult_mat_view
  8: */

 10: #include <petscmat.h>

 12: /*
 13:      B = A - B
 14:      norm = norm(B)
 15: */
 16: PetscErrorCode MatNormDifference(Mat A, Mat B, PetscReal *norm)
 17: {
 18:   MatAXPY(B, -1.0, A, DIFFERENT_NONZERO_PATTERN);
 19:   MatNorm(B, NORM_FROBENIUS, norm);
 20:   return 0;
 21: }

 23: int main(int argc, char **args)
 24: {
 25:   Mat          A, A_save, B, AT, ATT, BT, BTT, P, R, C, C1;
 26:   Vec          x, v1, v2, v3, v4;
 27:   PetscViewer  viewer;
 28:   PetscMPIInt  size, rank;
 29:   PetscInt     i, m, n, j, *idxn, M, N, nzp, rstart, rend;
 30:   PetscReal    norm, norm_abs, norm_tmp, fill = 4.0;
 31:   PetscRandom  rdm;
 32:   char         file[4][128];
 33:   PetscBool    flg, preload = PETSC_TRUE;
 34:   PetscScalar *a, rval, alpha, none = -1.0;
 35:   PetscBool    Test_MatMatMult = PETSC_TRUE, Test_MatMatTr = PETSC_TRUE, Test_MatPtAP = PETSC_TRUE, Test_MatRARt = PETSC_TRUE, Test_MatMatMatMult = PETSC_TRUE;
 36:   PetscBool    Test_MatAXPY = PETSC_FALSE, view = PETSC_FALSE;
 37:   PetscInt     pm, pn, pM, pN;
 38:   MatInfo      info;
 39:   PetscBool    seqaij;
 40:   MatType      mattype;
 41:   Mat          Cdensetest, Pdense, Cdense, Adense;

 44:   PetscInitialize(&argc, &args, (char *)0, help);
 45:   MPI_Comm_size(PETSC_COMM_WORLD, &size);
 46:   MPI_Comm_rank(PETSC_COMM_WORLD, &rank);

 48:   PetscOptionsGetReal(NULL, NULL, "-fill", &fill, NULL);
 49:   PetscOptionsGetBool(NULL, NULL, "-matops_view", &view, NULL);
 50:   if (view) PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_INFO);

 52:   /*  Load the matrices A_save and B */
 53:   PetscOptionsGetString(NULL, NULL, "-f0", file[0], sizeof(file[0]), &flg);
 55:   PetscOptionsGetString(NULL, NULL, "-f1", file[1], sizeof(file[1]), &flg);
 57:   PetscOptionsGetString(NULL, NULL, "-f2", file[2], sizeof(file[2]), &flg);
 58:   if (!flg) {
 59:     preload = PETSC_FALSE;
 60:   } else {
 61:     PetscOptionsGetString(NULL, NULL, "-f3", file[3], sizeof(file[3]), &flg);
 63:   }

 65:   PetscPreLoadBegin(preload, "Load system");
 66:   PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[2 * PetscPreLoadIt], FILE_MODE_READ, &viewer);
 67:   MatCreate(PETSC_COMM_WORLD, &A_save);
 68:   MatSetFromOptions(A_save);
 69:   MatLoad(A_save, viewer);
 70:   PetscViewerDestroy(&viewer);

 72:   PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[2 * PetscPreLoadIt + 1], FILE_MODE_READ, &viewer);
 73:   MatCreate(PETSC_COMM_WORLD, &B);
 74:   MatSetFromOptions(B);
 75:   MatLoad(B, viewer);
 76:   PetscViewerDestroy(&viewer);

 78:   MatGetType(B, &mattype);

 80:   MatGetSize(B, &M, &N);
 81:   nzp = PetscMax((PetscInt)(0.1 * M), 5);
 82:   PetscMalloc((nzp + 1) * (sizeof(PetscInt) + sizeof(PetscScalar)), &idxn);
 83:   a = (PetscScalar *)(idxn + nzp);

 85:   /* Create vectors v1 and v2 that are compatible with A_save */
 86:   VecCreate(PETSC_COMM_WORLD, &v1);
 87:   MatGetLocalSize(A_save, &m, NULL);
 88:   VecSetSizes(v1, m, PETSC_DECIDE);
 89:   VecSetFromOptions(v1);
 90:   VecDuplicate(v1, &v2);

 92:   PetscRandomCreate(PETSC_COMM_WORLD, &rdm);
 93:   PetscRandomSetFromOptions(rdm);
 94:   PetscOptionsGetReal(NULL, NULL, "-fill", &fill, NULL);

 96:   /* Test MatAXPY()    */
 97:   /*-------------------*/
 98:   PetscOptionsHasName(NULL, NULL, "-test_MatAXPY", &Test_MatAXPY);
 99:   if (Test_MatAXPY) {
100:     Mat Btmp;
101:     MatDuplicate(A_save, MAT_COPY_VALUES, &A);
102:     MatDuplicate(B, MAT_COPY_VALUES, &Btmp);
103:     MatAXPY(A, -1.0, B, DIFFERENT_NONZERO_PATTERN); /* A = -B + A_save */

105:     MatScale(A, -1.0);                                 /* A = -A = B - A_save */
106:     MatAXPY(Btmp, -1.0, A, DIFFERENT_NONZERO_PATTERN); /* Btmp = -A + B = A_save */
107:     MatMultEqual(A_save, Btmp, 10, &flg);
109:     MatDestroy(&A);
110:     MatDestroy(&Btmp);

112:     Test_MatMatMult    = PETSC_FALSE;
113:     Test_MatMatTr      = PETSC_FALSE;
114:     Test_MatPtAP       = PETSC_FALSE;
115:     Test_MatRARt       = PETSC_FALSE;
116:     Test_MatMatMatMult = PETSC_FALSE;
117:   }

119:   /* 1) Test MatMatMult() */
120:   /* ---------------------*/
121:   if (Test_MatMatMult) {
122:     MatDuplicate(A_save, MAT_COPY_VALUES, &A);
123:     MatCreateTranspose(A, &AT);
124:     MatCreateTranspose(AT, &ATT);
125:     MatCreateTranspose(B, &BT);
126:     MatCreateTranspose(BT, &BTT);

128:     MatMatMult(AT, B, MAT_INITIAL_MATRIX, fill, &C);
129:     MatMatMultEqual(AT, B, C, 10, &flg);
131:     MatDestroy(&C);

133:     MatMatMult(ATT, B, MAT_INITIAL_MATRIX, fill, &C);
134:     MatMatMultEqual(ATT, B, C, 10, &flg);
136:     MatDestroy(&C);

138:     MatMatMult(A, B, MAT_INITIAL_MATRIX, fill, &C);
139:     MatMatMultEqual(A, B, C, 10, &flg);
141:     /* ATT has different matrix type as A (although they have same internal data structure),
142:        we cannot call MatProductReplaceMats(ATT,NULL,NULL,C) and MatMatMult(ATT,B,MAT_REUSE_MATRIX,fill,&C) */
143:     MatDestroy(&C);

145:     MatMatMult(A, BTT, MAT_INITIAL_MATRIX, fill, &C);
146:     MatMatMultEqual(A, BTT, C, 10, &flg);
148:     MatDestroy(&C);

150:     MatMatMult(ATT, BTT, MAT_INITIAL_MATRIX, fill, &C);
151:     MatMatMultEqual(A, B, C, 10, &flg);
153:     MatDestroy(&C);

155:     MatDestroy(&BTT);
156:     MatDestroy(&BT);
157:     MatDestroy(&ATT);
158:     MatDestroy(&AT);

160:     MatMatMult(A, B, MAT_INITIAL_MATRIX, fill, &C);
161:     MatSetOptionsPrefix(C, "matmatmult_"); /* enable option '-matmatmult_' for matrix C */
162:     MatGetInfo(C, MAT_GLOBAL_SUM, &info);

164:     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
165:     alpha = 1.0;
166:     for (i = 0; i < 2; i++) {
167:       alpha -= 0.1;
168:       MatScale(A, alpha);
169:       MatMatMult(A, B, MAT_REUSE_MATRIX, fill, &C);
170:     }
171:     MatMatMultEqual(A, B, C, 10, &flg);
173:     MatDestroy(&A);

175:     /* Test MatDuplicate() of C=A*B */
176:     MatDuplicate(C, MAT_COPY_VALUES, &C1);
177:     MatDestroy(&C1);
178:     MatDestroy(&C);
179:   } /* if (Test_MatMatMult) */

181:   /* 2) Test MatTransposeMatMult() and MatMatTransposeMult() */
182:   /* ------------------------------------------------------- */
183:   if (Test_MatMatTr) {
184:     /* Create P */
185:     PetscInt PN, rstart, rend;
186:     PN  = M / 2;
187:     nzp = 5; /* num of nonzeros in each row of P */
188:     MatCreate(PETSC_COMM_WORLD, &P);
189:     MatSetSizes(P, PETSC_DECIDE, PETSC_DECIDE, M, PN);
190:     MatSetType(P, mattype);
191:     MatSeqAIJSetPreallocation(P, nzp, NULL);
192:     MatMPIAIJSetPreallocation(P, nzp, NULL, nzp, NULL);
193:     MatGetOwnershipRange(P, &rstart, &rend);
194:     for (i = 0; i < nzp; i++) PetscRandomGetValue(rdm, &a[i]);
195:     for (i = rstart; i < rend; i++) {
196:       for (j = 0; j < nzp; j++) {
197:         PetscRandomGetValue(rdm, &rval);
198:         idxn[j] = (PetscInt)(PetscRealPart(rval) * PN);
199:       }
200:       MatSetValues(P, 1, &i, nzp, idxn, a, ADD_VALUES);
201:     }
202:     MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
203:     MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);

205:     /* Create R = P^T */
206:     MatTranspose(P, MAT_INITIAL_MATRIX, &R);

208:     { /* Test R = P^T, C1 = R*B */
209:       MatMatMult(R, B, MAT_INITIAL_MATRIX, fill, &C1);
210:       MatTranspose(P, MAT_REUSE_MATRIX, &R);
211:       MatMatMult(R, B, MAT_REUSE_MATRIX, fill, &C1);
212:       MatDestroy(&C1);
213:     }

215:     /* C = P^T*B */
216:     MatTransposeMatMult(P, B, MAT_INITIAL_MATRIX, fill, &C);
217:     MatGetInfo(C, MAT_GLOBAL_SUM, &info);

219:     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
220:     MatTransposeMatMult(P, B, MAT_REUSE_MATRIX, fill, &C);
221:     if (view) {
222:       PetscPrintf(PETSC_COMM_WORLD, "C = P^T * B:\n");
223:       MatView(C, PETSC_VIEWER_STDOUT_WORLD);
224:     }
225:     MatProductClear(C);
226:     if (view) {
227:       PetscPrintf(PETSC_COMM_WORLD, "\nC = P^T * B after MatProductClear():\n");
228:       MatView(C, PETSC_VIEWER_STDOUT_WORLD);
229:     }

231:     /* Compare P^T*B and R*B */
232:     MatMatMult(R, B, MAT_INITIAL_MATRIX, fill, &C1);
233:     MatNormDifference(C, C1, &norm);
235:     MatDestroy(&C1);

237:     /* Test MatDuplicate() of C=P^T*B */
238:     MatDuplicate(C, MAT_COPY_VALUES, &C1);
239:     MatDestroy(&C1);
240:     MatDestroy(&C);

242:     /* C = B*R^T */
243:     PetscObjectTypeCompare((PetscObject)B, MATSEQAIJ, &seqaij);
244:     if (size == 1 && seqaij) {
245:       MatMatTransposeMult(B, R, MAT_INITIAL_MATRIX, fill, &C);
246:       MatSetOptionsPrefix(C, "matmatmulttr_"); /* enable '-matmatmulttr_' for matrix C */
247:       MatGetInfo(C, MAT_GLOBAL_SUM, &info);

249:       /* Test MAT_REUSE_MATRIX - reuse symbolic C */
250:       MatMatTransposeMult(B, R, MAT_REUSE_MATRIX, fill, &C);

252:       /* Check */
253:       MatMatMult(B, P, MAT_INITIAL_MATRIX, fill, &C1);
254:       MatNormDifference(C, C1, &norm);
256:       MatDestroy(&C1);
257:       MatDestroy(&C);
258:     }
259:     MatDestroy(&P);
260:     MatDestroy(&R);
261:   }

263:   /* 3) Test MatPtAP() */
264:   /*-------------------*/
265:   if (Test_MatPtAP) {
266:     PetscInt PN;
267:     Mat      Cdup;

269:     MatDuplicate(A_save, MAT_COPY_VALUES, &A);
270:     MatGetSize(A, &M, &N);
271:     MatGetLocalSize(A, &m, &n);

273:     PN  = M / 2;
274:     nzp = (PetscInt)(0.1 * PN + 1); /* num of nozeros in each row of P */
275:     MatCreate(PETSC_COMM_WORLD, &P);
276:     MatSetSizes(P, PETSC_DECIDE, PETSC_DECIDE, N, PN);
277:     MatSetType(P, mattype);
278:     MatSeqAIJSetPreallocation(P, nzp, NULL);
279:     MatMPIAIJSetPreallocation(P, nzp, NULL, nzp, NULL);
280:     for (i = 0; i < nzp; i++) PetscRandomGetValue(rdm, &a[i]);
281:     MatGetOwnershipRange(P, &rstart, &rend);
282:     for (i = rstart; i < rend; i++) {
283:       for (j = 0; j < nzp; j++) {
284:         PetscRandomGetValue(rdm, &rval);
285:         idxn[j] = (PetscInt)(PetscRealPart(rval) * PN);
286:       }
287:       MatSetValues(P, 1, &i, nzp, idxn, a, ADD_VALUES);
288:     }
289:     MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
290:     MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);

292:     /* MatView(P,PETSC_VIEWER_STDOUT_WORLD); */
293:     MatGetSize(P, &pM, &pN);
294:     MatGetLocalSize(P, &pm, &pn);
295:     MatPtAP(A, P, MAT_INITIAL_MATRIX, fill, &C);

297:     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
298:     alpha = 1.0;
299:     for (i = 0; i < 2; i++) {
300:       alpha -= 0.1;
301:       MatScale(A, alpha);
302:       MatPtAP(A, P, MAT_REUSE_MATRIX, fill, &C);
303:     }

305:     /* Test PtAP ops with P Dense and A either AIJ or SeqDense (it assumes MatPtAP_XAIJ_XAIJ is fine) */
306:     PetscObjectTypeCompare((PetscObject)A, MATSEQAIJ, &seqaij);
307:     if (seqaij) {
308:       MatConvert(C, MATSEQDENSE, MAT_INITIAL_MATRIX, &Cdensetest);
309:       MatConvert(P, MATSEQDENSE, MAT_INITIAL_MATRIX, &Pdense);
310:     } else {
311:       MatConvert(C, MATMPIDENSE, MAT_INITIAL_MATRIX, &Cdensetest);
312:       MatConvert(P, MATMPIDENSE, MAT_INITIAL_MATRIX, &Pdense);
313:     }

315:     /* test with A(AIJ), Pdense -- call MatPtAP_Basic() when np>1 */
316:     MatPtAP(A, Pdense, MAT_INITIAL_MATRIX, fill, &Cdense);
317:     MatPtAP(A, Pdense, MAT_REUSE_MATRIX, fill, &Cdense);
318:     MatPtAPMultEqual(A, Pdense, Cdense, 10, &flg);
320:     MatDestroy(&Cdense);

322:     /* test with A SeqDense */
323:     if (seqaij) {
324:       MatConvert(A, MATSEQDENSE, MAT_INITIAL_MATRIX, &Adense);
325:       MatPtAP(Adense, Pdense, MAT_INITIAL_MATRIX, fill, &Cdense);
326:       MatPtAP(Adense, Pdense, MAT_REUSE_MATRIX, fill, &Cdense);
327:       MatPtAPMultEqual(Adense, Pdense, Cdense, 10, &flg);
329:       MatDestroy(&Cdense);
330:       MatDestroy(&Adense);
331:     }
332:     MatDestroy(&Cdensetest);
333:     MatDestroy(&Pdense);

335:     /* Test MatDuplicate() of C=PtAP and MatView(Cdup,...) */
336:     MatDuplicate(C, MAT_COPY_VALUES, &Cdup);
337:     if (view) {
338:       PetscPrintf(PETSC_COMM_WORLD, "\nC = P^T * A * P:\n");
339:       MatView(C, PETSC_VIEWER_STDOUT_WORLD);

341:       MatProductClear(C);
342:       PetscPrintf(PETSC_COMM_WORLD, "\nC = P^T * A * P after MatProductClear():\n");
343:       MatView(C, PETSC_VIEWER_STDOUT_WORLD);

345:       PetscPrintf(PETSC_COMM_WORLD, "\nCdup:\n");
346:       MatView(Cdup, PETSC_VIEWER_STDOUT_WORLD);
347:     }
348:     MatDestroy(&Cdup);

350:     if (size > 1 || !seqaij) Test_MatRARt = PETSC_FALSE;
351:     /* 4) Test MatRARt() */
352:     /* ----------------- */
353:     if (Test_MatRARt) {
354:       Mat R, RARt, Rdense, RARtdense;
355:       MatTranspose(P, MAT_INITIAL_MATRIX, &R);

357:       /* Test MatRARt_Basic(), MatMatMatMult_Basic() */
358:       MatConvert(R, MATDENSE, MAT_INITIAL_MATRIX, &Rdense);
359:       MatRARt(A, Rdense, MAT_INITIAL_MATRIX, 2.0, &RARtdense);
360:       MatRARt(A, Rdense, MAT_REUSE_MATRIX, 2.0, &RARtdense);

362:       MatConvert(RARtdense, MATAIJ, MAT_INITIAL_MATRIX, &RARt);
363:       MatNormDifference(C, RARt, &norm);
365:       MatDestroy(&Rdense);
366:       MatDestroy(&RARtdense);
367:       MatDestroy(&RARt);

369:       /* Test MatRARt() for aij matrices */
370:       MatRARt(A, R, MAT_INITIAL_MATRIX, 2.0, &RARt);
371:       MatRARt(A, R, MAT_REUSE_MATRIX, 2.0, &RARt);
372:       MatNormDifference(C, RARt, &norm);
374:       MatDestroy(&R);
375:       MatDestroy(&RARt);
376:     }

378:     if (Test_MatMatMatMult && size == 1) {
379:       Mat R, RAP;
380:       MatTranspose(P, MAT_INITIAL_MATRIX, &R);
381:       MatMatMatMult(R, A, P, MAT_INITIAL_MATRIX, 2.0, &RAP);
382:       MatMatMatMult(R, A, P, MAT_REUSE_MATRIX, 2.0, &RAP);
383:       MatNormDifference(C, RAP, &norm);
385:       MatDestroy(&R);
386:       MatDestroy(&RAP);
387:     }

389:     /* Create vector x that is compatible with P */
390:     VecCreate(PETSC_COMM_WORLD, &x);
391:     MatGetLocalSize(P, &m, &n);
392:     VecSetSizes(x, n, PETSC_DECIDE);
393:     VecSetFromOptions(x);

395:     VecCreate(PETSC_COMM_WORLD, &v3);
396:     VecSetSizes(v3, n, PETSC_DECIDE);
397:     VecSetFromOptions(v3);
398:     VecDuplicate(v3, &v4);

400:     norm = 0.0;
401:     for (i = 0; i < 10; i++) {
402:       VecSetRandom(x, rdm);
403:       MatMult(P, x, v1);
404:       MatMult(A, v1, v2); /* v2 = A*P*x */

406:       MatMultTranspose(P, v2, v3); /* v3 = Pt*A*P*x */
407:       MatMult(C, x, v4);           /* v3 = C*x   */
408:       VecNorm(v4, NORM_2, &norm_abs);
409:       VecAXPY(v4, none, v3);
410:       VecNorm(v4, NORM_2, &norm_tmp);

412:       norm_tmp /= norm_abs;
413:       if (norm_tmp > norm) norm = norm_tmp;
414:     }

417:     MatDestroy(&A);
418:     MatDestroy(&P);
419:     MatDestroy(&C);
420:     VecDestroy(&v3);
421:     VecDestroy(&v4);
422:     VecDestroy(&x);
423:   }

425:   /* Destroy objects */
426:   VecDestroy(&v1);
427:   VecDestroy(&v2);
428:   PetscRandomDestroy(&rdm);
429:   PetscFree(idxn);

431:   MatDestroy(&A_save);
432:   MatDestroy(&B);

434:   PetscPreLoadEnd();
435:   PetscFinalize();
436:   return 0;
437: }

439: /*TEST

441:    test:
442:       suffix: 2_mattransposematmult_matmatmult
443:       nsize: 3
444:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
445:       args: -f0 ${DATAFILESPATH}/matrices/medium -f1 ${DATAFILESPATH}/matrices/medium -mattransposematmult_via at*b> ex94_2.tmp 2>&1

447:    test:
448:       suffix: 2_mattransposematmult_scalable
449:       nsize: 3
450:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
451:       args: -f0 ${DATAFILESPATH}/matrices/medium -f1 ${DATAFILESPATH}/matrices/medium -mattransposematmult_via scalable> ex94_2.tmp 2>&1
452:       output_file: output/ex94_1.out

454:    test:
455:       suffix: axpy_mpiaij
456:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
457:       nsize: 8
458:       args: -f0 ${DATAFILESPATH}/matrices/poisson_2d5p -f1 ${DATAFILESPATH}/matrices/poisson_2d13p -test_MatAXPY
459:       output_file: output/ex94_1.out

461:    test:
462:       suffix: axpy_mpibaij
463:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
464:       nsize: 8
465:       args: -f0 ${DATAFILESPATH}/matrices/poisson_2d5p -f1 ${DATAFILESPATH}/matrices/poisson_2d13p -test_MatAXPY -mat_type baij
466:       output_file: output/ex94_1.out

468:    test:
469:       suffix: axpy_mpisbaij
470:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
471:       nsize: 8
472:       args: -f0 ${DATAFILESPATH}/matrices/poisson_2d5p -f1 ${DATAFILESPATH}/matrices/poisson_2d13p -test_MatAXPY -mat_type sbaij
473:       output_file: output/ex94_1.out

475:    test:
476:       suffix: matmatmult
477:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
478:       args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -viewer_binary_skip_info
479:       output_file: output/ex94_1.out

481:    test:
482:       suffix: matmatmult_2
483:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
484:       args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -mat_type mpiaij -viewer_binary_skip_info
485:       output_file: output/ex94_1.out

487:    test:
488:       suffix: matmatmult_scalable
489:       nsize: 4
490:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
491:       args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -matmatmult_via scalable
492:       output_file: output/ex94_1.out

494:    test:
495:       suffix: ptap
496:       nsize: 3
497:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
498:       args: -f0 ${DATAFILESPATH}/matrices/medium -f1 ${DATAFILESPATH}/matrices/medium -matptap_via scalable
499:       output_file: output/ex94_1.out

501:    test:
502:       suffix: rap
503:       nsize: 3
504:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
505:       args: -f0 ${DATAFILESPATH}/matrices/medium -f1 ${DATAFILESPATH}/matrices/medium
506:       output_file: output/ex94_1.out

508:    test:
509:       suffix: scalable0
510:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
511:       args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -viewer_binary_skip_info
512:       output_file: output/ex94_1.out

514:    test:
515:       suffix: scalable1
516:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
517:       args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -viewer_binary_skip_info -matptap_via scalable
518:       output_file: output/ex94_1.out

520:    test:
521:       suffix: view
522:       nsize: 2
523:       requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
524:       args: -f0 ${DATAFILESPATH}/matrices/tiny -f1 ${DATAFILESPATH}/matrices/tiny -viewer_binary_skip_info -matops_view
525:       output_file: output/ex94_2.out

527: TEST*/