Actual source code: ex62.c


  2: static char help[] = "Test Matrix products for AIJ matrices\n\
  3: Input arguments are:\n\
  4:   -fA <input_file> -fB <input_file> -fC <input_file>: file to load\n\n";
  5: /* Example of usage:
  6:    ./ex62 -fA <A_binary> -fB <B_binary>
  7:    mpiexec -n 3 ./ex62 -fA medium -fB medium
  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,C,P,C1,R;
 26:   PetscViewer    viewer;
 28:   PetscMPIInt    size,rank;
 29:   PetscInt       i,j,*idxn,PM,PN = PETSC_DECIDE,rstart,rend;
 30:   PetscReal      norm;
 31:   PetscRandom    rdm;
 32:   char           file[2][PETSC_MAX_PATH_LEN] = { "", ""};
 33:   PetscScalar    *a,rval,alpha;
 34:   PetscBool      Test_MatMatMult=PETSC_TRUE,Test_MatTrMat=PETSC_TRUE,Test_MatMatTr=PETSC_TRUE;
 35:   PetscBool      Test_MatPtAP=PETSC_TRUE,Test_MatRARt=PETSC_TRUE,flg,seqaij,flgA,flgB;
 36:   MatInfo        info;
 37:   PetscInt       nzp  = 5; /* num of nonzeros in each row of P */
 38:   MatType        mattype;
 39:   const char     *deft = MATAIJ;
 40:   char           A_mattype[256], B_mattype[256];
 41:   PetscInt       mcheck = 10;

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

 47:   /*  Load the matrices A_save and B */
 48:   PetscOptionsBegin(PETSC_COMM_WORLD,"","","");
 49:   PetscOptionsBool("-test_rart","Test MatRARt","",Test_MatRARt,&Test_MatRARt,NULL);
 50:   PetscOptionsInt("-PN","Number of columns of P","",PN,&PN,NULL);
 51:   PetscOptionsInt("-mcheck","Number of matmult checks","",mcheck,&mcheck,NULL);
 52:   PetscOptionsString("-fA","Path for matrix A","",file[0],file[0],sizeof(file[0]),&flg);
 54:   PetscOptionsString("-fB","Path for matrix B","",file[1],file[1],sizeof(file[1]),&flg);
 55:   PetscOptionsFList("-A_mat_type","Matrix type","MatSetType",MatList,deft,A_mattype,256,&flgA);
 56:   PetscOptionsFList("-B_mat_type","Matrix type","MatSetType",MatList,deft,B_mattype,256,&flgB);
 57:   PetscOptionsEnd();

 59:   PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[0],FILE_MODE_READ,&viewer);
 60:   MatCreate(PETSC_COMM_WORLD,&A_save);
 61:   MatLoad(A_save,viewer);
 62:   PetscViewerDestroy(&viewer);

 64:   if (flg) {
 65:     PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[1],FILE_MODE_READ,&viewer);
 66:     MatCreate(PETSC_COMM_WORLD,&B);
 67:     MatLoad(B,viewer);
 68:     PetscViewerDestroy(&viewer);
 69:   } else {
 70:     PetscObjectReference((PetscObject)A_save);
 71:     B = A_save;
 72:   }

 74:   if (flgA) {
 75:     MatConvert(A_save,A_mattype,MAT_INPLACE_MATRIX,&A_save);
 76:   }
 77:   if (flgB) {
 78:     MatConvert(B,B_mattype,MAT_INPLACE_MATRIX,&B);
 79:   }
 80:   MatSetFromOptions(A_save);
 81:   MatSetFromOptions(B);

 83:   MatGetType(B,&mattype);

 85:   PetscMalloc(nzp*(sizeof(PetscInt)+sizeof(PetscScalar)),&idxn);
 86:   a    = (PetscScalar*)(idxn + nzp);

 88:   PetscRandomCreate(PETSC_COMM_WORLD,&rdm);
 89:   PetscRandomSetFromOptions(rdm);

 91:   /* 1) MatMatMult() */
 92:   /* ----------------*/
 93:   if (Test_MatMatMult) {
 94:     MatDuplicate(A_save,MAT_COPY_VALUES,&A);

 96:     /* (1.1) Test developer API */
 97:     MatProductCreate(A,B,NULL,&C);
 98:     MatSetOptionsPrefix(C,"AB_");
 99:     MatProductSetType(C,MATPRODUCT_AB);
100:     MatProductSetAlgorithm(C,MATPRODUCTALGORITHMDEFAULT);
101:     MatProductSetFill(C,PETSC_DEFAULT);
102:     MatProductSetFromOptions(C);
103:     /* we can inquire about MATOP_PRODUCTSYMBOLIC even if the destination matrix type has not been set yet */
104:     MatHasOperation(C,MATOP_PRODUCTSYMBOLIC,&flg);
105:     MatProductSymbolic(C);
106:     MatProductNumeric(C);
107:     MatMatMultEqual(A,B,C,mcheck,&flg);

110:     /* Test reuse symbolic C */
111:     alpha = 0.9;
112:     MatScale(A,alpha);
113:     MatProductNumeric(C);

115:     MatMatMultEqual(A,B,C,mcheck,&flg);
117:     MatDestroy(&C);

119:     /* (1.2) Test user driver */
120:     MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);

