xref: /petsc/src/mat/tests/ex62.c (revision 2fa40bb9206b96114faa7cb222621ec184d31cd2)
1 
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 */
9 
10 #include <petscmat.h>
11 
12 /*
13      B = A - B
14      norm = norm(B)
15 */
16 PetscErrorCode MatNormDifference(Mat A,Mat B,PetscReal *norm)
17 {
18   PetscErrorCode ierr;
19 
20   PetscFunctionBegin;
21   ierr = MatAXPY(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
22   ierr = MatNorm(B,NORM_FROBENIUS,norm);CHKERRQ(ierr);
23   PetscFunctionReturn(0);
24 }
25 
26 int main(int argc,char **args)
27 {
28   Mat            A,A_save,B,C,P,C1,R;
29   PetscViewer    viewer;
30   PetscErrorCode ierr;
31   PetscMPIInt    size,rank;
32   PetscInt       i,j,*idxn,PM,PN = PETSC_DECIDE,rstart,rend;
33   PetscReal      norm;
34   PetscRandom    rdm;
35   char           file[2][PETSC_MAX_PATH_LEN] = { "", ""};
36   PetscScalar    *a,rval,alpha;
37   PetscBool      Test_MatMatMult=PETSC_TRUE,Test_MatTrMat=PETSC_TRUE,Test_MatMatTr=PETSC_TRUE;
38   PetscBool      Test_MatPtAP=PETSC_TRUE,Test_MatRARt=PETSC_TRUE,flg,seqaij,flgA,flgB;
39   MatInfo        info;
40   PetscInt       nzp  = 5; /* num of nonzeros in each row of P */
41   MatType        mattype;
42   const char     *deft = MATAIJ;
43   char           A_mattype[256], B_mattype[256];
44   PetscInt       mcheck = 10;
45 
46   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
47   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(ierr);
48   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr);
49 
50   /*  Load the matrices A_save and B */
51   ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","","");CHKERRQ(ierr);
52   ierr = PetscOptionsBool("-test_rart","Test MatRARt","",Test_MatRARt,&Test_MatRARt,NULL);CHKERRQ(ierr);
53   ierr = PetscOptionsInt("-PN","Number of columns of P","",PN,&PN,NULL);CHKERRQ(ierr);
54   ierr = PetscOptionsInt("-mcheck","Number of matmult checks","",mcheck,&mcheck,NULL);CHKERRQ(ierr);
55   ierr = PetscOptionsString("-fA","Path for matrix A","",file[0],file[0],sizeof(file[0]),&flg);CHKERRQ(ierr);
56   if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_USER_INPUT,"Must indicate a file name for matrix A with the -fA option.");
57   ierr = PetscOptionsString("-fB","Path for matrix B","",file[1],file[1],sizeof(file[1]),&flg);CHKERRQ(ierr);
58   ierr = PetscOptionsFList("-A_mat_type","Matrix type","MatSetType",MatList,deft,A_mattype,256,&flgA);CHKERRQ(ierr);
59   ierr = PetscOptionsFList("-B_mat_type","Matrix type","MatSetType",MatList,deft,B_mattype,256,&flgB);CHKERRQ(ierr);
60   ierr = PetscOptionsEnd();CHKERRQ(ierr);
61 
62   ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[0],FILE_MODE_READ,&viewer);CHKERRQ(ierr);
63   ierr = MatCreate(PETSC_COMM_WORLD,&A_save);CHKERRQ(ierr);
64   ierr = MatLoad(A_save,viewer);CHKERRQ(ierr);
65   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
66 
67   if (flg) {
68     ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[1],FILE_MODE_READ,&viewer);CHKERRQ(ierr);
69     ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr);
70     ierr = MatLoad(B,viewer);CHKERRQ(ierr);
71     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
72   } else {
73     ierr = PetscObjectReference((PetscObject)A_save);CHKERRQ(ierr);
74     B = A_save;
75   }
76 
77   if (flgA) {
78     ierr = MatConvert(A_save,A_mattype,MAT_INPLACE_MATRIX,&A_save);CHKERRQ(ierr);
79   }
80   if (flgB) {
81     ierr = MatConvert(B,B_mattype,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr);
82   }
83   ierr = MatSetFromOptions(A_save);CHKERRQ(ierr);
84   ierr = MatSetFromOptions(B);CHKERRQ(ierr);
85 
86   ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
87 
88   ierr = PetscMalloc(nzp*(sizeof(PetscInt)+sizeof(PetscScalar)),&idxn);CHKERRQ(ierr);
89   a    = (PetscScalar*)(idxn + nzp);
90 
91   ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rdm);CHKERRQ(ierr);
92   ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr);
93 
94   /* 1) MatMatMult() */
95   /* ----------------*/
96   if (Test_MatMatMult) {
97     ierr = MatDuplicate(A_save,MAT_COPY_VALUES,&A);CHKERRQ(ierr);
98 
99     /* (1.1) Test developer API */
100     ierr = MatProductCreate(A,B,NULL,&C);CHKERRQ(ierr);
101     ierr = MatSetOptionsPrefix(C,"AB_");CHKERRQ(ierr);
102     ierr = MatProductSetType(C,MATPRODUCT_AB);CHKERRQ(ierr);
103     ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
104     ierr = MatProductSetFill(C,PETSC_DEFAULT);CHKERRQ(ierr);
105     ierr = MatProductSetFromOptions(C);CHKERRQ(ierr);
106     /* we can inquire about MATOP_PRODUCTSYMBOLIC even if the destination matrix type has not been set yet */
107     ierr = MatHasOperation(C,MATOP_PRODUCTSYMBOLIC,&flg);CHKERRQ(ierr);
108     ierr = MatProductSymbolic(C);CHKERRQ(ierr);
109     ierr = MatProductNumeric(C);CHKERRQ(ierr);
110     ierr = MatMatMultEqual(A,B,C,mcheck,&flg);CHKERRQ(ierr);
111     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in C=A*B");
112 
113     /* Test reuse symbolic C */
114     alpha = 0.9;
115     ierr = MatScale(A,alpha);CHKERRQ(ierr);
116     ierr = MatProductNumeric(C);CHKERRQ(ierr);
117 
118     ierr = MatMatMultEqual(A,B,C,mcheck,&flg);CHKERRQ(ierr);
119     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in C=A*B");
120     ierr = MatDestroy(&C);CHKERRQ(ierr);
121 
122     /* (1.2) Test user driver */
123     ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
124 
125     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
126     alpha = 1.0;
127     for (i=0; i<2; i++) {
128       alpha -= 0.1;
129       ierr   = MatScale(A,alpha);CHKERRQ(ierr);
130       ierr   = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
131     }
132     ierr = MatMatMultEqual(A,B,C,mcheck,&flg);CHKERRQ(ierr);
133     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error: MatMatMult()");
134     ierr = MatDestroy(&A);CHKERRQ(ierr);
135 
136     /* Test MatProductClear() */
137     ierr = MatProductClear(C);CHKERRQ(ierr);
138     ierr = MatDestroy(&C);CHKERRQ(ierr);
139 
140     /* Test MatMatMult() for dense and aij matrices */
141     ierr = PetscObjectTypeCompareAny((PetscObject)A,&flg,MATSEQAIJ,MATMPIAIJ,"");CHKERRQ(ierr);
142     if (flg) {
143       ierr = MatConvert(A_save,MATDENSE,MAT_INITIAL_MATRIX,&A);CHKERRQ(ierr);
144       ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
145       ierr = MatDestroy(&C);CHKERRQ(ierr);
146       ierr = MatDestroy(&A);CHKERRQ(ierr);
147     }
148   }
149 
150   /* Create P and R = P^T  */
151   /* --------------------- */
152   ierr = MatGetSize(B,&PM,NULL);CHKERRQ(ierr);
153   if (PN < 0) PN = PM/2;
154   ierr = MatCreate(PETSC_COMM_WORLD,&P);CHKERRQ(ierr);
155   ierr = MatSetSizes(P,PETSC_DECIDE,PETSC_DECIDE,PM,PN);CHKERRQ(ierr);
156   ierr = MatSetType(P,MATAIJ);CHKERRQ(ierr);
157   ierr = MatSeqAIJSetPreallocation(P,nzp,NULL);CHKERRQ(ierr);
158   ierr = MatMPIAIJSetPreallocation(P,nzp,NULL,nzp,NULL);CHKERRQ(ierr);
159   ierr = MatGetOwnershipRange(P,&rstart,&rend);CHKERRQ(ierr);
160   for (i=0; i<nzp; i++) {
161     ierr = PetscRandomGetValue(rdm,&a[i]);CHKERRQ(ierr);
162   }
163   for (i=rstart; i<rend; i++) {
164     for (j=0; j<nzp; j++) {
165       ierr    = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr);
166       idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
167     }
168     ierr = MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);CHKERRQ(ierr);
169   }
170   ierr = MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
171   ierr = MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
172 
173   ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&R);CHKERRQ(ierr);
174   ierr = MatConvert(P,mattype,MAT_INPLACE_MATRIX,&P);CHKERRQ(ierr);
175   ierr = MatConvert(R,mattype,MAT_INPLACE_MATRIX,&R);CHKERRQ(ierr);
176   ierr = MatSetFromOptions(P);CHKERRQ(ierr);
177   ierr = MatSetFromOptions(R);CHKERRQ(ierr);
178 
179   /* 2) MatTransposeMatMult() */
180   /* ------------------------ */
181   if (Test_MatTrMat) {
182     /* (2.1) Test developer driver C = P^T*B */
183     ierr = MatProductCreate(P,B,NULL,&C);CHKERRQ(ierr);
184     ierr = MatSetOptionsPrefix(C,"AtB_");CHKERRQ(ierr);
185     ierr = MatProductSetType(C,MATPRODUCT_AtB);CHKERRQ(ierr);
186     ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
187     ierr = MatProductSetFill(C,PETSC_DEFAULT);CHKERRQ(ierr);
188     ierr = MatProductSetFromOptions(C);CHKERRQ(ierr);
189     ierr = MatHasOperation(C,MATOP_PRODUCTSYMBOLIC,&flg);CHKERRQ(ierr);
190     if (flg) { /* run tests if supported */
191       ierr = MatProductSymbolic(C);CHKERRQ(ierr); /* equivalent to MatSetUp() */
192       ierr = MatSetOption(C,MAT_USE_INODES,PETSC_FALSE);CHKERRQ(ierr); /* illustrate how to call MatSetOption() */
193       ierr = MatProductNumeric(C);CHKERRQ(ierr);
194       ierr = MatProductNumeric(C);CHKERRQ(ierr); /* test reuse symbolic C */
195 
196       ierr = MatTransposeMatMultEqual(P,B,C,mcheck,&flg);CHKERRQ(ierr);
197       if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error: developer driver C = P^T*B");
198       ierr = MatDestroy(&C);CHKERRQ(ierr);
199 
200       /* (2.2) Test user driver C = P^T*B */
201       ierr = MatTransposeMatMult(P,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
202       ierr = MatTransposeMatMult(P,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
203       ierr = MatGetInfo(C,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
204       ierr = MatProductClear(C);CHKERRQ(ierr);
205 
206       /* Compare P^T*B and R*B */
207       ierr = MatMatMult(R,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C1);CHKERRQ(ierr);
208       ierr = MatNormDifference(C,C1,&norm);CHKERRQ(ierr);
209       if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatTransposeMatMult(): %g",(double)norm);
210       ierr = MatDestroy(&C1);CHKERRQ(ierr);
211 
212       /* Test MatDuplicate() of C=P^T*B */
213       ierr = MatDuplicate(C,MAT_COPY_VALUES,&C1);CHKERRQ(ierr);
214       ierr = MatDestroy(&C1);CHKERRQ(ierr);
215     } else {
216       ierr = PetscPrintf(PETSC_COMM_WORLD,"MatTransposeMatMult not supported\n");CHKERRQ(ierr);
217     }
218     ierr = MatDestroy(&C);CHKERRQ(ierr);
219   }
220 
221   /* 3) MatMatTransposeMult() */
222   /* ------------------------ */
223   if (Test_MatMatTr) {
224     /* C = B*R^T */
225     ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
226     if (seqaij) {
227       ierr = MatMatTransposeMult(B,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
228       ierr = MatSetOptionsPrefix(C,"ABt_");CHKERRQ(ierr); /* enable '-ABt_' for matrix C */
229       ierr = MatGetInfo(C,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
230 
231       /* Test MAT_REUSE_MATRIX - reuse symbolic C */
232       ierr = MatMatTransposeMult(B,R,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
233 
234       /* Check */
235       ierr = MatMatMult(B,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C1);CHKERRQ(ierr);
236       ierr = MatNormDifference(C,C1,&norm);CHKERRQ(ierr);
237       if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatTransposeMult() %g",(double)norm);
238       ierr = MatDestroy(&C1);CHKERRQ(ierr);
239       ierr = MatDestroy(&C);CHKERRQ(ierr);
240     }
241   }
242 
243   /* 4) Test MatPtAP() */
244   /*-------------------*/
245   if (Test_MatPtAP) {
246     ierr = MatDuplicate(A_save,MAT_COPY_VALUES,&A);CHKERRQ(ierr);
247 
248     /* (4.1) Test developer API */
249     ierr = MatProductCreate(A,P,NULL,&C);CHKERRQ(ierr);
250     ierr = MatSetOptionsPrefix(C,"PtAP_");CHKERRQ(ierr);
251     ierr = MatProductSetType(C,MATPRODUCT_PtAP);CHKERRQ(ierr);
252     ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
253     ierr = MatProductSetFill(C,PETSC_DEFAULT);CHKERRQ(ierr);
254     ierr = MatProductSetFromOptions(C);CHKERRQ(ierr);
255     ierr = MatProductSymbolic(C);CHKERRQ(ierr);
256     ierr = MatProductNumeric(C);CHKERRQ(ierr);
257     ierr = MatPtAPMultEqual(A,P,C,mcheck,&flg);CHKERRQ(ierr);
258     if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatProduct_PtAP");
259     ierr = MatProductNumeric(C);CHKERRQ(ierr); /* reuse symbolic C */
260 
261     ierr = MatPtAPMultEqual(A,P,C,mcheck,&flg);CHKERRQ(ierr);
262     if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatProduct_PtAP");
263     ierr = MatDestroy(&C);CHKERRQ(ierr);
264 
265     /* (4.2) Test user driver */
266     ierr = MatPtAP(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
267 
268     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
269     alpha = 1.0;
270     for (i=0; i<2; i++) {
271       alpha -= 0.1;
272       ierr   = MatScale(A,alpha);CHKERRQ(ierr);
273       ierr   = MatPtAP(A,P,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
274     }
275     ierr = MatPtAPMultEqual(A,P,C,mcheck,&flg);CHKERRQ(ierr);
276     if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP");
277 
278     /* 5) Test MatRARt() */
279     /* ----------------- */
280     if (Test_MatRARt) {
281       Mat RARt;
282 
283       /* (5.1) Test developer driver RARt = R*A*Rt */
284       ierr = MatProductCreate(A,R,NULL,&RARt);CHKERRQ(ierr);
285       ierr = MatSetOptionsPrefix(RARt,"RARt_");CHKERRQ(ierr);
286       ierr = MatProductSetType(RARt,MATPRODUCT_RARt);CHKERRQ(ierr);
287       ierr = MatProductSetAlgorithm(RARt,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
288       ierr = MatProductSetFill(RARt,PETSC_DEFAULT);CHKERRQ(ierr);
289       ierr = MatProductSetFromOptions(RARt);CHKERRQ(ierr);
290       ierr = MatHasOperation(RARt,MATOP_PRODUCTSYMBOLIC,&flg);CHKERRQ(ierr);
291       if (flg) {
292         ierr = MatProductSymbolic(RARt);CHKERRQ(ierr); /* equivalent to MatSetUp() */
293         ierr = MatSetOption(RARt,MAT_USE_INODES,PETSC_FALSE);CHKERRQ(ierr); /* illustrate how to call MatSetOption() */
294         ierr = MatProductNumeric(RARt);CHKERRQ(ierr);
295         ierr = MatProductNumeric(RARt);CHKERRQ(ierr); /* test reuse symbolic RARt */
296         ierr = MatDestroy(&RARt);CHKERRQ(ierr);
297 
298         /* (2.2) Test user driver RARt = R*A*Rt */
299         ierr = MatRARt(A,R,MAT_INITIAL_MATRIX,2.0,&RARt);CHKERRQ(ierr);
300         ierr = MatRARt(A,R,MAT_REUSE_MATRIX,2.0,&RARt);CHKERRQ(ierr);
301 
302         ierr = MatNormDifference(C,RARt,&norm);CHKERRQ(ierr);
303         if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"|PtAP - RARt| = %g",(double)norm);
304       } else {
305         ierr = PetscPrintf(PETSC_COMM_WORLD,"MatRARt not supported\n");CHKERRQ(ierr);
306       }
307       ierr = MatDestroy(&RARt);CHKERRQ(ierr);
308     }
309 
310     ierr = MatDestroy(&A);CHKERRQ(ierr);
311     ierr = MatDestroy(&C);CHKERRQ(ierr);
312   }
313 
314   /* Destroy objects */
315   ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr);
316   ierr = PetscFree(idxn);CHKERRQ(ierr);
317 
318   ierr = MatDestroy(&A_save);CHKERRQ(ierr);
319   ierr = MatDestroy(&B);CHKERRQ(ierr);
320   ierr = MatDestroy(&P);CHKERRQ(ierr);
321   ierr = MatDestroy(&R);CHKERRQ(ierr);
322 
323   ierr = PetscFinalize();
324   return ierr;
325 }
326 
327 /*TEST
328    test:
329      suffix: 1
330      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
331      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
332      output_file: output/ex62_1.out
333 
334    test:
335      suffix: 2_ab_scalable
336      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
337      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via scalable -matmatmult_via scalable -AtB_matproduct_atb_via outerproduct -mattransposematmult_via outerproduct
338      output_file: output/ex62_1.out
339 
340    test:
341      suffix: 3_ab_scalable_fast
342      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
343      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via scalable_fast -matmatmult_via scalable_fast -matmattransmult_via color
344      output_file: output/ex62_1.out
345 
346    test:
347      suffix: 4_ab_heap
348      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
349      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via heap -matmatmult_via heap -PtAP_matproduct_ptap_via rap -matptap_via rap
350      output_file: output/ex62_1.out
351 
352    test:
353      suffix: 5_ab_btheap
354      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
355      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via btheap -matmatmult_via btheap -matrart_via r*art
356      output_file: output/ex62_1.out
357 
358    test:
359      suffix: 6_ab_llcondensed
360      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
361      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via llcondensed -matmatmult_via llcondensed -matrart_via coloring_rart
362      output_file: output/ex62_1.out
363 
364    test:
365      suffix: 7_ab_rowmerge
366      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
367      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via rowmerge -matmatmult_via rowmerge
368      output_file: output/ex62_1.out
369 
370    test:
371      suffix: 8_ab_hypre
372      requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
373      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via hypre -matmatmult_via hypre -PtAP_matproduct_ptap_via hypre -matptap_via hypre
374      output_file: output/ex62_1.out
375 
376    test:
377      suffix: hypre_medium
378      nsize: {{1 3}}
379      requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
380      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -A_mat_type hypre -B_mat_type hypre -test_rart 0
381      output_file: output/ex62_hypre.out
382 
383    test:
384      suffix: hypre_tiny
385      nsize: {{1 3}}
386      requires: hypre !complex double !defined(PETSC_USE_64BIT_INDICES)
387      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
388      output_file: output/ex62_hypre.out
389 
390    test:
391      suffix: 9_mkl
392      TODO: broken MatScale?
393      requires: mkl datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
394      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -A_mat_type aijmkl -B_mat_type aijmkl
395      output_file: output/ex62_1.out
396 
397    test:
398      suffix: 10
399      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
400      nsize: 3
401      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
402      output_file: output/ex62_1.out
403 
404    test:
405      suffix: 10_backend
406      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
407      nsize: 3
408      args: -fA ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via backend -matmatmult_via backend -AtB_matproduct_atb_via backend -mattransposematmult_via backend -PtAP_matproduct_ptap_via backend -matptap_via backend
409      output_file: output/ex62_1.out
410 
411    test:
412      suffix: 11_ab_scalable
413      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
414      nsize: 3
415      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via scalable -matmatmult_via scalable -AtB_matproduct_atb_via scalable -mattransposematmult_via scalable
416      output_file: output/ex62_1.out
417 
418    test:
419      suffix: 12_ab_seqmpi
420      requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
421      nsize: 3
422      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via seqmpi -matmatmult_via seqmpi -AtB_matproduct_atb_via at*b -mattransposematmult_via at*b
423      output_file: output/ex62_1.out
424 
425    test:
426      suffix: 13_ab_hypre
427      requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
428      nsize: 3
429      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via hypre -matmatmult_via hypre -PtAP_matproduct_ptap_via hypre -matptap_via hypre
430      output_file: output/ex62_1.out
431 
432    test:
433      suffix: 14_seqaij
434      requires: !complex double !defined(PETSC_USE_64BIT_INDICES)
435      args: -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system
436      output_file: output/ex62_1.out
437 
438    test:
439      suffix: 14_seqaijcusparse
440      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
441      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
442      output_file: output/ex62_1.out
443 
444    test:
445      suffix: 14_seqaijcusparse_cpu
446      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
447      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_matproduct_ab_backend_cpu -matmatmult_backend_cpu -PtAP_matproduct_ptap_backend_cpu -matptap_backend_cpu -RARt_matproduct_rart_backend_cpu -matrart_backend_cpu
448      output_file: output/ex62_1.out
449 
450    test:
451      suffix: 14_mpiaijcusparse_seq
452      nsize: 1
453      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
454      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
455      output_file: output/ex62_1.out
456 
457    test:
458      suffix: 14_mpiaijcusparse_seq_cpu
459      nsize: 1
460      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
461      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_matproduct_ab_backend_cpu -matmatmult_backend_cpu -PtAP_matproduct_ptap_backend_cpu -matptap_backend_cpu
462      output_file: output/ex62_1.out
463 
464    test:
465      suffix: 14_mpiaijcusparse
466      nsize: 3
467      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
468      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
469      output_file: output/ex62_1.out
470 
471    test:
472      suffix: 14_mpiaijcusparse_cpu
473      nsize: 3
474      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
475      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_matproduct_ab_backend_cpu -matmatmult_backend_cpu -PtAP_matproduct_ptap_backend_cpu -matptap_backend_cpu
476      output_file: output/ex62_1.out
477 
478    test:
479      suffix: 14_seqaijkokkos
480      requires: kokkos_kernels !complex double !defined(PETSC_USE_64BIT_INDICES)
481      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
482      output_file: output/ex62_1.out
483 
484    # these tests use matrices with many zero rows
485    test:
486      suffix: 15_seqaijcusparse
487      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
488      args: -A_mat_type aijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
489      output_file: output/ex62_1.out
490 
491    test:
492      suffix: 15_mpiaijcusparse_seq
493      nsize: 1
494      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
495      args: -A_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
496      output_file: output/ex62_1.out
497 
498    test:
499      nsize: 3
500      suffix: 15_mpiaijcusparse
501      requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
502      args: -A_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
503      output_file: output/ex62_1.out
504 
505 TEST*/
506