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;

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

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

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

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

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

 77:   MatGetType(B,&mattype);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

295:     /* MatView(P,PETSC_VIEWER_STDOUT_WORLD); */
296:     MatGetSize(P,&pM,&pN);
297:     MatGetLocalSize(P,&pm,&pn);
298:     MatPtAP(A,P,MAT_INITIAL_MATRIX,fill,&C);

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

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

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

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

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

344:       MatProductClear(C);
345:       PetscPrintf(PETSC_COMM_WORLD,"\nC = P^T * A * P after MatProductClear():\n");
346:       MatView(C,PETSC_VIEWER_STDOUT_WORLD);

348:       PetscPrintf(PETSC_COMM_WORLD,"\nCdup:\n");
349:       MatView(Cdup,PETSC_VIEWER_STDOUT_WORLD);
350:     }
351:     MatDestroy(&Cdup);

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

360:       /* Test MatRARt_Basic(), MatMatMatMult_Basic() */
361:       MatConvert(R,MATDENSE,MAT_INITIAL_MATRIX,&Rdense);
362:       MatRARt(A,Rdense,MAT_INITIAL_MATRIX,2.0,&RARtdense);
363:       MatRARt(A,Rdense,MAT_REUSE_MATRIX,2.0,&RARtdense);

365:       MatConvert(RARtdense,MATAIJ,MAT_INITIAL_MATRIX,&RARt);
366:       MatNormDifference(C,RARt,&norm);
368:       MatDestroy(&Rdense);
369:       MatDestroy(&RARtdense);
370:       MatDestroy(&RARt);

372:       /* Test MatRARt() for aij matrices */
373:       MatRARt(A,R,MAT_INITIAL_MATRIX,2.0,&RARt);
374:       MatRARt(A,R,MAT_REUSE_MATRIX,2.0,&RARt);
375:       MatNormDifference(C,RARt,&norm);
377:       MatDestroy(&R);
378:       MatDestroy(&RARt);
379:     }

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

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

398:     VecCreate(PETSC_COMM_WORLD,&v3);
399:     VecSetSizes(v3,n,PETSC_DECIDE);
400:     VecSetFromOptions(v3);
401:     VecDuplicate(v3,&v4);

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

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

415:       norm_tmp /= norm_abs;
416:       if (norm_tmp > norm) norm = norm_tmp;
417:     }

420:     MatDestroy(&A);
421:     MatDestroy(&P);
422:     MatDestroy(&C);
423:     VecDestroy(&v3);
424:     VecDestroy(&v4);
425:     VecDestroy(&x);
426:   }

428:   /* Destroy objects */
429:   VecDestroy(&v1);
430:   VecDestroy(&v2);
431:   PetscRandomDestroy(&rdm);
432:   PetscFree(idxn);

434:   MatDestroy(&A_save);
435:   MatDestroy(&B);

437:   PetscPreLoadEnd();
438:   PetscFinalize();
439:   return 0;
440: }

442: /*TEST

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

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

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

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

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

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

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

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

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

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

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

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

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

530: TEST*/