xref: /petsc/src/mat/tests/ex70.c (revision 2c71b3e237ead271e4f3aa1505f92bf476e3413d)
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   PetscErrorCode ierr;
106280154eSStefano Zampini   PetscBool      wA = PETSC_FALSE, wB = PETSC_FALSE;
1175ab9b9fSStefano Zampini   PetscBool      wAv = PETSC_FALSE, wBv = PETSC_FALSE;
1275ab9b9fSStefano Zampini   PetscInt       lda,i,j,m,n;
136280154eSStefano Zampini 
146280154eSStefano Zampini   PetscFunctionBegin;
156280154eSStefano Zampini   if (a) {
166280154eSStefano Zampini     const PetscScalar *Aa;
176280154eSStefano Zampini     ierr = MatDenseGetArrayRead(A,&Aa);CHKERRQ(ierr);
186280154eSStefano Zampini     wA   = (PetscBool)(a != Aa);
1975ab9b9fSStefano Zampini     ierr = MatDenseGetLDA(A,&lda);CHKERRQ(ierr);
2075ab9b9fSStefano Zampini     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
2175ab9b9fSStefano Zampini     for (j=0;j<n;j++) {
2275ab9b9fSStefano Zampini       for (i=m;i<lda;i++) {
2375ab9b9fSStefano Zampini         if (Aa[j*lda +i] != MAGIC_NUMBER) wAv = PETSC_TRUE;
2475ab9b9fSStefano Zampini       }
2575ab9b9fSStefano Zampini     }
266280154eSStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&Aa);CHKERRQ(ierr);
276280154eSStefano Zampini   }
286280154eSStefano Zampini   if (b) {
296280154eSStefano Zampini     const PetscScalar *Bb;
306280154eSStefano Zampini     ierr = MatDenseGetArrayRead(B,&Bb);CHKERRQ(ierr);
316280154eSStefano Zampini     wB   = (PetscBool)(b != Bb);
3275ab9b9fSStefano Zampini     ierr = MatDenseGetLDA(B,&lda);CHKERRQ(ierr);
3375ab9b9fSStefano Zampini     ierr = MatGetLocalSize(B,&m,&n);CHKERRQ(ierr);
3475ab9b9fSStefano Zampini     for (j=0;j<n;j++) {
3575ab9b9fSStefano Zampini       for (i=m;i<lda;i++) {
3675ab9b9fSStefano Zampini         if (Bb[j*lda +i] != MAGIC_NUMBER) wBv = PETSC_TRUE;
3775ab9b9fSStefano Zampini       }
3875ab9b9fSStefano Zampini     }
396280154eSStefano Zampini     ierr = MatDenseRestoreArrayRead(B,&Bb);CHKERRQ(ierr);
406280154eSStefano Zampini   }
41*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(wA || wB,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Wrong array in first Mat? %d, Wrong array in second Mat? %d",wA,wB);
42*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(wAv || wBv,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Wrong data in first Mat? %d, Wrong data in second Mat? %d",wAv,wBv);
4375ab9b9fSStefano Zampini   PetscFunctionReturn(0);
4475ab9b9fSStefano Zampini }
4575ab9b9fSStefano Zampini 
4675ab9b9fSStefano Zampini typedef struct {
4775ab9b9fSStefano Zampini   Mat A;
4875ab9b9fSStefano Zampini   Mat P;
4975ab9b9fSStefano Zampini   Mat R;
5075ab9b9fSStefano Zampini } proj_data;
5175ab9b9fSStefano Zampini 
5275ab9b9fSStefano Zampini PetscErrorCode proj_destroy(void *ctx)
5375ab9b9fSStefano Zampini {
5475ab9b9fSStefano Zampini   proj_data      *userdata = (proj_data*)ctx;
5575ab9b9fSStefano Zampini   PetscErrorCode ierr;
5675ab9b9fSStefano Zampini 
5775ab9b9fSStefano Zampini   PetscFunctionBegin;
58*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!userdata,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing userdata");
5975ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->A);CHKERRQ(ierr);
6075ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->P);CHKERRQ(ierr);
6175ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->R);CHKERRQ(ierr);
6275ab9b9fSStefano Zampini   ierr = PetscFree(userdata);CHKERRQ(ierr);
6375ab9b9fSStefano Zampini   PetscFunctionReturn(0);
6475ab9b9fSStefano Zampini }
6575ab9b9fSStefano Zampini 
6675ab9b9fSStefano Zampini PetscErrorCode proj_mult(Mat S, Vec X, Vec Y)
6775ab9b9fSStefano Zampini {
6875ab9b9fSStefano Zampini   Mat            A,R,P;
6975ab9b9fSStefano Zampini   Vec            Ax,Ay;
7075ab9b9fSStefano Zampini   Vec            Px,Py;
7175ab9b9fSStefano Zampini   proj_data      *userdata;
7275ab9b9fSStefano Zampini   PetscErrorCode ierr;
7375ab9b9fSStefano Zampini 
7475ab9b9fSStefano Zampini   PetscFunctionBegin;
753ec1f749SStefano Zampini   ierr = MatShellGetContext(S,&userdata);CHKERRQ(ierr);
76*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!userdata,PetscObjectComm((PetscObject)S),PETSC_ERR_PLIB,"Missing userdata");
7775ab9b9fSStefano Zampini   A = userdata->A;
7875ab9b9fSStefano Zampini   R = userdata->R;
7975ab9b9fSStefano Zampini   P = userdata->P;
80*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A,PetscObjectComm((PetscObject)S),PETSC_ERR_PLIB,"Missing matrix");
81*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!R && !P,PetscObjectComm((PetscObject)S),PETSC_ERR_PLIB,"Missing projectors");
82*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(R && P,PetscObjectComm((PetscObject)S),PETSC_ERR_PLIB,"Both projectors");
8375ab9b9fSStefano Zampini   ierr = MatCreateVecs(A,&Ax,&Ay);CHKERRQ(ierr);
8475ab9b9fSStefano Zampini   if (R) {
8575ab9b9fSStefano Zampini     ierr = MatCreateVecs(R,&Py,&Px);CHKERRQ(ierr);
8675ab9b9fSStefano Zampini   } else {
8775ab9b9fSStefano Zampini     ierr = MatCreateVecs(P,&Px,&Py);CHKERRQ(ierr);
8875ab9b9fSStefano Zampini   }
8975ab9b9fSStefano Zampini   ierr = VecCopy(X,Px);CHKERRQ(ierr);
9075ab9b9fSStefano Zampini   if (P) {
9175ab9b9fSStefano Zampini     ierr = MatMult(P,Px,Py);CHKERRQ(ierr);
9275ab9b9fSStefano Zampini   } else {
9375ab9b9fSStefano Zampini     ierr = MatMultTranspose(R,Px,Py);CHKERRQ(ierr);
9475ab9b9fSStefano Zampini   }
9575ab9b9fSStefano Zampini   ierr = VecCopy(Py,Ax);CHKERRQ(ierr);
9675ab9b9fSStefano Zampini   ierr = MatMult(A,Ax,Ay);CHKERRQ(ierr);
9775ab9b9fSStefano Zampini   ierr = VecCopy(Ay,Py);CHKERRQ(ierr);
9875ab9b9fSStefano Zampini   if (P) {
9975ab9b9fSStefano Zampini     ierr = MatMultTranspose(P,Py,Px);CHKERRQ(ierr);
10075ab9b9fSStefano Zampini   } else {
10175ab9b9fSStefano Zampini     ierr = MatMult(R,Py,Px);CHKERRQ(ierr);
10275ab9b9fSStefano Zampini   }
10375ab9b9fSStefano Zampini   ierr = VecCopy(Px,Y);CHKERRQ(ierr);
10475ab9b9fSStefano Zampini   ierr = VecDestroy(&Px);CHKERRQ(ierr);
10575ab9b9fSStefano Zampini   ierr = VecDestroy(&Py);CHKERRQ(ierr);
10675ab9b9fSStefano Zampini   ierr = VecDestroy(&Ax);CHKERRQ(ierr);
10775ab9b9fSStefano Zampini   ierr = VecDestroy(&Ay);CHKERRQ(ierr);
10875ab9b9fSStefano Zampini   PetscFunctionReturn(0);
10975ab9b9fSStefano Zampini }
11075ab9b9fSStefano Zampini 
11175ab9b9fSStefano Zampini PetscErrorCode MyPtShellPMultSymbolic(Mat S, Mat P, Mat PtAP, void** ctx)
11275ab9b9fSStefano Zampini {
11375ab9b9fSStefano Zampini   PetscErrorCode ierr;
11475ab9b9fSStefano Zampini   proj_data      *userdata;
11575ab9b9fSStefano Zampini 
11675ab9b9fSStefano Zampini   PetscFunctionBegin;
11775ab9b9fSStefano Zampini   ierr = PetscNew(&userdata);CHKERRQ(ierr);
1183ec1f749SStefano Zampini   ierr = MatShellSetContext(PtAP,userdata);CHKERRQ(ierr);
11975ab9b9fSStefano Zampini   *ctx = (void *)userdata;
12075ab9b9fSStefano Zampini   PetscFunctionReturn(0);
12175ab9b9fSStefano Zampini }
12275ab9b9fSStefano Zampini 
12375ab9b9fSStefano Zampini PetscErrorCode MyPtShellPMultNumeric(Mat S, Mat P, Mat PtAP, void *ctx)
12475ab9b9fSStefano Zampini {
12575ab9b9fSStefano Zampini   Mat            A;
12675ab9b9fSStefano Zampini   PetscErrorCode ierr;
12775ab9b9fSStefano Zampini   proj_data      *userdata = (proj_data*)ctx;
12875ab9b9fSStefano Zampini 
12975ab9b9fSStefano Zampini   PetscFunctionBegin;
1303ec1f749SStefano Zampini   ierr = MatShellGetContext(S,&A);CHKERRQ(ierr);
13175ab9b9fSStefano Zampini   ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
13275ab9b9fSStefano Zampini   ierr = PetscObjectReference((PetscObject)P);CHKERRQ(ierr);
13375ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->A);CHKERRQ(ierr);
13475ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->P);CHKERRQ(ierr);
13575ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->R);CHKERRQ(ierr);
13675ab9b9fSStefano Zampini   userdata->A = A;
13775ab9b9fSStefano Zampini   userdata->P = P;
13875ab9b9fSStefano Zampini   ierr = MatShellSetOperation(PtAP,MATOP_MULT,(void (*)(void))proj_mult);CHKERRQ(ierr);
13975ab9b9fSStefano Zampini   ierr = MatSetUp(PtAP);CHKERRQ(ierr);
14075ab9b9fSStefano Zampini   ierr = MatAssemblyBegin(PtAP,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14175ab9b9fSStefano Zampini   ierr = MatAssemblyEnd(PtAP,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14275ab9b9fSStefano Zampini   PetscFunctionReturn(0);
14375ab9b9fSStefano Zampini }
14475ab9b9fSStefano Zampini 
14575ab9b9fSStefano Zampini PetscErrorCode MyRShellRtMultSymbolic(Mat S, Mat R, Mat RARt, void **ctx)
14675ab9b9fSStefano Zampini {
14775ab9b9fSStefano Zampini   PetscErrorCode ierr;
14875ab9b9fSStefano Zampini   proj_data      *userdata;
14975ab9b9fSStefano Zampini 
15075ab9b9fSStefano Zampini   PetscFunctionBegin;
15175ab9b9fSStefano Zampini   ierr = PetscNew(&userdata);CHKERRQ(ierr);
1523ec1f749SStefano Zampini   ierr = MatShellSetContext(RARt,userdata);CHKERRQ(ierr);
15375ab9b9fSStefano Zampini   *ctx = (void *)userdata;
15475ab9b9fSStefano Zampini   PetscFunctionReturn(0);
15575ab9b9fSStefano Zampini }
15675ab9b9fSStefano Zampini 
15775ab9b9fSStefano Zampini PetscErrorCode MyRShellRtMultNumeric(Mat S, Mat R, Mat RARt, void *ctx)
15875ab9b9fSStefano Zampini {
15975ab9b9fSStefano Zampini   Mat            A;
16075ab9b9fSStefano Zampini   PetscErrorCode ierr;
16175ab9b9fSStefano Zampini   proj_data      *userdata = (proj_data*)ctx;
16275ab9b9fSStefano Zampini 
16375ab9b9fSStefano Zampini   PetscFunctionBegin;
1643ec1f749SStefano Zampini   ierr = MatShellGetContext(S,&A);CHKERRQ(ierr);
16575ab9b9fSStefano Zampini   ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
16675ab9b9fSStefano Zampini   ierr = PetscObjectReference((PetscObject)R);CHKERRQ(ierr);
16775ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->A);CHKERRQ(ierr);
16875ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->P);CHKERRQ(ierr);
16975ab9b9fSStefano Zampini   ierr = MatDestroy(&userdata->R);CHKERRQ(ierr);
17075ab9b9fSStefano Zampini   userdata->A = A;
17175ab9b9fSStefano Zampini   userdata->R = R;
17275ab9b9fSStefano Zampini   ierr = MatShellSetOperation(RARt,MATOP_MULT,(void (*)(void))proj_mult);CHKERRQ(ierr);
17375ab9b9fSStefano Zampini   ierr = MatSetUp(RARt);CHKERRQ(ierr);
17475ab9b9fSStefano Zampini   ierr = MatAssemblyBegin(RARt,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17575ab9b9fSStefano Zampini   ierr = MatAssemblyEnd(RARt,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17675ab9b9fSStefano Zampini   PetscFunctionReturn(0);
17775ab9b9fSStefano Zampini }
17875ab9b9fSStefano Zampini 
17975ab9b9fSStefano Zampini PetscErrorCode MyMatShellMatMultNumeric(Mat S, Mat B, Mat C, void *ctx)
18075ab9b9fSStefano Zampini {
18175ab9b9fSStefano Zampini   PetscErrorCode ierr;
18275ab9b9fSStefano Zampini   Mat            A;
18375ab9b9fSStefano Zampini 
18475ab9b9fSStefano Zampini   PetscFunctionBegin;
1853ec1f749SStefano Zampini   ierr = MatShellGetContext(S,&A);CHKERRQ(ierr);
18675ab9b9fSStefano Zampini   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
18775ab9b9fSStefano Zampini   PetscFunctionReturn(0);
18875ab9b9fSStefano Zampini }
18975ab9b9fSStefano Zampini 
19075ab9b9fSStefano Zampini PetscErrorCode MyMatTransposeShellMatMultNumeric(Mat S, Mat B, Mat C, void *ctx)
19175ab9b9fSStefano Zampini {
19275ab9b9fSStefano Zampini   PetscErrorCode ierr;
19375ab9b9fSStefano Zampini   Mat            A;
19475ab9b9fSStefano Zampini 
19575ab9b9fSStefano Zampini   PetscFunctionBegin;
1963ec1f749SStefano Zampini   ierr = MatShellGetContext(S,&A);CHKERRQ(ierr);
19775ab9b9fSStefano Zampini   ierr = MatTransposeMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
19875ab9b9fSStefano Zampini   PetscFunctionReturn(0);
19975ab9b9fSStefano Zampini }
20075ab9b9fSStefano Zampini 
20175ab9b9fSStefano Zampini PetscErrorCode MyMatShellMatTransposeMultNumeric(Mat S, Mat B, Mat C, void *ctx)
20275ab9b9fSStefano Zampini {
20375ab9b9fSStefano Zampini   PetscErrorCode ierr;
20475ab9b9fSStefano Zampini   Mat            A;
20575ab9b9fSStefano Zampini 
20675ab9b9fSStefano Zampini   PetscFunctionBegin;
2073ec1f749SStefano Zampini   ierr = MatShellGetContext(S,&A);CHKERRQ(ierr);
20875ab9b9fSStefano Zampini   ierr = MatMatTransposeMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
2096280154eSStefano Zampini   PetscFunctionReturn(0);
2106280154eSStefano Zampini }
2116280154eSStefano Zampini 
2126280154eSStefano Zampini int main(int argc,char **args)
2136280154eSStefano Zampini {
21475ab9b9fSStefano Zampini   Mat            X,B,A,Bt,T,T2,PtAP = NULL,RARt = NULL, R = NULL;
21575ab9b9fSStefano Zampini   Vec            r,l,rs,ls;
21675ab9b9fSStefano Zampini   PetscInt       m,n,k,M = 10,N = 10,K = 5, ldx = 3, ldb = 5, ldr = 4;
2176280154eSStefano Zampini   const char     *deft = MATAIJ;
2186280154eSStefano Zampini   char           mattype[256];
2196280154eSStefano Zampini   PetscBool      flg,symm = PETSC_FALSE,testtt = PETSC_TRUE, testnest = PETSC_TRUE, testtranspose = PETSC_TRUE, testcircular = PETSC_FALSE, local = PETSC_TRUE;
2203604c0aeSStefano Zampini   PetscBool      testhtranspose = PETSC_TRUE;
22175ab9b9fSStefano Zampini   PetscBool      xgpu = PETSC_FALSE, bgpu = PETSC_FALSE, testshellops = PETSC_FALSE, testproj = PETSC_TRUE, testrart = PETSC_TRUE, testmatmatt = PETSC_TRUE, testmattmat = PETSC_TRUE;
22275ab9b9fSStefano Zampini   PetscScalar    *dataX = NULL,*dataB = NULL, *dataR = NULL, *dataBt = NULL;
22375ab9b9fSStefano Zampini   PetscScalar    *aX,*aB,*aBt;
224456288a8SStefano Zampini   PetscReal      err;
2256280154eSStefano Zampini   PetscErrorCode ierr;
2266280154eSStefano Zampini 
2276280154eSStefano Zampini   ierr = PetscInitialize(&argc,&args,NULL,help);if (ierr) return ierr;
2286280154eSStefano Zampini   ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr);
2296280154eSStefano Zampini   ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr);
2306280154eSStefano Zampini   ierr = PetscOptionsGetInt(NULL,NULL,"-K",&K,NULL);CHKERRQ(ierr);
2316280154eSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-symm",&symm,NULL);CHKERRQ(ierr);
2326280154eSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-local",&local,NULL);CHKERRQ(ierr);
2336280154eSStefano Zampini   ierr = PetscOptionsGetInt(NULL,NULL,"-ldx",&ldx,NULL);CHKERRQ(ierr);
2346280154eSStefano Zampini   ierr = PetscOptionsGetInt(NULL,NULL,"-ldb",&ldb,NULL);CHKERRQ(ierr);
23575ab9b9fSStefano Zampini   ierr = PetscOptionsGetInt(NULL,NULL,"-ldr",&ldr,NULL);CHKERRQ(ierr);
2366280154eSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testtranspose",&testtranspose,NULL);CHKERRQ(ierr);
2376280154eSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testnest",&testnest,NULL);CHKERRQ(ierr);
2386280154eSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testtt",&testtt,NULL);CHKERRQ(ierr);
2396280154eSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testcircular",&testcircular,NULL);CHKERRQ(ierr);
24075ab9b9fSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testshellops",&testshellops,NULL);CHKERRQ(ierr);
24175ab9b9fSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testproj",&testproj,NULL);CHKERRQ(ierr);
24275ab9b9fSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testrart",&testrart,NULL);CHKERRQ(ierr);
24375ab9b9fSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testmatmatt",&testmatmatt,NULL);CHKERRQ(ierr);
24475ab9b9fSStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-testmattmat",&testmattmat,NULL);CHKERRQ(ierr);
245456288a8SStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-xgpu",&xgpu,NULL);CHKERRQ(ierr);
246456288a8SStefano Zampini   ierr = PetscOptionsGetBool(NULL,NULL,"-bgpu",&bgpu,NULL);CHKERRQ(ierr);
24775ab9b9fSStefano Zampini   ierr = PetscOptionsGetScalar(NULL,NULL,"-magic_number",&MAGIC_NUMBER,NULL);CHKERRQ(ierr);
24875ab9b9fSStefano Zampini   if (M != N) testproj = PETSC_FALSE;
24975ab9b9fSStefano Zampini 
2506280154eSStefano Zampini   ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
2516280154eSStefano Zampini   ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2526280154eSStefano Zampini   ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr);
2536280154eSStefano Zampini   ierr = MatSetUp(A);CHKERRQ(ierr);
2546280154eSStefano Zampini   ierr = MatSetRandom(A,NULL);CHKERRQ(ierr);
2556280154eSStefano Zampini   if (M==N && symm) {
2566280154eSStefano Zampini     Mat AT;
2576280154eSStefano Zampini 
25875ab9b9fSStefano Zampini     ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&AT);CHKERRQ(ierr);
2596280154eSStefano Zampini     ierr = MatAXPY(A,1.0,AT,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
2606280154eSStefano Zampini     ierr = MatDestroy(&AT);CHKERRQ(ierr);
26175ab9b9fSStefano Zampini     ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
2626280154eSStefano Zampini   }
2636280154eSStefano Zampini   ierr = MatViewFromOptions(A,NULL,"-A_init_view");CHKERRQ(ierr);
2646280154eSStefano Zampini   ierr = PetscOptionsBegin(PETSC_COMM_WORLD,"","","");CHKERRQ(ierr);
265456288a8SStefano Zampini   ierr = PetscOptionsFList("-A_mat_type","Matrix type","MatSetType",MatList,deft,mattype,256,&flg);CHKERRQ(ierr);
2666280154eSStefano Zampini   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2676280154eSStefano Zampini   if (flg) {
2686280154eSStefano Zampini     Mat A2;
2696280154eSStefano Zampini 
270456288a8SStefano Zampini     ierr = MatDuplicate(A,MAT_COPY_VALUES,&A2);CHKERRQ(ierr);
271456288a8SStefano Zampini     ierr = MatConvert(A,mattype,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr);
2726280154eSStefano Zampini     ierr = MatMultEqual(A,A2,10,&flg);CHKERRQ(ierr);
2736280154eSStefano Zampini     if (!flg) {
2746280154eSStefano Zampini       Mat AE,A2E;
2756280154eSStefano Zampini 
2766280154eSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with convert\n");CHKERRQ(ierr);
2776280154eSStefano Zampini       ierr = MatComputeOperator(A,MATDENSE,&AE);CHKERRQ(ierr);
2786280154eSStefano Zampini       ierr = MatComputeOperator(A2,MATDENSE,&A2E);CHKERRQ(ierr);
2796280154eSStefano Zampini       ierr = MatView(AE,NULL);CHKERRQ(ierr);
2806280154eSStefano Zampini       ierr = MatView(A2E,NULL);CHKERRQ(ierr);
2816280154eSStefano Zampini       ierr = MatAXPY(A2E,-1.0,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2826280154eSStefano Zampini       ierr = MatView(A2E,NULL);CHKERRQ(ierr);
2836280154eSStefano Zampini       ierr = MatDestroy(&A2E);CHKERRQ(ierr);
2846280154eSStefano Zampini       ierr = MatDestroy(&AE);CHKERRQ(ierr);
2856280154eSStefano Zampini     }
286456288a8SStefano Zampini     ierr = MatDestroy(&A2);CHKERRQ(ierr);
2876280154eSStefano Zampini   }
2886280154eSStefano Zampini   ierr = MatViewFromOptions(A,NULL,"-A_view");CHKERRQ(ierr);
2896280154eSStefano Zampini 
2906280154eSStefano Zampini   ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
2916280154eSStefano Zampini   if (local) {
29275ab9b9fSStefano Zampini     PetscInt i;
29375ab9b9fSStefano Zampini 
294a0638e9dSStefano Zampini     ierr = PetscMalloc1((m+ldx)*K,&dataX);CHKERRQ(ierr);
295a0638e9dSStefano Zampini     ierr = PetscMalloc1((n+ldb)*K,&dataB);CHKERRQ(ierr);
296a0638e9dSStefano Zampini     for (i=0;i<(m+ldx)*K;i++) dataX[i] = MAGIC_NUMBER;
297a0638e9dSStefano Zampini     for (i=0;i<(n+ldb)*K;i++) dataB[i] = MAGIC_NUMBER;
2986280154eSStefano Zampini   }
2996280154eSStefano Zampini   ierr = MatCreateDense(PETSC_COMM_WORLD,n,PETSC_DECIDE,N,K,dataB,&B);CHKERRQ(ierr);
3006280154eSStefano Zampini   ierr = MatCreateDense(PETSC_COMM_WORLD,m,PETSC_DECIDE,M,K,dataX,&X);CHKERRQ(ierr);
30175ab9b9fSStefano Zampini   if (local) {
30275ab9b9fSStefano Zampini     ierr = MatDenseSetLDA(X,m+ldx);CHKERRQ(ierr);
30375ab9b9fSStefano Zampini     ierr = MatDenseSetLDA(B,n+ldb);CHKERRQ(ierr);
30475ab9b9fSStefano Zampini   }
30575ab9b9fSStefano Zampini   ierr = MatGetLocalSize(B,NULL,&k);CHKERRQ(ierr);
30675ab9b9fSStefano Zampini   if (local) {
30775ab9b9fSStefano Zampini     PetscInt i;
30875ab9b9fSStefano Zampini 
309a0638e9dSStefano Zampini     ierr = PetscMalloc1((k+ldr)*N,&dataBt);CHKERRQ(ierr);
310a0638e9dSStefano Zampini     for (i=0;i<(k+ldr)*N;i++) dataBt[i] = MAGIC_NUMBER;
31175ab9b9fSStefano Zampini   }
31275ab9b9fSStefano Zampini   ierr = MatCreateDense(PETSC_COMM_WORLD,k,n,K,N,dataBt,&Bt);CHKERRQ(ierr);
31375ab9b9fSStefano Zampini   if (local) {
31475ab9b9fSStefano Zampini     ierr = MatDenseSetLDA(Bt,k+ldr);CHKERRQ(ierr);
31575ab9b9fSStefano Zampini   }
3166280154eSStefano Zampini 
3176280154eSStefano Zampini   /* store pointer to dense data for testing */
3186280154eSStefano Zampini   ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&dataB);CHKERRQ(ierr);
3196280154eSStefano Zampini   ierr = MatDenseGetArrayRead(X,(const PetscScalar**)&dataX);CHKERRQ(ierr);
32075ab9b9fSStefano Zampini   ierr = MatDenseGetArrayRead(Bt,(const PetscScalar**)&dataBt);CHKERRQ(ierr);
3216280154eSStefano Zampini   aX   = dataX;
3226280154eSStefano Zampini   aB   = dataB;
32375ab9b9fSStefano Zampini   aBt  = dataBt;
32475ab9b9fSStefano Zampini   ierr = MatDenseRestoreArrayRead(Bt,(const PetscScalar**)&dataBt);CHKERRQ(ierr);
3256280154eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&dataB);CHKERRQ(ierr);
3266280154eSStefano Zampini   ierr = MatDenseRestoreArrayRead(X,(const PetscScalar**)&dataX);CHKERRQ(ierr);
3276280154eSStefano Zampini   if (local) {
3286280154eSStefano Zampini     dataX  = aX;
3296280154eSStefano Zampini     dataB  = aB;
33075ab9b9fSStefano Zampini     dataBt = aBt;
3316280154eSStefano Zampini   }
33275ab9b9fSStefano Zampini 
33375ab9b9fSStefano Zampini   ierr = MatSetRandom(X,NULL);CHKERRQ(ierr);
3346280154eSStefano Zampini   ierr = MatSetRandom(B,NULL);CHKERRQ(ierr);
33575ab9b9fSStefano Zampini   ierr = MatSetRandom(Bt,NULL);CHKERRQ(ierr);
33675ab9b9fSStefano Zampini   ierr = CheckLocal(X,NULL,aX,NULL);CHKERRQ(ierr);
33775ab9b9fSStefano Zampini   ierr = CheckLocal(Bt,B,aBt,aB);CHKERRQ(ierr);
33875ab9b9fSStefano Zampini 
339456288a8SStefano Zampini   /* convert to CUDA if needed */
340456288a8SStefano Zampini   if (bgpu) {
341456288a8SStefano Zampini     ierr = MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr);
34275ab9b9fSStefano Zampini     ierr = MatConvert(Bt,MATDENSECUDA,MAT_INPLACE_MATRIX,&Bt);CHKERRQ(ierr);
343456288a8SStefano Zampini   }
344456288a8SStefano Zampini   if (xgpu) {
345456288a8SStefano Zampini     ierr = MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X);CHKERRQ(ierr);
346456288a8SStefano Zampini   }
347456288a8SStefano Zampini   ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
3486280154eSStefano Zampini 
349e7b38fdfSStefano Zampini   /* Test MatDenseGetSubMatrix */
350e7b38fdfSStefano Zampini   {
351e7b38fdfSStefano Zampini     Mat B2,T3,T4;
352e7b38fdfSStefano Zampini 
353e7b38fdfSStefano Zampini     ierr = MatDuplicate(B,MAT_COPY_VALUES,&B2);CHKERRQ(ierr);
354e7b38fdfSStefano Zampini     ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&T4);CHKERRQ(ierr);
355e7b38fdfSStefano Zampini     ierr = MatSetRandom(T4,NULL);CHKERRQ(ierr);
356e7b38fdfSStefano Zampini     ierr = MatAXPY(B2,1.0,T4,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
357e7b38fdfSStefano Zampini     ierr = MatDenseGetSubMatrix(B,PetscMin(1,K),PetscMin(2,K),&T);CHKERRQ(ierr);
358e7b38fdfSStefano Zampini     ierr = MatDenseGetSubMatrix(T4,PetscMin(1,K),PetscMin(2,K),&T2);CHKERRQ(ierr);
359e7b38fdfSStefano Zampini     ierr = MatDenseGetSubMatrix(B2,PetscMin(1,K),PetscMin(2,K),&T3);CHKERRQ(ierr);
360e7b38fdfSStefano Zampini     ierr = MatAXPY(T,1.0,T2,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
361e7b38fdfSStefano Zampini     ierr = MatAXPY(T3,-1.0,T,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
362e7b38fdfSStefano Zampini     ierr = MatNorm(T3,NORM_FROBENIUS,&err);CHKERRQ(ierr);
363e7b38fdfSStefano Zampini     if (err > PETSC_SMALL) {
364e7b38fdfSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with MatDenseGetSubMatrix\n");CHKERRQ(ierr);
365e7b38fdfSStefano Zampini       ierr = MatView(T3,NULL);CHKERRQ(ierr);
366e7b38fdfSStefano Zampini     }
367e7b38fdfSStefano Zampini     ierr = MatDenseRestoreSubMatrix(B,&T);CHKERRQ(ierr);
368e7b38fdfSStefano Zampini     ierr = MatDenseRestoreSubMatrix(T4,&T2);CHKERRQ(ierr);
369e7b38fdfSStefano Zampini     ierr = MatDenseRestoreSubMatrix(B2,&T3);CHKERRQ(ierr);
370e7b38fdfSStefano Zampini     ierr = CheckLocal(B,NULL,aB,NULL);CHKERRQ(ierr);
371e7b38fdfSStefano Zampini     ierr = MatDestroy(&B2);CHKERRQ(ierr);
372e7b38fdfSStefano Zampini     ierr = MatDestroy(&T4);CHKERRQ(ierr);
373e7b38fdfSStefano Zampini   }
374e7b38fdfSStefano Zampini 
3756280154eSStefano Zampini   /* Test reusing a previously allocated dense buffer */
3766280154eSStefano Zampini   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X);CHKERRQ(ierr);
3776280154eSStefano Zampini   ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
3786280154eSStefano Zampini   ierr = MatMatMultEqual(A,B,X,10,&flg);CHKERRQ(ierr);
3796280154eSStefano Zampini   if (!flg) {
3806280154eSStefano Zampini     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with reusage\n");CHKERRQ(ierr);
3816280154eSStefano Zampini     ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
3826280154eSStefano Zampini     ierr = MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
3836280154eSStefano Zampini     ierr = MatView(T,NULL);CHKERRQ(ierr);
3846280154eSStefano Zampini     ierr = MatDestroy(&T);CHKERRQ(ierr);
3856280154eSStefano Zampini   }
3866280154eSStefano Zampini 
38775ab9b9fSStefano Zampini   /* Test MatTransposeMat and MatMatTranspose */
38875ab9b9fSStefano Zampini   if (testmattmat) {
38975ab9b9fSStefano Zampini     ierr = MatTransposeMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr);
39075ab9b9fSStefano Zampini     ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
39175ab9b9fSStefano Zampini     ierr = MatTransposeMatMultEqual(A,X,B,10,&flg);CHKERRQ(ierr);
39275ab9b9fSStefano Zampini     if (!flg) {
39375ab9b9fSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MatTransposeMat)\n");CHKERRQ(ierr);
39475ab9b9fSStefano Zampini       ierr = MatTransposeMatMult(A,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr);
39575ab9b9fSStefano Zampini       ierr = MatAXPY(T,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
39675ab9b9fSStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
39775ab9b9fSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
39875ab9b9fSStefano Zampini     }
39975ab9b9fSStefano Zampini   }
40075ab9b9fSStefano Zampini   if (testmatmatt) {
40175ab9b9fSStefano Zampini     ierr = MatMatTransposeMult(A,Bt,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X);CHKERRQ(ierr);
40275ab9b9fSStefano Zampini     ierr = CheckLocal(Bt,X,aBt,aX);CHKERRQ(ierr);
40375ab9b9fSStefano Zampini     ierr = MatMatTransposeMultEqual(A,Bt,X,10,&flg);CHKERRQ(ierr);
40475ab9b9fSStefano Zampini     if (!flg) {
40575ab9b9fSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MatMatTranspose)\n");CHKERRQ(ierr);
40675ab9b9fSStefano Zampini       ierr = MatMatTransposeMult(A,Bt,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
40775ab9b9fSStefano Zampini       ierr = MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
40875ab9b9fSStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
40975ab9b9fSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
41075ab9b9fSStefano Zampini     }
41175ab9b9fSStefano Zampini   }
41275ab9b9fSStefano Zampini 
41375ab9b9fSStefano Zampini   /* Test projection operations (PtAP and RARt) */
41475ab9b9fSStefano Zampini   if (testproj) {
41575ab9b9fSStefano Zampini     ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&PtAP);CHKERRQ(ierr);
41675ab9b9fSStefano Zampini     ierr = MatPtAPMultEqual(A,B,PtAP,10,&flg);CHKERRQ(ierr);
41775ab9b9fSStefano Zampini     if (!flg) {
41875ab9b9fSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with PtAP\n");CHKERRQ(ierr);
41975ab9b9fSStefano Zampini       ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
42075ab9b9fSStefano Zampini       ierr = MatTransposeMatMult(B,T,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T2);CHKERRQ(ierr);
42175ab9b9fSStefano Zampini       ierr = MatAXPY(T2,-1.0,PtAP,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
42275ab9b9fSStefano Zampini       ierr = MatView(T2,NULL);CHKERRQ(ierr);
42375ab9b9fSStefano Zampini       ierr = MatDestroy(&T2);CHKERRQ(ierr);
42475ab9b9fSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
42575ab9b9fSStefano Zampini     }
426a0638e9dSStefano Zampini     ierr = PetscMalloc1((k+ldr)*M,&dataR);CHKERRQ(ierr);
42775ab9b9fSStefano Zampini     ierr = MatCreateDense(PETSC_COMM_WORLD,PETSC_DECIDE,m,K,M,dataR,&R);CHKERRQ(ierr);
42875ab9b9fSStefano Zampini     ierr = MatDenseSetLDA(R,k+ldr);CHKERRQ(ierr);
42975ab9b9fSStefano Zampini     ierr = MatSetRandom(R,NULL);CHKERRQ(ierr);
43075ab9b9fSStefano Zampini     if (testrart) { /* fails for AIJCUSPARSE because RA operation is not defined */
43175ab9b9fSStefano Zampini       ierr = MatRARt(A,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&RARt);CHKERRQ(ierr);
43275ab9b9fSStefano Zampini       ierr = MatRARtMultEqual(A,R,RARt,10,&flg);CHKERRQ(ierr);
43375ab9b9fSStefano Zampini       if (!flg) {
43475ab9b9fSStefano Zampini         ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with RARt\n");CHKERRQ(ierr);
43575ab9b9fSStefano Zampini         ierr = MatMatTransposeMult(A,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
43675ab9b9fSStefano Zampini         ierr = MatMatMult(R,T,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T2);CHKERRQ(ierr);
43775ab9b9fSStefano Zampini         ierr = MatAXPY(T2,-1.0,RARt,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
43875ab9b9fSStefano Zampini         ierr = MatView(T2,NULL);CHKERRQ(ierr);
43975ab9b9fSStefano Zampini         ierr = MatDestroy(&T2);CHKERRQ(ierr);
44075ab9b9fSStefano Zampini         ierr = MatDestroy(&T);CHKERRQ(ierr);
44175ab9b9fSStefano Zampini       }
44275ab9b9fSStefano Zampini     }
44375ab9b9fSStefano Zampini   }
44475ab9b9fSStefano Zampini 
445456288a8SStefano Zampini   /* Test MatDenseGetColumnVec and friends */
44675ab9b9fSStefano Zampini   ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X);CHKERRQ(ierr);
447456288a8SStefano Zampini   ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
448456288a8SStefano Zampini   ierr = MatDuplicate(T,MAT_DO_NOT_COPY_VALUES,&T2);CHKERRQ(ierr);
449456288a8SStefano Zampini   for (k=0;k<K;k++) {
450456288a8SStefano Zampini     Vec Xv,Tv,T2v;
451456288a8SStefano Zampini 
452456288a8SStefano Zampini     ierr = MatDenseGetColumnVecRead(X,k,&Xv);CHKERRQ(ierr);
453456288a8SStefano Zampini     ierr = MatDenseGetColumnVec(T,k,&Tv);CHKERRQ(ierr);
454456288a8SStefano Zampini     ierr = MatDenseGetColumnVecWrite(T2,k,&T2v);CHKERRQ(ierr);
455456288a8SStefano Zampini     ierr = VecCopy(Xv,T2v);CHKERRQ(ierr);
456456288a8SStefano Zampini     ierr = VecAXPY(Tv,-1.,Xv);CHKERRQ(ierr);
457456288a8SStefano Zampini     ierr = MatDenseRestoreColumnVecRead(X,k,&Xv);CHKERRQ(ierr);
458456288a8SStefano Zampini     ierr = MatDenseRestoreColumnVec(T,k,&Tv);CHKERRQ(ierr);
459456288a8SStefano Zampini     ierr = MatDenseRestoreColumnVecWrite(T2,k,&T2v);CHKERRQ(ierr);
460456288a8SStefano Zampini   }
461456288a8SStefano Zampini   ierr = MatNorm(T,NORM_FROBENIUS,&err);CHKERRQ(ierr);
462456288a8SStefano Zampini   if (err > PETSC_SMALL) {
463456288a8SStefano Zampini     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with MatDenseGetColumnVec\n");CHKERRQ(ierr);
464456288a8SStefano Zampini     ierr = MatView(T,NULL);CHKERRQ(ierr);
465456288a8SStefano Zampini   }
466456288a8SStefano Zampini   ierr = MatAXPY(T2,-1.,X,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
467456288a8SStefano Zampini   ierr = MatNorm(T2,NORM_FROBENIUS,&err);CHKERRQ(ierr);
468456288a8SStefano Zampini   if (err > PETSC_SMALL) {
469456288a8SStefano Zampini     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with MatDenseGetColumnVecWrite\n");CHKERRQ(ierr);
470456288a8SStefano Zampini     ierr = MatView(T2,NULL);CHKERRQ(ierr);
471456288a8SStefano Zampini   }
472456288a8SStefano Zampini   ierr = MatDestroy(&T);CHKERRQ(ierr);
473456288a8SStefano Zampini   ierr = MatDestroy(&T2);CHKERRQ(ierr);
474456288a8SStefano Zampini 
475456288a8SStefano Zampini   /* Test with MatShell */
47675ab9b9fSStefano Zampini   ierr = MatDuplicate(A,MAT_COPY_VALUES,&T);CHKERRQ(ierr);
47775ab9b9fSStefano Zampini   ierr = MatConvert(T,MATSHELL,MAT_INITIAL_MATRIX,&T2);CHKERRQ(ierr);
47875ab9b9fSStefano Zampini   ierr = MatDestroy(&T);CHKERRQ(ierr);
47975ab9b9fSStefano Zampini 
48075ab9b9fSStefano Zampini   /* scale matrix */
48175ab9b9fSStefano Zampini   ierr = MatScale(A,2.0);CHKERRQ(ierr);
48275ab9b9fSStefano Zampini   ierr = MatScale(T2,2.0);CHKERRQ(ierr);
48375ab9b9fSStefano Zampini   ierr = MatCreateVecs(A,&r,&l);CHKERRQ(ierr);
48475ab9b9fSStefano Zampini   ierr = VecSetRandom(r,NULL);CHKERRQ(ierr);
48575ab9b9fSStefano Zampini   ierr = VecSetRandom(l,NULL);CHKERRQ(ierr);
48675ab9b9fSStefano Zampini   ierr = MatCreateVecs(T2,&rs,&ls);CHKERRQ(ierr);
48775ab9b9fSStefano Zampini   ierr = VecCopy(r,rs);CHKERRQ(ierr);
48875ab9b9fSStefano Zampini   ierr = VecCopy(l,ls);CHKERRQ(ierr);
48975ab9b9fSStefano Zampini   if (testproj) {
49075ab9b9fSStefano Zampini     ierr = MatDiagonalScale(A,r,r);CHKERRQ(ierr);
49175ab9b9fSStefano Zampini     ierr = MatDiagonalScale(T2,rs,rs);CHKERRQ(ierr);
49275ab9b9fSStefano Zampini   } else {
49375ab9b9fSStefano Zampini     ierr = MatDiagonalScale(A,l,r);CHKERRQ(ierr);
49475ab9b9fSStefano Zampini     ierr = MatDiagonalScale(T2,ls,rs);CHKERRQ(ierr);
49575ab9b9fSStefano Zampini   }
49675ab9b9fSStefano Zampini   ierr = MatDuplicate(A,MAT_COPY_VALUES,&T);CHKERRQ(ierr);
49775ab9b9fSStefano Zampini   ierr = MatAXPY(A,4.5,T,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
49875ab9b9fSStefano Zampini   ierr = MatAXPY(T2,4.5,T,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
49975ab9b9fSStefano Zampini   ierr = MatMultEqual(T2,A,10,&flg);CHKERRQ(ierr);
50075ab9b9fSStefano Zampini   if (!flg) {
50175ab9b9fSStefano Zampini     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with MATSHELL (MatMult)\n");CHKERRQ(ierr);
50275ab9b9fSStefano Zampini   }
50375ab9b9fSStefano Zampini   ierr = MatMultTransposeEqual(T2,A,10,&flg);CHKERRQ(ierr);
50475ab9b9fSStefano Zampini   if (!flg) {
50575ab9b9fSStefano Zampini     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with MATSHELL (MatMultTranspose)\n");CHKERRQ(ierr);
50675ab9b9fSStefano Zampini   }
50775ab9b9fSStefano Zampini   ierr = MatDestroy(&T);CHKERRQ(ierr);
50875ab9b9fSStefano Zampini   ierr = VecDestroy(&ls);CHKERRQ(ierr);
50975ab9b9fSStefano Zampini   ierr = VecDestroy(&rs);CHKERRQ(ierr);
51075ab9b9fSStefano Zampini   ierr = VecDestroy(&l);CHKERRQ(ierr);
51175ab9b9fSStefano Zampini   ierr = VecDestroy(&r);CHKERRQ(ierr);
51275ab9b9fSStefano Zampini 
51375ab9b9fSStefano Zampini   /* recompute projections, test reusage */
51475ab9b9fSStefano Zampini   if (PtAP) { ierr = MatPtAP(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&PtAP);CHKERRQ(ierr); }
51575ab9b9fSStefano Zampini   if (RARt) { ierr = MatRARt(A,R,MAT_REUSE_MATRIX,PETSC_DEFAULT,&RARt);CHKERRQ(ierr); }
51675ab9b9fSStefano Zampini   if (testshellops) { /* test callbacks for user defined MatProducts */
51775ab9b9fSStefano Zampini     ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_AB,NULL,MyMatShellMatMultNumeric,NULL,MATDENSE,MATDENSE);CHKERRQ(ierr);
51875ab9b9fSStefano Zampini     ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_AB,NULL,MyMatShellMatMultNumeric,NULL,MATDENSECUDA,MATDENSECUDA);CHKERRQ(ierr);
51975ab9b9fSStefano Zampini     ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_AtB,NULL,MyMatTransposeShellMatMultNumeric,NULL,MATDENSE,MATDENSE);CHKERRQ(ierr);
52075ab9b9fSStefano Zampini     ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_AtB,NULL,MyMatTransposeShellMatMultNumeric,NULL,MATDENSECUDA,MATDENSECUDA);CHKERRQ(ierr);
52175ab9b9fSStefano Zampini     ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_ABt,NULL,MyMatShellMatTransposeMultNumeric,NULL,MATDENSE,MATDENSE);CHKERRQ(ierr);
52275ab9b9fSStefano Zampini     ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_ABt,NULL,MyMatShellMatTransposeMultNumeric,NULL,MATDENSECUDA,MATDENSECUDA);CHKERRQ(ierr);
52375ab9b9fSStefano Zampini     if (testproj) {
52475ab9b9fSStefano Zampini       ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_PtAP,MyPtShellPMultSymbolic,MyPtShellPMultNumeric,proj_destroy,MATDENSE,MATSHELL);CHKERRQ(ierr);
52575ab9b9fSStefano Zampini       ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_PtAP,MyPtShellPMultSymbolic,MyPtShellPMultNumeric,proj_destroy,MATDENSECUDA,MATSHELL);CHKERRQ(ierr);
52675ab9b9fSStefano Zampini       ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_RARt,MyRShellRtMultSymbolic,MyRShellRtMultNumeric,proj_destroy,MATDENSE,MATSHELL);CHKERRQ(ierr);
52775ab9b9fSStefano Zampini       ierr = MatShellSetMatProductOperation(T2,MATPRODUCT_RARt,MyRShellRtMultSymbolic,MyRShellRtMultNumeric,proj_destroy,MATDENSECUDA,MATSHELL);CHKERRQ(ierr);
52875ab9b9fSStefano Zampini     }
52975ab9b9fSStefano Zampini   }
53075ab9b9fSStefano Zampini   ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
53175ab9b9fSStefano Zampini   /* we either use the shell operations or the loop over columns code, applying the operator */
532456288a8SStefano Zampini   ierr = MatMatMult(T2,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X);CHKERRQ(ierr);
533456288a8SStefano Zampini   ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
534456288a8SStefano Zampini   ierr = MatMatMultEqual(T2,B,X,10,&flg);CHKERRQ(ierr);
535456288a8SStefano Zampini   if (!flg) {
536456288a8SStefano Zampini     ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MATSHELL)\n");CHKERRQ(ierr);
537456288a8SStefano Zampini     ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
538456288a8SStefano Zampini     ierr = MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
539456288a8SStefano Zampini     ierr = MatView(T,NULL);CHKERRQ(ierr);
540456288a8SStefano Zampini     ierr = MatDestroy(&T);CHKERRQ(ierr);
541456288a8SStefano Zampini   }
54275ab9b9fSStefano Zampini   if (testproj) {
54375ab9b9fSStefano Zampini     ierr = MatPtAPMultEqual(T2,B,PtAP,10,&flg);CHKERRQ(ierr);
54475ab9b9fSStefano Zampini     if (!flg) {
54573d7ae1dSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with PtAP (MATSHELL)\n");CHKERRQ(ierr);
54675ab9b9fSStefano Zampini     }
54775ab9b9fSStefano Zampini     if (testshellops) { /* projections fail if the product operations are not specified */
54875ab9b9fSStefano Zampini       ierr = MatPtAP(T2,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
54975ab9b9fSStefano Zampini       ierr = MatPtAP(T2,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
55075ab9b9fSStefano Zampini       ierr = MatPtAPMultEqual(T2,B,T,10,&flg);CHKERRQ(ierr);
55175ab9b9fSStefano Zampini       if (!flg) {
55275ab9b9fSStefano Zampini         Mat TE;
5536718818eSStefano Zampini 
55473d7ae1dSStefano Zampini         ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with PtAP (MATSHELL user defined)\n");CHKERRQ(ierr);
55575ab9b9fSStefano Zampini         ierr = MatComputeOperator(T,MATDENSE,&TE);CHKERRQ(ierr);
55675ab9b9fSStefano Zampini         ierr = MatView(TE,NULL);CHKERRQ(ierr);
55775ab9b9fSStefano Zampini         ierr = MatView(PtAP,NULL);CHKERRQ(ierr);
55875ab9b9fSStefano Zampini         ierr = MatAXPY(TE,-1.0,PtAP,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
55975ab9b9fSStefano Zampini         ierr = MatView(TE,NULL);CHKERRQ(ierr);
56075ab9b9fSStefano Zampini         ierr = MatDestroy(&TE);CHKERRQ(ierr);
56175ab9b9fSStefano Zampini       }
56275ab9b9fSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
56375ab9b9fSStefano Zampini     }
56475ab9b9fSStefano Zampini     if (RARt) {
56575ab9b9fSStefano Zampini       ierr = MatRARtMultEqual(T2,R,RARt,10,&flg);CHKERRQ(ierr);
56675ab9b9fSStefano Zampini       if (!flg) {
56773d7ae1dSStefano Zampini         ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with RARt (MATSHELL)\n");CHKERRQ(ierr);
56875ab9b9fSStefano Zampini       }
56975ab9b9fSStefano Zampini     }
57075ab9b9fSStefano Zampini     if (testshellops) {
57175ab9b9fSStefano Zampini       ierr = MatRARt(T2,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
57275ab9b9fSStefano Zampini       ierr = MatRARt(T2,R,MAT_REUSE_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
57375ab9b9fSStefano Zampini       ierr = MatRARtMultEqual(T2,R,T,10,&flg);CHKERRQ(ierr);
57475ab9b9fSStefano Zampini       if (!flg) {
57575ab9b9fSStefano Zampini         Mat TE;
57675ab9b9fSStefano Zampini 
57773d7ae1dSStefano Zampini         ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with RARt (MATSHELL user defined)\n");CHKERRQ(ierr);
57875ab9b9fSStefano Zampini         ierr = MatComputeOperator(T,MATDENSE,&TE);CHKERRQ(ierr);
57975ab9b9fSStefano Zampini         ierr = MatView(TE,NULL);CHKERRQ(ierr);
58075ab9b9fSStefano Zampini         if (RARt) {
58175ab9b9fSStefano Zampini           ierr = MatView(RARt,NULL);CHKERRQ(ierr);
58275ab9b9fSStefano Zampini           ierr = MatAXPY(TE,-1.0,RARt,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
58375ab9b9fSStefano Zampini           ierr = MatView(TE,NULL);CHKERRQ(ierr);
58475ab9b9fSStefano Zampini         }
58575ab9b9fSStefano Zampini         ierr = MatDestroy(&TE);CHKERRQ(ierr);
58675ab9b9fSStefano Zampini       }
58775ab9b9fSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
58875ab9b9fSStefano Zampini     }
58975ab9b9fSStefano Zampini   }
59075ab9b9fSStefano Zampini 
59175ab9b9fSStefano Zampini   if (testmattmat) { /* we either use the shell operations or the loop over columns code applying the transposed operator */
592456288a8SStefano Zampini     ierr = MatTransposeMatMult(T2,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr);
593456288a8SStefano Zampini     ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
594456288a8SStefano Zampini     ierr = MatTransposeMatMultEqual(T2,X,B,10,&flg);CHKERRQ(ierr);
595456288a8SStefano Zampini     if (!flg) {
596456288a8SStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MatTranspose, MATSHELL)\n");CHKERRQ(ierr);
5976718818eSStefano Zampini       ierr = MatTransposeMatMult(A,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
5986718818eSStefano Zampini       ierr = MatAXPY(T,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
5996718818eSStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
6006718818eSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
6016718818eSStefano Zampini     }
602456288a8SStefano Zampini   }
60375ab9b9fSStefano Zampini   if (testmatmatt && testshellops) { /* only when shell operations are set */
60475ab9b9fSStefano Zampini     ierr = MatMatTransposeMult(T2,Bt,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X);CHKERRQ(ierr);
60575ab9b9fSStefano Zampini     ierr = CheckLocal(Bt,X,aBt,aX);CHKERRQ(ierr);
60675ab9b9fSStefano Zampini     ierr = MatMatTransposeMultEqual(T2,Bt,X,10,&flg);CHKERRQ(ierr);
60775ab9b9fSStefano Zampini     if (!flg) {
60875ab9b9fSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with reusage (MatMatTranspose, MATSHELL)\n");CHKERRQ(ierr);
60975ab9b9fSStefano Zampini       ierr = MatMatTransposeMult(A,Bt,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
61075ab9b9fSStefano Zampini       ierr = MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
61175ab9b9fSStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
61275ab9b9fSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
61375ab9b9fSStefano Zampini     }
61475ab9b9fSStefano Zampini   }
615456288a8SStefano Zampini   ierr = MatDestroy(&T2);CHKERRQ(ierr);
616456288a8SStefano Zampini 
6176280154eSStefano Zampini   if (testnest) { /* test with MatNest */
6186280154eSStefano Zampini     Mat NA;
6196280154eSStefano Zampini 
6206280154eSStefano Zampini     ierr = MatCreateNest(PETSC_COMM_WORLD,1,NULL,1,NULL,&A,&NA);CHKERRQ(ierr);
6216280154eSStefano Zampini     ierr = MatViewFromOptions(NA,NULL,"-NA_view");CHKERRQ(ierr);
6226280154eSStefano Zampini     ierr = MatMatMult(NA,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X);CHKERRQ(ierr);
6236280154eSStefano Zampini     ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
6246280154eSStefano Zampini     ierr = MatMatMultEqual(NA,B,X,10,&flg);CHKERRQ(ierr);
6256280154eSStefano Zampini     if (!flg) {
6266280154eSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with Nest\n");CHKERRQ(ierr);
6276280154eSStefano Zampini       ierr = MatMatMult(NA,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
6286280154eSStefano Zampini       ierr = MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
6296280154eSStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
6306280154eSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
6316280154eSStefano Zampini     }
6326280154eSStefano Zampini     ierr = MatDestroy(&NA);CHKERRQ(ierr);
6336280154eSStefano Zampini   }
6346280154eSStefano Zampini 
6356280154eSStefano Zampini   if (testtranspose) { /* test with Transpose */
6366280154eSStefano Zampini     Mat TA;
6376280154eSStefano Zampini 
63875ab9b9fSStefano Zampini     ierr = MatCreateTranspose(A,&TA);CHKERRQ(ierr);
6396280154eSStefano Zampini     ierr = MatMatMult(TA,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr);
6406280154eSStefano Zampini     ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
6416280154eSStefano Zampini     ierr = MatMatMultEqual(TA,X,B,10,&flg);CHKERRQ(ierr);
6426280154eSStefano Zampini     if (!flg) {
6436280154eSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with Transpose\n");CHKERRQ(ierr);
64475ab9b9fSStefano Zampini       ierr = MatMatMult(TA,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
64575ab9b9fSStefano Zampini       ierr = MatAXPY(T,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
6466280154eSStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
6476280154eSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
6486280154eSStefano Zampini     }
6496280154eSStefano Zampini     ierr = MatDestroy(&TA);CHKERRQ(ierr);
6506280154eSStefano Zampini   }
6516280154eSStefano Zampini 
6523604c0aeSStefano Zampini   if (testhtranspose) { /* test with Hermitian Transpose */
6533604c0aeSStefano Zampini     Mat TA;
6543604c0aeSStefano Zampini 
6553604c0aeSStefano Zampini     ierr = MatCreateHermitianTranspose(A,&TA);CHKERRQ(ierr);
6563604c0aeSStefano Zampini     ierr = MatMatMult(TA,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr);
6573604c0aeSStefano Zampini     ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
6583604c0aeSStefano Zampini     ierr = MatMatMultEqual(TA,X,B,10,&flg);CHKERRQ(ierr);
6593604c0aeSStefano Zampini     if (!flg) {
6603604c0aeSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with Transpose\n");CHKERRQ(ierr);
6613604c0aeSStefano Zampini       ierr = MatMatMult(TA,X,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
6623604c0aeSStefano Zampini       ierr = MatAXPY(T,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
6633604c0aeSStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
6643604c0aeSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
6653604c0aeSStefano Zampini     }
6663604c0aeSStefano Zampini     ierr = MatDestroy(&TA);CHKERRQ(ierr);
6673604c0aeSStefano Zampini   }
6683604c0aeSStefano Zampini 
6696280154eSStefano Zampini   if (testtt) { /* test with Transpose(Transpose) */
6706280154eSStefano Zampini     Mat TA, TTA;
6716280154eSStefano Zampini 
67275ab9b9fSStefano Zampini     ierr = MatCreateTranspose(A,&TA);CHKERRQ(ierr);
67375ab9b9fSStefano Zampini     ierr = MatCreateTranspose(TA,&TTA);CHKERRQ(ierr);
6746280154eSStefano Zampini     ierr = MatMatMult(TTA,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X);CHKERRQ(ierr);
6756280154eSStefano Zampini     ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
6766280154eSStefano Zampini     ierr = MatMatMultEqual(TTA,B,X,10,&flg);CHKERRQ(ierr);
6776280154eSStefano Zampini     if (!flg) {
6786280154eSStefano Zampini       ierr = PetscPrintf(PETSC_COMM_WORLD,"Error with Transpose(Transpose)\n");CHKERRQ(ierr);
6796280154eSStefano Zampini       ierr = MatMatMult(TTA,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
6806280154eSStefano Zampini       ierr = MatAXPY(T,-1.0,X,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
6816280154eSStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
6826280154eSStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
6836280154eSStefano Zampini     }
6846280154eSStefano Zampini     ierr = MatDestroy(&TA);CHKERRQ(ierr);
6856280154eSStefano Zampini     ierr = MatDestroy(&TTA);CHKERRQ(ierr);
6866280154eSStefano Zampini   }
6876280154eSStefano Zampini 
6886280154eSStefano Zampini   if (testcircular) { /* test circular */
6896280154eSStefano Zampini     Mat AB;
6906280154eSStefano Zampini 
6916280154eSStefano Zampini     ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AB);CHKERRQ(ierr);
6926280154eSStefano Zampini     ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&X);CHKERRQ(ierr);
6936280154eSStefano Zampini     ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
6946280154eSStefano Zampini     if (M == N && N == K) {
6956280154eSStefano Zampini       ierr = MatMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr);
6966280154eSStefano Zampini     } else {
6976280154eSStefano Zampini       ierr = MatTransposeMatMult(A,X,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr);
6986280154eSStefano Zampini     }
6996280154eSStefano Zampini     ierr = CheckLocal(B,X,aB,aX);CHKERRQ(ierr);
7006280154eSStefano Zampini     ierr = MatDestroy(&AB);CHKERRQ(ierr);
7016280154eSStefano Zampini   }
7022b723ba2SStefano Zampini 
7032b723ba2SStefano Zampini   /* Test by Pierre Jolivet */
7042b723ba2SStefano Zampini   {
7052b723ba2SStefano Zampini     Mat C,D,D2,AtA;
7062b723ba2SStefano Zampini     ierr = MatCreateNormal(A,&AtA);CHKERRQ(ierr);
7072b723ba2SStefano Zampini     ierr = MatDuplicate(X,MAT_DO_NOT_COPY_VALUES,&C);CHKERRQ(ierr);
7082b723ba2SStefano Zampini     ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&D);CHKERRQ(ierr);
7092b723ba2SStefano Zampini     ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&D2);CHKERRQ(ierr);
7102b723ba2SStefano Zampini     ierr = MatSetRandom(B,NULL);CHKERRQ(ierr);
7112b723ba2SStefano Zampini     ierr = MatSetRandom(C,NULL);CHKERRQ(ierr);
7122b723ba2SStefano Zampini     ierr = MatSetRandom(D,NULL);CHKERRQ(ierr);
7132b723ba2SStefano Zampini     ierr = MatSetRandom(D2,NULL);CHKERRQ(ierr);
7142b723ba2SStefano Zampini     ierr = MatProductCreateWithMat(A,B,NULL,C);CHKERRQ(ierr);
7152b723ba2SStefano Zampini     ierr = MatProductSetType(C,MATPRODUCT_AB);CHKERRQ(ierr);
7162b723ba2SStefano Zampini     ierr = MatProductSetFromOptions(C);CHKERRQ(ierr);
7172b723ba2SStefano Zampini     ierr = MatProductSymbolic(C);CHKERRQ(ierr);
7182b723ba2SStefano Zampini     ierr = MatProductCreateWithMat(A,C,NULL,D);CHKERRQ(ierr);
7192b723ba2SStefano Zampini     ierr = MatProductSetType(D, MATPRODUCT_AtB);CHKERRQ(ierr);
7202b723ba2SStefano Zampini     ierr = MatProductSetFromOptions(D);CHKERRQ(ierr);
7212b723ba2SStefano Zampini     ierr = MatProductSymbolic(D);CHKERRQ(ierr);
7222b723ba2SStefano Zampini     ierr = MatProductNumeric(C);CHKERRQ(ierr);
7232b723ba2SStefano Zampini     ierr = MatProductNumeric(D);CHKERRQ(ierr);
7242b723ba2SStefano Zampini     ierr = MatMatMultEqual(AtA,B,D,10,&flg);CHKERRQ(ierr);
7252b723ba2SStefano Zampini     if (!flg) {
7262b723ba2SStefano Zampini       ierr = MatMatMult(AtA,C,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&T);CHKERRQ(ierr);
7272b723ba2SStefano Zampini       ierr = MatAXPY(T,-1.0,D,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
7282b723ba2SStefano Zampini       ierr = MatView(T,NULL);CHKERRQ(ierr);
7292b723ba2SStefano Zampini       ierr = MatDestroy(&T);CHKERRQ(ierr);
7302b723ba2SStefano Zampini     }
7312b723ba2SStefano Zampini     ierr = MatDestroy(&C);CHKERRQ(ierr);
7322b723ba2SStefano Zampini     ierr = MatDestroy(&D);CHKERRQ(ierr);
7332b723ba2SStefano Zampini     ierr = MatDestroy(&D2);CHKERRQ(ierr);
7342b723ba2SStefano Zampini     ierr = MatDestroy(&AtA);CHKERRQ(ierr);
7352b723ba2SStefano Zampini   }
7362b723ba2SStefano Zampini 
7376280154eSStefano Zampini   ierr = MatDestroy(&X);CHKERRQ(ierr);
73875ab9b9fSStefano Zampini   ierr = MatDestroy(&Bt);CHKERRQ(ierr);
7396280154eSStefano Zampini   ierr = MatDestroy(&B);CHKERRQ(ierr);
7406280154eSStefano Zampini   ierr = MatDestroy(&A);CHKERRQ(ierr);
74175ab9b9fSStefano Zampini   ierr = MatDestroy(&R);CHKERRQ(ierr);
74275ab9b9fSStefano Zampini   ierr = MatDestroy(&PtAP);CHKERRQ(ierr);
74375ab9b9fSStefano Zampini   ierr = MatDestroy(&RARt);CHKERRQ(ierr);
7446280154eSStefano Zampini   ierr = PetscFree(dataX);CHKERRQ(ierr);
7456280154eSStefano Zampini   ierr = PetscFree(dataB);CHKERRQ(ierr);
74675ab9b9fSStefano Zampini   ierr = PetscFree(dataR);CHKERRQ(ierr);
74775ab9b9fSStefano Zampini   ierr = PetscFree(dataBt);CHKERRQ(ierr);
7486280154eSStefano Zampini   ierr = PetscFinalize();
7496280154eSStefano Zampini   return ierr;
7506280154eSStefano Zampini }
7516280154eSStefano Zampini 
7526280154eSStefano Zampini /*TEST
7536280154eSStefano Zampini 
7546280154eSStefano Zampini   test:
7556280154eSStefano Zampini     suffix: 1
75675ab9b9fSStefano Zampini     args: -local {{0 1}} -testshellops
7576280154eSStefano Zampini 
7586280154eSStefano Zampini   test:
7596280154eSStefano Zampini     output_file: output/ex70_1.out
760456288a8SStefano Zampini     requires: cuda
761456288a8SStefano Zampini     suffix: 1_cuda
762686594dbSStefano Zampini     args: -local {{0 1}} -xgpu {{0 1}} -bgpu {{0 1}} -A_mat_type {{seqaijcusparse seqaij}} -testshellops {{0 1}}
763456288a8SStefano Zampini 
764456288a8SStefano Zampini   test:
765456288a8SStefano Zampini     output_file: output/ex70_1.out
7666280154eSStefano Zampini     nsize: 2
7676280154eSStefano Zampini     suffix: 1_par
76875ab9b9fSStefano Zampini     args: -local {{0 1}} -testmatmatt 0
7696280154eSStefano Zampini 
7706280154eSStefano Zampini   test:
771456288a8SStefano Zampini     output_file: output/ex70_1.out
772456288a8SStefano Zampini     requires: cuda
773456288a8SStefano Zampini     nsize: 2
774456288a8SStefano Zampini     suffix: 1_par_cuda
77575ab9b9fSStefano Zampini     args: -local {{0 1}} -xgpu {{0 1}} -bgpu {{0 1}} -A_mat_type {{mpiaijcusparse mpiaij}} -testnest 0 -testmatmatt 0 -matmatmult_Bbn 3
776456288a8SStefano Zampini 
777456288a8SStefano Zampini   test:
7786280154eSStefano Zampini     output_file: output/ex70_1.out
7796280154eSStefano Zampini     suffix: 2
7806280154eSStefano Zampini     nsize: 1
7816280154eSStefano Zampini     args: -M {{7 11}} -N {{12 9}} -K {{1 3}} -local {{0 1}}
7826280154eSStefano Zampini 
7838a311839SJunchao Zhang   testset:
784456288a8SStefano Zampini     requires: cuda
785456288a8SStefano Zampini     output_file: output/ex70_1.out
786456288a8SStefano Zampini     nsize: 1
787456288a8SStefano Zampini     args: -M 7 -N 9 -K 2 -local {{0 1}} -testnest 0 -A_mat_type {{seqdensecuda seqdense}} -xgpu {{0 1}} -bgpu {{0 1}}
7888a311839SJunchao Zhang     test:
7898a311839SJunchao Zhang       requires: !complex
7908a311839SJunchao Zhang       suffix: 2_cuda_real
7918a311839SJunchao Zhang     test:
7928a311839SJunchao Zhang       # complex+single gives a little bigger error in the MatDenseGetColumnVec test
7938a311839SJunchao Zhang       requires: complex !single
7948a311839SJunchao Zhang       suffix: 2_cuda_complex
795456288a8SStefano Zampini 
796456288a8SStefano Zampini   test:
7976280154eSStefano Zampini     output_file: output/ex70_1.out
7986280154eSStefano Zampini     suffix: 2_par
7996280154eSStefano Zampini     nsize: 2
80075ab9b9fSStefano Zampini     args: -M {{7 11}} -N {{12 9}} -K {{1 3}} -local {{0 1}} -testcircular -testmatmatt 0
8016280154eSStefano Zampini 
8026280154eSStefano Zampini   test:
803456288a8SStefano Zampini     requires: cuda
804456288a8SStefano Zampini     output_file: output/ex70_1.out
805456288a8SStefano Zampini     suffix: 2_par_cuda
806456288a8SStefano Zampini     nsize: 2
80775ab9b9fSStefano Zampini     args: -M 11 -N 9 -K 1 -local {{0 1}} -testcircular 0 -A_mat_type mpiaijcusparse -xgpu -bgpu -testnest 0 -testmatmatt 0
808456288a8SStefano Zampini 
809456288a8SStefano Zampini   test:
8106280154eSStefano Zampini     output_file: output/ex70_1.out
8116280154eSStefano Zampini     suffix: 3
812456288a8SStefano Zampini     nsize: {{1 3}}
81375ab9b9fSStefano Zampini     args: -M 13 -N 13 -K {{1 3}} -local {{0 1}} -A_mat_type sbaij -symm -testproj 0 -testmatmatt 0
8146280154eSStefano Zampini 
8156280154eSStefano Zampini   test:
8166280154eSStefano Zampini     output_file: output/ex70_1.out
8176280154eSStefano Zampini     suffix: 4
8186280154eSStefano Zampini     nsize: 1
8196280154eSStefano Zampini     args: -M 3 -N 3 -K 3 -local {{0 1}} -testcircular
8206280154eSStefano Zampini 
8216280154eSStefano Zampini   test:
8226280154eSStefano Zampini     output_file: output/ex70_1.out
8236280154eSStefano Zampini     suffix: 5
8246280154eSStefano Zampini     nsize: {{2 4}}
825a0638e9dSStefano Zampini     args: -M 3 -N 3 -K 3 -local {{0 1}} -testcircular -testmatmatt 0
8266280154eSStefano Zampini 
8276280154eSStefano Zampini   test:
8286280154eSStefano Zampini     output_file: output/ex70_1.out
8296280154eSStefano Zampini     suffix: 6
8306280154eSStefano Zampini     nsize: 1
83175ab9b9fSStefano Zampini     args: -M {{1 3}} -N {{2 5}} -K {{1 2}} -local {{0 1}} -testcircular
8326280154eSStefano Zampini 
8336280154eSStefano Zampini   test:
8346280154eSStefano Zampini     output_file: output/ex70_1.out
8356280154eSStefano Zampini     suffix: 7
8366280154eSStefano Zampini     nsize: 1
837456288a8SStefano Zampini     args: -M 13 -N 13 -K {{1 3}} -local {{0 1}} -A_mat_type dense -testnest -testcircular
8386718818eSStefano Zampini 
8396280154eSStefano Zampini TEST*/
840