xref: /petsc/src/mat/tests/ex70.c (revision 3faff0630ddb0e5c928de8ab5c63f2cda2d2edd1)
16280154eSStefano Zampini #include <petscmat.h>
26280154eSStefano Zampini 
375ab9b9fSStefano Zampini static char help[] = "Tests MatMat operations with MAT_REUSE_MATRIX and already allocated dense result.\n\n";
475ab9b9fSStefano Zampini 
575ab9b9fSStefano Zampini static PetscScalar MAGIC_NUMBER = 12345;
66280154eSStefano Zampini 
79371c9d4SSatish Balay static PetscErrorCode CheckLocal(Mat A, Mat B, PetscScalar *a, PetscScalar *b) {
86280154eSStefano Zampini   PetscBool wA = PETSC_FALSE, wB = PETSC_FALSE;
975ab9b9fSStefano Zampini   PetscBool wAv = PETSC_FALSE, wBv = PETSC_FALSE;
1075ab9b9fSStefano Zampini   PetscInt  lda, i, j, m, n;
116280154eSStefano Zampini 
126280154eSStefano Zampini   PetscFunctionBegin;
136280154eSStefano Zampini   if (a) {
146280154eSStefano Zampini     const PetscScalar *Aa;
159566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &Aa));
166280154eSStefano Zampini     wA = (PetscBool)(a != Aa);
179566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(A, &lda));
189566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(A, &m, &n));
1975ab9b9fSStefano Zampini     for (j = 0; j < n; j++) {
2075ab9b9fSStefano Zampini       for (i = m; i < lda; i++) {
2175ab9b9fSStefano Zampini         if (Aa[j * lda + i] != MAGIC_NUMBER) wAv = PETSC_TRUE;
2275ab9b9fSStefano Zampini       }
2375ab9b9fSStefano Zampini     }
249566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &Aa));
256280154eSStefano Zampini   }
266280154eSStefano Zampini   if (b) {
276280154eSStefano Zampini     const PetscScalar *Bb;
289566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &Bb));
296280154eSStefano Zampini     wB = (PetscBool)(b != Bb);
309566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(B, &lda));
319566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(B, &m, &n));
3275ab9b9fSStefano Zampini     for (j = 0; j < n; j++) {
3375ab9b9fSStefano Zampini       for (i = m; i < lda; i++) {
3475ab9b9fSStefano Zampini         if (Bb[j * lda + i] != MAGIC_NUMBER) wBv = PETSC_TRUE;
3575ab9b9fSStefano Zampini       }
3675ab9b9fSStefano Zampini     }
379566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &Bb));
386280154eSStefano Zampini   }
3908401ef6SPierre Jolivet   PetscCheck(!wA && !wB, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Wrong array in first Mat? %d, Wrong array in second Mat? %d", wA, wB);
4008401ef6SPierre Jolivet   PetscCheck(!wAv && !wBv, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Wrong data in first Mat? %d, Wrong data in second Mat? %d", wAv, wBv);
4175ab9b9fSStefano Zampini   PetscFunctionReturn(0);
4275ab9b9fSStefano Zampini }
4375ab9b9fSStefano Zampini 
4475ab9b9fSStefano Zampini typedef struct {
4575ab9b9fSStefano Zampini   Mat A;
4675ab9b9fSStefano Zampini   Mat P;
4775ab9b9fSStefano Zampini   Mat R;
4875ab9b9fSStefano Zampini } proj_data;
4975ab9b9fSStefano Zampini 
509371c9d4SSatish Balay PetscErrorCode proj_destroy(void *ctx) {
5175ab9b9fSStefano Zampini   proj_data *userdata = (proj_data *)ctx;
5275ab9b9fSStefano Zampini 
5375ab9b9fSStefano Zampini   PetscFunctionBegin;
5428b400f6SJacob Faibussowitsch   PetscCheck(userdata, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing userdata");
559566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->A));
569566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->P));
579566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->R));
589566063dSJacob Faibussowitsch   PetscCall(PetscFree(userdata));
5975ab9b9fSStefano Zampini   PetscFunctionReturn(0);
6075ab9b9fSStefano Zampini }
6175ab9b9fSStefano Zampini 
629371c9d4SSatish Balay PetscErrorCode proj_mult(Mat S, Vec X, Vec Y) {
6375ab9b9fSStefano Zampini   Mat        A, R, P;
6475ab9b9fSStefano Zampini   Vec        Ax, Ay;
6575ab9b9fSStefano Zampini   Vec        Px, Py;
6675ab9b9fSStefano Zampini   proj_data *userdata;
6775ab9b9fSStefano Zampini 
6875ab9b9fSStefano Zampini   PetscFunctionBegin;
699566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S, &userdata));
7028b400f6SJacob Faibussowitsch   PetscCheck(userdata, PetscObjectComm((PetscObject)S), PETSC_ERR_PLIB, "Missing userdata");
7175ab9b9fSStefano Zampini   A = userdata->A;
7275ab9b9fSStefano Zampini   R = userdata->R;
7375ab9b9fSStefano Zampini   P = userdata->P;
7428b400f6SJacob Faibussowitsch   PetscCheck(A, PetscObjectComm((PetscObject)S), PETSC_ERR_PLIB, "Missing matrix");
75e00437b9SBarry Smith   PetscCheck(R || P, PetscObjectComm((PetscObject)S), PETSC_ERR_PLIB, "Missing projectors");
76e00437b9SBarry Smith   PetscCheck(!R || !P, PetscObjectComm((PetscObject)S), PETSC_ERR_PLIB, "Both projectors");
779566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(A, &Ax, &Ay));
7875ab9b9fSStefano Zampini   if (R) {
799566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(R, &Py, &Px));
8075ab9b9fSStefano Zampini   } else {
819566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(P, &Px, &Py));
8275ab9b9fSStefano Zampini   }
839566063dSJacob Faibussowitsch   PetscCall(VecCopy(X, Px));
8475ab9b9fSStefano Zampini   if (P) {
859566063dSJacob Faibussowitsch     PetscCall(MatMult(P, Px, Py));
8675ab9b9fSStefano Zampini   } else {
879566063dSJacob Faibussowitsch     PetscCall(MatMultTranspose(R, Px, Py));
8875ab9b9fSStefano Zampini   }
899566063dSJacob Faibussowitsch   PetscCall(VecCopy(Py, Ax));
909566063dSJacob Faibussowitsch   PetscCall(MatMult(A, Ax, Ay));
919566063dSJacob Faibussowitsch   PetscCall(VecCopy(Ay, Py));
9275ab9b9fSStefano Zampini   if (P) {
939566063dSJacob Faibussowitsch     PetscCall(MatMultTranspose(P, Py, Px));
9475ab9b9fSStefano Zampini   } else {
959566063dSJacob Faibussowitsch     PetscCall(MatMult(R, Py, Px));
9675ab9b9fSStefano Zampini   }
979566063dSJacob Faibussowitsch   PetscCall(VecCopy(Px, Y));
989566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Px));
999566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Py));
1009566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Ax));
1019566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Ay));
10275ab9b9fSStefano Zampini   PetscFunctionReturn(0);
10375ab9b9fSStefano Zampini }
10475ab9b9fSStefano Zampini 
1059371c9d4SSatish Balay PetscErrorCode MyPtShellPMultSymbolic(Mat S, Mat P, Mat PtAP, void **ctx) {
10675ab9b9fSStefano Zampini   proj_data *userdata;
10775ab9b9fSStefano Zampini 
10875ab9b9fSStefano Zampini   PetscFunctionBegin;
1099566063dSJacob Faibussowitsch   PetscCall(PetscNew(&userdata));
1109566063dSJacob Faibussowitsch   PetscCall(MatShellSetContext(PtAP, userdata));
11175ab9b9fSStefano Zampini   *ctx = (void *)userdata;
11275ab9b9fSStefano Zampini   PetscFunctionReturn(0);
11375ab9b9fSStefano Zampini }
11475ab9b9fSStefano Zampini 
1159371c9d4SSatish Balay PetscErrorCode MyPtShellPMultNumeric(Mat S, Mat P, Mat PtAP, void *ctx) {
11675ab9b9fSStefano Zampini   Mat        A;
11775ab9b9fSStefano Zampini   proj_data *userdata = (proj_data *)ctx;
11875ab9b9fSStefano Zampini 
11975ab9b9fSStefano Zampini   PetscFunctionBegin;
1209566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S, &A));
1219566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)A));
1229566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)P));
1239566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->A));
1249566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->P));
1259566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->R));
12675ab9b9fSStefano Zampini   userdata->A = A;
12775ab9b9fSStefano Zampini   userdata->P = P;
1289566063dSJacob Faibussowitsch   PetscCall(MatShellSetOperation(PtAP, MATOP_MULT, (void (*)(void))proj_mult));
1299566063dSJacob Faibussowitsch   PetscCall(MatSetUp(PtAP));
1309566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(PtAP, MAT_FINAL_ASSEMBLY));
1319566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(PtAP, MAT_FINAL_ASSEMBLY));
13275ab9b9fSStefano Zampini   PetscFunctionReturn(0);
13375ab9b9fSStefano Zampini }
13475ab9b9fSStefano Zampini 
1359371c9d4SSatish Balay PetscErrorCode MyRShellRtMultSymbolic(Mat S, Mat R, Mat RARt, void **ctx) {
13675ab9b9fSStefano Zampini   proj_data *userdata;
13775ab9b9fSStefano Zampini 
13875ab9b9fSStefano Zampini   PetscFunctionBegin;
1399566063dSJacob Faibussowitsch   PetscCall(PetscNew(&userdata));
1409566063dSJacob Faibussowitsch   PetscCall(MatShellSetContext(RARt, userdata));
14175ab9b9fSStefano Zampini   *ctx = (void *)userdata;
14275ab9b9fSStefano Zampini   PetscFunctionReturn(0);
14375ab9b9fSStefano Zampini }
14475ab9b9fSStefano Zampini 
1459371c9d4SSatish Balay PetscErrorCode MyRShellRtMultNumeric(Mat S, Mat R, Mat RARt, void *ctx) {
14675ab9b9fSStefano Zampini   Mat        A;
14775ab9b9fSStefano Zampini   proj_data *userdata = (proj_data *)ctx;
14875ab9b9fSStefano Zampini 
14975ab9b9fSStefano Zampini   PetscFunctionBegin;
1509566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S, &A));
1519566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)A));
1529566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)R));
1539566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->A));
1549566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->P));
1559566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->R));
15675ab9b9fSStefano Zampini   userdata->A = A;
15775ab9b9fSStefano Zampini   userdata->R = R;
1589566063dSJacob Faibussowitsch   PetscCall(MatShellSetOperation(RARt, MATOP_MULT, (void (*)(void))proj_mult));
1599566063dSJacob Faibussowitsch   PetscCall(MatSetUp(RARt));
1609566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(RARt, MAT_FINAL_ASSEMBLY));
1619566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(RARt, MAT_FINAL_ASSEMBLY));
16275ab9b9fSStefano Zampini   PetscFunctionReturn(0);
16375ab9b9fSStefano Zampini }
16475ab9b9fSStefano Zampini 
1659371c9d4SSatish Balay PetscErrorCode MyMatShellMatMultNumeric(Mat S, Mat B, Mat C, void *ctx) {
16675ab9b9fSStefano Zampini   Mat A;
16775ab9b9fSStefano Zampini 
16875ab9b9fSStefano Zampini   PetscFunctionBegin;
1699566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S, &A));
1709566063dSJacob Faibussowitsch   PetscCall(MatMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &C));
17175ab9b9fSStefano Zampini   PetscFunctionReturn(0);
17275ab9b9fSStefano Zampini }
17375ab9b9fSStefano Zampini 
1749371c9d4SSatish Balay PetscErrorCode MyMatTransposeShellMatMultNumeric(Mat S, Mat B, Mat C, void *ctx) {
17575ab9b9fSStefano Zampini   Mat A;
17675ab9b9fSStefano Zampini 
17775ab9b9fSStefano Zampini   PetscFunctionBegin;
1789566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S, &A));
1799566063dSJacob Faibussowitsch   PetscCall(MatTransposeMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &C));
18075ab9b9fSStefano Zampini   PetscFunctionReturn(0);
18175ab9b9fSStefano Zampini }
18275ab9b9fSStefano Zampini 
1839371c9d4SSatish Balay PetscErrorCode MyMatShellMatTransposeMultNumeric(Mat S, Mat B, Mat C, void *ctx) {
18475ab9b9fSStefano Zampini   Mat A;
18575ab9b9fSStefano Zampini 
18675ab9b9fSStefano Zampini   PetscFunctionBegin;
1879566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S, &A));
1889566063dSJacob Faibussowitsch   PetscCall(MatMatTransposeMult(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &C));
1896280154eSStefano Zampini   PetscFunctionReturn(0);
1906280154eSStefano Zampini }
1916280154eSStefano Zampini 
1929371c9d4SSatish Balay int main(int argc, char **args) {
19375ab9b9fSStefano Zampini   Mat          X, B, A, Bt, T, T2, PtAP = NULL, RARt = NULL, R = NULL;
19475ab9b9fSStefano Zampini   Vec          r, l, rs, ls;
19575ab9b9fSStefano Zampini   PetscInt     m, n, k, M = 10, N = 10, K = 5, ldx = 3, ldb = 5, ldr = 4;
1966280154eSStefano Zampini   const char  *deft = MATAIJ;
1976280154eSStefano Zampini   char         mattype[256];
1986280154eSStefano Zampini   PetscBool    flg, symm = PETSC_FALSE, testtt = PETSC_TRUE, testnest = PETSC_TRUE, testtranspose = PETSC_TRUE, testcircular = PETSC_FALSE, local = PETSC_TRUE;
199013e2dc7SBarry Smith   PetscBool    testhtranspose = PETSC_FALSE; /* Hermitian transpose is not handled correctly and generates an error */
20075ab9b9fSStefano Zampini   PetscBool    xgpu = PETSC_FALSE, bgpu = PETSC_FALSE, testshellops = PETSC_FALSE, testproj = PETSC_TRUE, testrart = PETSC_TRUE, testmatmatt = PETSC_TRUE, testmattmat = PETSC_TRUE;
20175ab9b9fSStefano Zampini   PetscScalar *dataX = NULL, *dataB = NULL, *dataR = NULL, *dataBt = NULL;
20275ab9b9fSStefano Zampini   PetscScalar *aX, *aB, *aBt;
203456288a8SStefano Zampini   PetscReal    err;
2046280154eSStefano Zampini 
205327415f7SBarry Smith   PetscFunctionBeginUser;
2069566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &args, NULL, help));
2079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-N", &N, NULL));
2089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-M", &M, NULL));
2099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-K", &K, NULL));
2109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-symm", &symm, NULL));
2119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-local", &local, NULL));
2129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-ldx", &ldx, NULL));
2139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-ldb", &ldb, NULL));
2149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-ldr", &ldr, NULL));
2159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testtranspose", &testtranspose, NULL));
2169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testnest", &testnest, NULL));
2179566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testtt", &testtt, NULL));
2189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testcircular", &testcircular, NULL));
2199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testshellops", &testshellops, NULL));
2209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testproj", &testproj, NULL));
2219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testrart", &testrart, NULL));
2229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testmatmatt", &testmatmatt, NULL));
2239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-testmattmat", &testmattmat, NULL));
2249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-xgpu", &xgpu, NULL));
2259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-bgpu", &bgpu, NULL));
2269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(NULL, NULL, "-magic_number", &MAGIC_NUMBER, NULL));
22775ab9b9fSStefano Zampini   if (M != N) testproj = PETSC_FALSE;
22875ab9b9fSStefano Zampini 
2299566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
2309566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, M, N));
2319566063dSJacob Faibussowitsch   PetscCall(MatSetType(A, MATAIJ));
2329566063dSJacob Faibussowitsch   PetscCall(MatSetUp(A));
2339566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(A, NULL));
2346280154eSStefano Zampini   if (M == N && symm) {
2356280154eSStefano Zampini     Mat AT;
2366280154eSStefano Zampini 
2379566063dSJacob Faibussowitsch     PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &AT));
2389566063dSJacob Faibussowitsch     PetscCall(MatAXPY(A, 1.0, AT, DIFFERENT_NONZERO_PATTERN));
2399566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&AT));
2409566063dSJacob Faibussowitsch     PetscCall(MatSetOption(A, MAT_SYMMETRIC, PETSC_TRUE));
2416280154eSStefano Zampini   }
2429566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(A, NULL, "-A_init_view"));
243d0609cedSBarry Smith   PetscOptionsBegin(PETSC_COMM_WORLD, "", "", "");
2449566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-A_mat_type", "Matrix type", "MatSetType", MatList, deft, mattype, 256, &flg));
245d0609cedSBarry Smith   PetscOptionsEnd();
2466280154eSStefano Zampini   if (flg) {
2476280154eSStefano Zampini     Mat A2;
2486280154eSStefano Zampini 
2499566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
2509566063dSJacob Faibussowitsch     PetscCall(MatConvert(A, mattype, MAT_INPLACE_MATRIX, &A));
2519566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(A, A2, 10, &flg));
2526280154eSStefano Zampini     if (!flg) {
2536280154eSStefano Zampini       Mat AE, A2E;
2546280154eSStefano Zampini 
2559566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with convert\n"));
2569566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(A, MATDENSE, &AE));
2579566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(A2, MATDENSE, &A2E));
2589566063dSJacob Faibussowitsch       PetscCall(MatView(AE, NULL));
2599566063dSJacob Faibussowitsch       PetscCall(MatView(A2E, NULL));
2609566063dSJacob Faibussowitsch       PetscCall(MatAXPY(A2E, -1.0, A, SAME_NONZERO_PATTERN));
2619566063dSJacob Faibussowitsch       PetscCall(MatView(A2E, NULL));
2629566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&A2E));
2639566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&AE));
2646280154eSStefano Zampini     }
2659566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A2));
2666280154eSStefano Zampini   }
2679566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(A, NULL, "-A_view"));
2686280154eSStefano Zampini 
2699566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(A, &m, &n));
2706280154eSStefano Zampini   if (local) {
27175ab9b9fSStefano Zampini     PetscInt i;
27275ab9b9fSStefano Zampini 
2739566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((m + ldx) * K, &dataX));
2749566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((n + ldb) * K, &dataB));
275a0638e9dSStefano Zampini     for (i = 0; i < (m + ldx) * K; i++) dataX[i] = MAGIC_NUMBER;
276a0638e9dSStefano Zampini     for (i = 0; i < (n + ldb) * K; i++) dataB[i] = MAGIC_NUMBER;
2776280154eSStefano Zampini   }
2789566063dSJacob Faibussowitsch   PetscCall(MatCreateDense(PETSC_COMM_WORLD, n, PETSC_DECIDE, N, K, dataB, &B));
2799566063dSJacob Faibussowitsch   PetscCall(MatCreateDense(PETSC_COMM_WORLD, m, PETSC_DECIDE, M, K, dataX, &X));
28075ab9b9fSStefano Zampini   if (local) {
2819566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(X, m + ldx));
2829566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(B, n + ldb));
28375ab9b9fSStefano Zampini   }
2849566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(B, NULL, &k));
28575ab9b9fSStefano Zampini   if (local) {
28675ab9b9fSStefano Zampini     PetscInt i;
28775ab9b9fSStefano Zampini 
2889566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((k + ldr) * N, &dataBt));
289a0638e9dSStefano Zampini     for (i = 0; i < (k + ldr) * N; i++) dataBt[i] = MAGIC_NUMBER;
29075ab9b9fSStefano Zampini   }
2919566063dSJacob Faibussowitsch   PetscCall(MatCreateDense(PETSC_COMM_WORLD, k, n, K, N, dataBt, &Bt));
2921baa6e33SBarry Smith   if (local) PetscCall(MatDenseSetLDA(Bt, k + ldr));
2936280154eSStefano Zampini 
2946280154eSStefano Zampini   /* store pointer to dense data for testing */
2959566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, (const PetscScalar **)&dataB));
2969566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X, (const PetscScalar **)&dataX));
2979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(Bt, (const PetscScalar **)&dataBt));
2986280154eSStefano Zampini   aX  = dataX;
2996280154eSStefano Zampini   aB  = dataB;
30075ab9b9fSStefano Zampini   aBt = dataBt;
3019566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(Bt, (const PetscScalar **)&dataBt));
3029566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, (const PetscScalar **)&dataB));
3039566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, (const PetscScalar **)&dataX));
3046280154eSStefano Zampini   if (local) {
3056280154eSStefano Zampini     dataX  = aX;
3066280154eSStefano Zampini     dataB  = aB;
30775ab9b9fSStefano Zampini     dataBt = aBt;
3086280154eSStefano Zampini   }
30975ab9b9fSStefano Zampini 
3109566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(X, NULL));
3119566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(B, NULL));
3129566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(Bt, NULL));
3139566063dSJacob Faibussowitsch   PetscCall(CheckLocal(X, NULL, aX, NULL));
3149566063dSJacob Faibussowitsch   PetscCall(CheckLocal(Bt, B, aBt, aB));
31575ab9b9fSStefano Zampini 
316456288a8SStefano Zampini   /* convert to CUDA if needed */
317456288a8SStefano Zampini   if (bgpu) {
3189566063dSJacob Faibussowitsch     PetscCall(MatConvert(B, MATDENSECUDA, MAT_INPLACE_MATRIX, &B));
3199566063dSJacob Faibussowitsch     PetscCall(MatConvert(Bt, MATDENSECUDA, MAT_INPLACE_MATRIX, &Bt));
320456288a8SStefano Zampini   }
32148a46eb9SPierre Jolivet   if (xgpu) PetscCall(MatConvert(X, MATDENSECUDA, MAT_INPLACE_MATRIX, &X));
3229566063dSJacob Faibussowitsch   PetscCall(CheckLocal(B, X, aB, aX));
3236280154eSStefano Zampini 
324e7b38fdfSStefano Zampini   /* Test MatDenseGetSubMatrix */
325e7b38fdfSStefano Zampini   {
326e7b38fdfSStefano Zampini     Mat B2, T3, T4;
327e7b38fdfSStefano Zampini 
3289566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
3299566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &T4));
3309566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(T4, NULL));
3319566063dSJacob Faibussowitsch     PetscCall(MatAXPY(B2, 1.0, T4, SAME_NONZERO_PATTERN));
332a2748737SPierre Jolivet     PetscCall(MatDenseGetSubMatrix(B, PETSC_DECIDE, PETSC_DECIDE, PetscMin(1, K - 1), PetscMin(2, K), &T));
333a2748737SPierre Jolivet     PetscCall(MatDenseGetSubMatrix(T4, PETSC_DECIDE, PETSC_DECIDE, PetscMin(1, K - 1), PetscMin(2, K), &T2));
334a2748737SPierre Jolivet     PetscCall(MatDenseGetSubMatrix(B2, PETSC_DECIDE, PETSC_DECIDE, PetscMin(1, K - 1), PetscMin(2, K), &T3));
3359566063dSJacob Faibussowitsch     PetscCall(MatAXPY(T, 1.0, T2, SAME_NONZERO_PATTERN));
3369566063dSJacob Faibussowitsch     PetscCall(MatAXPY(T3, -1.0, T, SAME_NONZERO_PATTERN));
3379566063dSJacob Faibussowitsch     PetscCall(MatNorm(T3, NORM_FROBENIUS, &err));
338e7b38fdfSStefano Zampini     if (err > PETSC_SMALL) {
3399566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with MatDenseGetSubMatrix\n"));
3409566063dSJacob Faibussowitsch       PetscCall(MatView(T3, NULL));
341e7b38fdfSStefano Zampini     }
3429566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreSubMatrix(B, &T));
3439566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreSubMatrix(T4, &T2));
3449566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreSubMatrix(B2, &T3));
3459566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, NULL, aB, NULL));
3469566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B2));
3479566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&T4));
348a2748737SPierre Jolivet     if (N >= 2) {
349a2748737SPierre Jolivet       PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
350a2748737SPierre Jolivet       PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &T4));
351a2748737SPierre Jolivet       PetscCall(MatSetRandom(T4, NULL));
352a2748737SPierre Jolivet       PetscCall(MatAXPY(B2, 1.0, T4, SAME_NONZERO_PATTERN));
353a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(B, N - 2, PETSC_DECIDE, PetscMin(1, K - 1), PetscMin(2, K), &T));
354a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(T4, N - 2, PETSC_DECIDE, PetscMin(1, K - 1), PetscMin(2, K), &T2));
355a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(B2, N - 2, PETSC_DECIDE, PetscMin(1, K - 1), PetscMin(2, K), &T3));
356a2748737SPierre Jolivet       PetscCall(MatAXPY(T, 1.0, T2, SAME_NONZERO_PATTERN));
357a2748737SPierre Jolivet       PetscCall(MatAXPY(T3, -1.0, T, SAME_NONZERO_PATTERN));
358a2748737SPierre Jolivet       PetscCall(MatNorm(T3, NORM_FROBENIUS, &err));
359a2748737SPierre Jolivet       if (err > PETSC_SMALL) {
360a2748737SPierre Jolivet         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with MatDenseGetSubMatrix\n"));
361a2748737SPierre Jolivet         PetscCall(MatView(T3, NULL));
362a2748737SPierre Jolivet       }
363a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(B, &T));
364a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(T4, &T2));
365a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(B2, &T3));
366a2748737SPierre Jolivet       PetscCall(CheckLocal(B, NULL, aB, NULL));
367a2748737SPierre Jolivet       PetscCall(MatDestroy(&B2));
368a2748737SPierre Jolivet       PetscCall(MatDestroy(&T4));
369a2748737SPierre Jolivet       PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
370a2748737SPierre Jolivet       PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &T4));
371a2748737SPierre Jolivet       PetscCall(MatSetRandom(T4, NULL));
372a2748737SPierre Jolivet       PetscCall(MatAXPY(B2, 1.0, T4, SAME_NONZERO_PATTERN));
373a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(B, PETSC_DECIDE, 2, PetscMin(1, K - 1), PetscMin(2, K), &T));
374a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(T4, PETSC_DECIDE, 2, PetscMin(1, K - 1), PetscMin(2, K), &T2));
375a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(B2, PETSC_DECIDE, 2, PetscMin(1, K - 1), PetscMin(2, K), &T3));
376a2748737SPierre Jolivet       PetscCall(MatAXPY(T, 1.0, T2, SAME_NONZERO_PATTERN));
377a2748737SPierre Jolivet       PetscCall(MatAXPY(T3, -1.0, T, SAME_NONZERO_PATTERN));
378a2748737SPierre Jolivet       PetscCall(MatNorm(T3, NORM_FROBENIUS, &err));
379a2748737SPierre Jolivet       if (err > PETSC_SMALL) {
380a2748737SPierre Jolivet         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with MatDenseGetSubMatrix\n"));
381a2748737SPierre Jolivet         PetscCall(MatView(T3, NULL));
382a2748737SPierre Jolivet       }
383a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(B, &T));
384a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(T4, &T2));
385a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(B2, &T3));
386a2748737SPierre Jolivet       PetscCall(CheckLocal(B, NULL, aB, NULL));
387a2748737SPierre Jolivet       PetscCall(MatDestroy(&B2));
388a2748737SPierre Jolivet       PetscCall(MatDestroy(&T4));
389a2748737SPierre Jolivet     }
390e7b38fdfSStefano Zampini   }
391e7b38fdfSStefano Zampini 
3926280154eSStefano Zampini   /* Test reusing a previously allocated dense buffer */
3939566063dSJacob Faibussowitsch   PetscCall(MatMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &X));
3949566063dSJacob Faibussowitsch   PetscCall(CheckLocal(B, X, aB, aX));
3959566063dSJacob Faibussowitsch   PetscCall(MatMatMultEqual(A, B, X, 10, &flg));
3966280154eSStefano Zampini   if (!flg) {
3979566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with reusage\n"));
3989566063dSJacob Faibussowitsch     PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
3999566063dSJacob Faibussowitsch     PetscCall(MatAXPY(T, -1.0, X, SAME_NONZERO_PATTERN));
4009566063dSJacob Faibussowitsch     PetscCall(MatView(T, NULL));
4019566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&T));
4026280154eSStefano Zampini   }
4036280154eSStefano Zampini 
40475ab9b9fSStefano Zampini   /* Test MatTransposeMat and MatMatTranspose */
40575ab9b9fSStefano Zampini   if (testmattmat) {
4069566063dSJacob Faibussowitsch     PetscCall(MatTransposeMatMult(A, X, MAT_REUSE_MATRIX, PETSC_DEFAULT, &B));
4079566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, X, aB, aX));
4089566063dSJacob Faibussowitsch     PetscCall(MatTransposeMatMultEqual(A, X, B, 10, &flg));
40975ab9b9fSStefano Zampini     if (!flg) {
4109566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with reusage (MatTransposeMat)\n"));
4119566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(A, X, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &B));
4129566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, B, SAME_NONZERO_PATTERN));
4139566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
4149566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
41575ab9b9fSStefano Zampini     }
41675ab9b9fSStefano Zampini   }
41775ab9b9fSStefano Zampini   if (testmatmatt) {
4189566063dSJacob Faibussowitsch     PetscCall(MatMatTransposeMult(A, Bt, MAT_REUSE_MATRIX, PETSC_DEFAULT, &X));
4199566063dSJacob Faibussowitsch     PetscCall(CheckLocal(Bt, X, aBt, aX));
4209566063dSJacob Faibussowitsch     PetscCall(MatMatTransposeMultEqual(A, Bt, X, 10, &flg));
42175ab9b9fSStefano Zampini     if (!flg) {
4229566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with reusage (MatMatTranspose)\n"));
4239566063dSJacob Faibussowitsch       PetscCall(MatMatTransposeMult(A, Bt, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
4249566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, X, SAME_NONZERO_PATTERN));
4259566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
4269566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
42775ab9b9fSStefano Zampini     }
42875ab9b9fSStefano Zampini   }
42975ab9b9fSStefano Zampini 
43075ab9b9fSStefano Zampini   /* Test projection operations (PtAP and RARt) */
43175ab9b9fSStefano Zampini   if (testproj) {
4329566063dSJacob Faibussowitsch     PetscCall(MatPtAP(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &PtAP));
4339566063dSJacob Faibussowitsch     PetscCall(MatPtAPMultEqual(A, B, PtAP, 10, &flg));
43475ab9b9fSStefano Zampini     if (!flg) {
4359566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with PtAP\n"));
4369566063dSJacob Faibussowitsch       PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
4379566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(B, T, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T2));
4389566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T2, -1.0, PtAP, SAME_NONZERO_PATTERN));
4399566063dSJacob Faibussowitsch       PetscCall(MatView(T2, NULL));
4409566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T2));
4419566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
44275ab9b9fSStefano Zampini     }
4439566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((k + ldr) * M, &dataR));
4449566063dSJacob Faibussowitsch     PetscCall(MatCreateDense(PETSC_COMM_WORLD, PETSC_DECIDE, m, K, M, dataR, &R));
4459566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(R, k + ldr));
4469566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(R, NULL));
44775ab9b9fSStefano Zampini     if (testrart) { /* fails for AIJCUSPARSE because RA operation is not defined */
4489566063dSJacob Faibussowitsch       PetscCall(MatRARt(A, R, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &RARt));
4499566063dSJacob Faibussowitsch       PetscCall(MatRARtMultEqual(A, R, RARt, 10, &flg));
45075ab9b9fSStefano Zampini       if (!flg) {
4519566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with RARt\n"));
4529566063dSJacob Faibussowitsch         PetscCall(MatMatTransposeMult(A, R, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
4539566063dSJacob Faibussowitsch         PetscCall(MatMatMult(R, T, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T2));
4549566063dSJacob Faibussowitsch         PetscCall(MatAXPY(T2, -1.0, RARt, SAME_NONZERO_PATTERN));
4559566063dSJacob Faibussowitsch         PetscCall(MatView(T2, NULL));
4569566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&T2));
4579566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&T));
45875ab9b9fSStefano Zampini       }
45975ab9b9fSStefano Zampini     }
46075ab9b9fSStefano Zampini   }
46175ab9b9fSStefano Zampini 
462456288a8SStefano Zampini   /* Test MatDenseGetColumnVec and friends */
4639566063dSJacob Faibussowitsch   PetscCall(MatMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &X));
4649566063dSJacob Faibussowitsch   PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
4659566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(T, MAT_DO_NOT_COPY_VALUES, &T2));
466456288a8SStefano Zampini   for (k = 0; k < K; k++) {
467456288a8SStefano Zampini     Vec Xv, Tv, T2v;
468456288a8SStefano Zampini 
4699566063dSJacob Faibussowitsch     PetscCall(MatDenseGetColumnVecRead(X, k, &Xv));
4709566063dSJacob Faibussowitsch     PetscCall(MatDenseGetColumnVec(T, k, &Tv));
4719566063dSJacob Faibussowitsch     PetscCall(MatDenseGetColumnVecWrite(T2, k, &T2v));
4729566063dSJacob Faibussowitsch     PetscCall(VecCopy(Xv, T2v));
4739566063dSJacob Faibussowitsch     PetscCall(VecAXPY(Tv, -1., Xv));
4749566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreColumnVecRead(X, k, &Xv));
4759566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreColumnVec(T, k, &Tv));
4769566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreColumnVecWrite(T2, k, &T2v));
477456288a8SStefano Zampini   }
4789566063dSJacob Faibussowitsch   PetscCall(MatNorm(T, NORM_FROBENIUS, &err));
479456288a8SStefano Zampini   if (err > PETSC_SMALL) {
4809566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with MatDenseGetColumnVec\n"));
4819566063dSJacob Faibussowitsch     PetscCall(MatView(T, NULL));
482456288a8SStefano Zampini   }
4839566063dSJacob Faibussowitsch   PetscCall(MatAXPY(T2, -1., X, SAME_NONZERO_PATTERN));
4849566063dSJacob Faibussowitsch   PetscCall(MatNorm(T2, NORM_FROBENIUS, &err));
485456288a8SStefano Zampini   if (err > PETSC_SMALL) {
4869566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with MatDenseGetColumnVecWrite\n"));
4879566063dSJacob Faibussowitsch     PetscCall(MatView(T2, NULL));
488456288a8SStefano Zampini   }
4899566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T));
4909566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T2));
491456288a8SStefano Zampini 
492456288a8SStefano Zampini   /* Test with MatShell */
4939566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &T));
4949566063dSJacob Faibussowitsch   PetscCall(MatConvert(T, MATSHELL, MAT_INITIAL_MATRIX, &T2));
4959566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T));
49675ab9b9fSStefano Zampini 
49775ab9b9fSStefano Zampini   /* scale matrix */
4989566063dSJacob Faibussowitsch   PetscCall(MatScale(A, 2.0));
4999566063dSJacob Faibussowitsch   PetscCall(MatScale(T2, 2.0));
5009566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(A, &r, &l));
5019566063dSJacob Faibussowitsch   PetscCall(VecSetRandom(r, NULL));
5029566063dSJacob Faibussowitsch   PetscCall(VecSetRandom(l, NULL));
5039566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(T2, &rs, &ls));
5049566063dSJacob Faibussowitsch   PetscCall(VecCopy(r, rs));
5059566063dSJacob Faibussowitsch   PetscCall(VecCopy(l, ls));
50675ab9b9fSStefano Zampini   if (testproj) {
5079566063dSJacob Faibussowitsch     PetscCall(MatDiagonalScale(A, r, r));
5089566063dSJacob Faibussowitsch     PetscCall(MatDiagonalScale(T2, rs, rs));
50975ab9b9fSStefano Zampini   } else {
5109566063dSJacob Faibussowitsch     PetscCall(MatDiagonalScale(A, l, r));
5119566063dSJacob Faibussowitsch     PetscCall(MatDiagonalScale(T2, ls, rs));
51275ab9b9fSStefano Zampini   }
5139566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &T));
5149566063dSJacob Faibussowitsch   PetscCall(MatAXPY(A, 4.5, T, SAME_NONZERO_PATTERN));
5159566063dSJacob Faibussowitsch   PetscCall(MatAXPY(T2, 4.5, T, DIFFERENT_NONZERO_PATTERN));
5169566063dSJacob Faibussowitsch   PetscCall(MatMultEqual(T2, A, 10, &flg));
51748a46eb9SPierre Jolivet   if (!flg) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with MATSHELL (MatMult)\n"));
5189566063dSJacob Faibussowitsch   PetscCall(MatMultTransposeEqual(T2, A, 10, &flg));
51948a46eb9SPierre Jolivet   if (!flg) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with MATSHELL (MatMultTranspose)\n"));
5209566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T));
5219566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ls));
5229566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&rs));
5239566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l));
5249566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&r));
52575ab9b9fSStefano Zampini 
52675ab9b9fSStefano Zampini   /* recompute projections, test reusage */
5279566063dSJacob Faibussowitsch   if (PtAP) PetscCall(MatPtAP(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &PtAP));
5289566063dSJacob Faibussowitsch   if (RARt) PetscCall(MatRARt(A, R, MAT_REUSE_MATRIX, PETSC_DEFAULT, &RARt));
52975ab9b9fSStefano Zampini   if (testshellops) { /* test callbacks for user defined MatProducts */
5309566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_AB, NULL, MyMatShellMatMultNumeric, NULL, MATDENSE, MATDENSE));
5319566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_AB, NULL, MyMatShellMatMultNumeric, NULL, MATDENSECUDA, MATDENSECUDA));
5329566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_AtB, NULL, MyMatTransposeShellMatMultNumeric, NULL, MATDENSE, MATDENSE));
5339566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_AtB, NULL, MyMatTransposeShellMatMultNumeric, NULL, MATDENSECUDA, MATDENSECUDA));
5349566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_ABt, NULL, MyMatShellMatTransposeMultNumeric, NULL, MATDENSE, MATDENSE));
5359566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_ABt, NULL, MyMatShellMatTransposeMultNumeric, NULL, MATDENSECUDA, MATDENSECUDA));
53675ab9b9fSStefano Zampini     if (testproj) {
5379566063dSJacob Faibussowitsch       PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_PtAP, MyPtShellPMultSymbolic, MyPtShellPMultNumeric, proj_destroy, MATDENSE, MATSHELL));
5389566063dSJacob Faibussowitsch       PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_PtAP, MyPtShellPMultSymbolic, MyPtShellPMultNumeric, proj_destroy, MATDENSECUDA, MATSHELL));
5399566063dSJacob Faibussowitsch       PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_RARt, MyRShellRtMultSymbolic, MyRShellRtMultNumeric, proj_destroy, MATDENSE, MATSHELL));
5409566063dSJacob Faibussowitsch       PetscCall(MatShellSetMatProductOperation(T2, MATPRODUCT_RARt, MyRShellRtMultSymbolic, MyRShellRtMultNumeric, proj_destroy, MATDENSECUDA, MATSHELL));
54175ab9b9fSStefano Zampini     }
54275ab9b9fSStefano Zampini   }
5439566063dSJacob Faibussowitsch   PetscCall(CheckLocal(B, X, aB, aX));
54475ab9b9fSStefano Zampini   /* we either use the shell operations or the loop over columns code, applying the operator */
5459566063dSJacob Faibussowitsch   PetscCall(MatMatMult(T2, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &X));
5469566063dSJacob Faibussowitsch   PetscCall(CheckLocal(B, X, aB, aX));
5479566063dSJacob Faibussowitsch   PetscCall(MatMatMultEqual(T2, B, X, 10, &flg));
548456288a8SStefano Zampini   if (!flg) {
5499566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with reusage (MATSHELL)\n"));
5509566063dSJacob Faibussowitsch     PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
5519566063dSJacob Faibussowitsch     PetscCall(MatAXPY(T, -1.0, X, SAME_NONZERO_PATTERN));
5529566063dSJacob Faibussowitsch     PetscCall(MatView(T, NULL));
5539566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&T));
554456288a8SStefano Zampini   }
55575ab9b9fSStefano Zampini   if (testproj) {
5569566063dSJacob Faibussowitsch     PetscCall(MatPtAPMultEqual(T2, B, PtAP, 10, &flg));
55748a46eb9SPierre Jolivet     if (!flg) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with PtAP (MATSHELL)\n"));
55875ab9b9fSStefano Zampini     if (testshellops) { /* projections fail if the product operations are not specified */
5599566063dSJacob Faibussowitsch       PetscCall(MatPtAP(T2, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
5609566063dSJacob Faibussowitsch       PetscCall(MatPtAP(T2, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &T));
5619566063dSJacob Faibussowitsch       PetscCall(MatPtAPMultEqual(T2, B, T, 10, &flg));
56275ab9b9fSStefano Zampini       if (!flg) {
56375ab9b9fSStefano Zampini         Mat TE;
5646718818eSStefano Zampini 
5659566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with PtAP (MATSHELL user defined)\n"));
5669566063dSJacob Faibussowitsch         PetscCall(MatComputeOperator(T, MATDENSE, &TE));
5679566063dSJacob Faibussowitsch         PetscCall(MatView(TE, NULL));
5689566063dSJacob Faibussowitsch         PetscCall(MatView(PtAP, NULL));
5699566063dSJacob Faibussowitsch         PetscCall(MatAXPY(TE, -1.0, PtAP, SAME_NONZERO_PATTERN));
5709566063dSJacob Faibussowitsch         PetscCall(MatView(TE, NULL));
5719566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&TE));
57275ab9b9fSStefano Zampini       }
5739566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
57475ab9b9fSStefano Zampini     }
57575ab9b9fSStefano Zampini     if (RARt) {
5769566063dSJacob Faibussowitsch       PetscCall(MatRARtMultEqual(T2, R, RARt, 10, &flg));
57748a46eb9SPierre Jolivet       if (!flg) PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with RARt (MATSHELL)\n"));
57875ab9b9fSStefano Zampini     }
57975ab9b9fSStefano Zampini     if (testshellops) {
5809566063dSJacob Faibussowitsch       PetscCall(MatRARt(T2, R, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
5819566063dSJacob Faibussowitsch       PetscCall(MatRARt(T2, R, MAT_REUSE_MATRIX, PETSC_DEFAULT, &T));
5829566063dSJacob Faibussowitsch       PetscCall(MatRARtMultEqual(T2, R, T, 10, &flg));
58375ab9b9fSStefano Zampini       if (!flg) {
58475ab9b9fSStefano Zampini         Mat TE;
58575ab9b9fSStefano Zampini 
5869566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with RARt (MATSHELL user defined)\n"));
5879566063dSJacob Faibussowitsch         PetscCall(MatComputeOperator(T, MATDENSE, &TE));
5889566063dSJacob Faibussowitsch         PetscCall(MatView(TE, NULL));
58975ab9b9fSStefano Zampini         if (RARt) {
5909566063dSJacob Faibussowitsch           PetscCall(MatView(RARt, NULL));
5919566063dSJacob Faibussowitsch           PetscCall(MatAXPY(TE, -1.0, RARt, SAME_NONZERO_PATTERN));
5929566063dSJacob Faibussowitsch           PetscCall(MatView(TE, NULL));
59375ab9b9fSStefano Zampini         }
5949566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&TE));
59575ab9b9fSStefano Zampini       }
5969566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
59775ab9b9fSStefano Zampini     }
59875ab9b9fSStefano Zampini   }
59975ab9b9fSStefano Zampini 
60075ab9b9fSStefano Zampini   if (testmattmat) { /* we either use the shell operations or the loop over columns code applying the transposed operator */
6019566063dSJacob Faibussowitsch     PetscCall(MatTransposeMatMult(T2, X, MAT_REUSE_MATRIX, PETSC_DEFAULT, &B));
6029566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, X, aB, aX));
6039566063dSJacob Faibussowitsch     PetscCall(MatTransposeMatMultEqual(T2, X, B, 10, &flg));
604456288a8SStefano Zampini     if (!flg) {
6059566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with reusage (MatTranspose, MATSHELL)\n"));
6069566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(A, X, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
6079566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, B, SAME_NONZERO_PATTERN));
6089566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
6099566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6106718818eSStefano Zampini     }
611456288a8SStefano Zampini   }
61275ab9b9fSStefano Zampini   if (testmatmatt && testshellops) { /* only when shell operations are set */
6139566063dSJacob Faibussowitsch     PetscCall(MatMatTransposeMult(T2, Bt, MAT_REUSE_MATRIX, PETSC_DEFAULT, &X));
6149566063dSJacob Faibussowitsch     PetscCall(CheckLocal(Bt, X, aBt, aX));
6159566063dSJacob Faibussowitsch     PetscCall(MatMatTransposeMultEqual(T2, Bt, X, 10, &flg));
61675ab9b9fSStefano Zampini     if (!flg) {
6179566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with reusage (MatMatTranspose, MATSHELL)\n"));
6189566063dSJacob Faibussowitsch       PetscCall(MatMatTransposeMult(A, Bt, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
6199566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, X, SAME_NONZERO_PATTERN));
6209566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
6219566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
62275ab9b9fSStefano Zampini     }
62375ab9b9fSStefano Zampini   }
6249566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T2));
625456288a8SStefano Zampini 
6266280154eSStefano Zampini   if (testnest) { /* test with MatNest */
6276280154eSStefano Zampini     Mat NA;
6286280154eSStefano Zampini 
6299566063dSJacob Faibussowitsch     PetscCall(MatCreateNest(PETSC_COMM_WORLD, 1, NULL, 1, NULL, &A, &NA));
6309566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(NA, NULL, "-NA_view"));
6319566063dSJacob Faibussowitsch     PetscCall(MatMatMult(NA, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &X));
6329566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, X, aB, aX));
6339566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(NA, B, X, 10, &flg));
6346280154eSStefano Zampini     if (!flg) {
6359566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with Nest\n"));
6369566063dSJacob Faibussowitsch       PetscCall(MatMatMult(NA, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
6379566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, X, SAME_NONZERO_PATTERN));
6389566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
6399566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6406280154eSStefano Zampini     }
6419566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&NA));
6426280154eSStefano Zampini   }
6436280154eSStefano Zampini 
6446280154eSStefano Zampini   if (testtranspose) { /* test with Transpose */
6456280154eSStefano Zampini     Mat TA;
6466280154eSStefano Zampini 
6479566063dSJacob Faibussowitsch     PetscCall(MatCreateTranspose(A, &TA));
6489566063dSJacob Faibussowitsch     PetscCall(MatMatMult(TA, X, MAT_REUSE_MATRIX, PETSC_DEFAULT, &B));
6499566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, X, aB, aX));
6509566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(TA, X, B, 10, &flg));
6516280154eSStefano Zampini     if (!flg) {
6529566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with Transpose\n"));
6539566063dSJacob Faibussowitsch       PetscCall(MatMatMult(TA, X, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
6549566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, B, SAME_NONZERO_PATTERN));
6559566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
6569566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6576280154eSStefano Zampini     }
6589566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&TA));
6596280154eSStefano Zampini   }
6606280154eSStefano Zampini 
6613604c0aeSStefano Zampini   if (testhtranspose) { /* test with Hermitian Transpose */
6623604c0aeSStefano Zampini     Mat TA;
6633604c0aeSStefano Zampini 
6649566063dSJacob Faibussowitsch     PetscCall(MatCreateHermitianTranspose(A, &TA));
6659566063dSJacob Faibussowitsch     PetscCall(MatMatMult(TA, X, MAT_REUSE_MATRIX, PETSC_DEFAULT, &B));
6669566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, X, aB, aX));
6679566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(TA, X, B, 10, &flg));
6683604c0aeSStefano Zampini     if (!flg) {
6699566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with Transpose\n"));
6709566063dSJacob Faibussowitsch       PetscCall(MatMatMult(TA, X, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
6719566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, B, SAME_NONZERO_PATTERN));
6729566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
6739566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6743604c0aeSStefano Zampini     }
6759566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&TA));
6763604c0aeSStefano Zampini   }
6773604c0aeSStefano Zampini 
6786280154eSStefano Zampini   if (testtt) { /* test with Transpose(Transpose) */
6796280154eSStefano Zampini     Mat TA, TTA;
6806280154eSStefano Zampini 
6819566063dSJacob Faibussowitsch     PetscCall(MatCreateTranspose(A, &TA));
6829566063dSJacob Faibussowitsch     PetscCall(MatCreateTranspose(TA, &TTA));
6839566063dSJacob Faibussowitsch     PetscCall(MatMatMult(TTA, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &X));
6849566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, X, aB, aX));
6859566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(TTA, B, X, 10, &flg));
6866280154eSStefano Zampini     if (!flg) {
6879566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with Transpose(Transpose)\n"));
6889566063dSJacob Faibussowitsch       PetscCall(MatMatMult(TTA, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
6899566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, X, SAME_NONZERO_PATTERN));
6909566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
6919566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6926280154eSStefano Zampini     }
6939566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&TA));
6949566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&TTA));
6956280154eSStefano Zampini   }
6966280154eSStefano Zampini 
6976280154eSStefano Zampini   if (testcircular) { /* test circular */
6986280154eSStefano Zampini     Mat AB;
6996280154eSStefano Zampini 
7009566063dSJacob Faibussowitsch     PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &AB));
7019566063dSJacob Faibussowitsch     PetscCall(MatMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &X));
7029566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, X, aB, aX));
7036280154eSStefano Zampini     if (M == N && N == K) {
7049566063dSJacob Faibussowitsch       PetscCall(MatMatMult(A, X, MAT_REUSE_MATRIX, PETSC_DEFAULT, &B));
7056280154eSStefano Zampini     } else {
7069566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(A, X, MAT_REUSE_MATRIX, PETSC_DEFAULT, &B));
7076280154eSStefano Zampini     }
7089566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B, X, aB, aX));
7099566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&AB));
7106280154eSStefano Zampini   }
7112b723ba2SStefano Zampini 
7122b723ba2SStefano Zampini   /* Test by Pierre Jolivet */
7132b723ba2SStefano Zampini   {
7142b723ba2SStefano Zampini     Mat C, D, D2, AtA;
7159566063dSJacob Faibussowitsch     PetscCall(MatCreateNormal(A, &AtA));
7169566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(X, MAT_DO_NOT_COPY_VALUES, &C));
7179566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &D));
7189566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &D2));
7199566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(B, NULL));
7209566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(C, NULL));
7219566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(D, NULL));
7229566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(D2, NULL));
7239566063dSJacob Faibussowitsch     PetscCall(MatProductCreateWithMat(A, B, NULL, C));
7249566063dSJacob Faibussowitsch     PetscCall(MatProductSetType(C, MATPRODUCT_AB));
7259566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions(C));
7269566063dSJacob Faibussowitsch     PetscCall(MatProductSymbolic(C));
7279566063dSJacob Faibussowitsch     PetscCall(MatProductCreateWithMat(A, C, NULL, D));
7289566063dSJacob Faibussowitsch     PetscCall(MatProductSetType(D, MATPRODUCT_AtB));
7299566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions(D));
7309566063dSJacob Faibussowitsch     PetscCall(MatProductSymbolic(D));
7319566063dSJacob Faibussowitsch     PetscCall(MatProductNumeric(C));
732*3faff063SStefano Zampini     PetscCall(MatMatMultEqual(A, B, C, 10, &flg));
733*3faff063SStefano Zampini     if (!flg) {
734*3faff063SStefano Zampini       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with Normal (AB != C)\n"));
735*3faff063SStefano Zampini       PetscCall(MatView(A, NULL));
736*3faff063SStefano Zampini       PetscCall(MatView(B, NULL));
737*3faff063SStefano Zampini       PetscCall(MatView(C, NULL));
738*3faff063SStefano Zampini     }
7399566063dSJacob Faibussowitsch     PetscCall(MatProductNumeric(D));
7409566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(AtA, B, D, 10, &flg));
7412b723ba2SStefano Zampini     if (!flg) {
742*3faff063SStefano Zampini       PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error with Normal (2)\n"));
7439566063dSJacob Faibussowitsch       PetscCall(MatMatMult(AtA, C, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &T));
744*3faff063SStefano Zampini       PetscCall(MatView(D, NULL));
745*3faff063SStefano Zampini       PetscCall(MatView(T, NULL));
7469566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T, -1.0, D, SAME_NONZERO_PATTERN));
7479566063dSJacob Faibussowitsch       PetscCall(MatView(T, NULL));
7489566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
7492b723ba2SStefano Zampini     }
7509566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&C));
7519566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
7529566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D2));
7539566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&AtA));
7542b723ba2SStefano Zampini   }
7552b723ba2SStefano Zampini 
7569566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&X));
7579566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&Bt));
7589566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B));
7599566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A));
7609566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&R));
7619566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&PtAP));
7629566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&RARt));
7639566063dSJacob Faibussowitsch   PetscCall(PetscFree(dataX));
7649566063dSJacob Faibussowitsch   PetscCall(PetscFree(dataB));
7659566063dSJacob Faibussowitsch   PetscCall(PetscFree(dataR));
7669566063dSJacob Faibussowitsch   PetscCall(PetscFree(dataBt));
7679566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
768b122ec5aSJacob Faibussowitsch   return 0;
7696280154eSStefano Zampini }
7706280154eSStefano Zampini 
7716280154eSStefano Zampini /*TEST
7726280154eSStefano Zampini 
7736280154eSStefano Zampini   test:
7746280154eSStefano Zampini     suffix: 1
77575ab9b9fSStefano Zampini     args: -local {{0 1}} -testshellops
7766280154eSStefano Zampini 
7776280154eSStefano Zampini   test:
7786280154eSStefano Zampini     output_file: output/ex70_1.out
779456288a8SStefano Zampini     requires: cuda
780456288a8SStefano Zampini     suffix: 1_cuda
781686594dbSStefano Zampini     args: -local {{0 1}} -xgpu {{0 1}} -bgpu {{0 1}} -A_mat_type {{seqaijcusparse seqaij}} -testshellops {{0 1}}
782456288a8SStefano Zampini 
783456288a8SStefano Zampini   test:
784456288a8SStefano Zampini     output_file: output/ex70_1.out
7856280154eSStefano Zampini     nsize: 2
7866280154eSStefano Zampini     suffix: 1_par
78775ab9b9fSStefano Zampini     args: -local {{0 1}} -testmatmatt 0
7886280154eSStefano Zampini 
7896280154eSStefano Zampini   test:
790456288a8SStefano Zampini     output_file: output/ex70_1.out
791456288a8SStefano Zampini     requires: cuda
792456288a8SStefano Zampini     nsize: 2
793456288a8SStefano Zampini     suffix: 1_par_cuda
79475ab9b9fSStefano Zampini     args: -local {{0 1}} -xgpu {{0 1}} -bgpu {{0 1}} -A_mat_type {{mpiaijcusparse mpiaij}} -testnest 0 -testmatmatt 0 -matmatmult_Bbn 3
795456288a8SStefano Zampini 
796456288a8SStefano Zampini   test:
7976280154eSStefano Zampini     output_file: output/ex70_1.out
7986280154eSStefano Zampini     suffix: 2
7996280154eSStefano Zampini     nsize: 1
8006280154eSStefano Zampini     args: -M {{7 11}} -N {{12 9}} -K {{1 3}} -local {{0 1}}
8016280154eSStefano Zampini 
8028a311839SJunchao Zhang   testset:
803456288a8SStefano Zampini     requires: cuda
804456288a8SStefano Zampini     output_file: output/ex70_1.out
805456288a8SStefano Zampini     nsize: 1
806456288a8SStefano Zampini     args: -M 7 -N 9 -K 2 -local {{0 1}} -testnest 0 -A_mat_type {{seqdensecuda seqdense}} -xgpu {{0 1}} -bgpu {{0 1}}
8078a311839SJunchao Zhang     test:
8088a311839SJunchao Zhang       requires: !complex
8098a311839SJunchao Zhang       suffix: 2_cuda_real
8108a311839SJunchao Zhang     test:
8118a311839SJunchao Zhang       # complex+single gives a little bigger error in the MatDenseGetColumnVec test
8128a311839SJunchao Zhang       requires: complex !single
8138a311839SJunchao Zhang       suffix: 2_cuda_complex
814456288a8SStefano Zampini 
815456288a8SStefano Zampini   test:
8166280154eSStefano Zampini     output_file: output/ex70_1.out
8176280154eSStefano Zampini     suffix: 2_par
8186280154eSStefano Zampini     nsize: 2
81975ab9b9fSStefano Zampini     args: -M {{7 11}} -N {{12 9}} -K {{1 3}} -local {{0 1}} -testcircular -testmatmatt 0
8206280154eSStefano Zampini 
8216280154eSStefano Zampini   test:
822456288a8SStefano Zampini     requires: cuda
823456288a8SStefano Zampini     output_file: output/ex70_1.out
824456288a8SStefano Zampini     suffix: 2_par_cuda
825456288a8SStefano Zampini     nsize: 2
82675ab9b9fSStefano Zampini     args: -M 11 -N 9 -K 1 -local {{0 1}} -testcircular 0 -A_mat_type mpiaijcusparse -xgpu -bgpu -testnest 0 -testmatmatt 0
827456288a8SStefano Zampini 
828456288a8SStefano Zampini   test:
8296280154eSStefano Zampini     output_file: output/ex70_1.out
8306280154eSStefano Zampini     suffix: 3
831456288a8SStefano Zampini     nsize: {{1 3}}
83275ab9b9fSStefano Zampini     args: -M 13 -N 13 -K {{1 3}} -local {{0 1}} -A_mat_type sbaij -symm -testproj 0 -testmatmatt 0
8336280154eSStefano Zampini 
8346280154eSStefano Zampini   test:
8356280154eSStefano Zampini     output_file: output/ex70_1.out
8366280154eSStefano Zampini     suffix: 4
8376280154eSStefano Zampini     nsize: 1
8386280154eSStefano Zampini     args: -M 3 -N 3 -K 3 -local {{0 1}} -testcircular
8396280154eSStefano Zampini 
8406280154eSStefano Zampini   test:
8416280154eSStefano Zampini     output_file: output/ex70_1.out
8426280154eSStefano Zampini     suffix: 5
8436280154eSStefano Zampini     nsize: {{2 4}}
844a0638e9dSStefano Zampini     args: -M 3 -N 3 -K 3 -local {{0 1}} -testcircular -testmatmatt 0
8456280154eSStefano Zampini 
8466280154eSStefano Zampini   test:
8476280154eSStefano Zampini     output_file: output/ex70_1.out
8486280154eSStefano Zampini     suffix: 6
8496280154eSStefano Zampini     nsize: 1
85075ab9b9fSStefano Zampini     args: -M {{1 3}} -N {{2 5}} -K {{1 2}} -local {{0 1}} -testcircular
8516280154eSStefano Zampini 
8526280154eSStefano Zampini   test:
8536280154eSStefano Zampini     output_file: output/ex70_1.out
8546280154eSStefano Zampini     suffix: 7
8556280154eSStefano Zampini     nsize: 1
856456288a8SStefano Zampini     args: -M 13 -N 13 -K {{1 3}} -local {{0 1}} -A_mat_type dense -testnest -testcircular
8576718818eSStefano Zampini 
8586280154eSStefano Zampini TEST*/
859