1c20d7725SJed Brown static char help[] = "Test Matrix products for AIJ matrices\n\
2c20d7725SJed Brown Input arguments are:\n\
3c20d7725SJed Brown -fA <input_file> -fB <input_file> -fC <input_file>: file to load\n\n";
4c20d7725SJed Brown /* Example of usage:
5c20d7725SJed Brown ./ex62 -fA <A_binary> -fB <B_binary>
6c20d7725SJed Brown mpiexec -n 3 ./ex62 -fA medium -fB medium
7c20d7725SJed Brown */
8c20d7725SJed Brown
9c20d7725SJed Brown #include <petscmat.h>
10c20d7725SJed Brown
11c20d7725SJed Brown /*
12c20d7725SJed Brown B = A - B
13c20d7725SJed Brown norm = norm(B)
14c20d7725SJed Brown */
MatNormDifference(Mat A,Mat B,PetscReal * norm)15d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNormDifference(Mat A, Mat B, PetscReal *norm)
16d71ae5a4SJacob Faibussowitsch {
17c20d7725SJed Brown PetscFunctionBegin;
189566063dSJacob Faibussowitsch PetscCall(MatAXPY(B, -1.0, A, DIFFERENT_NONZERO_PATTERN));
199566063dSJacob Faibussowitsch PetscCall(MatNorm(B, NORM_FROBENIUS, norm));
203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
21c20d7725SJed Brown }
22c20d7725SJed Brown
main(int argc,char ** args)23d71ae5a4SJacob Faibussowitsch int main(int argc, char **args)
24d71ae5a4SJacob Faibussowitsch {
25c20d7725SJed Brown Mat A, A_save, B, C, P, C1, R;
26c20d7725SJed Brown PetscViewer viewer;
27c20d7725SJed Brown PetscMPIInt size, rank;
2820b3374bSStefano Zampini PetscInt i, j, *idxn, PM, PN = PETSC_DECIDE, rstart, rend;
29c20d7725SJed Brown PetscReal norm;
30c20d7725SJed Brown PetscRandom rdm;
3120b3374bSStefano Zampini char file[2][PETSC_MAX_PATH_LEN] = {"", ""};
32c20d7725SJed Brown PetscScalar *a, rval, alpha;
33c20d7725SJed Brown PetscBool Test_MatMatMult = PETSC_TRUE, Test_MatTrMat = PETSC_TRUE, Test_MatMatTr = PETSC_TRUE;
3420b3374bSStefano Zampini PetscBool Test_MatPtAP = PETSC_TRUE, Test_MatRARt = PETSC_TRUE, flg, seqaij, flgA, flgB;
35c20d7725SJed Brown MatInfo info;
3620b3374bSStefano Zampini PetscInt nzp = 5; /* num of nonzeros in each row of P */
37c20d7725SJed Brown MatType mattype;
3820b3374bSStefano Zampini const char *deft = MATAIJ;
3920b3374bSStefano Zampini char A_mattype[256], B_mattype[256];
4020b3374bSStefano Zampini PetscInt mcheck = 10;
41c20d7725SJed Brown
42327415f7SBarry Smith PetscFunctionBeginUser;
43c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &args, NULL, help));
449566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
459566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
46c20d7725SJed Brown
47c20d7725SJed Brown /* Load the matrices A_save and B */
48d0609cedSBarry Smith PetscOptionsBegin(PETSC_COMM_WORLD, "", "", "");
499566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-test_rart", "Test MatRARt", "", Test_MatRARt, &Test_MatRARt, NULL));
509566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-PN", "Number of columns of P", "", PN, &PN, NULL));
519566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-mcheck", "Number of matmult checks", "", mcheck, &mcheck, NULL));
529566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-fA", "Path for matrix A", "", file[0], file[0], sizeof(file[0]), &flg));
5328b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT, "Must indicate a file name for matrix A with the -fA option.");
549566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-fB", "Path for matrix B", "", file[1], file[1], sizeof(file[1]), &flg));
559566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-A_mat_type", "Matrix type", "MatSetType", MatList, deft, A_mattype, 256, &flgA));
569566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-B_mat_type", "Matrix type", "MatSetType", MatList, deft, B_mattype, 256, &flgB));
57d0609cedSBarry Smith PetscOptionsEnd();
58c20d7725SJed Brown
599566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[0], FILE_MODE_READ, &viewer));
609566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &A_save));
619566063dSJacob Faibussowitsch PetscCall(MatLoad(A_save, viewer));
629566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer));
63c20d7725SJed Brown
6420b3374bSStefano Zampini if (flg) {
659566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[1], FILE_MODE_READ, &viewer));
669566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &B));
679566063dSJacob Faibussowitsch PetscCall(MatLoad(B, viewer));
689566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer));
6920b3374bSStefano Zampini } else {
709566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A_save));
7120b3374bSStefano Zampini B = A_save;
7220b3374bSStefano Zampini }
7320b3374bSStefano Zampini
7448a46eb9SPierre Jolivet if (flgA) PetscCall(MatConvert(A_save, A_mattype, MAT_INPLACE_MATRIX, &A_save));
7548a46eb9SPierre Jolivet if (flgB) PetscCall(MatConvert(B, B_mattype, MAT_INPLACE_MATRIX, &B));
769566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A_save));
779566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(B));
78c20d7725SJed Brown
799566063dSJacob Faibussowitsch PetscCall(MatGetType(B, &mattype));
80c20d7725SJed Brown
81f1e99121SPierre Jolivet PetscCall(PetscMalloc2(nzp, &idxn, nzp, &a));
82c20d7725SJed Brown
839566063dSJacob Faibussowitsch PetscCall(PetscRandomCreate(PETSC_COMM_WORLD, &rdm));
849566063dSJacob Faibussowitsch PetscCall(PetscRandomSetFromOptions(rdm));
85c20d7725SJed Brown
86c20d7725SJed Brown /* 1) MatMatMult() */
87c20d7725SJed Brown /* ----------------*/
88c20d7725SJed Brown if (Test_MatMatMult) {
899566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A_save, MAT_COPY_VALUES, &A));
90c20d7725SJed Brown
91c20d7725SJed Brown /* (1.1) Test developer API */
929566063dSJacob Faibussowitsch PetscCall(MatProductCreate(A, B, NULL, &C));
939566063dSJacob Faibussowitsch PetscCall(MatSetOptionsPrefix(C, "AB_"));
949566063dSJacob Faibussowitsch PetscCall(MatProductSetType(C, MATPRODUCT_AB));
959566063dSJacob Faibussowitsch PetscCall(MatProductSetAlgorithm(C, MATPRODUCTALGORITHMDEFAULT));
96fb842aefSJose E. Roman PetscCall(MatProductSetFill(C, PETSC_DETERMINE));
979566063dSJacob Faibussowitsch PetscCall(MatProductSetFromOptions(C));
98910fa13fSStefano Zampini /* we can inquire about MATOP_PRODUCTSYMBOLIC even if the destination matrix type has not been set yet */
999566063dSJacob Faibussowitsch PetscCall(MatHasOperation(C, MATOP_PRODUCTSYMBOLIC, &flg));
1009566063dSJacob Faibussowitsch PetscCall(MatProductSymbolic(C));
1019566063dSJacob Faibussowitsch PetscCall(MatProductNumeric(C));
1029566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(A, B, C, mcheck, &flg));
10328b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Error in C=A*B");
104c20d7725SJed Brown
105c20d7725SJed Brown /* Test reuse symbolic C */
106c20d7725SJed Brown alpha = 0.9;
1079566063dSJacob Faibussowitsch PetscCall(MatScale(A, alpha));
1089566063dSJacob Faibussowitsch PetscCall(MatProductNumeric(C));
109c20d7725SJed Brown
1109566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(A, B, C, mcheck, &flg));
11128b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Error in C=A*B");
1129566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
113c20d7725SJed Brown
114c20d7725SJed Brown /* (1.2) Test user driver */
115fb842aefSJose E. Roman PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &C));
116c20d7725SJed Brown
117c20d7725SJed Brown /* Test MAT_REUSE_MATRIX - reuse symbolic C */
118c20d7725SJed Brown alpha = 1.0;
119c20d7725SJed Brown for (i = 0; i < 2; i++) {
120c20d7725SJed Brown alpha -= 0.1;
1219566063dSJacob Faibussowitsch PetscCall(MatScale(A, alpha));
122fb842aefSJose E. Roman PetscCall(MatMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DETERMINE, &C));
123c20d7725SJed Brown }
1249566063dSJacob Faibussowitsch PetscCall(MatMatMultEqual(A, B, C, mcheck, &flg));
12528b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Error: MatMatMult()");
1269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A));
1274417c5e8SHong Zhang
1284417c5e8SHong Zhang /* Test MatProductClear() */
1299566063dSJacob Faibussowitsch PetscCall(MatProductClear(C));
1309566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
131544a5e07SHong Zhang
132544a5e07SHong Zhang /* Test MatMatMult() for dense and aij matrices */
1339566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &flg, MATSEQAIJ, MATMPIAIJ, ""));
13420b3374bSStefano Zampini if (flg) {
1359566063dSJacob Faibussowitsch PetscCall(MatConvert(A_save, MATDENSE, MAT_INITIAL_MATRIX, &A));
136fb842aefSJose E. Roman PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &C));
1379566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
1389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A));
13920b3374bSStefano Zampini }
140c20d7725SJed Brown }
141c20d7725SJed Brown
142c20d7725SJed Brown /* Create P and R = P^T */
143c20d7725SJed Brown /* --------------------- */
1449566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, &PM, NULL));
14520b3374bSStefano Zampini if (PN < 0) PN = PM / 2;
1469566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &P));
1479566063dSJacob Faibussowitsch PetscCall(MatSetSizes(P, PETSC_DECIDE, PETSC_DECIDE, PM, PN));
1489566063dSJacob Faibussowitsch PetscCall(MatSetType(P, MATAIJ));
1499566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(P, nzp, NULL));
1509566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(P, nzp, NULL, nzp, NULL));
1519566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(P, &rstart, &rend));
15248a46eb9SPierre Jolivet for (i = 0; i < nzp; i++) PetscCall(PetscRandomGetValue(rdm, &a[i]));
153c20d7725SJed Brown for (i = rstart; i < rend; i++) {
154c20d7725SJed Brown for (j = 0; j < nzp; j++) {
1559566063dSJacob Faibussowitsch PetscCall(PetscRandomGetValue(rdm, &rval));
156c20d7725SJed Brown idxn[j] = (PetscInt)(PetscRealPart(rval) * PN);
157c20d7725SJed Brown }
1589566063dSJacob Faibussowitsch PetscCall(MatSetValues(P, 1, &i, nzp, idxn, a, ADD_VALUES));
159c20d7725SJed Brown }
1609566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY));
1619566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY));
162c20d7725SJed Brown
1639566063dSJacob Faibussowitsch PetscCall(MatTranspose(P, MAT_INITIAL_MATRIX, &R));
1649566063dSJacob Faibussowitsch PetscCall(MatConvert(P, mattype, MAT_INPLACE_MATRIX, &P));
1659566063dSJacob Faibussowitsch PetscCall(MatConvert(R, mattype, MAT_INPLACE_MATRIX, &R));
1669566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(P));
1679566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(R));
168c20d7725SJed Brown
169c20d7725SJed Brown /* 2) MatTransposeMatMult() */
170c20d7725SJed Brown /* ------------------------ */
171c20d7725SJed Brown if (Test_MatTrMat) {
172c20d7725SJed Brown /* (2.1) Test developer driver C = P^T*B */
1739566063dSJacob Faibussowitsch PetscCall(MatProductCreate(P, B, NULL, &C));
1749566063dSJacob Faibussowitsch PetscCall(MatSetOptionsPrefix(C, "AtB_"));
1759566063dSJacob Faibussowitsch PetscCall(MatProductSetType(C, MATPRODUCT_AtB));
1769566063dSJacob Faibussowitsch PetscCall(MatProductSetAlgorithm(C, MATPRODUCTALGORITHMDEFAULT));
177fb842aefSJose E. Roman PetscCall(MatProductSetFill(C, PETSC_DETERMINE));
1789566063dSJacob Faibussowitsch PetscCall(MatProductSetFromOptions(C));
1799566063dSJacob Faibussowitsch PetscCall(MatHasOperation(C, MATOP_PRODUCTSYMBOLIC, &flg));
180263f2b91SStefano Zampini if (flg) { /* run tests if supported */
1819566063dSJacob Faibussowitsch PetscCall(MatProductSymbolic(C)); /* equivalent to MatSetUp() */
1829566063dSJacob Faibussowitsch PetscCall(MatSetOption(C, MAT_USE_INODES, PETSC_FALSE)); /* illustrate how to call MatSetOption() */
1839566063dSJacob Faibussowitsch PetscCall(MatProductNumeric(C));
1849566063dSJacob Faibussowitsch PetscCall(MatProductNumeric(C)); /* test reuse symbolic C */
18567b3012eSStefano Zampini
1869566063dSJacob Faibussowitsch PetscCall(MatTransposeMatMultEqual(P, B, C, mcheck, &flg));
18728b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error: developer driver C = P^T*B");
1889566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
189c20d7725SJed Brown
190c20d7725SJed Brown /* (2.2) Test user driver C = P^T*B */
191fb842aefSJose E. Roman PetscCall(MatTransposeMatMult(P, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &C));
192fb842aefSJose E. Roman PetscCall(MatTransposeMatMult(P, B, MAT_REUSE_MATRIX, PETSC_DETERMINE, &C));
1939566063dSJacob Faibussowitsch PetscCall(MatGetInfo(C, MAT_GLOBAL_SUM, &info));
1949566063dSJacob Faibussowitsch PetscCall(MatProductClear(C));
195c20d7725SJed Brown
196c20d7725SJed Brown /* Compare P^T*B and R*B */
197fb842aefSJose E. Roman PetscCall(MatMatMult(R, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &C1));
1989566063dSJacob Faibussowitsch PetscCall(MatNormDifference(C, C1, &norm));
19908401ef6SPierre Jolivet PetscCheck(norm <= PETSC_SMALL, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatTransposeMatMult(): %g", (double)norm);
2009566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C1));
201c20d7725SJed Brown
202c20d7725SJed Brown /* Test MatDuplicate() of C=P^T*B */
2039566063dSJacob Faibussowitsch PetscCall(MatDuplicate(C, MAT_COPY_VALUES, &C1));
2049566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C1));
205263f2b91SStefano Zampini } else {
2069566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "MatTransposeMatMult not supported\n"));
207263f2b91SStefano Zampini }
2089566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
209c20d7725SJed Brown }
210c20d7725SJed Brown
21167b3012eSStefano Zampini /* 3) MatMatTransposeMult() */
212c20d7725SJed Brown /* ------------------------ */
213c20d7725SJed Brown if (Test_MatMatTr) {
214c20d7725SJed Brown /* C = B*R^T */
2159566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompare((PetscObject)B, MATSEQAIJ, &seqaij));
21620b3374bSStefano Zampini if (seqaij) {
217fb842aefSJose E. Roman PetscCall(MatMatTransposeMult(B, R, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &C));
2189566063dSJacob Faibussowitsch PetscCall(MatSetOptionsPrefix(C, "ABt_")); /* enable '-ABt_' for matrix C */
2199566063dSJacob Faibussowitsch PetscCall(MatGetInfo(C, MAT_GLOBAL_SUM, &info));
220c20d7725SJed Brown
221c20d7725SJed Brown /* Test MAT_REUSE_MATRIX - reuse symbolic C */
222fb842aefSJose E. Roman PetscCall(MatMatTransposeMult(B, R, MAT_REUSE_MATRIX, PETSC_DETERMINE, &C));
223c20d7725SJed Brown
224c20d7725SJed Brown /* Check */
225fb842aefSJose E. Roman PetscCall(MatMatMult(B, P, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &C1));
2269566063dSJacob Faibussowitsch PetscCall(MatNormDifference(C, C1, &norm));
22708401ef6SPierre Jolivet PetscCheck(norm <= PETSC_SMALL, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatMatTransposeMult() %g", (double)norm);
2289566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C1));
2299566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
230c20d7725SJed Brown }
231c20d7725SJed Brown }
232c20d7725SJed Brown
233c20d7725SJed Brown /* 4) Test MatPtAP() */
234c20d7725SJed Brown /*-------------------*/
235c20d7725SJed Brown if (Test_MatPtAP) {
2369566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A_save, MAT_COPY_VALUES, &A));
237c20d7725SJed Brown
238c20d7725SJed Brown /* (4.1) Test developer API */
2399566063dSJacob Faibussowitsch PetscCall(MatProductCreate(A, P, NULL, &C));
2409566063dSJacob Faibussowitsch PetscCall(MatSetOptionsPrefix(C, "PtAP_"));
2419566063dSJacob Faibussowitsch PetscCall(MatProductSetType(C, MATPRODUCT_PtAP));
2429566063dSJacob Faibussowitsch PetscCall(MatProductSetAlgorithm(C, MATPRODUCTALGORITHMDEFAULT));
243fb842aefSJose E. Roman PetscCall(MatProductSetFill(C, PETSC_DETERMINE));
2449566063dSJacob Faibussowitsch PetscCall(MatProductSetFromOptions(C));
2459566063dSJacob Faibussowitsch PetscCall(MatProductSymbolic(C));
2469566063dSJacob Faibussowitsch PetscCall(MatProductNumeric(C));
2479566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A, P, C, mcheck, &flg));
24828b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatProduct_PtAP");
2499566063dSJacob Faibussowitsch PetscCall(MatProductNumeric(C)); /* reuse symbolic C */
250c20d7725SJed Brown
2519566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A, P, C, mcheck, &flg));
252*206664d9SJunchao Zhang PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatProduct_PtAP with reused symbolic");
2539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
254c20d7725SJed Brown
255c20d7725SJed Brown /* (4.2) Test user driver */
256fb842aefSJose E. Roman PetscCall(MatPtAP(A, P, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &C));
257*206664d9SJunchao Zhang PetscCall(MatPtAPMultEqual(A, P, C, mcheck, &flg));
258*206664d9SJunchao Zhang PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatPtAP with MAT_INITIAL_MATRIX");
259c20d7725SJed Brown
260c20d7725SJed Brown /* Test MAT_REUSE_MATRIX - reuse symbolic C */
261c20d7725SJed Brown alpha = 1.0;
262c20d7725SJed Brown for (i = 0; i < 2; i++) {
263c20d7725SJed Brown alpha -= 0.1;
2649566063dSJacob Faibussowitsch PetscCall(MatScale(A, alpha));
265fb842aefSJose E. Roman PetscCall(MatPtAP(A, P, MAT_REUSE_MATRIX, PETSC_DETERMINE, &C));
266c20d7725SJed Brown }
2679566063dSJacob Faibussowitsch PetscCall(MatPtAPMultEqual(A, P, C, mcheck, &flg));
268*206664d9SJunchao Zhang PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatPtAP with MAT_REUSE_MATRIX");
269c20d7725SJed Brown
270c20d7725SJed Brown /* 5) Test MatRARt() */
271c20d7725SJed Brown /* ----------------- */
272c20d7725SJed Brown if (Test_MatRARt) {
273c20d7725SJed Brown Mat RARt;
27467b3012eSStefano Zampini
27567b3012eSStefano Zampini /* (5.1) Test developer driver RARt = R*A*Rt */
2769566063dSJacob Faibussowitsch PetscCall(MatProductCreate(A, R, NULL, &RARt));
2779566063dSJacob Faibussowitsch PetscCall(MatSetOptionsPrefix(RARt, "RARt_"));
2789566063dSJacob Faibussowitsch PetscCall(MatProductSetType(RARt, MATPRODUCT_RARt));
2799566063dSJacob Faibussowitsch PetscCall(MatProductSetAlgorithm(RARt, MATPRODUCTALGORITHMDEFAULT));
280fb842aefSJose E. Roman PetscCall(MatProductSetFill(RARt, PETSC_DETERMINE));
2819566063dSJacob Faibussowitsch PetscCall(MatProductSetFromOptions(RARt));
2829566063dSJacob Faibussowitsch PetscCall(MatHasOperation(RARt, MATOP_PRODUCTSYMBOLIC, &flg));
283263f2b91SStefano Zampini if (flg) {
2849566063dSJacob Faibussowitsch PetscCall(MatProductSymbolic(RARt)); /* equivalent to MatSetUp() */
2859566063dSJacob Faibussowitsch PetscCall(MatSetOption(RARt, MAT_USE_INODES, PETSC_FALSE)); /* illustrate how to call MatSetOption() */
2869566063dSJacob Faibussowitsch PetscCall(MatProductNumeric(RARt));
2879566063dSJacob Faibussowitsch PetscCall(MatProductNumeric(RARt)); /* test reuse symbolic RARt */
2889566063dSJacob Faibussowitsch PetscCall(MatDestroy(&RARt));
28967b3012eSStefano Zampini
29067b3012eSStefano Zampini /* (2.2) Test user driver RARt = R*A*Rt */
2919566063dSJacob Faibussowitsch PetscCall(MatRARt(A, R, MAT_INITIAL_MATRIX, 2.0, &RARt));
2929566063dSJacob Faibussowitsch PetscCall(MatRARt(A, R, MAT_REUSE_MATRIX, 2.0, &RARt));
29367b3012eSStefano Zampini
2949566063dSJacob Faibussowitsch PetscCall(MatNormDifference(C, RARt, &norm));
29508401ef6SPierre Jolivet PetscCheck(norm <= PETSC_SMALL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "|PtAP - RARt| = %g", (double)norm);
296263f2b91SStefano Zampini } else {
2979566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "MatRARt not supported\n"));
298263f2b91SStefano Zampini }
2999566063dSJacob Faibussowitsch PetscCall(MatDestroy(&RARt));
300c20d7725SJed Brown }
301c20d7725SJed Brown
3029566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A));
3039566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
304c20d7725SJed Brown }
305c20d7725SJed Brown
306c20d7725SJed Brown /* Destroy objects */
3079566063dSJacob Faibussowitsch PetscCall(PetscRandomDestroy(&rdm));
308f1e99121SPierre Jolivet PetscCall(PetscFree2(idxn, a));
309c20d7725SJed Brown
3109566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A_save));
3119566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B));
3129566063dSJacob Faibussowitsch PetscCall(MatDestroy(&P));
3139566063dSJacob Faibussowitsch PetscCall(MatDestroy(&R));
314c20d7725SJed Brown
3159566063dSJacob Faibussowitsch PetscCall(PetscFinalize());
316b122ec5aSJacob Faibussowitsch return 0;
317c20d7725SJed Brown }
318c20d7725SJed Brown
319c20d7725SJed Brown /*TEST
320c20d7725SJed Brown test:
321c20d7725SJed Brown suffix: 1
322dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
323c20d7725SJed Brown args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
3243886731fSPierre Jolivet output_file: output/empty.out
325c20d7725SJed Brown
326c20d7725SJed Brown test:
327c20d7725SJed Brown suffix: 2_ab_scalable
328dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
3293e662e0bSHong Zhang 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
3303886731fSPierre Jolivet output_file: output/empty.out
331c20d7725SJed Brown
332c20d7725SJed Brown test:
333c20d7725SJed Brown suffix: 3_ab_scalable_fast
334dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
3353e662e0bSHong Zhang args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm scalable_fast -matmatmult_via scalable_fast -matmattransmult_via color
3363886731fSPierre Jolivet output_file: output/empty.out
337c20d7725SJed Brown
338c20d7725SJed Brown test:
339c20d7725SJed Brown suffix: 4_ab_heap
340dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
3413e662e0bSHong Zhang 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
3423886731fSPierre Jolivet output_file: output/empty.out
343c20d7725SJed Brown
344c20d7725SJed Brown test:
345c20d7725SJed Brown suffix: 5_ab_btheap
346dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
3473e662e0bSHong Zhang args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm btheap -matmatmult_via btheap -matrart_via r*art
3483886731fSPierre Jolivet output_file: output/empty.out
349c20d7725SJed Brown
350c20d7725SJed Brown test:
351c20d7725SJed Brown suffix: 6_ab_llcondensed
352dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
3533e662e0bSHong Zhang args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm llcondensed -matmatmult_via llcondensed -matrart_via coloring_rart
3543886731fSPierre Jolivet output_file: output/empty.out
355c20d7725SJed Brown
356c20d7725SJed Brown test:
357c20d7725SJed Brown suffix: 7_ab_rowmerge
358dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
3593e662e0bSHong Zhang args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_mat_product_algorithm rowmerge -matmatmult_via rowmerge
3603886731fSPierre Jolivet output_file: output/empty.out
361c20d7725SJed Brown
362c20d7725SJed Brown test:
363c20d7725SJed Brown suffix: 8_ab_hypre
364dfd57a17SPierre Jolivet requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
3653e662e0bSHong Zhang 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
3663886731fSPierre Jolivet output_file: output/empty.out
367c20d7725SJed Brown
368c20d7725SJed Brown test:
369263f2b91SStefano Zampini suffix: hypre_medium
370263f2b91SStefano Zampini nsize: {{1 3}}
371263f2b91SStefano Zampini requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
372263f2b91SStefano Zampini args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -A_mat_type hypre -B_mat_type hypre -test_rart 0
373263f2b91SStefano Zampini output_file: output/ex62_hypre.out
374263f2b91SStefano Zampini
375263f2b91SStefano Zampini test:
376263f2b91SStefano Zampini suffix: hypre_tiny
377263f2b91SStefano Zampini nsize: {{1 3}}
378263f2b91SStefano Zampini requires: hypre !complex double !defined(PETSC_USE_64BIT_INDICES)
379263f2b91SStefano Zampini 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
380263f2b91SStefano Zampini output_file: output/ex62_hypre.out
381263f2b91SStefano Zampini
382263f2b91SStefano Zampini test:
383cec0a6c6SStefano Zampini suffix: 9_mkl
38415df37b9SStefano Zampini TODO: broken MatScale?
385b88df2e7SBarry Smith requires: mkl_sparse datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
386cec0a6c6SStefano Zampini args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -A_mat_type aijmkl -B_mat_type aijmkl
3873886731fSPierre Jolivet output_file: output/empty.out
388cec0a6c6SStefano Zampini
389cec0a6c6SStefano Zampini test:
390c20d7725SJed Brown suffix: 10
391dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
392c20d7725SJed Brown nsize: 3
393c20d7725SJed Brown args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
3943886731fSPierre Jolivet output_file: output/empty.out
395c20d7725SJed Brown
396c20d7725SJed Brown test:
3973cea4f0aSStefano Zampini suffix: 10_backend
398dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
3993cea4f0aSStefano Zampini nsize: 3
4003e662e0bSHong Zhang 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
4013886731fSPierre Jolivet output_file: output/empty.out
4023cea4f0aSStefano Zampini
4033cea4f0aSStefano Zampini test:
404c20d7725SJed Brown suffix: 11_ab_scalable
405dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
406c20d7725SJed Brown nsize: 3
4073e662e0bSHong Zhang 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
4083886731fSPierre Jolivet output_file: output/empty.out
409c20d7725SJed Brown
410c20d7725SJed Brown test:
411c20d7725SJed Brown suffix: 12_ab_seqmpi
412dfd57a17SPierre Jolivet requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
413c20d7725SJed Brown nsize: 3
4143e662e0bSHong Zhang 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
4153886731fSPierre Jolivet output_file: output/empty.out
416c20d7725SJed Brown
417c20d7725SJed Brown test:
418c20d7725SJed Brown suffix: 13_ab_hypre
419dfd57a17SPierre Jolivet requires: hypre datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
420c20d7725SJed Brown nsize: 3
4213e662e0bSHong Zhang 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
4223886731fSPierre Jolivet output_file: output/empty.out
423c20d7725SJed Brown
42420b3374bSStefano Zampini test:
42520b3374bSStefano Zampini suffix: 14_seqaij
426dfd57a17SPierre Jolivet requires: !complex double !defined(PETSC_USE_64BIT_INDICES)
42720b3374bSStefano Zampini args: -fA ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system -fB ${wPETSC_DIR}/share/petsc/datafiles/matrices/tiny_system
4283886731fSPierre Jolivet output_file: output/empty.out
42920b3374bSStefano Zampini
43020b3374bSStefano Zampini test:
43120b3374bSStefano Zampini suffix: 14_seqaijcusparse
432dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
4331a2c6b5cSJunchao Zhang 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
4343886731fSPierre Jolivet output_file: output/empty.out
43520b3374bSStefano Zampini
43620b3374bSStefano Zampini test:
43765e4b4d4SStefano Zampini suffix: 14_seqaijcusparse_cpu
438dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
4393e662e0bSHong Zhang 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
4403886731fSPierre Jolivet output_file: output/empty.out
44165e4b4d4SStefano Zampini
44265e4b4d4SStefano Zampini test:
4435cb69cabSStefano Zampini suffix: 14_mpiaijcusparse_seq
4445cb69cabSStefano Zampini nsize: 1
445dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
4461a2c6b5cSJunchao Zhang 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
4473886731fSPierre Jolivet output_file: output/empty.out
4485cb69cabSStefano Zampini
4495cb69cabSStefano Zampini test:
45065e4b4d4SStefano Zampini suffix: 14_mpiaijcusparse_seq_cpu
45165e4b4d4SStefano Zampini nsize: 1
452dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
4534005f4d6SPierre Jolivet 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 -test_rart 0
4543886731fSPierre Jolivet output_file: output/empty.out
45565e4b4d4SStefano Zampini
45665e4b4d4SStefano Zampini test:
4575cb69cabSStefano Zampini suffix: 14_mpiaijcusparse
4585cb69cabSStefano Zampini nsize: 3
459dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
4601a2c6b5cSJunchao Zhang 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
4613886731fSPierre Jolivet output_file: output/empty.out
4625cb69cabSStefano Zampini
4635cb69cabSStefano Zampini test:
46465e4b4d4SStefano Zampini suffix: 14_mpiaijcusparse_cpu
46565e4b4d4SStefano Zampini nsize: 3
466dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES)
4674005f4d6SPierre Jolivet 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 -test_rart 0
4683886731fSPierre Jolivet output_file: output/empty.out
46965e4b4d4SStefano Zampini
47065e4b4d4SStefano Zampini test:
471076ba34aSJunchao Zhang nsize: {{1 3}}
472076ba34aSJunchao Zhang suffix: 14_aijkokkos
473dcfd994dSJunchao Zhang requires: kokkos_kernels !complex double !defined(PETSC_USE_64BIT_INDICES)
47420b3374bSStefano Zampini 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
4753886731fSPierre Jolivet output_file: output/empty.out
47620b3374bSStefano Zampini
4775cb69cabSStefano Zampini # these tests use matrices with many zero rows
47820b3374bSStefano Zampini test:
47920b3374bSStefano Zampini suffix: 15_seqaijcusparse
480dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
4811a2c6b5cSJunchao Zhang args: -A_mat_type aijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
4823886731fSPierre Jolivet output_file: output/empty.out
4835cb69cabSStefano Zampini
4845cb69cabSStefano Zampini test:
4855cb69cabSStefano Zampini suffix: 15_mpiaijcusparse_seq
4865cb69cabSStefano Zampini nsize: 1
487dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
4881a2c6b5cSJunchao Zhang args: -A_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
4893886731fSPierre Jolivet output_file: output/empty.out
4905cb69cabSStefano Zampini
4915cb69cabSStefano Zampini test:
4925cb69cabSStefano Zampini nsize: 3
4935cb69cabSStefano Zampini suffix: 15_mpiaijcusparse
494dfd57a17SPierre Jolivet requires: cuda !complex double !defined(PETSC_USE_64BIT_INDICES) datafilespath
4951a2c6b5cSJunchao Zhang args: -A_mat_type mpiaijcusparse -mat_form_explicit_transpose -fA ${DATAFILESPATH}/matrices/matmatmult/A4.BGriffith
4963886731fSPierre Jolivet output_file: output/empty.out
4975cb69cabSStefano Zampini
498c20d7725SJed Brown TEST*/
499