xref: /petsc/src/mat/tests/ex66.c (revision 8cc725e69398de546bdc828d7b714aa2223f5218)
153022affSStefano Zampini static char help[] = "Tests MATH2OPUS\n\n";
2c4fb69feSStefano Zampini 
3c4fb69feSStefano Zampini #include <petscmat.h>
4c4fb69feSStefano Zampini #include <petscsf.h>
5c4fb69feSStefano Zampini 
6c4fb69feSStefano Zampini static PetscScalar GenEntry_Symm(PetscInt sdim, PetscReal x[], PetscReal y[], void *ctx)
7c4fb69feSStefano Zampini {
8c4fb69feSStefano Zampini     PetscInt  d;
9c4fb69feSStefano Zampini     PetscReal clength = sdim == 3 ? 0.2 : 0.1;
10c4fb69feSStefano Zampini     PetscReal dist, diff = 0.0;
11c4fb69feSStefano Zampini 
12c4fb69feSStefano Zampini     for (d = 0; d < sdim; d++) { diff += (x[d] - y[d]) * (x[d] - y[d]); }
13c4fb69feSStefano Zampini     dist = PetscSqrtReal(diff);
14c4fb69feSStefano Zampini     return PetscExpReal(-dist / clength);
15c4fb69feSStefano Zampini }
16c4fb69feSStefano Zampini 
17c4fb69feSStefano Zampini static PetscScalar GenEntry_Unsymm(PetscInt sdim, PetscReal x[], PetscReal y[], void *ctx)
18c4fb69feSStefano Zampini {
19c4fb69feSStefano Zampini     PetscInt  d;
20c4fb69feSStefano Zampini     PetscReal clength = sdim == 3 ? 0.2 : 0.1;
21c4fb69feSStefano Zampini     PetscReal dist, diff = 0.0, nx = 0.0, ny = 0.0;
22c4fb69feSStefano Zampini 
23c4fb69feSStefano Zampini     for (d = 0; d < sdim; d++) { nx += x[d]*x[d]; }
24c4fb69feSStefano Zampini     for (d = 0; d < sdim; d++) { ny += y[d]*y[d]; }
25c4fb69feSStefano Zampini     for (d = 0; d < sdim; d++) { diff += (x[d] - y[d]) * (x[d] - y[d]); }
26c4fb69feSStefano Zampini     dist = PetscSqrtReal(diff);
27c4fb69feSStefano Zampini     return nx > ny ? PetscExpReal(-dist / clength) : PetscExpReal(-dist / clength) + 1.;
28c4fb69feSStefano Zampini }
29c4fb69feSStefano Zampini 
30c4fb69feSStefano Zampini int main(int argc,char **argv)
31c4fb69feSStefano Zampini {
32c4fb69feSStefano Zampini   Mat            A,B,C,D;
33c4fb69feSStefano Zampini   Vec            v,x,y,Ax,Ay,Bx,By;
34c4fb69feSStefano Zampini   PetscRandom    r;
35c4fb69feSStefano Zampini   PetscLayout    map;
36c4fb69feSStefano Zampini   PetscScalar    *Adata = NULL, *Cdata = NULL, scale = 1.0;
37c4fb69feSStefano Zampini   PetscReal      *coords,nA,nD,nB,err,nX,norms[3];
38300d917bSStefano Zampini   PetscInt       N, n = 64, dim = 1, i, j, nrhs = 11, lda = 0, ldc = 0, ldu = 0, nlr = 7, nt, ntrials = 2;
39c4fb69feSStefano Zampini   PetscMPIInt    size,rank;
40c4fb69feSStefano Zampini   PetscBool      testlayout = PETSC_FALSE, flg, symm = PETSC_FALSE, Asymm = PETSC_TRUE, kernel = PETSC_TRUE;
4153022affSStefano Zampini   PetscBool      checkexpl = PETSC_FALSE, agpu = PETSC_FALSE, bgpu = PETSC_FALSE, cgpu = PETSC_FALSE, flgglob;
42300d917bSStefano Zampini   PetscBool      testtrans, testnorm, randommat = PETSC_TRUE, testorthog, testcompress, testhlru;
43c4fb69feSStefano Zampini   void           (*approxnormfunc)(void);
44c4fb69feSStefano Zampini   void           (*Anormfunc)(void);
45c4fb69feSStefano Zampini 
4653022affSStefano Zampini #if defined(PETSC_HAVE_MPI_INIT_THREAD)
47c4fb69feSStefano Zampini   PETSC_MPI_THREAD_REQUIRED = MPI_THREAD_MULTIPLE;
4853022affSStefano Zampini #endif
499566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc,&argv,(char*) 0,help));
509566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-ng",&N,&flgglob));
519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-nrhs",&nrhs,NULL));
539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-dim",&dim,NULL));
549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-lda",&lda,NULL));
559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-ldc",&ldc,NULL));
569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-nlr",&nlr,NULL));
579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-ldu",&ldu,NULL));
589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL,NULL,"-matmattrials",&ntrials,NULL));
599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-randommat",&randommat,NULL));
609566063dSJacob Faibussowitsch   if (!flgglob) PetscCall(PetscOptionsGetBool(NULL,NULL,"-testlayout",&testlayout,NULL));
619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-Asymm",&Asymm,NULL));
629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-symm",&symm,NULL));
639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-kernel",&kernel,NULL));
649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-checkexpl",&checkexpl,NULL));
659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-agpu",&agpu,NULL));
669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-bgpu",&bgpu,NULL));
679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL,NULL,"-cgpu",&cgpu,NULL));
689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(NULL,NULL,"-scale",&scale,NULL));
69c4fb69feSStefano Zampini   if (!Asymm) symm = PETSC_FALSE;
70c4fb69feSStefano Zampini 
719566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size));
72300d917bSStefano Zampini 
73300d917bSStefano Zampini   /* Disable tests for unimplemented variants */
74c4fb69feSStefano Zampini   testtrans = (PetscBool)(size == 1 || symm);
75c4fb69feSStefano Zampini   testnorm = (PetscBool)(size == 1 || symm);
7653022affSStefano Zampini   testorthog = (PetscBool)(size == 1 || symm);
7753022affSStefano Zampini   testcompress = (PetscBool)(size == 1 || symm);
78300d917bSStefano Zampini   testhlru = (PetscBool)(size == 1);
79c4fb69feSStefano Zampini 
809566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
819566063dSJacob Faibussowitsch   PetscCall(PetscLayoutCreate(PETSC_COMM_WORLD,&map));
82c4fb69feSStefano Zampini   if (testlayout) {
83c4fb69feSStefano Zampini     if (rank%2) n = PetscMax(2*n-5*rank,0);
84c4fb69feSStefano Zampini     else n = 2*n+rank;
85c4fb69feSStefano Zampini   }
8653022affSStefano Zampini   if (!flgglob) {
879566063dSJacob Faibussowitsch     PetscCall(PetscLayoutSetLocalSize(map,n));
889566063dSJacob Faibussowitsch     PetscCall(PetscLayoutSetUp(map));
899566063dSJacob Faibussowitsch     PetscCall(PetscLayoutGetSize(map,&N));
9053022affSStefano Zampini   } else {
919566063dSJacob Faibussowitsch     PetscCall(PetscLayoutSetSize(map,N));
929566063dSJacob Faibussowitsch     PetscCall(PetscLayoutSetUp(map));
939566063dSJacob Faibussowitsch     PetscCall(PetscLayoutGetLocalSize(map,&n));
9453022affSStefano Zampini   }
959566063dSJacob Faibussowitsch   PetscCall(PetscLayoutDestroy(&map));
96c4fb69feSStefano Zampini 
97c4fb69feSStefano Zampini   if (lda) {
989566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(N*(n+lda),&Adata));
99c4fb69feSStefano Zampini   }
1009566063dSJacob Faibussowitsch   PetscCall(MatCreateDense(PETSC_COMM_WORLD,n,n,N,N,Adata,&A));
1019566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(A,n+lda));
102c4fb69feSStefano Zampini 
10353022affSStefano Zampini   /* Create random points; these are replicated in order to populate a dense matrix and to compare sequential and dense runs
10453022affSStefano Zampini      The constructor for MATH2OPUS can take as input the distributed coordinates and replicates them internally in case
10553022affSStefano Zampini      a kernel construction is requested */
1069566063dSJacob Faibussowitsch   PetscCall(PetscRandomCreate(PETSC_COMM_WORLD,&r));
1079566063dSJacob Faibussowitsch   PetscCall(PetscRandomSetFromOptions(r));
1089566063dSJacob Faibussowitsch   PetscCall(PetscRandomSetSeed(r,123456));
1099566063dSJacob Faibussowitsch   PetscCall(PetscRandomSeed(r));
1109566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(N*dim,&coords));
1119566063dSJacob Faibussowitsch   PetscCall(PetscRandomGetValuesReal(r,N*dim,coords));
1129566063dSJacob Faibussowitsch   PetscCall(PetscRandomDestroy(&r));
11353022affSStefano Zampini 
114c4fb69feSStefano Zampini   if (kernel || !randommat) {
11553022affSStefano Zampini     MatH2OpusKernel k = Asymm ? GenEntry_Symm : GenEntry_Unsymm;
116c4fb69feSStefano Zampini     PetscInt        ist,ien;
117c4fb69feSStefano Zampini 
1189566063dSJacob Faibussowitsch     PetscCall(MatGetOwnershipRange(A,&ist,&ien));
119c4fb69feSStefano Zampini     for (i = ist; i < ien; i++) {
120c4fb69feSStefano Zampini       for (j = 0; j < N; j++) {
1219566063dSJacob Faibussowitsch         PetscCall(MatSetValue(A,i,j,(*k)(dim,coords + i*dim,coords + j*dim,NULL),INSERT_VALUES));
122c4fb69feSStefano Zampini       }
123c4fb69feSStefano Zampini     }
1249566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
1259566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
126c4fb69feSStefano Zampini     if (kernel) {
1279566063dSJacob Faibussowitsch       PetscCall(MatCreateH2OpusFromKernel(PETSC_COMM_WORLD,n,n,N,N,dim,coords + ist*dim,PETSC_TRUE,k,NULL,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&B));
128c4fb69feSStefano Zampini     } else {
1299566063dSJacob Faibussowitsch       PetscCall(MatCreateH2OpusFromMat(A,dim,coords + ist*dim,PETSC_TRUE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&B));
130c4fb69feSStefano Zampini     }
131c4fb69feSStefano Zampini   } else {
13253022affSStefano Zampini     PetscInt ist;
13353022affSStefano Zampini 
1349566063dSJacob Faibussowitsch     PetscCall(MatGetOwnershipRange(A,&ist,NULL));
1359566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(A,NULL));
136c4fb69feSStefano Zampini     if (Asymm) {
1379566063dSJacob Faibussowitsch       PetscCall(MatTranspose(A,MAT_INITIAL_MATRIX,&B));
1389566063dSJacob Faibussowitsch       PetscCall(MatAXPY(A,1.0,B,SAME_NONZERO_PATTERN));
1399566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&B));
1409566063dSJacob Faibussowitsch       PetscCall(MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE));
141c4fb69feSStefano Zampini     }
1429566063dSJacob Faibussowitsch     PetscCall(MatCreateH2OpusFromMat(A,dim,coords + ist*dim,PETSC_TRUE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&B));
143c4fb69feSStefano Zampini   }
1449566063dSJacob Faibussowitsch   PetscCall(PetscFree(coords));
145c4fb69feSStefano Zampini   if (agpu) {
1469566063dSJacob Faibussowitsch     PetscCall(MatConvert(A,MATDENSECUDA,MAT_INPLACE_MATRIX,&A));
147c4fb69feSStefano Zampini   }
1489566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(A,NULL,"-A_view"));
149c4fb69feSStefano Zampini 
1509566063dSJacob Faibussowitsch   PetscCall(MatSetOption(B,MAT_SYMMETRIC,symm));
151c4fb69feSStefano Zampini 
152c4fb69feSStefano Zampini   /* assemble the H-matrix */
1539566063dSJacob Faibussowitsch   PetscCall(MatBindToCPU(B,(PetscBool)!bgpu));
1549566063dSJacob Faibussowitsch   PetscCall(MatSetFromOptions(B));
1559566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
1569566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
1579566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(B,NULL,"-B_view"));
158c4fb69feSStefano Zampini 
159c4fb69feSStefano Zampini   /* Test MatScale */
1609566063dSJacob Faibussowitsch   PetscCall(MatScale(A,scale));
1619566063dSJacob Faibussowitsch   PetscCall(MatScale(B,scale));
162c4fb69feSStefano Zampini 
163c4fb69feSStefano Zampini   /* Test MatMult */
1649566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(A,&Ax,&Ay));
1659566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(B,&Bx,&By));
1669566063dSJacob Faibussowitsch   PetscCall(VecSetRandom(Ax,NULL));
1679566063dSJacob Faibussowitsch   PetscCall(VecCopy(Ax,Bx));
1689566063dSJacob Faibussowitsch   PetscCall(MatMult(A,Ax,Ay));
1699566063dSJacob Faibussowitsch   PetscCall(MatMult(B,Bx,By));
1709566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(Ay,NULL,"-mult_vec_view"));
1719566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(By,NULL,"-mult_vec_view"));
1729566063dSJacob Faibussowitsch   PetscCall(VecNorm(Ay,NORM_INFINITY,&nX));
1739566063dSJacob Faibussowitsch   PetscCall(VecAXPY(Ay,-1.0,By));
1749566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(Ay,NULL,"-mult_vec_view"));
1759566063dSJacob Faibussowitsch   PetscCall(VecNorm(Ay,NORM_INFINITY,&err));
1769566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMult err %g\n",err/nX));
1779566063dSJacob Faibussowitsch   PetscCall(VecScale(By,-1.0));
1789566063dSJacob Faibussowitsch   PetscCall(MatMultAdd(B,Bx,By,By));
1799566063dSJacob Faibussowitsch   PetscCall(VecNorm(By,NORM_INFINITY,&err));
1809566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(By,NULL,"-mult_vec_view"));
1814c3a5f3cSStefano Zampini   if (err > 10.*PETSC_SMALL) {
1829566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMultAdd err %g\n",err));
183c4fb69feSStefano Zampini   }
184c4fb69feSStefano Zampini 
185c4fb69feSStefano Zampini   /* Test MatNorm */
1869566063dSJacob Faibussowitsch   PetscCall(MatNorm(A,NORM_INFINITY,&norms[0]));
1879566063dSJacob Faibussowitsch   PetscCall(MatNorm(A,NORM_1,&norms[1]));
188c4fb69feSStefano Zampini   norms[2] = -1.; /* NORM_2 not supported */
1899566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"A Matrix norms:        infty=%g, norm_1=%g, norm_2=%g\n",(double)norms[0],(double)norms[1],(double)norms[2]));
1909566063dSJacob Faibussowitsch   PetscCall(MatGetOperation(A,MATOP_NORM,&Anormfunc));
1919566063dSJacob Faibussowitsch   PetscCall(MatGetOperation(B,MATOP_NORM,&approxnormfunc));
1929566063dSJacob Faibussowitsch   PetscCall(MatSetOperation(A,MATOP_NORM,approxnormfunc));
1939566063dSJacob Faibussowitsch   PetscCall(MatNorm(A,NORM_INFINITY,&norms[0]));
1949566063dSJacob Faibussowitsch   PetscCall(MatNorm(A,NORM_1,&norms[1]));
1959566063dSJacob Faibussowitsch   PetscCall(MatNorm(A,NORM_2,&norms[2]));
1969566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"A Approx Matrix norms: infty=%g, norm_1=%g, norm_2=%g\n",(double)norms[0],(double)norms[1],(double)norms[2]));
197c4fb69feSStefano Zampini   if (testnorm) {
1989566063dSJacob Faibussowitsch     PetscCall(MatNorm(B,NORM_INFINITY,&norms[0]));
1999566063dSJacob Faibussowitsch     PetscCall(MatNorm(B,NORM_1,&norms[1]));
2009566063dSJacob Faibussowitsch     PetscCall(MatNorm(B,NORM_2,&norms[2]));
201c4fb69feSStefano Zampini   } else {
202c4fb69feSStefano Zampini     norms[0] = -1.;
203c4fb69feSStefano Zampini     norms[1] = -1.;
204c4fb69feSStefano Zampini     norms[2] = -1.;
205c4fb69feSStefano Zampini   }
2069566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD,"B Approx Matrix norms: infty=%g, norm_1=%g, norm_2=%g\n",(double)norms[0],(double)norms[1],(double)norms[2]));
2079566063dSJacob Faibussowitsch   PetscCall(MatSetOperation(A,MATOP_NORM,Anormfunc));
208c4fb69feSStefano Zampini 
209c4fb69feSStefano Zampini   /* Test MatDuplicate */
2109566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D));
2119566063dSJacob Faibussowitsch   PetscCall(MatSetOption(D,MAT_SYMMETRIC,symm));
2129566063dSJacob Faibussowitsch   PetscCall(MatMultEqual(B,D,10,&flg));
213c4fb69feSStefano Zampini   if (!flg) {
2149566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMult error after MatDuplicate\n"));
215c4fb69feSStefano Zampini   }
216c4fb69feSStefano Zampini   if (testtrans) {
2179566063dSJacob Faibussowitsch     PetscCall(MatMultTransposeEqual(B,D,10,&flg));
218c4fb69feSStefano Zampini     if (!flg) {
2199566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMultTranspose error after MatDuplicate\n"));
220c4fb69feSStefano Zampini     }
221c4fb69feSStefano Zampini   }
2229566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&D));
223c4fb69feSStefano Zampini 
224c4fb69feSStefano Zampini   if (testtrans) { /* MatMultTranspose for nonsymmetric matrices not implemented */
2259566063dSJacob Faibussowitsch     PetscCall(VecSetRandom(Ay,NULL));
2269566063dSJacob Faibussowitsch     PetscCall(VecCopy(Ay,By));
2279566063dSJacob Faibussowitsch     PetscCall(MatMultTranspose(A,Ay,Ax));
2289566063dSJacob Faibussowitsch     PetscCall(MatMultTranspose(B,By,Bx));
2299566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(Ax,NULL,"-multtrans_vec_view"));
2309566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(Bx,NULL,"-multtrans_vec_view"));
2319566063dSJacob Faibussowitsch     PetscCall(VecNorm(Ax,NORM_INFINITY,&nX));
2329566063dSJacob Faibussowitsch     PetscCall(VecAXPY(Ax,-1.0,Bx));
2339566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(Ax,NULL,"-multtrans_vec_view"));
2349566063dSJacob Faibussowitsch     PetscCall(VecNorm(Ax,NORM_INFINITY,&err));
2359566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMultTranspose err %g\n",err/nX));
2369566063dSJacob Faibussowitsch     PetscCall(VecScale(Bx,-1.0));
2379566063dSJacob Faibussowitsch     PetscCall(MatMultTransposeAdd(B,By,Bx,Bx));
2389566063dSJacob Faibussowitsch     PetscCall(VecNorm(Bx,NORM_INFINITY,&err));
2394c3a5f3cSStefano Zampini     if (err > 10.*PETSC_SMALL) {
2409566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMultTransposeAdd err %g\n",err));
241c4fb69feSStefano Zampini     }
242c4fb69feSStefano Zampini   }
2439566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Ax));
2449566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Ay));
2459566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&Bx));
2469566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&By));
247c4fb69feSStefano Zampini 
248c4fb69feSStefano Zampini   /* Test MatMatMult */
249c4fb69feSStefano Zampini   if (ldc) {
2509566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs*(n+ldc),&Cdata));
251c4fb69feSStefano Zampini   }
2529566063dSJacob Faibussowitsch   PetscCall(MatCreateDense(PETSC_COMM_WORLD,n,PETSC_DECIDE,N,nrhs,Cdata,&C));
2539566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(C,n+ldc));
2549566063dSJacob Faibussowitsch   PetscCall(MatSetRandom(C,NULL));
255c4fb69feSStefano Zampini   if (cgpu) {
2569566063dSJacob Faibussowitsch     PetscCall(MatConvert(C,MATDENSECUDA,MAT_INPLACE_MATRIX,&C));
257c4fb69feSStefano Zampini   }
258c4fb69feSStefano Zampini   for (nt = 0; nt < ntrials; nt++) {
2599566063dSJacob Faibussowitsch     PetscCall(MatMatMult(B,C,nt ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX,PETSC_DEFAULT,&D));
2609566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(D,NULL,"-bc_view"));
2619566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)D,&flg,MATSEQDENSE,MATMPIDENSE,""));
262c4fb69feSStefano Zampini     if (flg) {
2639566063dSJacob Faibussowitsch       PetscCall(MatCreateVecs(B,&x,&y));
2649566063dSJacob Faibussowitsch       PetscCall(MatCreateVecs(D,NULL,&v));
265c4fb69feSStefano Zampini       for (i = 0; i < nrhs; i++) {
2669566063dSJacob Faibussowitsch         PetscCall(MatGetColumnVector(D,v,i));
2679566063dSJacob Faibussowitsch         PetscCall(MatGetColumnVector(C,x,i));
2689566063dSJacob Faibussowitsch         PetscCall(MatMult(B,x,y));
2699566063dSJacob Faibussowitsch         PetscCall(VecAXPY(y,-1.0,v));
2709566063dSJacob Faibussowitsch         PetscCall(VecNorm(y,NORM_INFINITY,&err));
2719566063dSJacob Faibussowitsch         if (err > 10.*PETSC_SMALL) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMat err %" PetscInt_FMT " %g\n",i,err));
272c4fb69feSStefano Zampini       }
2739566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&y));
2749566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&x));
2759566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&v));
276c4fb69feSStefano Zampini     }
277c4fb69feSStefano Zampini   }
2789566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&D));
279c4fb69feSStefano Zampini 
280c4fb69feSStefano Zampini   /* Test MatTransposeMatMult */
281c4fb69feSStefano Zampini   if (testtrans) { /* MatMultTranspose for nonsymmetric matrices not implemented */
282c4fb69feSStefano Zampini     for (nt = 0; nt < ntrials; nt++) {
2839566063dSJacob Faibussowitsch       PetscCall(MatTransposeMatMult(B,C,nt ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX,PETSC_DEFAULT,&D));
2849566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(D,NULL,"-btc_view"));
2859566063dSJacob Faibussowitsch       PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)D,&flg,MATSEQDENSE,MATMPIDENSE,""));
286c4fb69feSStefano Zampini       if (flg) {
2879566063dSJacob Faibussowitsch         PetscCall(MatCreateVecs(B,&y,&x));
2889566063dSJacob Faibussowitsch         PetscCall(MatCreateVecs(D,NULL,&v));
289c4fb69feSStefano Zampini         for (i = 0; i < nrhs; i++) {
2909566063dSJacob Faibussowitsch           PetscCall(MatGetColumnVector(D,v,i));
2919566063dSJacob Faibussowitsch           PetscCall(MatGetColumnVector(C,x,i));
2929566063dSJacob Faibussowitsch           PetscCall(MatMultTranspose(B,x,y));
2939566063dSJacob Faibussowitsch           PetscCall(VecAXPY(y,-1.0,v));
2949566063dSJacob Faibussowitsch           PetscCall(VecNorm(y,NORM_INFINITY,&err));
2959566063dSJacob Faibussowitsch           if (err > 10.*PETSC_SMALL) PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatTransMat err %" PetscInt_FMT " %g\n",i,err));
296c4fb69feSStefano Zampini         }
2979566063dSJacob Faibussowitsch         PetscCall(VecDestroy(&y));
2989566063dSJacob Faibussowitsch         PetscCall(VecDestroy(&x));
2999566063dSJacob Faibussowitsch         PetscCall(VecDestroy(&v));
300c4fb69feSStefano Zampini       }
301c4fb69feSStefano Zampini     }
3029566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
303c4fb69feSStefano Zampini   }
304c4fb69feSStefano Zampini 
305300d917bSStefano Zampini   /* Test basis orthogonalization */
30653022affSStefano Zampini   if (testorthog) {
3079566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D));
3089566063dSJacob Faibussowitsch     PetscCall(MatSetOption(D,MAT_SYMMETRIC,symm));
3099566063dSJacob Faibussowitsch     PetscCall(MatH2OpusOrthogonalize(D));
3109566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(B,D,10,&flg));
31153022affSStefano Zampini     if (!flg) {
3129566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMult error after basis ortogonalization\n"));
31353022affSStefano Zampini     }
3149566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
31553022affSStefano Zampini   }
31653022affSStefano Zampini 
317300d917bSStefano Zampini   /* Test matrix compression */
31853022affSStefano Zampini   if (testcompress) {
3199566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D));
3209566063dSJacob Faibussowitsch     PetscCall(MatSetOption(D,MAT_SYMMETRIC,symm));
3219566063dSJacob Faibussowitsch     PetscCall(MatH2OpusCompress(D,PETSC_SMALL));
3229566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
32353022affSStefano Zampini   }
32453022affSStefano Zampini 
325300d917bSStefano Zampini   /* Test low-rank update */
326300d917bSStefano Zampini   if (testhlru) {
327300d917bSStefano Zampini     Mat         U, V;
328300d917bSStefano Zampini     PetscScalar *Udata = NULL, *Vdata = NULL;
329300d917bSStefano Zampini 
330300d917bSStefano Zampini     if (ldu) {
3319566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(nlr*(n+ldu),&Udata));
3329566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(nlr*(n+ldu+2),&Vdata));
333300d917bSStefano Zampini     }
3349566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D));
3359566063dSJacob Faibussowitsch     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)D),n,PETSC_DECIDE,N,nlr,Udata,&U));
3369566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(U,n+ldu));
3379566063dSJacob Faibussowitsch     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)D),n,PETSC_DECIDE,N,nlr,Vdata,&V));
3389566063dSJacob Faibussowitsch     if (ldu) PetscCall(MatDenseSetLDA(V,n+ldu+2));
3399566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(U,NULL));
3409566063dSJacob Faibussowitsch     PetscCall(MatSetRandom(V,NULL));
3419566063dSJacob Faibussowitsch     PetscCall(MatH2OpusLowRankUpdate(D,U,V,0.5));
3429566063dSJacob Faibussowitsch     PetscCall(MatH2OpusLowRankUpdate(D,U,V,-0.5));
3439566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(B,D,10,&flg));
344300d917bSStefano Zampini     if (!flg) {
3459566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"MatMult error after low-rank update\n"));
346300d917bSStefano Zampini     }
3479566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
3489566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&U));
3499566063dSJacob Faibussowitsch     PetscCall(PetscFree(Udata));
3509566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&V));
3519566063dSJacob Faibussowitsch     PetscCall(PetscFree(Vdata));
352300d917bSStefano Zampini   }
353300d917bSStefano Zampini 
354c4fb69feSStefano Zampini   /* check explicit operator */
355c4fb69feSStefano Zampini   if (checkexpl) {
356c4fb69feSStefano Zampini     Mat Be, Bet;
357c4fb69feSStefano Zampini 
3589566063dSJacob Faibussowitsch     PetscCall(MatComputeOperator(B,MATDENSE,&D));
3599566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(D,MAT_COPY_VALUES,&Be));
3609566063dSJacob Faibussowitsch     PetscCall(MatNorm(D,NORM_FROBENIUS,&nB));
3619566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(D,NULL,"-expl_view"));
3629566063dSJacob Faibussowitsch     PetscCall(MatAXPY(D,-1.0,A,SAME_NONZERO_PATTERN));
3639566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(D,NULL,"-diff_view"));
3649566063dSJacob Faibussowitsch     PetscCall(MatNorm(D,NORM_FROBENIUS,&nD));
3659566063dSJacob Faibussowitsch     PetscCall(MatNorm(A,NORM_FROBENIUS,&nA));
3669566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Approximation error %g (%g / %g, %g)\n",nD/nA,nD,nA,nB));
3679566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
368c4fb69feSStefano Zampini 
369c4fb69feSStefano Zampini     if (testtrans) { /* MatMultTranspose for nonsymmetric matrices not implemented */
3709566063dSJacob Faibussowitsch       PetscCall(MatTranspose(A,MAT_INPLACE_MATRIX,&A));
3719566063dSJacob Faibussowitsch       PetscCall(MatComputeOperatorTranspose(B,MATDENSE,&D));
3729566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(D,MAT_COPY_VALUES,&Bet));
3739566063dSJacob Faibussowitsch       PetscCall(MatNorm(D,NORM_FROBENIUS,&nB));
3749566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(D,NULL,"-expl_trans_view"));
3759566063dSJacob Faibussowitsch       PetscCall(MatAXPY(D,-1.0,A,SAME_NONZERO_PATTERN));
3769566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(D,NULL,"-diff_trans_view"));
3779566063dSJacob Faibussowitsch       PetscCall(MatNorm(D,NORM_FROBENIUS,&nD));
3789566063dSJacob Faibussowitsch       PetscCall(MatNorm(A,NORM_FROBENIUS,&nA));
3799566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Approximation error transpose %g (%g / %g, %g)\n",nD/nA,nD,nA,nB));
3809566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&D));
381c4fb69feSStefano Zampini 
3829566063dSJacob Faibussowitsch       PetscCall(MatTranspose(Bet,MAT_INPLACE_MATRIX,&Bet));
3839566063dSJacob Faibussowitsch       PetscCall(MatAXPY(Be,-1.0,Bet,SAME_NONZERO_PATTERN));
3849566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(Be,NULL,"-diff_expl_view"));
3859566063dSJacob Faibussowitsch       PetscCall(MatNorm(Be,NORM_FROBENIUS,&nB));
3869566063dSJacob Faibussowitsch       PetscCall(PetscPrintf(PETSC_COMM_WORLD,"Approximation error B - (B^T)^T %g\n",nB));
3879566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Be));
3889566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Bet));
389c4fb69feSStefano Zampini     }
390c4fb69feSStefano Zampini   }
3919566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A));
3929566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B));
3939566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&C));
3949566063dSJacob Faibussowitsch   PetscCall(PetscFree(Cdata));
3959566063dSJacob Faibussowitsch   PetscCall(PetscFree(Adata));
3969566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
397b122ec5aSJacob Faibussowitsch   return 0;
398c4fb69feSStefano Zampini }
399c4fb69feSStefano Zampini 
400c4fb69feSStefano Zampini /*TEST
401c4fb69feSStefano Zampini 
402c4fb69feSStefano Zampini    build:
40353022affSStefano Zampini      requires: h2opus
404c4fb69feSStefano Zampini 
405c4fb69feSStefano Zampini #tests from kernel
406c4fb69feSStefano Zampini    test:
40753022affSStefano Zampini      requires: h2opus
408c4fb69feSStefano Zampini      nsize: 1
409c4fb69feSStefano Zampini      suffix: 1
410c4fb69feSStefano Zampini      args: -n {{17 33}} -kernel 1 -dim {{1 2 3}} -symm {{0 1}} -checkexpl -bgpu 0
411c4fb69feSStefano Zampini 
412c4fb69feSStefano Zampini    test:
41353022affSStefano Zampini      requires: h2opus
414c4fb69feSStefano Zampini      nsize: 1
415c4fb69feSStefano Zampini      suffix: 1_ld
416c4fb69feSStefano Zampini      output_file: output/ex66_1.out
417300d917bSStefano Zampini      args: -n 33 -kernel 1 -dim 1 -lda 13 -ldc 11 -ldu 17 -symm 0 -checkexpl -bgpu 0
418c4fb69feSStefano Zampini 
419c4fb69feSStefano Zampini    test:
42053022affSStefano Zampini      requires: h2opus cuda
421c4fb69feSStefano Zampini      nsize: 1
422c4fb69feSStefano Zampini      suffix: 1_cuda
423c4fb69feSStefano Zampini      output_file: output/ex66_1.out
424c4fb69feSStefano Zampini      args: -n {{17 33}} -kernel 1 -dim {{1 2 3}} -symm {{0 1}} -checkexpl -bgpu 1
425c4fb69feSStefano Zampini 
426c4fb69feSStefano Zampini    test:
42753022affSStefano Zampini      requires: h2opus cuda
428c4fb69feSStefano Zampini      nsize: 1
429c4fb69feSStefano Zampini      suffix: 1_cuda_ld
430c4fb69feSStefano Zampini      output_file: output/ex66_1.out
431300d917bSStefano Zampini      args: -n 33 -kernel 1 -dim 1 -lda 13 -ldc 11 -ldu 17 -symm 0 -checkexpl -bgpu 1
432c4fb69feSStefano Zampini 
433c4fb69feSStefano Zampini    test:
43453022affSStefano Zampini      requires: h2opus
43553022affSStefano Zampini      nsize: {{2 3}}
436c4fb69feSStefano Zampini      suffix: 1_par
43753022affSStefano Zampini      args: -n 64 -symm -kernel 1 -dim 1 -ldc 12 -testlayout {{0 1}} -bgpu 0 -cgpu 0
438c4fb69feSStefano Zampini 
439c4fb69feSStefano Zampini    test:
44053022affSStefano Zampini      requires: h2opus cuda
44153022affSStefano Zampini      nsize: {{2 3}}
442c4fb69feSStefano Zampini      suffix: 1_par_cuda
44353022affSStefano Zampini      args: -n 64 -symm -kernel 1 -dim 1 -ldc 12 -testlayout {{0 1}} -bgpu {{0 1}} -cgpu {{0 1}}
444c4fb69feSStefano Zampini      output_file: output/ex66_1_par.out
445c4fb69feSStefano Zampini 
446c4fb69feSStefano Zampini #tests from matrix sampling (parallel or unsymmetric not supported)
447c4fb69feSStefano Zampini    test:
44853022affSStefano Zampini      requires: h2opus
449c4fb69feSStefano Zampini      nsize: 1
450c4fb69feSStefano Zampini      suffix: 2
451c4fb69feSStefano Zampini      args: -n {{17 33}} -kernel 0 -dim 2 -symm 1 -checkexpl -bgpu 0
452c4fb69feSStefano Zampini 
453c4fb69feSStefano Zampini    test:
45453022affSStefano Zampini      requires: h2opus cuda
455c4fb69feSStefano Zampini      nsize: 1
456c4fb69feSStefano Zampini      suffix: 2_cuda
457c4fb69feSStefano Zampini      output_file: output/ex66_2.out
458c4fb69feSStefano Zampini      args: -n {{17 33}} -kernel 0 -dim 2 -symm 1 -checkexpl -bgpu {{0 1}} -agpu {{0 1}}
459c4fb69feSStefano Zampini 
46053022affSStefano Zampini #tests view operation
46153022affSStefano Zampini    test:
46253022affSStefano Zampini      requires: h2opus !cuda
463*8cc725e6SPierre Jolivet      filter: grep -v " MPI process" | grep -v "\[" | grep -v "\]"
46453022affSStefano Zampini      nsize: {{1 2 3}}
46553022affSStefano Zampini      suffix: view
46653022affSStefano Zampini      args: -ng 64 -kernel 1 -dim 2 -symm 1 -checkexpl -B_view -mat_h2opus_leafsize 17 -mat_h2opus_normsamples 13 -mat_h2opus_indexmap_view ::ascii_matlab -mat_approximate_norm_samples 2 -mat_h2opus_normsamples 2
46753022affSStefano Zampini 
46853022affSStefano Zampini    test:
46953022affSStefano Zampini      requires: h2opus cuda
470*8cc725e6SPierre Jolivet      filter: grep -v " MPI process" | grep -v "\[" | grep -v "\]"
47153022affSStefano Zampini      nsize: {{1 2 3}}
47253022affSStefano Zampini      suffix: view_cuda
47353022affSStefano Zampini      args: -ng 64 -kernel 1 -dim 2 -symm 1 -checkexpl -bgpu -B_view -mat_h2opus_leafsize 17 -mat_h2opus_normsamples 13 -mat_h2opus_indexmap_view ::ascii_matlab -mat_approximate_norm_samples 2 -mat_h2opus_normsamples 2
47453022affSStefano Zampini 
475c4fb69feSStefano Zampini TEST*/
476