122:     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
123:     alpha = 1.0;
124:     for (i=0; i<2; i++) {
125:       alpha -= 0.1;
126:       MatScale(A,alpha);
127:       MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);
128:     }
129:     MatMatMultEqual(A,B,C,mcheck,&flg);
131:     MatDestroy(&A);

133:     /* Test MatProductClear() */
134:     MatProductClear(C);
135:     MatDestroy(&C);

137:     /* Test MatMatMult() for dense and aij matrices */
138:     PetscObjectTypeCompareAny((PetscObject)A,&flg,MATSEQAIJ,MATMPIAIJ,"");
139:     if (flg) {
140:       MatConvert(A_save,MATDENSE,MAT_INITIAL_MATRIX,&A);
141:       MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);
142:       MatDestroy(&C);
143:       MatDestroy(&A);
144:     }
145:   }

147:   /* Create P and R = P^T  */
148:   /* --------------------- */
149:   MatGetSize(B,&PM,NULL);
150:   if (PN < 0) PN = PM/2;
151:   MatCreate(PETSC_COMM_WORLD,&P);
152:   MatSetSizes(P,PETSC_DECIDE,PETSC_DECIDE,PM,PN);
153:   MatSetType(P,MATAIJ);
154:   MatSeqAIJSetPreallocation(P,nzp,NULL);
155:   MatMPIAIJSetPreallocation(P,nzp,NULL,nzp,NULL);
156:   MatGetOwnershipRange(P,&rstart,&rend);
157:   for (i=0; i<nzp; i++) {
158:     PetscRandomGetValue(rdm,&a[i]);
159:   }
160:   for (i=rstart; i<rend; i++) {
161:     for (j=0; j<nzp; j++) {
162:       PetscRandomGetValue(rdm,&rval);
163:       idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
164:     }
165:     MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);
166:   }
167:   MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
168:   MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);

170:   MatTranspose(P,MAT_INITIAL_MATRIX,&R);
171:   MatConvert(P,mattype,MAT_INPLACE_MATRIX,&P);
172:   MatConvert(R,mattype,MAT_INPLACE_MATRIX,&R);
173:   MatSetFromOptions(P);
174:   MatSetFromOptions(R);

