xref: /petsc/src/mat/tests/ex66.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
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   PetscErrorCode ierr;
46c4fb69feSStefano Zampini 
4753022affSStefano Zampini #if defined(PETSC_HAVE_MPI_INIT_THREAD)
48c4fb69feSStefano Zampini   PETSC_MPI_THREAD_REQUIRED = MPI_THREAD_MULTIPLE;
4953022affSStefano Zampini #endif
50c4fb69feSStefano Zampini   ierr = PetscInitialize(&argc,&argv,(char*) 0,help);if (ierr) return ierr;
51*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-ng",&N,&flgglob));
52*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL));
53*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-nrhs",&nrhs,NULL));
54*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-dim",&dim,NULL));
55*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-lda",&lda,NULL));
56*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-ldc",&ldc,NULL));
57*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-nlr",&nlr,NULL));
58*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-ldu",&ldu,NULL));
59*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-matmattrials",&ntrials,NULL));
60*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-randommat",&randommat,NULL));
61*5f80ce2aSJacob Faibussowitsch   if (!flgglob) CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-testlayout",&testlayout,NULL));
62*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-Asymm",&Asymm,NULL));
63*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-symm",&symm,NULL));
64*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-kernel",&kernel,NULL));
65*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-checkexpl",&checkexpl,NULL));
66*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-agpu",&agpu,NULL));
67*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-bgpu",&bgpu,NULL));
68*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(NULL,NULL,"-cgpu",&cgpu,NULL));
69*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetScalar(NULL,NULL,"-scale",&scale,NULL));
70c4fb69feSStefano Zampini   if (!Asymm) symm = PETSC_FALSE;
71c4fb69feSStefano Zampini 
72*5f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_size(PETSC_COMM_WORLD,&size));
73300d917bSStefano Zampini 
74300d917bSStefano Zampini   /* Disable tests for unimplemented variants */
75c4fb69feSStefano Zampini   testtrans = (PetscBool)(size == 1 || symm);
76c4fb69feSStefano Zampini   testnorm = (PetscBool)(size == 1 || symm);
7753022affSStefano Zampini   testorthog = (PetscBool)(size == 1 || symm);
7853022affSStefano Zampini   testcompress = (PetscBool)(size == 1 || symm);
79300d917bSStefano Zampini   testhlru = (PetscBool)(size == 1);
80c4fb69feSStefano Zampini 
81*5f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
82*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLayoutCreate(PETSC_COMM_WORLD,&map));
83c4fb69feSStefano Zampini   if (testlayout) {
84c4fb69feSStefano Zampini     if (rank%2) n = PetscMax(2*n-5*rank,0);
85c4fb69feSStefano Zampini     else n = 2*n+rank;
86c4fb69feSStefano Zampini   }
8753022affSStefano Zampini   if (!flgglob) {
88*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscLayoutSetLocalSize(map,n));
89*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscLayoutSetUp(map));
90*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscLayoutGetSize(map,&N));
9153022affSStefano Zampini   } else {
92*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscLayoutSetSize(map,N));
93*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscLayoutSetUp(map));
94*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscLayoutGetLocalSize(map,&n));
9553022affSStefano Zampini   }
96*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscLayoutDestroy(&map));
97c4fb69feSStefano Zampini 
98c4fb69feSStefano Zampini   if (lda) {
99*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscMalloc1(N*(n+lda),&Adata));
100c4fb69feSStefano Zampini   }
101*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateDense(PETSC_COMM_WORLD,n,n,N,N,Adata,&A));
102*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDenseSetLDA(A,n+lda));
103c4fb69feSStefano Zampini 
10453022affSStefano Zampini   /* Create random points; these are replicated in order to populate a dense matrix and to compare sequential and dense runs
10553022affSStefano Zampini      The constructor for MATH2OPUS can take as input the distributed coordinates and replicates them internally in case
10653022affSStefano Zampini      a kernel construction is requested */
107*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomCreate(PETSC_COMM_WORLD,&r));
108*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomSetFromOptions(r));
109*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomSetSeed(r,123456));
110*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomSeed(r));
111*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMalloc1(N*dim,&coords));
112*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomGetValuesReal(r,N*dim,coords));
113*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscRandomDestroy(&r));
11453022affSStefano Zampini 
115c4fb69feSStefano Zampini   if (kernel || !randommat) {
11653022affSStefano Zampini     MatH2OpusKernel k = Asymm ? GenEntry_Symm : GenEntry_Unsymm;
117c4fb69feSStefano Zampini     PetscInt        ist,ien;
118c4fb69feSStefano Zampini 
119*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetOwnershipRange(A,&ist,&ien));
120c4fb69feSStefano Zampini     for (i = ist; i < ien; i++) {
121c4fb69feSStefano Zampini       for (j = 0; j < N; j++) {
122*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatSetValue(A,i,j,(*k)(dim,coords + i*dim,coords + j*dim,NULL),INSERT_VALUES));
123c4fb69feSStefano Zampini       }
124c4fb69feSStefano Zampini     }
125*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
126*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
127c4fb69feSStefano Zampini     if (kernel) {
128*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateH2OpusFromKernel(PETSC_COMM_WORLD,n,n,N,N,dim,coords + ist*dim,PETSC_TRUE,k,NULL,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&B));
129c4fb69feSStefano Zampini     } else {
130*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateH2OpusFromMat(A,dim,coords + ist*dim,PETSC_TRUE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&B));
131c4fb69feSStefano Zampini     }
132c4fb69feSStefano Zampini   } else {
13353022affSStefano Zampini     PetscInt ist;
13453022affSStefano Zampini 
135*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetOwnershipRange(A,&ist,NULL));
136*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetRandom(A,NULL));
137c4fb69feSStefano Zampini     if (Asymm) {
138*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatTranspose(A,MAT_INITIAL_MATRIX,&B));
139*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(A,1.0,B,SAME_NONZERO_PATTERN));
140*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&B));
141*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE));
142c4fb69feSStefano Zampini     }
143*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateH2OpusFromMat(A,dim,coords + ist*dim,PETSC_TRUE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&B));
144c4fb69feSStefano Zampini   }
145*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(coords));
146c4fb69feSStefano Zampini   if (agpu) {
147*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(A,MATDENSECUDA,MAT_INPLACE_MATRIX,&A));
148c4fb69feSStefano Zampini   }
149*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(A,NULL,"-A_view"));
150c4fb69feSStefano Zampini 
151*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetOption(B,MAT_SYMMETRIC,symm));
152c4fb69feSStefano Zampini 
153c4fb69feSStefano Zampini   /* assemble the H-matrix */
154*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatBindToCPU(B,(PetscBool)!bgpu));
155*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetFromOptions(B));
156*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
157*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
158*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatViewFromOptions(B,NULL,"-B_view"));
159c4fb69feSStefano Zampini 
160c4fb69feSStefano Zampini   /* Test MatScale */
161*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatScale(A,scale));
162*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatScale(B,scale));
163c4fb69feSStefano Zampini 
164c4fb69feSStefano Zampini   /* Test MatMult */
165*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateVecs(A,&Ax,&Ay));
166*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateVecs(B,&Bx,&By));
167*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecSetRandom(Ax,NULL));
168*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCopy(Ax,Bx));
169*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMult(A,Ax,Ay));
170*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMult(B,Bx,By));
171*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecViewFromOptions(Ay,NULL,"-mult_vec_view"));
172*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecViewFromOptions(By,NULL,"-mult_vec_view"));
173*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecNorm(Ay,NORM_INFINITY,&nX));
174*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecAXPY(Ay,-1.0,By));
175*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecViewFromOptions(Ay,NULL,"-mult_vec_view"));
176*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecNorm(Ay,NORM_INFINITY,&err));
177*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMult err %g\n",err/nX));
178*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecScale(By,-1.0));
179*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultAdd(B,Bx,By,By));
180*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecNorm(By,NORM_INFINITY,&err));
181*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecViewFromOptions(By,NULL,"-mult_vec_view"));
1824c3a5f3cSStefano Zampini   if (err > 10.*PETSC_SMALL) {
183*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMultAdd err %g\n",err));
184c4fb69feSStefano Zampini   }
185c4fb69feSStefano Zampini 
186c4fb69feSStefano Zampini   /* Test MatNorm */
187*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatNorm(A,NORM_INFINITY,&norms[0]));
188*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatNorm(A,NORM_1,&norms[1]));
189c4fb69feSStefano Zampini   norms[2] = -1.; /* NORM_2 not supported */
190*5f80ce2aSJacob Faibussowitsch   CHKERRQ(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]));
191*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetOperation(A,MATOP_NORM,&Anormfunc));
192*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetOperation(B,MATOP_NORM,&approxnormfunc));
193*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetOperation(A,MATOP_NORM,approxnormfunc));
194*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatNorm(A,NORM_INFINITY,&norms[0]));
195*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatNorm(A,NORM_1,&norms[1]));
196*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatNorm(A,NORM_2,&norms[2]));
197*5f80ce2aSJacob Faibussowitsch   CHKERRQ(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]));
198c4fb69feSStefano Zampini   if (testnorm) {
199*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(B,NORM_INFINITY,&norms[0]));
200*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(B,NORM_1,&norms[1]));
201*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(B,NORM_2,&norms[2]));
202c4fb69feSStefano Zampini   } else {
203c4fb69feSStefano Zampini     norms[0] = -1.;
204c4fb69feSStefano Zampini     norms[1] = -1.;
205c4fb69feSStefano Zampini     norms[2] = -1.;
206c4fb69feSStefano Zampini   }
207*5f80ce2aSJacob Faibussowitsch   CHKERRQ(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]));
208*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetOperation(A,MATOP_NORM,Anormfunc));
209c4fb69feSStefano Zampini 
210c4fb69feSStefano Zampini   /* Test MatDuplicate */
211*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDuplicate(B,MAT_COPY_VALUES,&D));
212*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetOption(D,MAT_SYMMETRIC,symm));
213*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultEqual(B,D,10,&flg));
214c4fb69feSStefano Zampini   if (!flg) {
215*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMult error after MatDuplicate\n"));
216c4fb69feSStefano Zampini   }
217c4fb69feSStefano Zampini   if (testtrans) {
218*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultTransposeEqual(B,D,10,&flg));
219c4fb69feSStefano Zampini     if (!flg) {
220*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMultTranspose error after MatDuplicate\n"));
221c4fb69feSStefano Zampini     }
222c4fb69feSStefano Zampini   }
223*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&D));
224c4fb69feSStefano Zampini 
225c4fb69feSStefano Zampini   if (testtrans) { /* MatMultTranspose for nonsymmetric matrices not implemented */
226*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecSetRandom(Ay,NULL));
227*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecCopy(Ay,By));
228*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultTranspose(A,Ay,Ax));
229*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultTranspose(B,By,Bx));
230*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecViewFromOptions(Ax,NULL,"-multtrans_vec_view"));
231*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecViewFromOptions(Bx,NULL,"-multtrans_vec_view"));
232*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecNorm(Ax,NORM_INFINITY,&nX));
233*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecAXPY(Ax,-1.0,Bx));
234*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecViewFromOptions(Ax,NULL,"-multtrans_vec_view"));
235*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecNorm(Ax,NORM_INFINITY,&err));
236*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMultTranspose err %g\n",err/nX));
237*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecScale(Bx,-1.0));
238*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultTransposeAdd(B,By,Bx,Bx));
239*5f80ce2aSJacob Faibussowitsch     CHKERRQ(VecNorm(Bx,NORM_INFINITY,&err));
2404c3a5f3cSStefano Zampini     if (err > 10.*PETSC_SMALL) {
241*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMultTransposeAdd err %g\n",err));
242c4fb69feSStefano Zampini     }
243c4fb69feSStefano Zampini   }
244*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&Ax));
245*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&Ay));
246*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&Bx));
247*5f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&By));
248c4fb69feSStefano Zampini 
249c4fb69feSStefano Zampini   /* Test MatMatMult */
250c4fb69feSStefano Zampini   if (ldc) {
251*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscMalloc1(nrhs*(n+ldc),&Cdata));
252c4fb69feSStefano Zampini   }
253*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateDense(PETSC_COMM_WORLD,n,PETSC_DECIDE,N,nrhs,Cdata,&C));
254*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDenseSetLDA(C,n+ldc));
255*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetRandom(C,NULL));
256c4fb69feSStefano Zampini   if (cgpu) {
257*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatConvert(C,MATDENSECUDA,MAT_INPLACE_MATRIX,&C));
258c4fb69feSStefano Zampini   }
259c4fb69feSStefano Zampini   for (nt = 0; nt < ntrials; nt++) {
260*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMult(B,C,nt ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX,PETSC_DEFAULT,&D));
261*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatViewFromOptions(D,NULL,"-bc_view"));
262*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectBaseTypeCompareAny((PetscObject)D,&flg,MATSEQDENSE,MATMPIDENSE,""));
263c4fb69feSStefano Zampini     if (flg) {
264*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateVecs(B,&x,&y));
265*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatCreateVecs(D,NULL,&v));
266c4fb69feSStefano Zampini       for (i = 0; i < nrhs; i++) {
267*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetColumnVector(D,v,i));
268*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatGetColumnVector(C,x,i));
269*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatMult(B,x,y));
270*5f80ce2aSJacob Faibussowitsch         CHKERRQ(VecAXPY(y,-1.0,v));
271*5f80ce2aSJacob Faibussowitsch         CHKERRQ(VecNorm(y,NORM_INFINITY,&err));
272*5f80ce2aSJacob Faibussowitsch         if (err > 10.*PETSC_SMALL) CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMat err %" PetscInt_FMT " %g\n",i,err));
273c4fb69feSStefano Zampini       }
274*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&y));
275*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&x));
276*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&v));
277c4fb69feSStefano Zampini     }
278c4fb69feSStefano Zampini   }
279*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&D));
280c4fb69feSStefano Zampini 
281c4fb69feSStefano Zampini   /* Test MatTransposeMatMult */
282c4fb69feSStefano Zampini   if (testtrans) { /* MatMultTranspose for nonsymmetric matrices not implemented */
283c4fb69feSStefano Zampini     for (nt = 0; nt < ntrials; nt++) {
284*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatTransposeMatMult(B,C,nt ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX,PETSC_DEFAULT,&D));
285*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatViewFromOptions(D,NULL,"-btc_view"));
286*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscObjectBaseTypeCompareAny((PetscObject)D,&flg,MATSEQDENSE,MATMPIDENSE,""));
287c4fb69feSStefano Zampini       if (flg) {
288*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatCreateVecs(B,&y,&x));
289*5f80ce2aSJacob Faibussowitsch         CHKERRQ(MatCreateVecs(D,NULL,&v));
290c4fb69feSStefano Zampini         for (i = 0; i < nrhs; i++) {
291*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatGetColumnVector(D,v,i));
292*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatGetColumnVector(C,x,i));
293*5f80ce2aSJacob Faibussowitsch           CHKERRQ(MatMultTranspose(B,x,y));
294*5f80ce2aSJacob Faibussowitsch           CHKERRQ(VecAXPY(y,-1.0,v));
295*5f80ce2aSJacob Faibussowitsch           CHKERRQ(VecNorm(y,NORM_INFINITY,&err));
296*5f80ce2aSJacob Faibussowitsch           if (err > 10.*PETSC_SMALL) CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatTransMat err %" PetscInt_FMT " %g\n",i,err));
297c4fb69feSStefano Zampini         }
298*5f80ce2aSJacob Faibussowitsch         CHKERRQ(VecDestroy(&y));
299*5f80ce2aSJacob Faibussowitsch         CHKERRQ(VecDestroy(&x));
300*5f80ce2aSJacob Faibussowitsch         CHKERRQ(VecDestroy(&v));
301c4fb69feSStefano Zampini       }
302c4fb69feSStefano Zampini     }
303*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&D));
304c4fb69feSStefano Zampini   }
305c4fb69feSStefano Zampini 
306300d917bSStefano Zampini   /* Test basis orthogonalization */
30753022affSStefano Zampini   if (testorthog) {
308*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDuplicate(B,MAT_COPY_VALUES,&D));
309*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetOption(D,MAT_SYMMETRIC,symm));
310*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatH2OpusOrthogonalize(D));
311*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultEqual(B,D,10,&flg));
31253022affSStefano Zampini     if (!flg) {
313*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMult error after basis ortogonalization\n"));
31453022affSStefano Zampini     }
315*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&D));
31653022affSStefano Zampini   }
31753022affSStefano Zampini 
318300d917bSStefano Zampini   /* Test matrix compression */
31953022affSStefano Zampini   if (testcompress) {
320*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDuplicate(B,MAT_COPY_VALUES,&D));
321*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetOption(D,MAT_SYMMETRIC,symm));
322*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatH2OpusCompress(D,PETSC_SMALL));
323*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&D));
32453022affSStefano Zampini   }
32553022affSStefano Zampini 
326300d917bSStefano Zampini   /* Test low-rank update */
327300d917bSStefano Zampini   if (testhlru) {
328300d917bSStefano Zampini     Mat         U, V;
329300d917bSStefano Zampini     PetscScalar *Udata = NULL, *Vdata = NULL;
330300d917bSStefano Zampini 
331300d917bSStefano Zampini     if (ldu) {
332*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscMalloc1(nlr*(n+ldu),&Udata));
333*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscMalloc1(nlr*(n+ldu+2),&Vdata));
334300d917bSStefano Zampini     }
335*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDuplicate(B,MAT_COPY_VALUES,&D));
336*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateDense(PetscObjectComm((PetscObject)D),n,PETSC_DECIDE,N,nlr,Udata,&U));
337*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDenseSetLDA(U,n+ldu));
338*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatCreateDense(PetscObjectComm((PetscObject)D),n,PETSC_DECIDE,N,nlr,Vdata,&V));
339*5f80ce2aSJacob Faibussowitsch     if (ldu) CHKERRQ(MatDenseSetLDA(V,n+ldu+2));
340*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetRandom(U,NULL));
341*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetRandom(V,NULL));
342*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatH2OpusLowRankUpdate(D,U,V,0.5));
343*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatH2OpusLowRankUpdate(D,U,V,-0.5));
344*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMultEqual(B,D,10,&flg));
345300d917bSStefano Zampini     if (!flg) {
346*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"MatMult error after low-rank update\n"));
347300d917bSStefano Zampini     }
348*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&D));
349*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&U));
350*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree(Udata));
351*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&V));
352*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscFree(Vdata));
353300d917bSStefano Zampini   }
354300d917bSStefano Zampini 
355c4fb69feSStefano Zampini   /* check explicit operator */
356c4fb69feSStefano Zampini   if (checkexpl) {
357c4fb69feSStefano Zampini     Mat Be, Bet;
358c4fb69feSStefano Zampini 
359*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatComputeOperator(B,MATDENSE,&D));
360*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDuplicate(D,MAT_COPY_VALUES,&Be));
361*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(D,NORM_FROBENIUS,&nB));
362*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatViewFromOptions(D,NULL,"-expl_view"));
363*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatAXPY(D,-1.0,A,SAME_NONZERO_PATTERN));
364*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatViewFromOptions(D,NULL,"-diff_view"));
365*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(D,NORM_FROBENIUS,&nD));
366*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatNorm(A,NORM_FROBENIUS,&nA));
367*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Approximation error %g (%g / %g, %g)\n",nD/nA,nD,nA,nB));
368*5f80ce2aSJacob Faibussowitsch     CHKERRQ(MatDestroy(&D));
369c4fb69feSStefano Zampini 
370c4fb69feSStefano Zampini     if (testtrans) { /* MatMultTranspose for nonsymmetric matrices not implemented */
371*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatTranspose(A,MAT_INPLACE_MATRIX,&A));
372*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatComputeOperatorTranspose(B,MATDENSE,&D));
373*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDuplicate(D,MAT_COPY_VALUES,&Bet));
374*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(D,NORM_FROBENIUS,&nB));
375*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatViewFromOptions(D,NULL,"-expl_trans_view"));
376*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(D,-1.0,A,SAME_NONZERO_PATTERN));
377*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatViewFromOptions(D,NULL,"-diff_trans_view"));
378*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(D,NORM_FROBENIUS,&nD));
379*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(A,NORM_FROBENIUS,&nA));
380*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Approximation error transpose %g (%g / %g, %g)\n",nD/nA,nD,nA,nB));
381*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&D));
382c4fb69feSStefano Zampini 
383*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatTranspose(Bet,MAT_INPLACE_MATRIX,&Bet));
384*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatAXPY(Be,-1.0,Bet,SAME_NONZERO_PATTERN));
385*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatViewFromOptions(Be,NULL,"-diff_expl_view"));
386*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatNorm(Be,NORM_FROBENIUS,&nB));
387*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"Approximation error B - (B^T)^T %g\n",nB));
388*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&Be));
389*5f80ce2aSJacob Faibussowitsch       CHKERRQ(MatDestroy(&Bet));
390c4fb69feSStefano Zampini     }
391c4fb69feSStefano Zampini   }
392*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&A));
393*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&B));
394*5f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&C));
395*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(Cdata));
396*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(Adata));
397c4fb69feSStefano Zampini   ierr = PetscFinalize();
398c4fb69feSStefano Zampini   return ierr;
399c4fb69feSStefano Zampini }
400c4fb69feSStefano Zampini 
401c4fb69feSStefano Zampini /*TEST
402c4fb69feSStefano Zampini 
403c4fb69feSStefano Zampini    build:
40453022affSStefano Zampini      requires: h2opus
405c4fb69feSStefano Zampini 
406c4fb69feSStefano Zampini #tests from kernel
407c4fb69feSStefano Zampini    test:
40853022affSStefano Zampini      requires: h2opus
409c4fb69feSStefano Zampini      nsize: 1
410c4fb69feSStefano Zampini      suffix: 1
411c4fb69feSStefano Zampini      args: -n {{17 33}} -kernel 1 -dim {{1 2 3}} -symm {{0 1}} -checkexpl -bgpu 0
412c4fb69feSStefano Zampini 
413c4fb69feSStefano Zampini    test:
41453022affSStefano Zampini      requires: h2opus
415c4fb69feSStefano Zampini      nsize: 1
416c4fb69feSStefano Zampini      suffix: 1_ld
417c4fb69feSStefano Zampini      output_file: output/ex66_1.out
418300d917bSStefano Zampini      args: -n 33 -kernel 1 -dim 1 -lda 13 -ldc 11 -ldu 17 -symm 0 -checkexpl -bgpu 0
419c4fb69feSStefano Zampini 
420c4fb69feSStefano Zampini    test:
42153022affSStefano Zampini      requires: h2opus cuda
422c4fb69feSStefano Zampini      nsize: 1
423c4fb69feSStefano Zampini      suffix: 1_cuda
424c4fb69feSStefano Zampini      output_file: output/ex66_1.out
425c4fb69feSStefano Zampini      args: -n {{17 33}} -kernel 1 -dim {{1 2 3}} -symm {{0 1}} -checkexpl -bgpu 1
426c4fb69feSStefano Zampini 
427c4fb69feSStefano Zampini    test:
42853022affSStefano Zampini      requires: h2opus cuda
429c4fb69feSStefano Zampini      nsize: 1
430c4fb69feSStefano Zampini      suffix: 1_cuda_ld
431c4fb69feSStefano Zampini      output_file: output/ex66_1.out
432300d917bSStefano Zampini      args: -n 33 -kernel 1 -dim 1 -lda 13 -ldc 11 -ldu 17 -symm 0 -checkexpl -bgpu 1
433c4fb69feSStefano Zampini 
434c4fb69feSStefano Zampini    test:
43553022affSStefano Zampini      requires: h2opus
43653022affSStefano Zampini      nsize: {{2 3}}
437c4fb69feSStefano Zampini      suffix: 1_par
43853022affSStefano Zampini      args: -n 64 -symm -kernel 1 -dim 1 -ldc 12 -testlayout {{0 1}} -bgpu 0 -cgpu 0
439c4fb69feSStefano Zampini 
440c4fb69feSStefano Zampini    test:
44153022affSStefano Zampini      requires: h2opus cuda
44253022affSStefano Zampini      nsize: {{2 3}}
443c4fb69feSStefano Zampini      suffix: 1_par_cuda
44453022affSStefano Zampini      args: -n 64 -symm -kernel 1 -dim 1 -ldc 12 -testlayout {{0 1}} -bgpu {{0 1}} -cgpu {{0 1}}
445c4fb69feSStefano Zampini      output_file: output/ex66_1_par.out
446c4fb69feSStefano Zampini 
447c4fb69feSStefano Zampini #tests from matrix sampling (parallel or unsymmetric not supported)
448c4fb69feSStefano Zampini    test:
44953022affSStefano Zampini      requires: h2opus
450c4fb69feSStefano Zampini      nsize: 1
451c4fb69feSStefano Zampini      suffix: 2
452c4fb69feSStefano Zampini      args: -n {{17 33}} -kernel 0 -dim 2 -symm 1 -checkexpl -bgpu 0
453c4fb69feSStefano Zampini 
454c4fb69feSStefano Zampini    test:
45553022affSStefano Zampini      requires: h2opus cuda
456c4fb69feSStefano Zampini      nsize: 1
457c4fb69feSStefano Zampini      suffix: 2_cuda
458c4fb69feSStefano Zampini      output_file: output/ex66_2.out
459c4fb69feSStefano Zampini      args: -n {{17 33}} -kernel 0 -dim 2 -symm 1 -checkexpl -bgpu {{0 1}} -agpu {{0 1}}
460c4fb69feSStefano Zampini 
46153022affSStefano Zampini #tests view operation
46253022affSStefano Zampini    test:
46353022affSStefano Zampini      requires: h2opus !cuda
46453022affSStefano Zampini      filter: grep -v "MPI processes" | grep -v "\[" | grep -v "\]"
46553022affSStefano Zampini      nsize: {{1 2 3}}
46653022affSStefano Zampini      suffix: view
46753022affSStefano 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
46853022affSStefano Zampini 
46953022affSStefano Zampini    test:
47053022affSStefano Zampini      requires: h2opus cuda
47153022affSStefano Zampini      filter: grep -v "MPI processes" | grep -v "\[" | grep -v "\]"
47253022affSStefano Zampini      nsize: {{1 2 3}}
47353022affSStefano Zampini      suffix: view_cuda
47453022affSStefano 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
47553022affSStefano Zampini 
476c4fb69feSStefano Zampini TEST*/
477