xref: /petsc/src/mat/tests/ex70.c (revision 1baa6e3354bfe224b33a0c158f482508792a8a6e)
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 
76280154eSStefano Zampini static PetscErrorCode CheckLocal(Mat A, Mat B, PetscScalar *a, PetscScalar *b)
86280154eSStefano Zampini {
96280154eSStefano Zampini   PetscBool      wA = PETSC_FALSE, wB = PETSC_FALSE;
1075ab9b9fSStefano Zampini   PetscBool      wAv = PETSC_FALSE, wBv = PETSC_FALSE;
1175ab9b9fSStefano Zampini   PetscInt       lda,i,j,m,n;
126280154eSStefano Zampini 
136280154eSStefano Zampini   PetscFunctionBegin;
146280154eSStefano Zampini   if (a) {
156280154eSStefano Zampini     const PetscScalar *Aa;
169566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&Aa));
176280154eSStefano Zampini     wA   = (PetscBool)(a != Aa);
189566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(A,&lda));
199566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(A,&m,&n));
2075ab9b9fSStefano Zampini     for (j=0;j<n;j++) {
2175ab9b9fSStefano Zampini       for (i=m;i<lda;i++) {
2275ab9b9fSStefano Zampini         if (Aa[j*lda +i] != MAGIC_NUMBER) wAv = PETSC_TRUE;
2375ab9b9fSStefano Zampini       }
2475ab9b9fSStefano Zampini     }
259566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&Aa));
266280154eSStefano Zampini   }
276280154eSStefano Zampini   if (b) {
286280154eSStefano Zampini     const PetscScalar *Bb;
299566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B,&Bb));
306280154eSStefano Zampini     wB   = (PetscBool)(b != Bb);
319566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(B,&lda));
329566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(B,&m,&n));
3375ab9b9fSStefano Zampini     for (j=0;j<n;j++) {
3475ab9b9fSStefano Zampini       for (i=m;i<lda;i++) {
3575ab9b9fSStefano Zampini         if (Bb[j*lda +i] != MAGIC_NUMBER) wBv = PETSC_TRUE;
3675ab9b9fSStefano Zampini       }
3775ab9b9fSStefano Zampini     }
389566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B,&Bb));
396280154eSStefano Zampini   }
4008401ef6SPierre Jolivet   PetscCheck(!wA && !wB,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Wrong array in first Mat? %d, Wrong array in second Mat? %d",wA,wB);
4108401ef6SPierre Jolivet   PetscCheck(!wAv && !wBv,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Wrong data in first Mat? %d, Wrong data in second Mat? %d",wAv,wBv);
4275ab9b9fSStefano Zampini   PetscFunctionReturn(0);
4375ab9b9fSStefano Zampini }
4475ab9b9fSStefano Zampini 
4575ab9b9fSStefano Zampini typedef struct {
4675ab9b9fSStefano Zampini   Mat A;
4775ab9b9fSStefano Zampini   Mat P;
4875ab9b9fSStefano Zampini   Mat R;
4975ab9b9fSStefano Zampini } proj_data;
5075ab9b9fSStefano Zampini 
5175ab9b9fSStefano Zampini PetscErrorCode proj_destroy(void *ctx)
5275ab9b9fSStefano Zampini {
5375ab9b9fSStefano Zampini   proj_data      *userdata = (proj_data*)ctx;
5475ab9b9fSStefano Zampini 
5575ab9b9fSStefano Zampini   PetscFunctionBegin;
5628b400f6SJacob Faibussowitsch   PetscCheck(userdata,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing userdata");
579566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->A));
589566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->P));
599566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->R));
609566063dSJacob Faibussowitsch   PetscCall(PetscFree(userdata));
6175ab9b9fSStefano Zampini   PetscFunctionReturn(0);
6275ab9b9fSStefano Zampini }
6375ab9b9fSStefano Zampini 
6475ab9b9fSStefano Zampini PetscErrorCode proj_mult(Mat S, Vec X, Vec Y)
6575ab9b9fSStefano Zampini {
6675ab9b9fSStefano Zampini   Mat            A,R,P;
6775ab9b9fSStefano Zampini   Vec            Ax,Ay;
6875ab9b9fSStefano Zampini   Vec            Px,Py;
6975ab9b9fSStefano Zampini   proj_data      *userdata;
7075ab9b9fSStefano Zampini 
7175ab9b9fSStefano Zampini   PetscFunctionBegin;
729566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S,&userdata));
7328b400f6SJacob Faibussowitsch   PetscCheck(userdata,PetscObjectComm((PetscObject)S),PETSC_ERR_PLIB,"Missing userdata");
7475ab9b9fSStefano Zampini   A = userdata->A;
7575ab9b9fSStefano Zampini   R = userdata->R;
7675ab9b9fSStefano Zampini   P = userdata->P;
7728b400f6SJacob Faibussowitsch   PetscCheck(A,PetscObjectComm((PetscObject)S),PETSC_ERR_PLIB,"Missing matrix");
78e00437b9SBarry Smith   PetscCheck(R || P,PetscObjectComm((PetscObject)S),PETSC_ERR_PLIB,"Missing projectors");
79e00437b9SBarry Smith   PetscCheck(!R || !P,PetscObjectComm((PetscObject)S),PETSC_ERR_PLIB,"Both projectors");
809566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(A,&Ax,&Ay));
8175ab9b9fSStefano Zampini   if (R) {
829566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(R,&Py,&Px));
8375ab9b9fSStefano Zampini   } else {
849566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(P,&Px,&Py));
8575ab9b9fSStefano Zampini   }
869566063dSJacob Faibussowitsch   PetscCall(VecCopy(X,Px));
8775ab9b9fSStefano Zampini   if (P) {
889566063dSJacob Faibussowitsch     PetscCall(MatMult(P,Px,Py));
8975ab9b9fSStefano Zampini   } else {
909566063dSJacob Faibussowitsch     PetscCall(MatMultTranspose(R,Px,Py));
9175ab9b9fSStefano Zampini   }
929566063dSJacob Faibussowitsch   PetscCall(VecCopy(Py,Ax));
939566063dSJacob Faibussowitsch   PetscCall(MatMult(A,Ax,Ay));
949566063dSJacob Faibussowitsch   PetscCall(VecCopy(Ay,Py));
9575ab9b9fSStefano Zampini   if (P) {
969566063dSJacob Faibussowitsch     PetscCall(MatMultTranspose(P,Py,Px));
9775ab9b9fSStefano Zampini   } else {
989566063dSJacob Faibussowitsch     PetscCall(MatMult(R,Py,Px));
9975ab9b9fSStefano Zampini   }
1009566063dSJacob Faibussowitsch   PetscCall(VecCopy(Px,Y));
1019566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Px));
1029566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Py));
1039566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Ax));
1049566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Ay));
10575ab9b9fSStefano Zampini   PetscFunctionReturn(0);
10675ab9b9fSStefano Zampini }
10775ab9b9fSStefano Zampini 
10875ab9b9fSStefano Zampini PetscErrorCode MyPtShellPMultSymbolic(Mat S, Mat P, Mat PtAP, void** ctx)
10975ab9b9fSStefano Zampini {
11075ab9b9fSStefano Zampini   proj_data      *userdata;
11175ab9b9fSStefano Zampini 
11275ab9b9fSStefano Zampini   PetscFunctionBegin;
1139566063dSJacob Faibussowitsch   PetscCall(PetscNew(&userdata));
1149566063dSJacob Faibussowitsch   PetscCall(MatShellSetContext(PtAP,userdata));
11575ab9b9fSStefano Zampini   *ctx = (void *)userdata;
11675ab9b9fSStefano Zampini   PetscFunctionReturn(0);
11775ab9b9fSStefano Zampini }
11875ab9b9fSStefano Zampini 
11975ab9b9fSStefano Zampini PetscErrorCode MyPtShellPMultNumeric(Mat S, Mat P, Mat PtAP, void *ctx)
12075ab9b9fSStefano Zampini {
12175ab9b9fSStefano Zampini   Mat            A;
12275ab9b9fSStefano Zampini   proj_data      *userdata = (proj_data*)ctx;
12375ab9b9fSStefano Zampini 
12475ab9b9fSStefano Zampini   PetscFunctionBegin;
1259566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S,&A));
1269566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)A));
1279566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)P));
1289566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->A));
1299566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->P));
1309566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->R));
13175ab9b9fSStefano Zampini   userdata->A = A;
13275ab9b9fSStefano Zampini   userdata->P = P;
1339566063dSJacob Faibussowitsch   PetscCall(MatShellSetOperation(PtAP,MATOP_MULT,(void (*)(void))proj_mult));
1349566063dSJacob Faibussowitsch   PetscCall(MatSetUp(PtAP));
1359566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(PtAP,MAT_FINAL_ASSEMBLY));
1369566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(PtAP,MAT_FINAL_ASSEMBLY));
13775ab9b9fSStefano Zampini   PetscFunctionReturn(0);
13875ab9b9fSStefano Zampini }
13975ab9b9fSStefano Zampini 
14075ab9b9fSStefano Zampini PetscErrorCode MyRShellRtMultSymbolic(Mat S, Mat R, Mat RARt, void **ctx)
14175ab9b9fSStefano Zampini {
14275ab9b9fSStefano Zampini   proj_data      *userdata;
14375ab9b9fSStefano Zampini 
14475ab9b9fSStefano Zampini   PetscFunctionBegin;
1459566063dSJacob Faibussowitsch   PetscCall(PetscNew(&userdata));
1469566063dSJacob Faibussowitsch   PetscCall(MatShellSetContext(RARt,userdata));
14775ab9b9fSStefano Zampini   *ctx = (void *)userdata;
14875ab9b9fSStefano Zampini   PetscFunctionReturn(0);
14975ab9b9fSStefano Zampini }
15075ab9b9fSStefano Zampini 
15175ab9b9fSStefano Zampini PetscErrorCode MyRShellRtMultNumeric(Mat S, Mat R, Mat RARt, void *ctx)
15275ab9b9fSStefano Zampini {
15375ab9b9fSStefano Zampini   Mat            A;
15475ab9b9fSStefano Zampini   proj_data      *userdata = (proj_data*)ctx;
15575ab9b9fSStefano Zampini 
15675ab9b9fSStefano Zampini   PetscFunctionBegin;
1579566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S,&A));
1589566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)A));
1599566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)R));
1609566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->A));
1619566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->P));
1629566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&userdata->R));
16375ab9b9fSStefano Zampini   userdata->A = A;
16475ab9b9fSStefano Zampini   userdata->R = R;
1659566063dSJacob Faibussowitsch   PetscCall(MatShellSetOperation(RARt,MATOP_MULT,(void (*)(void))proj_mult));
1669566063dSJacob Faibussowitsch   PetscCall(MatSetUp(RARt));
1679566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(RARt,MAT_FINAL_ASSEMBLY));
1689566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(RARt,MAT_FINAL_ASSEMBLY));
16975ab9b9fSStefano Zampini   PetscFunctionReturn(0);
17075ab9b9fSStefano Zampini }
17175ab9b9fSStefano Zampini 
17275ab9b9fSStefano Zampini PetscErrorCode MyMatShellMatMultNumeric(Mat S, Mat B, Mat C, void *ctx)
17375ab9b9fSStefano Zampini {
17475ab9b9fSStefano Zampini   Mat            A;
17575ab9b9fSStefano Zampini 
17675ab9b9fSStefano Zampini   PetscFunctionBegin;
1779566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S,&A));
1789566063dSJacob Faibussowitsch   PetscCall(MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C));
17975ab9b9fSStefano Zampini   PetscFunctionReturn(0);
18075ab9b9fSStefano Zampini }
18175ab9b9fSStefano Zampini 
18275ab9b9fSStefano Zampini PetscErrorCode MyMatTransposeShellMatMultNumeric(Mat S, Mat B, Mat C, void *ctx)
18375ab9b9fSStefano Zampini {
18475ab9b9fSStefano Zampini   Mat            A;
18575ab9b9fSStefano Zampini 
18675ab9b9fSStefano Zampini   PetscFunctionBegin;
1879566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S,&A));
1889566063dSJacob Faibussowitsch   PetscCall(MatTransposeMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C));
18975ab9b9fSStefano Zampini   PetscFunctionReturn(0);
19075ab9b9fSStefano Zampini }
19175ab9b9fSStefano Zampini 
19275ab9b9fSStefano Zampini PetscErrorCode MyMatShellMatTransposeMultNumeric(Mat S, Mat B, Mat C, void *ctx)
19375ab9b9fSStefano Zampini {
19475ab9b9fSStefano Zampini   Mat            A;
19575ab9b9fSStefano Zampini 
19675ab9b9fSStefano Zampini   PetscFunctionBegin;
1979566063dSJacob Faibussowitsch   PetscCall(MatShellGetContext(S,&A));
1989566063dSJacob Faibussowitsch   PetscCall(MatMatTransposeMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C));
1996280154eSStefano Zampini   PetscFunctionReturn(0);
2006280154eSStefano Zampini }
2016280154eSStefano Zampini 
2026280154eSStefano Zampini int main(int argc,char **args)
2036280154eSStefano Zampini {
20475ab9b9fSStefano Zampini   Mat            X,B,A,Bt,T,T2,PtAP = NULL,RARt = NULL, R = NULL;
20575ab9b9fSStefano Zampini   Vec            r,l,rs,ls;
20675ab9b9fSStefano Zampini   PetscInt       m,n,k,M = 10,N = 10,K = 5, ldx = 3, ldb = 5, ldr = 4;
2076280154eSStefano Zampini   const char     *deft = MATAIJ;
2086280154eSStefano Zampini   char           mattype[256];
2096280154eSStefano Zampini   PetscBool      flg,symm = PETSC_FALSE,testtt = PETSC_TRUE, testnest = PETSC_TRUE, testtranspose = PETSC_TRUE, testcircular = PETSC_FALSE, local = PETSC_TRUE;
2103604c0aeSStefano Zampini   PetscBool      testhtranspose = PETSC_TRUE;
21175ab9b9fSStefano Zampini   PetscBool      xgpu = PETSC_FALSE, bgpu = PETSC_FALSE, testshellops = PETSC_FALSE, testproj = PETSC_TRUE, testrart = PETSC_TRUE, testmatmatt = PETSC_TRUE, testmattmat = PETSC_TRUE;
21275ab9b9fSStefano Zampini   PetscScalar    *dataX = NULL,*dataB = NULL, *dataR = NULL, *dataBt = NULL;
21375ab9b9fSStefano Zampini   PetscScalar    *aX,*aB,*aBt;
214456288a8SStefano Zampini   PetscReal      err;
2156280154eSStefano Zampini 
2169566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc,&args,NULL,help));
2179566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL));
2189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL));
2199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-K",&K,NULL));
2209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-symm",&symm,NULL));
2219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-local",&local,NULL));
2229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-ldx",&ldx,NULL));
2239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-ldb",&ldb,NULL));
2249566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-ldr",&ldr,NULL));
2259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testtranspose",&testtranspose,NULL));
2269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testnest",&testnest,NULL));
2279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testtt",&testtt,NULL));
2289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testcircular",&testcircular,NULL));
2299566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testshellops",&testshellops,NULL));
2309566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testproj",&testproj,NULL));
2319566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testrart",&testrart,NULL));
2329566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testmatmatt",&testmatmatt,NULL));
2339566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-testmattmat",&testmattmat,NULL));
2349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-xgpu",&xgpu,NULL));
2359566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-bgpu",&bgpu,NULL));
2369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(NULL,NULL,"-magic_number",&MAGIC_NUMBER,NULL));
23775ab9b9fSStefano Zampini   if (M != N) testproj = PETSC_FALSE;
23875ab9b9fSStefano Zampini 
2399566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_WORLD,&A));
2409566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N));
2419566063dSJacob Faibussowitsch   PetscCall(MatSetType(A,MATAIJ));
2429566063dSJacob Faibussowitsch   PetscCall(MatSetUp(A));
2439566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(A,NULL));
2446280154eSStefano Zampini   if (M==N && symm) {
2456280154eSStefano Zampini     Mat AT;
2466280154eSStefano Zampini 
2479566063dSJacob Faibussowitsch     PetscCall(MatTranspose(A,MAT_INITIAL_MATRIX,&AT));
2489566063dSJacob Faibussowitsch     PetscCall(MatAXPY(A,1.0,AT,DIFFERENT_NONZERO_PATTERN));
2499566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&AT));
2509566063dSJacob Faibussowitsch     PetscCall(MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE));
2516280154eSStefano Zampini   }
2529566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(A,NULL,"-A_init_view"));
253d0609cedSBarry Smith   PetscOptionsBegin(PETSC_COMM_WORLD,"","","");
2549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-A_mat_type","Matrix type","MatSetType",MatList,deft,mattype,256,&flg));
255d0609cedSBarry Smith   PetscOptionsEnd();
2566280154eSStefano Zampini   if (flg) {
2576280154eSStefano Zampini     Mat A2;
2586280154eSStefano Zampini 
2599566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(A,MAT_COPY_VALUES,&A2));
2609566063dSJacob Faibussowitsch     PetscCall(MatConvert(A,mattype,MAT_INPLACE_MATRIX,&A));
2619566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(A,A2,10,&flg));
2626280154eSStefano Zampini     if (!flg) {
2636280154eSStefano Zampini       Mat AE,A2E;
2646280154eSStefano Zampini 
2659566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with convert\n"));
2669566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(A,MATDENSE,&AE));
2679566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(A2,MATDENSE,&A2E));
2689566063dSJacob Faibussowitsch       PetscCall(MatView(AE,NULL));
2699566063dSJacob Faibussowitsch       PetscCall(MatView(A2E,NULL));
2709566063dSJacob Faibussowitsch       PetscCall(MatAXPY(A2E,-1.0,A,SAME_NONZERO_PATTERN));
2719566063dSJacob Faibussowitsch       PetscCall(MatView(A2E,NULL));
2729566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&A2E));
2739566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&AE));
2746280154eSStefano Zampini     }
2759566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A2));
2766280154eSStefano Zampini   }
2779566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(A,NULL,"-A_view"));
2786280154eSStefano Zampini 
2799566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(A,&m,&n));
2806280154eSStefano Zampini   if (local) {
28175ab9b9fSStefano Zampini     PetscInt i;
28275ab9b9fSStefano Zampini 
2839566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((m+ldx)*K,&dataX));
2849566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((n+ldb)*K,&dataB));
285a0638e9dSStefano Zampini     for (i=0;i<(m+ldx)*K;i++) dataX[i] = MAGIC_NUMBER;
286a0638e9dSStefano Zampini     for (i=0;i<(n+ldb)*K;i++) dataB[i] = MAGIC_NUMBER;
2876280154eSStefano Zampini   }
2889566063dSJacob Faibussowitsch   PetscCall(MatCreateDense(PETSC_COMM_WORLD,n,PETSC_DECIDE,N,K,dataB,&B));
2899566063dSJacob Faibussowitsch   PetscCall(MatCreateDense(PETSC_COMM_WORLD,m,PETSC_DECIDE,M,K,dataX,&X));
29075ab9b9fSStefano Zampini   if (local) {
2919566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(X,m+ldx));
2929566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(B,n+ldb));
29375ab9b9fSStefano Zampini   }
2949566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(B,NULL,&k));
29575ab9b9fSStefano Zampini   if (local) {
29675ab9b9fSStefano Zampini     PetscInt i;
29775ab9b9fSStefano Zampini 
2989566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((k+ldr)*N,&dataBt));
299a0638e9dSStefano Zampini     for (i=0;i<(k+ldr)*N;i++) dataBt[i] = MAGIC_NUMBER;
30075ab9b9fSStefano Zampini   }
3019566063dSJacob Faibussowitsch   PetscCall(MatCreateDense(PETSC_COMM_WORLD,k,n,K,N,dataBt,&Bt));
302*1baa6e33SBarry Smith   if (local) PetscCall(MatDenseSetLDA(Bt,k+ldr));
3036280154eSStefano Zampini 
3046280154eSStefano Zampini   /* store pointer to dense data for testing */
3059566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,(const PetscScalar**)&dataB));
3069566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X,(const PetscScalar**)&dataX));
3079566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(Bt,(const PetscScalar**)&dataBt));
3086280154eSStefano Zampini   aX   = dataX;
3096280154eSStefano Zampini   aB   = dataB;
31075ab9b9fSStefano Zampini   aBt  = dataBt;
3119566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(Bt,(const PetscScalar**)&dataBt));
3129566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,(const PetscScalar**)&dataB));
3139566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X,(const PetscScalar**)&dataX));
3146280154eSStefano Zampini   if (local) {
3156280154eSStefano Zampini     dataX  = aX;
3166280154eSStefano Zampini     dataB  = aB;
31775ab9b9fSStefano Zampini     dataBt = aBt;
3186280154eSStefano Zampini   }
31975ab9b9fSStefano Zampini 
3209566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(X,NULL));
3219566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(B,NULL));
3229566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(Bt,NULL));
3239566063dSJacob Faibussowitsch   PetscCall(CheckLocal(X,NULL,aX,NULL));
3249566063dSJacob Faibussowitsch   PetscCall(CheckLocal(Bt,B,aBt,aB));
32575ab9b9fSStefano Zampini 
326456288a8SStefano Zampini   /* convert to CUDA if needed */
327456288a8SStefano Zampini   if (bgpu) {
3289566063dSJacob Faibussowitsch     PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B));
3299566063dSJacob Faibussowitsch     PetscCall(MatConvert(Bt,MATDENSECUDA,MAT_INPLACE_MATRIX,&Bt));
330456288a8SStefano Zampini   }
331456288a8SStefano Zampini   if (xgpu) {
3329566063dSJacob Faibussowitsch     PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X));
333456288a8SStefano Zampini   }
3349566063dSJacob Faibussowitsch   PetscCall(CheckLocal(B,X,aB,aX));
3356280154eSStefano Zampini 
336e7b38fdfSStefano Zampini   /* Test MatDenseGetSubMatrix */
337e7b38fdfSStefano Zampini   {
338e7b38fdfSStefano Zampini     Mat B2,T3,T4;
339e7b38fdfSStefano Zampini 
3409566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&B2));
3419566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&T4));
3429566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(T4,NULL));
3439566063dSJacob Faibussowitsch     PetscCall(MatAXPY(B2,1.0,T4,SAME_NONZERO_PATTERN));
344a2748737SPierre Jolivet     PetscCall(MatDenseGetSubMatrix(B,PETSC_DECIDE,PETSC_DECIDE,PetscMin(1,K-1),PetscMin(2,K),&T));
345a2748737SPierre Jolivet     PetscCall(MatDenseGetSubMatrix(T4,PETSC_DECIDE,PETSC_DECIDE,PetscMin(1,K-1),PetscMin(2,K),&T2));
346a2748737SPierre Jolivet     PetscCall(MatDenseGetSubMatrix(B2,PETSC_DECIDE,PETSC_DECIDE,PetscMin(1,K-1),PetscMin(2,K),&T3));
3479566063dSJacob Faibussowitsch     PetscCall(MatAXPY(T,1.0,T2,SAME_NONZERO_PATTERN));
3489566063dSJacob Faibussowitsch     PetscCall(MatAXPY(T3,-1.0,T,SAME_NONZERO_PATTERN));
3499566063dSJacob Faibussowitsch     PetscCall(MatNorm(T3,NORM_FROBENIUS,&err));
350e7b38fdfSStefano Zampini     if (err > PETSC_SMALL) {
3519566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with MatDenseGetSubMatrix\n"));
3529566063dSJacob Faibussowitsch       PetscCall(MatView(T3,NULL));
353e7b38fdfSStefano Zampini     }
3549566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreSubMatrix(B,&T));
3559566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreSubMatrix(T4,&T2));
3569566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreSubMatrix(B2,&T3));
3579566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,NULL,aB,NULL));
3589566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B2));
3599566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&T4));
360a2748737SPierre Jolivet     if (N >= 2) {
361a2748737SPierre Jolivet       PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&B2));
362a2748737SPierre Jolivet       PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&T4));
363a2748737SPierre Jolivet       PetscCall(MatSetRandom(T4,NULL));
364a2748737SPierre Jolivet       PetscCall(MatAXPY(B2,1.0,T4,SAME_NONZERO_PATTERN));
365a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(B,N-2,PETSC_DECIDE,PetscMin(1,K-1),PetscMin(2,K),&T));
366a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(T4,N-2,PETSC_DECIDE,PetscMin(1,K-1),PetscMin(2,K),&T2));
367a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(B2,N-2,PETSC_DECIDE,PetscMin(1,K-1),PetscMin(2,K),&T3));
368a2748737SPierre Jolivet       PetscCall(MatAXPY(T,1.0,T2,SAME_NONZERO_PATTERN));
369a2748737SPierre Jolivet       PetscCall(MatAXPY(T3,-1.0,T,SAME_NONZERO_PATTERN));
370a2748737SPierre Jolivet       PetscCall(MatNorm(T3,NORM_FROBENIUS,&err));
371a2748737SPierre Jolivet       if (err > PETSC_SMALL) {
372a2748737SPierre Jolivet         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with MatDenseGetSubMatrix\n"));
373a2748737SPierre Jolivet         PetscCall(MatView(T3,NULL));
374a2748737SPierre Jolivet       }
375a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(B,&T));
376a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(T4,&T2));
377a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(B2,&T3));
378a2748737SPierre Jolivet       PetscCall(CheckLocal(B,NULL,aB,NULL));
379a2748737SPierre Jolivet       PetscCall(MatDestroy(&B2));
380a2748737SPierre Jolivet       PetscCall(MatDestroy(&T4));
381a2748737SPierre Jolivet       PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&B2));
382a2748737SPierre Jolivet       PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&T4));
383a2748737SPierre Jolivet       PetscCall(MatSetRandom(T4,NULL));
384a2748737SPierre Jolivet       PetscCall(MatAXPY(B2,1.0,T4,SAME_NONZERO_PATTERN));
385a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(B,PETSC_DECIDE,2,PetscMin(1,K-1),PetscMin(2,K),&T));
386a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(T4,PETSC_DECIDE,2,PetscMin(1,K-1),PetscMin(2,K),&T2));
387a2748737SPierre Jolivet       PetscCall(MatDenseGetSubMatrix(B2,PETSC_DECIDE,2,PetscMin(1,K-1),PetscMin(2,K),&T3));
388a2748737SPierre Jolivet       PetscCall(MatAXPY(T,1.0,T2,SAME_NONZERO_PATTERN));
389a2748737SPierre Jolivet       PetscCall(MatAXPY(T3,-1.0,T,SAME_NONZERO_PATTERN));
390a2748737SPierre Jolivet       PetscCall(MatNorm(T3,NORM_FROBENIUS,&err));
391a2748737SPierre Jolivet       if (err > PETSC_SMALL) {
392a2748737SPierre Jolivet         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with MatDenseGetSubMatrix\n"));
393a2748737SPierre Jolivet         PetscCall(MatView(T3,NULL));
394a2748737SPierre Jolivet       }
395a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(B,&T));
396a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(T4,&T2));
397a2748737SPierre Jolivet       PetscCall(MatDenseRestoreSubMatrix(B2,&T3));
398a2748737SPierre Jolivet       PetscCall(CheckLocal(B,NULL,aB,NULL));
399a2748737SPierre Jolivet       PetscCall(MatDestroy(&B2));
400a2748737SPierre Jolivet       PetscCall(MatDestroy(&T4));
401a2748737SPierre Jolivet     }
402e7b38fdfSStefano Zampini   }
403e7b38fdfSStefano Zampini 
4046280154eSStefano Zampini   /* Test reusing a previously allocated dense buffer */
4059566063dSJacob Faibussowitsch   PetscCall(MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X));
4069566063dSJacob Faibussowitsch   PetscCall(CheckLocal(B,X,aB,aX));
4079566063dSJacob Faibussowitsch   PetscCall(MatMatMultEqual(A,B,X,10,&flg));
4086280154eSStefano Zampini   if (!flg) {
4099566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with reusage\n"));
4109566063dSJacob Faibussowitsch     PetscCall(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
4119566063dSJacob Faibussowitsch     PetscCall(MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN));
4129566063dSJacob Faibussowitsch     PetscCall(MatView(T,NULL));
4139566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&T));
4146280154eSStefano Zampini   }
4156280154eSStefano Zampini 
41675ab9b9fSStefano Zampini   /* Test MatTransposeMat and MatMatTranspose */
41775ab9b9fSStefano Zampini   if (testmattmat) {
4189566063dSJacob Faibussowitsch     PetscCall(MatTransposeMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B));
4199566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,X,aB,aX));
4209566063dSJacob Faibussowitsch     PetscCall(MatTransposeMatMultEqual(A,X,B,10,&flg));
42175ab9b9fSStefano Zampini     if (!flg) {
4229566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MatTransposeMat)\n"));
4239566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(A,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B));
4249566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,B,SAME_NONZERO_PATTERN));
4259566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
4269566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
42775ab9b9fSStefano Zampini     }
42875ab9b9fSStefano Zampini   }
42975ab9b9fSStefano Zampini   if (testmatmatt) {
4309566063dSJacob Faibussowitsch     PetscCall(MatMatTransposeMult(A,Bt,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X));
4319566063dSJacob Faibussowitsch     PetscCall(CheckLocal(Bt,X,aBt,aX));
4329566063dSJacob Faibussowitsch     PetscCall(MatMatTransposeMultEqual(A,Bt,X,10,&flg));
43375ab9b9fSStefano Zampini     if (!flg) {
4349566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MatMatTranspose)\n"));
4359566063dSJacob Faibussowitsch       PetscCall(MatMatTransposeMult(A,Bt,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
4369566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN));
4379566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
4389566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
43975ab9b9fSStefano Zampini     }
44075ab9b9fSStefano Zampini   }
44175ab9b9fSStefano Zampini 
44275ab9b9fSStefano Zampini   /* Test projection operations (PtAP and RARt) */
44375ab9b9fSStefano Zampini   if (testproj) {
4449566063dSJacob Faibussowitsch     PetscCall(MatPtAP(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&PtAP));
4459566063dSJacob Faibussowitsch     PetscCall(MatPtAPMultEqual(A,B,PtAP,10,&flg));
44675ab9b9fSStefano Zampini     if (!flg) {
4479566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with PtAP\n"));
4489566063dSJacob Faibussowitsch       PetscCall(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
4499566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(B,T,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T2));
4509566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T2,-1.0,PtAP,SAME_NONZERO_PATTERN));
4519566063dSJacob Faibussowitsch       PetscCall(MatView(T2,NULL));
4529566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T2));
4539566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
45475ab9b9fSStefano Zampini     }
4559566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1((k+ldr)*M,&dataR));
4569566063dSJacob Faibussowitsch     PetscCall(MatCreateDense(PETSC_COMM_WORLD,PETSC_DECIDE,m,K,M,dataR,&R));
4579566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(R,k+ldr));
4589566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(R,NULL));
45975ab9b9fSStefano Zampini     if (testrart) { /* fails for AIJCUSPARSE because RA operation is not defined */
4609566063dSJacob Faibussowitsch       PetscCall(MatRARt(A,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&RARt));
4619566063dSJacob Faibussowitsch       PetscCall(MatRARtMultEqual(A,R,RARt,10,&flg));
46275ab9b9fSStefano Zampini       if (!flg) {
4639566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with RARt\n"));
4649566063dSJacob Faibussowitsch         PetscCall(MatMatTransposeMult(A,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
4659566063dSJacob Faibussowitsch         PetscCall(MatMatMult(R,T,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T2));
4669566063dSJacob Faibussowitsch         PetscCall(MatAXPY(T2,-1.0,RARt,SAME_NONZERO_PATTERN));
4679566063dSJacob Faibussowitsch         PetscCall(MatView(T2,NULL));
4689566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&T2));
4699566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&T));
47075ab9b9fSStefano Zampini       }
47175ab9b9fSStefano Zampini     }
47275ab9b9fSStefano Zampini   }
47375ab9b9fSStefano Zampini 
474456288a8SStefano Zampini   /* Test MatDenseGetColumnVec and friends */
4759566063dSJacob Faibussowitsch   PetscCall(MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X));
4769566063dSJacob Faibussowitsch   PetscCall(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
4779566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(T,MAT_DO_NOT_COPY_VALUES,&T2));
478456288a8SStefano Zampini   for (k=0;k<K;k++) {
479456288a8SStefano Zampini     Vec Xv,Tv,T2v;
480456288a8SStefano Zampini 
4819566063dSJacob Faibussowitsch     PetscCall(MatDenseGetColumnVecRead(X,k,&Xv));
4829566063dSJacob Faibussowitsch     PetscCall(MatDenseGetColumnVec(T,k,&Tv));
4839566063dSJacob Faibussowitsch     PetscCall(MatDenseGetColumnVecWrite(T2,k,&T2v));
4849566063dSJacob Faibussowitsch     PetscCall(VecCopy(Xv,T2v));
4859566063dSJacob Faibussowitsch     PetscCall(VecAXPY(Tv,-1.,Xv));
4869566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreColumnVecRead(X,k,&Xv));
4879566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreColumnVec(T,k,&Tv));
4889566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreColumnVecWrite(T2,k,&T2v));
489456288a8SStefano Zampini   }
4909566063dSJacob Faibussowitsch   PetscCall(MatNorm(T,NORM_FROBENIUS,&err));
491456288a8SStefano Zampini   if (err > PETSC_SMALL) {
4929566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with MatDenseGetColumnVec\n"));
4939566063dSJacob Faibussowitsch     PetscCall(MatView(T,NULL));
494456288a8SStefano Zampini   }
4959566063dSJacob Faibussowitsch   PetscCall(MatAXPY(T2,-1.,X,SAME_NONZERO_PATTERN));
4969566063dSJacob Faibussowitsch   PetscCall(MatNorm(T2,NORM_FROBENIUS,&err));
497456288a8SStefano Zampini   if (err > PETSC_SMALL) {
4989566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with MatDenseGetColumnVecWrite\n"));
4999566063dSJacob Faibussowitsch     PetscCall(MatView(T2,NULL));
500456288a8SStefano Zampini   }
5019566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T));
5029566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T2));
503456288a8SStefano Zampini 
504456288a8SStefano Zampini   /* Test with MatShell */
5059566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A,MAT_COPY_VALUES,&T));
5069566063dSJacob Faibussowitsch   PetscCall(MatConvert(T,MATSHELL,MAT_INITIAL_MATRIX,&T2));
5079566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T));
50875ab9b9fSStefano Zampini 
50975ab9b9fSStefano Zampini   /* scale matrix */
5109566063dSJacob Faibussowitsch   PetscCall(MatScale(A,2.0));
5119566063dSJacob Faibussowitsch   PetscCall(MatScale(T2,2.0));
5129566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(A,&r,&l));
5139566063dSJacob Faibussowitsch   PetscCall(VecSetRandom(r,NULL));
5149566063dSJacob Faibussowitsch   PetscCall(VecSetRandom(l,NULL));
5159566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(T2,&rs,&ls));
5169566063dSJacob Faibussowitsch   PetscCall(VecCopy(r,rs));
5179566063dSJacob Faibussowitsch   PetscCall(VecCopy(l,ls));
51875ab9b9fSStefano Zampini   if (testproj) {
5199566063dSJacob Faibussowitsch     PetscCall(MatDiagonalScale(A,r,r));
5209566063dSJacob Faibussowitsch     PetscCall(MatDiagonalScale(T2,rs,rs));
52175ab9b9fSStefano Zampini   } else {
5229566063dSJacob Faibussowitsch     PetscCall(MatDiagonalScale(A,l,r));
5239566063dSJacob Faibussowitsch     PetscCall(MatDiagonalScale(T2,ls,rs));
52475ab9b9fSStefano Zampini   }
5259566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A,MAT_COPY_VALUES,&T));
5269566063dSJacob Faibussowitsch   PetscCall(MatAXPY(A,4.5,T,SAME_NONZERO_PATTERN));
5279566063dSJacob Faibussowitsch   PetscCall(MatAXPY(T2,4.5,T,DIFFERENT_NONZERO_PATTERN));
5289566063dSJacob Faibussowitsch   PetscCall(MatMultEqual(T2,A,10,&flg));
52975ab9b9fSStefano Zampini   if (!flg) {
5309566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with MATSHELL (MatMult)\n"));
53175ab9b9fSStefano Zampini   }
5329566063dSJacob Faibussowitsch   PetscCall(MatMultTransposeEqual(T2,A,10,&flg));
53375ab9b9fSStefano Zampini   if (!flg) {
5349566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with MATSHELL (MatMultTranspose)\n"));
53575ab9b9fSStefano Zampini   }
5369566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T));
5379566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&ls));
5389566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&rs));
5399566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l));
5409566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&r));
54175ab9b9fSStefano Zampini 
54275ab9b9fSStefano Zampini   /* recompute projections, test reusage */
5439566063dSJacob Faibussowitsch   if (PtAP) PetscCall(MatPtAP(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&PtAP));
5449566063dSJacob Faibussowitsch   if (RARt) PetscCall(MatRARt(A,R,MAT_REUSE_MATRIX,PETSC_DEFAULT,&RARt));
54575ab9b9fSStefano Zampini   if (testshellops) { /* test callbacks for user defined MatProducts */
5469566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_AB,NULL,MyMatShellMatMultNumeric,NULL,MATDENSE,MATDENSE));
5479566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_AB,NULL,MyMatShellMatMultNumeric,NULL,MATDENSECUDA,MATDENSECUDA));
5489566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_AtB,NULL,MyMatTransposeShellMatMultNumeric,NULL,MATDENSE,MATDENSE));
5499566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_AtB,NULL,MyMatTransposeShellMatMultNumeric,NULL,MATDENSECUDA,MATDENSECUDA));
5509566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_ABt,NULL,MyMatShellMatTransposeMultNumeric,NULL,MATDENSE,MATDENSE));
5519566063dSJacob Faibussowitsch     PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_ABt,NULL,MyMatShellMatTransposeMultNumeric,NULL,MATDENSECUDA,MATDENSECUDA));
55275ab9b9fSStefano Zampini     if (testproj) {
5539566063dSJacob Faibussowitsch       PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_PtAP,MyPtShellPMultSymbolic,MyPtShellPMultNumeric,proj_destroy,MATDENSE,MATSHELL));
5549566063dSJacob Faibussowitsch       PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_PtAP,MyPtShellPMultSymbolic,MyPtShellPMultNumeric,proj_destroy,MATDENSECUDA,MATSHELL));
5559566063dSJacob Faibussowitsch       PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_RARt,MyRShellRtMultSymbolic,MyRShellRtMultNumeric,proj_destroy,MATDENSE,MATSHELL));
5569566063dSJacob Faibussowitsch       PetscCall(MatShellSetMatProductOperation(T2,MATPRODUCT_RARt,MyRShellRtMultSymbolic,MyRShellRtMultNumeric,proj_destroy,MATDENSECUDA,MATSHELL));
55775ab9b9fSStefano Zampini     }
55875ab9b9fSStefano Zampini   }
5599566063dSJacob Faibussowitsch   PetscCall(CheckLocal(B,X,aB,aX));
56075ab9b9fSStefano Zampini   /* we either use the shell operations or the loop over columns code, applying the operator */
5619566063dSJacob Faibussowitsch   PetscCall(MatMatMult(T2,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X));
5629566063dSJacob Faibussowitsch   PetscCall(CheckLocal(B,X,aB,aX));
5639566063dSJacob Faibussowitsch   PetscCall(MatMatMultEqual(T2,B,X,10,&flg));
564456288a8SStefano Zampini   if (!flg) {
5659566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MATSHELL)\n"));
5669566063dSJacob Faibussowitsch     PetscCall(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
5679566063dSJacob Faibussowitsch     PetscCall(MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN));
5689566063dSJacob Faibussowitsch     PetscCall(MatView(T,NULL));
5699566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&T));
570456288a8SStefano Zampini   }
57175ab9b9fSStefano Zampini   if (testproj) {
5729566063dSJacob Faibussowitsch     PetscCall(MatPtAPMultEqual(T2,B,PtAP,10,&flg));
57375ab9b9fSStefano Zampini     if (!flg) {
5749566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with PtAP (MATSHELL)\n"));
57575ab9b9fSStefano Zampini     }
57675ab9b9fSStefano Zampini     if (testshellops) { /* projections fail if the product operations are not specified */
5779566063dSJacob Faibussowitsch       PetscCall(MatPtAP(T2,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
5789566063dSJacob Faibussowitsch       PetscCall(MatPtAP(T2,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&T));
5799566063dSJacob Faibussowitsch       PetscCall(MatPtAPMultEqual(T2,B,T,10,&flg));
58075ab9b9fSStefano Zampini       if (!flg) {
58175ab9b9fSStefano Zampini         Mat TE;
5826718818eSStefano Zampini 
5839566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with PtAP (MATSHELL user defined)\n"));
5849566063dSJacob Faibussowitsch         PetscCall(MatComputeOperator(T,MATDENSE,&TE));
5859566063dSJacob Faibussowitsch         PetscCall(MatView(TE,NULL));
5869566063dSJacob Faibussowitsch         PetscCall(MatView(PtAP,NULL));
5879566063dSJacob Faibussowitsch         PetscCall(MatAXPY(TE,-1.0,PtAP,SAME_NONZERO_PATTERN));
5889566063dSJacob Faibussowitsch         PetscCall(MatView(TE,NULL));
5899566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&TE));
59075ab9b9fSStefano Zampini       }
5919566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
59275ab9b9fSStefano Zampini     }
59375ab9b9fSStefano Zampini     if (RARt) {
5949566063dSJacob Faibussowitsch       PetscCall(MatRARtMultEqual(T2,R,RARt,10,&flg));
59575ab9b9fSStefano Zampini       if (!flg) {
5969566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with RARt (MATSHELL)\n"));
59775ab9b9fSStefano Zampini       }
59875ab9b9fSStefano Zampini     }
59975ab9b9fSStefano Zampini     if (testshellops) {
6009566063dSJacob Faibussowitsch       PetscCall(MatRARt(T2,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
6019566063dSJacob Faibussowitsch       PetscCall(MatRARt(T2,R,MAT_REUSE_MATRIX,PETSC_DEFAULT,&T));
6029566063dSJacob Faibussowitsch       PetscCall(MatRARtMultEqual(T2,R,T,10,&flg));
60375ab9b9fSStefano Zampini       if (!flg) {
60475ab9b9fSStefano Zampini         Mat TE;
60575ab9b9fSStefano Zampini 
6069566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with RARt (MATSHELL user defined)\n"));
6079566063dSJacob Faibussowitsch         PetscCall(MatComputeOperator(T,MATDENSE,&TE));
6089566063dSJacob Faibussowitsch         PetscCall(MatView(TE,NULL));
60975ab9b9fSStefano Zampini         if (RARt) {
6109566063dSJacob Faibussowitsch           PetscCall(MatView(RARt,NULL));
6119566063dSJacob Faibussowitsch           PetscCall(MatAXPY(TE,-1.0,RARt,SAME_NONZERO_PATTERN));
6129566063dSJacob Faibussowitsch           PetscCall(MatView(TE,NULL));
61375ab9b9fSStefano Zampini         }
6149566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&TE));
61575ab9b9fSStefano Zampini       }
6169566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
61775ab9b9fSStefano Zampini     }
61875ab9b9fSStefano Zampini   }
61975ab9b9fSStefano Zampini 
62075ab9b9fSStefano Zampini   if (testmattmat) { /* we either use the shell operations or the loop over columns code applying the transposed operator */
6219566063dSJacob Faibussowitsch     PetscCall(MatTransposeMatMult(T2,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B));
6229566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,X,aB,aX));
6239566063dSJacob Faibussowitsch     PetscCall(MatTransposeMatMultEqual(T2,X,B,10,&flg));
624456288a8SStefano Zampini     if (!flg) {
6259566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MatTranspose, MATSHELL)\n"));
6269566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(A,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
6279566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,B,SAME_NONZERO_PATTERN));
6289566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
6299566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6306718818eSStefano Zampini     }
631456288a8SStefano Zampini   }
63275ab9b9fSStefano Zampini   if (testmatmatt && testshellops) { /* only when shell operations are set */
6339566063dSJacob Faibussowitsch     PetscCall(MatMatTransposeMult(T2,Bt,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X));
6349566063dSJacob Faibussowitsch     PetscCall(CheckLocal(Bt,X,aBt,aX));
6359566063dSJacob Faibussowitsch     PetscCall(MatMatTransposeMultEqual(T2,Bt,X,10,&flg));
63675ab9b9fSStefano Zampini     if (!flg) {
6379566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MatMatTranspose, MATSHELL)\n"));
6389566063dSJacob Faibussowitsch       PetscCall(MatMatTransposeMult(A,Bt,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
6399566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN));
6409566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
6419566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
64275ab9b9fSStefano Zampini     }
64375ab9b9fSStefano Zampini   }
6449566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T2));
645456288a8SStefano Zampini 
6466280154eSStefano Zampini   if (testnest) { /* test with MatNest */
6476280154eSStefano Zampini     Mat NA;
6486280154eSStefano Zampini 
6499566063dSJacob Faibussowitsch     PetscCall(MatCreateNest(PETSC_COMM_WORLD,1,NULL,1,NULL,&A,&NA));
6509566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(NA,NULL,"-NA_view"));
6519566063dSJacob Faibussowitsch     PetscCall(MatMatMult(NA,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X));
6529566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,X,aB,aX));
6539566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(NA,B,X,10,&flg));
6546280154eSStefano Zampini     if (!flg) {
6559566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with Nest\n"));
6569566063dSJacob Faibussowitsch       PetscCall(MatMatMult(NA,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
6579566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN));
6589566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
6599566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6606280154eSStefano Zampini     }
6619566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&NA));
6626280154eSStefano Zampini   }
6636280154eSStefano Zampini 
6646280154eSStefano Zampini   if (testtranspose) { /* test with Transpose */
6656280154eSStefano Zampini     Mat TA;
6666280154eSStefano Zampini 
6679566063dSJacob Faibussowitsch     PetscCall(MatCreateTranspose(A,&TA));
6689566063dSJacob Faibussowitsch     PetscCall(MatMatMult(TA,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B));
6699566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,X,aB,aX));
6709566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(TA,X,B,10,&flg));
6716280154eSStefano Zampini     if (!flg) {
6729566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with Transpose\n"));
6739566063dSJacob Faibussowitsch       PetscCall(MatMatMult(TA,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
6749566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,B,SAME_NONZERO_PATTERN));
6759566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
6769566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6776280154eSStefano Zampini     }
6789566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&TA));
6796280154eSStefano Zampini   }
6806280154eSStefano Zampini 
6813604c0aeSStefano Zampini   if (testhtranspose) { /* test with Hermitian Transpose */
6823604c0aeSStefano Zampini     Mat TA;
6833604c0aeSStefano Zampini 
6849566063dSJacob Faibussowitsch     PetscCall(MatCreateHermitianTranspose(A,&TA));
6859566063dSJacob Faibussowitsch     PetscCall(MatMatMult(TA,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B));
6869566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,X,aB,aX));
6879566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(TA,X,B,10,&flg));
6883604c0aeSStefano Zampini     if (!flg) {
6899566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with Transpose\n"));
6909566063dSJacob Faibussowitsch       PetscCall(MatMatMult(TA,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
6919566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,B,SAME_NONZERO_PATTERN));
6929566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
6939566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
6943604c0aeSStefano Zampini     }
6959566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&TA));
6963604c0aeSStefano Zampini   }
6973604c0aeSStefano Zampini 
6986280154eSStefano Zampini   if (testtt) { /* test with Transpose(Transpose) */
6996280154eSStefano Zampini     Mat TA, TTA;
7006280154eSStefano Zampini 
7019566063dSJacob Faibussowitsch     PetscCall(MatCreateTranspose(A,&TA));
7029566063dSJacob Faibussowitsch     PetscCall(MatCreateTranspose(TA,&TTA));
7039566063dSJacob Faibussowitsch     PetscCall(MatMatMult(TTA,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X));
7049566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,X,aB,aX));
7059566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(TTA,B,X,10,&flg));
7066280154eSStefano Zampini     if (!flg) {
7079566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Error with Transpose(Transpose)\n"));
7089566063dSJacob Faibussowitsch       PetscCall(MatMatMult(TTA,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
7099566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN));
7109566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
7119566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
7126280154eSStefano Zampini     }
7139566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&TA));
7149566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&TTA));
7156280154eSStefano Zampini   }
7166280154eSStefano Zampini 
7176280154eSStefano Zampini   if (testcircular) { /* test circular */
7186280154eSStefano Zampini     Mat AB;
7196280154eSStefano Zampini 
7209566063dSJacob Faibussowitsch     PetscCall(MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AB));
7219566063dSJacob Faibussowitsch     PetscCall(MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X));
7229566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,X,aB,aX));
7236280154eSStefano Zampini     if (M == N && N == K) {
7249566063dSJacob Faibussowitsch       PetscCall(MatMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B));
7256280154eSStefano Zampini     } else {
7269566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B));
7276280154eSStefano Zampini     }
7289566063dSJacob Faibussowitsch     PetscCall(CheckLocal(B,X,aB,aX));
7299566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&AB));
7306280154eSStefano Zampini   }
7312b723ba2SStefano Zampini 
7322b723ba2SStefano Zampini   /* Test by Pierre Jolivet */
7332b723ba2SStefano Zampini   {
7342b723ba2SStefano Zampini     Mat C,D,D2,AtA;
7359566063dSJacob Faibussowitsch     PetscCall(MatCreateNormal(A,&AtA));
7369566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(X,MAT_DO_NOT_COPY_VALUES,&C));
7379566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&D));
7389566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&D2));
7399566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(B,NULL));
7409566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(C,NULL));
7419566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(D,NULL));
7429566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(D2,NULL));
7439566063dSJacob Faibussowitsch     PetscCall(MatProductCreateWithMat(A,B,NULL,C));
7449566063dSJacob Faibussowitsch     PetscCall(MatProductSetType(C,MATPRODUCT_AB));
7459566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions(C));
7469566063dSJacob Faibussowitsch     PetscCall(MatProductSymbolic(C));
7479566063dSJacob Faibussowitsch     PetscCall(MatProductCreateWithMat(A,C,NULL,D));
7489566063dSJacob Faibussowitsch     PetscCall(MatProductSetType(D, MATPRODUCT_AtB));
7499566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions(D));
7509566063dSJacob Faibussowitsch     PetscCall(MatProductSymbolic(D));
7519566063dSJacob Faibussowitsch     PetscCall(MatProductNumeric(C));
7529566063dSJacob Faibussowitsch     PetscCall(MatProductNumeric(D));
7539566063dSJacob Faibussowitsch     PetscCall(MatMatMultEqual(AtA,B,D,10,&flg));
7542b723ba2SStefano Zampini     if (!flg) {
7559566063dSJacob Faibussowitsch       PetscCall(MatMatMult(AtA,C,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T));
7569566063dSJacob Faibussowitsch       PetscCall(MatAXPY(T,-1.0,D,SAME_NONZERO_PATTERN));
7579566063dSJacob Faibussowitsch       PetscCall(MatView(T,NULL));
7589566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&T));
7592b723ba2SStefano Zampini     }
7609566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&C));
7619566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
7629566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D2));
7639566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&AtA));
7642b723ba2SStefano Zampini   }
7652b723ba2SStefano Zampini 
7669566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&X));
7679566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&Bt));
7689566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B));
7699566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A));
7709566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&R));
7719566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&PtAP));
7729566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&RARt));
7739566063dSJacob Faibussowitsch   PetscCall(PetscFree(dataX));
7749566063dSJacob Faibussowitsch   PetscCall(PetscFree(dataB));
7759566063dSJacob Faibussowitsch   PetscCall(PetscFree(dataR));
7769566063dSJacob Faibussowitsch   PetscCall(PetscFree(dataBt));
7779566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
778b122ec5aSJacob Faibussowitsch   return 0;
7796280154eSStefano Zampini }
7806280154eSStefano Zampini 
7816280154eSStefano Zampini /*TEST
7826280154eSStefano Zampini 
7836280154eSStefano Zampini   test:
7846280154eSStefano Zampini     suffix: 1
78575ab9b9fSStefano Zampini     args: -local {{0 1}} -testshellops
7866280154eSStefano Zampini 
7876280154eSStefano Zampini   test:
7886280154eSStefano Zampini     output_file: output/ex70_1.out
789456288a8SStefano Zampini     requires: cuda
790456288a8SStefano Zampini     suffix: 1_cuda
791686594dbSStefano Zampini     args: -local {{0 1}} -xgpu {{0 1}} -bgpu {{0 1}} -A_mat_type {{seqaijcusparse seqaij}} -testshellops {{0 1}}
792456288a8SStefano Zampini 
793456288a8SStefano Zampini   test:
794456288a8SStefano Zampini     output_file: output/ex70_1.out
7956280154eSStefano Zampini     nsize: 2
7966280154eSStefano Zampini     suffix: 1_par
79775ab9b9fSStefano Zampini     args: -local {{0 1}} -testmatmatt 0
7986280154eSStefano Zampini 
7996280154eSStefano Zampini   test:
800456288a8SStefano Zampini     output_file: output/ex70_1.out
801456288a8SStefano Zampini     requires: cuda
802456288a8SStefano Zampini     nsize: 2
803456288a8SStefano Zampini     suffix: 1_par_cuda
80475ab9b9fSStefano Zampini     args: -local {{0 1}} -xgpu {{0 1}} -bgpu {{0 1}} -A_mat_type {{mpiaijcusparse mpiaij}} -testnest 0 -testmatmatt 0 -matmatmult_Bbn 3
805456288a8SStefano Zampini 
806456288a8SStefano Zampini   test:
8076280154eSStefano Zampini     output_file: output/ex70_1.out
8086280154eSStefano Zampini     suffix: 2
8096280154eSStefano Zampini     nsize: 1
8106280154eSStefano Zampini     args: -M {{7 11}} -N {{12 9}} -K {{1 3}} -local {{0 1}}
8116280154eSStefano Zampini 
8128a311839SJunchao Zhang   testset:
813456288a8SStefano Zampini     requires: cuda
814456288a8SStefano Zampini     output_file: output/ex70_1.out
815456288a8SStefano Zampini     nsize: 1
816456288a8SStefano Zampini     args: -M 7 -N 9 -K 2 -local {{0 1}} -testnest 0 -A_mat_type {{seqdensecuda seqdense}} -xgpu {{0 1}} -bgpu {{0 1}}
8178a311839SJunchao Zhang     test:
8188a311839SJunchao Zhang       requires: !complex
8198a311839SJunchao Zhang       suffix: 2_cuda_real
8208a311839SJunchao Zhang     test:
8218a311839SJunchao Zhang       # complex+single gives a little bigger error in the MatDenseGetColumnVec test
8228a311839SJunchao Zhang       requires: complex !single
8238a311839SJunchao Zhang       suffix: 2_cuda_complex
824456288a8SStefano Zampini 
825456288a8SStefano Zampini   test:
8266280154eSStefano Zampini     output_file: output/ex70_1.out
8276280154eSStefano Zampini     suffix: 2_par
8286280154eSStefano Zampini     nsize: 2
82975ab9b9fSStefano Zampini     args: -M {{7 11}} -N {{12 9}} -K {{1 3}} -local {{0 1}} -testcircular -testmatmatt 0
8306280154eSStefano Zampini 
8316280154eSStefano Zampini   test:
832456288a8SStefano Zampini     requires: cuda
833456288a8SStefano Zampini     output_file: output/ex70_1.out
834456288a8SStefano Zampini     suffix: 2_par_cuda
835456288a8SStefano Zampini     nsize: 2
83675ab9b9fSStefano Zampini     args: -M 11 -N 9 -K 1 -local {{0 1}} -testcircular 0 -A_mat_type mpiaijcusparse -xgpu -bgpu -testnest 0 -testmatmatt 0
837456288a8SStefano Zampini 
838456288a8SStefano Zampini   test:
8396280154eSStefano Zampini     output_file: output/ex70_1.out
8406280154eSStefano Zampini     suffix: 3
841456288a8SStefano Zampini     nsize: {{1 3}}
84275ab9b9fSStefano Zampini     args: -M 13 -N 13 -K {{1 3}} -local {{0 1}} -A_mat_type sbaij -symm -testproj 0 -testmatmatt 0
8436280154eSStefano Zampini 
8446280154eSStefano Zampini   test:
8456280154eSStefano Zampini     output_file: output/ex70_1.out
8466280154eSStefano Zampini     suffix: 4
8476280154eSStefano Zampini     nsize: 1
8486280154eSStefano Zampini     args: -M 3 -N 3 -K 3 -local {{0 1}} -testcircular
8496280154eSStefano Zampini 
8506280154eSStefano Zampini   test:
8516280154eSStefano Zampini     output_file: output/ex70_1.out
8526280154eSStefano Zampini     suffix: 5
8536280154eSStefano Zampini     nsize: {{2 4}}
854a0638e9dSStefano Zampini     args: -M 3 -N 3 -K 3 -local {{0 1}} -testcircular -testmatmatt 0
8556280154eSStefano Zampini 
8566280154eSStefano Zampini   test:
8576280154eSStefano Zampini     output_file: output/ex70_1.out
8586280154eSStefano Zampini     suffix: 6
8596280154eSStefano Zampini     nsize: 1
86075ab9b9fSStefano Zampini     args: -M {{1 3}} -N {{2 5}} -K {{1 2}} -local {{0 1}} -testcircular
8616280154eSStefano Zampini 
8626280154eSStefano Zampini   test:
8636280154eSStefano Zampini     output_file: output/ex70_1.out
8646280154eSStefano Zampini     suffix: 7
8656280154eSStefano Zampini     nsize: 1
866456288a8SStefano Zampini     args: -M 13 -N 13 -K {{1 3}} -local {{0 1}} -A_mat_type dense -testnest -testcircular
8676718818eSStefano Zampini 
8686280154eSStefano Zampini TEST*/
869