176:   /* 2) MatTransposeMatMult() */
177:   /* ------------------------ */
178:   if (Test_MatTrMat) {
179:     /* (2.1) Test developer driver C = P^T*B */
180:     MatProductCreate(P,B,NULL,&C);
181:     MatSetOptionsPrefix(C,"AtB_");
182:     MatProductSetType(C,MATPRODUCT_AtB);
183:     MatProductSetAlgorithm(C,MATPRODUCTALGORITHMDEFAULT);
184:     MatProductSetFill(C,PETSC_DEFAULT);
185:     MatProductSetFromOptions(C);
186:     MatHasOperation(C,MATOP_PRODUCTSYMBOLIC,&flg);
187:     if (flg) { /* run tests if supported */
188:       MatProductSymbolic(C); /* equivalent to MatSetUp() */
189:       MatSetOption(C,MAT_USE_INODES,PETSC_FALSE); /* illustrate how to call MatSetOption() */
190:       MatProductNumeric(C);
191:       MatProductNumeric(C); /* test reuse symbolic C */

193:       MatTransposeMatMultEqual(P,B,C,mcheck,&flg);
195:       MatDestroy(&C);

197:       /* (2.2) Test user driver C = P^T*B */
198:       MatTransposeMatMult(P,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);
199:       MatTransposeMatMult(P,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);
200:       MatGetInfo(C,MAT_GLOBAL_SUM,&info);
201:       MatProductClear(C);

203:       /* Compare P^T*B and R*B */
204:       MatMatMult(R,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C1);
205:       MatNormDifference(C,C1,&norm);
207:       MatDestroy(&C1);

209:       /* Test MatDuplicate() of C=P^T*B */
210:       MatDuplicate(C,MAT_COPY_VALUES,&C1);
211:       MatDestroy(&C1);
212:     } else {
213:       PetscPrintf(PETSC_COMM_WORLD,"MatTransposeMatMult not supported\n");
214:     }
215:     MatDestroy(&C);
216:   }

218:   /* 3) MatMatTransposeMult() */
219:   /* ------------------------ */
220:   if (Test_MatMatTr) {
221:     /* C = B*R^T */
222:     PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);
223:     if (seqaij) {
224:       MatMatTransposeMult(B,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);
225:       MatSetOptionsPrefix(C,"ABt_"); /* enable '-ABt_' for matrix C */
226:       MatGetInfo(C,MAT_GLOBAL_SUM,&info);

228:       /* Test MAT_REUSE_MATRIX - reuse symbolic C */
229:       MatMatTransposeMult(B,R,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);

231:       /* Check */
232:       MatMatMult(B,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C1);
233:       MatNormDifference(C,C1,&norm);
235:       MatDestroy(&C1);
236:       MatDestroy(&C);
237:     }
238:   }

240:   /* 4) Test MatPtAP() */
241:   /*-------------------*/
242:   if (Test_MatPtAP) {
243:     MatDuplicate(A_save,MAT_COPY_VALUES,&A);

245:     /* (4.1) Test developer API */
246:     MatProductCreate(A,P,NULL,&C);
247:     MatSetOptionsPrefix(C,"PtAP_");
248:     MatProductSetType(C,MATPRODUCT_PtAP);
249:     MatProductSetAlgorithm(C,MATPRODUCTALGORITHMDEFAULT);
250:     MatProductSetFill(C,PETSC_DEFAULT);
251:     MatProductSetFromOptions(C);
252:     MatProductSymbolic(C);
253:     MatProductNumeric(C);
254:     MatPtAPMultEqual(A,P,C,mcheck,&flg);
256:     MatProductNumeric(C); /* reuse symbolic C */

258:     MatPtAPMultEqual(A,P,C,mcheck,&flg);
260:     MatDestroy(&C);

262:     /* (4.2) Test user driver */
263:     MatPtAP(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);

265:     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
266:     alpha = 1.0;
267:     for (i=0; i<2; i++) {
268:       alpha -= 0.1;
269:       MatScale(A,alpha);
270:       MatPtAP(A,P,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);
271:     }
272:     MatPtAPMultEqual(A,P,C,mcheck,&flg);

275:     /* 5) Test MatRARt() */
276:     /* ----------------- */
277:     if (Test_MatRARt) {
278:       Mat RARt;

280:       /* (5.1) Test developer driver RARt = R*A*Rt */
281:       MatProductCreate(A,R,NULL,&RARt);
282:       MatSetOptionsPrefix(RARt,"RARt_");
283:       MatProductSetType(RARt,MATPRODUCT_RARt);
284:       MatProductSetAlgorithm(RARt,MATPRODUCTALGORITHMDEFAULT);
285:       MatProductSetFill(RARt,PETSC_DEFAULT);
286:       MatProductSetFromOptions(RARt);
287:       MatHasOperation(RARt,MATOP_PRODUCTSYMBOLIC,&flg);
288:       if (flg) {
289:         MatProductSymbolic(RARt); /* equivalent to MatSetUp() */
290:         MatSetOption(RARt,MAT_USE_INODES,PETSC_FALSE); /* illustrate how to call MatSetOption() */
291:         MatProductNumeric(RARt);
292:         MatProductNumeric(RARt); /* test reuse symbolic RARt */
293:         MatDestroy(&RARt);

295:         /* (2.2) Test user driver RARt = R*A*Rt */
296:         MatRARt(A,R,MAT_INITIAL_MATRIX,2.0,&RARt);
297:         MatRARt(A,R,MAT_REUSE_MATRIX,2.0,&RARt);

299:         MatNormDifference(C,RARt,&norm);
301:       } else {
302:         PetscPrintf(PETSC_COMM_WORLD,"MatRARt not supported\n");
303:       }
304:       MatDestroy(&RARt);
305:     }

307:     MatDestroy(&A);
308:     MatDestroy(&C);
309:   }

311:   /* Destroy objects */
312:   PetscRandomDestroy(&rdm);
313:   PetscFree(idxn);

315:   MatDestroy(&A_save);
316:   MatDestroy(&B);
317:   MatDestroy(&P);
318:   MatDestroy(&R);

320:   PetscFinalize();
321:   return 0;
322: }

324: /*TEST
325:    test:
326:      suffix: 1
327:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
328:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
329:      output_file: output/ex62_1.out

331:    test:
332:      suffix: 2_ab_scalable
333:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
334:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm scalable -matmatmult_via scalable -AtB_mat_product_algorithm outerproduct -mattransposematmult_via outerproduct
335:      output_file: output/ex62_1.out

337:    test:
338:      suffix: 3_ab_scalable_fast
339:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
340:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm scalable_fast -matmatmult_via scalable_fast -matmattransmult_via color
341:      output_file: output/ex62_1.out

343:    test:
344:      suffix: 4_ab_heap
345:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
346:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm heap -matmatmult_via heap -PtAP_mat_product_algorithm rap -matptap_via rap
347:      output_file: output/ex62_1.out

349:    test:
350:      suffix: 5_ab_btheap
351:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
352:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm btheap -matmatmult_via btheap -matrart_via r*art
353:      output_file: output/ex62_1.out

355:    test:
356:      suffix: 6_ab_llcondensed
357:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
358:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm llcondensed -matmatmult_via llcondensed -matrart_via coloring_rart
359:      output_file: output/ex62_1.out

361:    test:
362:      suffix: 7_ab_rowmerge
363:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
364:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm rowmerge -matmatmult_via rowmerge
365:      output_file: output/ex62_1.out

367:    test:
368:      suffix: 8_ab_hypre
369:      requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
370:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm hypre -matmatmult_via hypre -PtAP_mat_product_algorithm hypre -matptap_via hypre
371:      output_file: output/ex62_1.out

373:    test:
374:      suffix: hypre_medium
375:      nsize: {{1 3}}
376:      requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
377:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -A_mat_type hypre -B_mat_type hypre -test_rart 0
378:      output_file: output/ex62_hypre.out

380:    test:
381:      suffix: hypre_tiny
382:      nsize: {{1 3}}
383:      requires: hypre !complex double !defined(PETSC_USE_64BIT_INDICES)
384:      args: -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -A_mat_type hypre -B_mat_type hypre -test_rart 0
385:      output_file: output/ex62_hypre.out

387:    test:
388:      suffix: 9_mkl
389:      TODO: broken MatScale?
390:      requires: mkl_sparse datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
391:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -A_mat_type aijmkl -B_mat_type aijmkl
392:      output_file: output/ex62_1.out

394:    test:
395:      suffix: 10
396:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
397:      nsize: 3
398:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
399:      output_file: output/ex62_1.out

401:    test:
402:      suffix: 10_backend
403:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
404:      nsize: 3
405:      args: -fA ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm backend -matmatmult_via backend -AtB_mat_product_algorithm backend -mattransposematmult_via backend -PtAP_mat_product_algorithm backend -matptap_via backend
406:      output_file: output/ex62_1.out

408:    test:
409:      suffix: 11_ab_scalable
410:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
411:      nsize: 3
412:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm scalable -matmatmult_via scalable -AtB_mat_product_algorithm scalable -mattransposematmult_via scalable
413:      output_file: output/ex62_1.out

415:    test:
416:      suffix: 12_ab_seqmpi
417:      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
418:      nsize: 3
419:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm seqmpi -matmatmult_via seqmpi -AtB_mat_product_algorithm at*b -mattransposematmult_via at*b
420:      output_file: output/ex62_1.out

422:    test:
423:      suffix: 13_ab_hypre
424:      requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
425:      nsize: 3
426:      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm hypre -matmatmult_via hypre -PtAP_mat_product_algorithm hypre -matptap_via hypre
427:      output_file: output/ex62_1.out

429:    test:
430:      suffix: 14_seqaij
431:      requires: !complex double !defined(PETSC_USE_64BIT_INDICES)
432:      args: -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system
433:      output_file: output/ex62_1.out

435:    test:
436:      suffix: 14_seqaijcusparse
437:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
438:      args: -A_mat_type aijcusparse -B_mat_type aijcusparse -mat_form_explicit_transpose -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system
439:      output_file: output/ex62_1.out

441:    test:
442:      suffix: 14_seqaijcusparse_cpu
443:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
444:      args: -A_mat_type aijcusparse -B_mat_type aijcusparse -mat_form_explicit_transpose -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -AB_mat_product_algorithm_backend_cpu -matmatmult_backend_cpu -PtAP_mat_product_algorithm_backend_cpu -matptap_backend_cpu -RARt_mat_product_algorithm_backend_cpu -matrart_backend_cpu
445:      output_file: output/ex62_1.out

447:    test:
448:      suffix: 14_mpiaijcusparse_seq
449:      nsize: 1
450:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
451:      args: -A_mat_type mpiaijcusparse -B_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system
452:      output_file: output/ex62_1.out

454:    test:
455:      suffix: 14_mpiaijcusparse_seq_cpu
456:      nsize: 1
457:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
458:      args: -A_mat_type mpiaijcusparse -B_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -AB_mat_product_algorithm_backend_cpu -matmatmult_backend_cpu -PtAP_mat_product_algorithm_backend_cpu -matptap_backend_cpu
459:      output_file: output/ex62_1.out

461:    test:
462:      suffix: 14_mpiaijcusparse
463:      nsize: 3
464:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
465:      args: -A_mat_type mpiaijcusparse -B_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system
466:      output_file: output/ex62_1.out

468:    test:
469:      suffix: 14_mpiaijcusparse_cpu
470:      nsize: 3
471:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
472:      args: -A_mat_type mpiaijcusparse -B_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -AB_mat_product_algorithm_backend_cpu -matmatmult_backend_cpu -PtAP_mat_product_algorithm_backend_cpu -matptap_backend_cpu
473:      output_file: output/ex62_1.out

475:    test:
476:      nsize: {{1 3}}
477:      suffix: 14_aijkokkos
478:      requires: !sycl kokkos_kernels !complex double !defined(PETSC_USE_64BIT_INDICES)
479:      args: -A_mat_type aijkokkos -B_mat_type aijkokkos -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system
480:      output_file: output/ex62_1.out

482:    # these tests use matrices with many zero rows
483:    test:
484:      suffix: 15_seqaijcusparse
485:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
486:      args: -A_mat_type aijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
487:      output_file: output/ex62_1.out

489:    test:
490:      suffix: 15_mpiaijcusparse_seq
491:      nsize: 1
492:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
493:      args: -A_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
494:      output_file: output/ex62_1.out

496:    test:
497:      nsize: 3
498:      suffix: 15_mpiaijcusparse
499:      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
500:      args: -A_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
501:      output_file: output/ex62_1.out

503: TEST*/