xref: /petsc/src/mat/tests/ex115.c (revision 2c71b3e237ead271e4f3aa1505f92bf476e3413d)
1c4762a1bSJed Brown 
2c4762a1bSJed Brown static char help[] = "Tests MatHYPRE\n";
3c4762a1bSJed Brown 
4c4762a1bSJed Brown #include <petscmathypre.h>
5c4762a1bSJed Brown 
6c4762a1bSJed Brown int main(int argc,char **args)
7c4762a1bSJed Brown {
8c4762a1bSJed Brown   Mat                A,B,C,D;
9c4762a1bSJed Brown   Mat                pAB,CD,CAB;
10c4762a1bSJed Brown   hypre_ParCSRMatrix *parcsr;
11c4762a1bSJed Brown   PetscReal          err;
12c4762a1bSJed Brown   PetscInt           i,j,N = 6, M = 6;
13c4762a1bSJed Brown   PetscErrorCode     ierr;
14c4762a1bSJed Brown   PetscBool          flg,testptap = PETSC_TRUE,testmatmatmult = PETSC_TRUE;
15c4762a1bSJed Brown   PetscReal          norm;
16c4762a1bSJed Brown   char               file[256];
17c4762a1bSJed Brown 
18c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
19589a23caSBarry Smith   ierr = PetscOptionsGetString(NULL,NULL,"-f",file,sizeof(file),&flg);CHKERRQ(ierr);
20c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX)
21c4762a1bSJed Brown   testptap = PETSC_FALSE;
22c4762a1bSJed Brown   testmatmatmult = PETSC_FALSE;
23c4762a1bSJed Brown   ierr = PetscOptionsInsertString(NULL,"-options_left 0");CHKERRQ(ierr);
24c4762a1bSJed Brown #endif
25c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-ptap",&testptap,NULL);CHKERRQ(ierr);
26c4762a1bSJed Brown   ierr = PetscOptionsGetBool(NULL,NULL,"-matmatmult",&testmatmatmult,NULL);CHKERRQ(ierr);
27c4762a1bSJed Brown   ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
28c4762a1bSJed Brown   if (!flg) { /* Create a matrix and test MatSetValues */
29c4762a1bSJed Brown     PetscMPIInt size;
30c4762a1bSJed Brown 
31ffc4695bSBarry Smith     ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRMPI(ierr);
32c4762a1bSJed Brown     ierr = PetscOptionsGetInt(NULL,NULL,"-M",&M,NULL);CHKERRQ(ierr);
33c4762a1bSJed Brown     ierr = PetscOptionsGetInt(NULL,NULL,"-N",&N,NULL);CHKERRQ(ierr);
34c4762a1bSJed Brown     ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
35c4762a1bSJed Brown     ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr);
36c4762a1bSJed Brown     ierr = MatSeqAIJSetPreallocation(A,9,NULL);CHKERRQ(ierr);
37c4762a1bSJed Brown     ierr = MatMPIAIJSetPreallocation(A,9,NULL,9,NULL);CHKERRQ(ierr);
38c4762a1bSJed Brown     ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr);
39c4762a1bSJed Brown     ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
40c4762a1bSJed Brown     ierr = MatSetType(B,MATHYPRE);CHKERRQ(ierr);
41c4762a1bSJed Brown     if (M == N) {
42c4762a1bSJed Brown       ierr = MatHYPRESetPreallocation(B,9,NULL,9,NULL);CHKERRQ(ierr);
43c4762a1bSJed Brown     } else {
44c4762a1bSJed Brown       ierr = MatHYPRESetPreallocation(B,6,NULL,6,NULL);CHKERRQ(ierr);
45c4762a1bSJed Brown     }
46c4762a1bSJed Brown     if (M == N) {
47c4762a1bSJed Brown       for (i=0; i<M; i++) {
48c4762a1bSJed Brown         PetscInt    cols[] = {0,1,2,3,4,5};
49c4762a1bSJed Brown         PetscScalar vals[] = {0,1./size,2./size,3./size,4./size,5./size};
50c4762a1bSJed Brown         for (j=i-2; j<i+1; j++) {
51c4762a1bSJed Brown           if (j >= N) {
52c4762a1bSJed Brown             ierr = MatSetValue(A,i,N-1,(1.*j*N+i)/(3.*N*size),ADD_VALUES);CHKERRQ(ierr);
53c4762a1bSJed Brown             ierr = MatSetValue(B,i,N-1,(1.*j*N+i)/(3.*N*size),ADD_VALUES);CHKERRQ(ierr);
54c4762a1bSJed Brown           } else if (i > j) {
55c4762a1bSJed Brown             ierr = MatSetValue(A,i,PetscMin(j,N-1),(1.*j*N+i)/(2.*N*size),ADD_VALUES);CHKERRQ(ierr);
56c4762a1bSJed Brown             ierr = MatSetValue(B,i,PetscMin(j,N-1),(1.*j*N+i)/(2.*N*size),ADD_VALUES);CHKERRQ(ierr);
57c4762a1bSJed Brown           } else {
58c4762a1bSJed Brown             ierr = MatSetValue(A,i,PetscMin(j,N-1),-1.-(1.*j*N+i)/(4.*N*size),ADD_VALUES);CHKERRQ(ierr);
59c4762a1bSJed Brown             ierr = MatSetValue(B,i,PetscMin(j,N-1),-1.-(1.*j*N+i)/(4.*N*size),ADD_VALUES);CHKERRQ(ierr);
60c4762a1bSJed Brown           }
61c4762a1bSJed Brown         }
62c4762a1bSJed Brown         ierr = MatSetValues(A,1,&i,PetscMin(6,N),cols,vals,ADD_VALUES);CHKERRQ(ierr);
63c4762a1bSJed Brown         ierr = MatSetValues(B,1,&i,PetscMin(6,N),cols,vals,ADD_VALUES);CHKERRQ(ierr);
64c4762a1bSJed Brown       }
65c4762a1bSJed Brown     } else {
66c4762a1bSJed Brown       PetscInt  rows[2];
67c4762a1bSJed Brown       PetscBool test_offproc = PETSC_FALSE;
68c4762a1bSJed Brown 
691e1ea65dSPierre Jolivet       ierr = PetscOptionsGetBool(NULL,NULL,"-test_offproc",&test_offproc,NULL);CHKERRQ(ierr);
70c4762a1bSJed Brown       if (test_offproc) {
71c4762a1bSJed Brown         const PetscInt *ranges;
72c4762a1bSJed Brown         PetscMPIInt    rank;
73c4762a1bSJed Brown 
74ffc4695bSBarry Smith         ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr);
75c4762a1bSJed Brown         ierr = MatGetOwnershipRanges(A,&ranges);CHKERRQ(ierr);
76c4762a1bSJed Brown         rows[0] = ranges[(rank+1)%size];
77c4762a1bSJed Brown         rows[1] = ranges[(rank+1)%size + 1];
78c4762a1bSJed Brown       } else {
79c4762a1bSJed Brown         ierr = MatGetOwnershipRange(A,&rows[0],&rows[1]);CHKERRQ(ierr);
80c4762a1bSJed Brown       }
81c4762a1bSJed Brown       for (i=rows[0];i<rows[1];i++) {
82c4762a1bSJed Brown         PetscInt    cols[] = {0,1,2,3,4,5};
83c4762a1bSJed Brown         PetscScalar vals[] = {-1,1,-2,2,-3,3};
84c4762a1bSJed Brown 
85c4762a1bSJed Brown         ierr = MatSetValues(A,1,&i,PetscMin(6,N),cols,vals,INSERT_VALUES);CHKERRQ(ierr);
86c4762a1bSJed Brown         ierr = MatSetValues(B,1,&i,PetscMin(6,N),cols,vals,INSERT_VALUES);CHKERRQ(ierr);
87c4762a1bSJed Brown       }
88c4762a1bSJed Brown     }
89c4762a1bSJed Brown     /* MAT_FLUSH_ASSEMBLY currently not supported */
90c4762a1bSJed Brown     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
91c4762a1bSJed Brown     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
92c4762a1bSJed Brown     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
93c4762a1bSJed Brown     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
94c4762a1bSJed Brown 
95c4762a1bSJed Brown #if defined(PETSC_USE_COMPLEX)
96c4762a1bSJed Brown     /* make the matrix imaginary */
97c4762a1bSJed Brown     ierr = MatScale(A,PETSC_i);CHKERRQ(ierr);
98c4762a1bSJed Brown     ierr = MatScale(B,PETSC_i);CHKERRQ(ierr);
99c4762a1bSJed Brown #endif
100c4762a1bSJed Brown 
101c4762a1bSJed Brown     /* MatAXPY further exercises MatSetValues_HYPRE */
102c4762a1bSJed Brown     ierr = MatAXPY(B,-1.,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
103c4762a1bSJed Brown     ierr = MatConvert(B,MATMPIAIJ,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr);
104c4762a1bSJed Brown     ierr = MatNorm(C,NORM_INFINITY,&err);CHKERRQ(ierr);
105*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(err > PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatSetValues %g",err);
106c4762a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
107c4762a1bSJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
108c4762a1bSJed Brown   } else {
109c4762a1bSJed Brown     PetscViewer viewer;
110c4762a1bSJed Brown 
111c4762a1bSJed Brown     ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&viewer);CHKERRQ(ierr);
112c4762a1bSJed Brown     ierr = MatSetFromOptions(A);CHKERRQ(ierr);
113c4762a1bSJed Brown     ierr = MatLoad(A,viewer);CHKERRQ(ierr);
114c4762a1bSJed Brown     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
115c4762a1bSJed Brown     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
116c4762a1bSJed Brown   }
117c4762a1bSJed Brown 
118c4762a1bSJed Brown   /* check conversion routines */
119c4762a1bSJed Brown   ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr);
120c4762a1bSJed Brown   ierr = MatConvert(A,MATHYPRE,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr);
121c4762a1bSJed Brown   ierr = MatConvert(B,MATIS,MAT_INITIAL_MATRIX,&D);CHKERRQ(ierr);
122c4762a1bSJed Brown   ierr = MatConvert(B,MATIS,MAT_REUSE_MATRIX,&D);CHKERRQ(ierr);
123c4762a1bSJed Brown   ierr = MatConvert(B,MATAIJ,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr);
124c4762a1bSJed Brown   ierr = MatConvert(B,MATAIJ,MAT_REUSE_MATRIX,&C);CHKERRQ(ierr);
125c4762a1bSJed Brown   ierr = MatAXPY(C,-1.,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
126c4762a1bSJed Brown   ierr = MatNorm(C,NORM_INFINITY,&err);CHKERRQ(ierr);
127*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(err > PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat AIJ %g",err);
128c4762a1bSJed Brown   ierr = MatDestroy(&C);CHKERRQ(ierr);
129c4762a1bSJed Brown   ierr = MatConvert(D,MATAIJ,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr);
130c4762a1bSJed Brown   ierr = MatAXPY(C,-1.,A,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
131c4762a1bSJed Brown   ierr = MatNorm(C,NORM_INFINITY,&err);CHKERRQ(ierr);
132*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(err > PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error Mat IS %g",err);
133c4762a1bSJed Brown   ierr = MatDestroy(&C);CHKERRQ(ierr);
134c4762a1bSJed Brown   ierr = MatDestroy(&D);CHKERRQ(ierr);
135c4762a1bSJed Brown 
136c4762a1bSJed Brown   /* check MatCreateFromParCSR */
137c4762a1bSJed Brown   ierr = MatHYPREGetParCSR(B,&parcsr);CHKERRQ(ierr);
138c4762a1bSJed Brown   ierr = MatCreateFromParCSR(parcsr,MATAIJ,PETSC_COPY_VALUES,&D);CHKERRQ(ierr);
139c4762a1bSJed Brown   ierr = MatDestroy(&D);CHKERRQ(ierr);
140c4762a1bSJed Brown   ierr = MatCreateFromParCSR(parcsr,MATHYPRE,PETSC_USE_POINTER,&C);CHKERRQ(ierr);
141c4762a1bSJed Brown 
142c4762a1bSJed Brown   /* check MatMult operations */
143c4762a1bSJed Brown   ierr = MatMultEqual(A,B,4,&flg);CHKERRQ(ierr);
144*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMult B");
145c4762a1bSJed Brown   ierr = MatMultEqual(A,C,4,&flg);CHKERRQ(ierr);
146*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMult C");
147c4762a1bSJed Brown   ierr = MatMultAddEqual(A,B,4,&flg);CHKERRQ(ierr);
148*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultAdd B");
149c4762a1bSJed Brown   ierr = MatMultAddEqual(A,C,4,&flg);CHKERRQ(ierr);
150*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultAdd C");
151c4762a1bSJed Brown   ierr = MatMultTransposeEqual(A,B,4,&flg);CHKERRQ(ierr);
152*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTranspose B");
153c4762a1bSJed Brown   ierr = MatMultTransposeEqual(A,C,4,&flg);CHKERRQ(ierr);
154*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTranspose C");
155c4762a1bSJed Brown   ierr = MatMultTransposeAddEqual(A,B,4,&flg);CHKERRQ(ierr);
156*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTransposeAdd B");
157c4762a1bSJed Brown   ierr = MatMultTransposeAddEqual(A,C,4,&flg);CHKERRQ(ierr);
158*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!flg,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMultTransposeAdd C");
159c4762a1bSJed Brown 
160c4762a1bSJed Brown   /* check PtAP */
161c4762a1bSJed Brown   if (testptap && M == N) {
162c4762a1bSJed Brown     Mat pP,hP;
163c4762a1bSJed Brown 
164c4762a1bSJed Brown     /* PETSc MatPtAP -> output is a MatAIJ
165c4762a1bSJed Brown        It uses HYPRE functions when -matptap_via hypre is specified at command line */
166c4762a1bSJed Brown     ierr = MatPtAP(A,A,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pP);CHKERRQ(ierr);
167c4762a1bSJed Brown     ierr = MatPtAP(A,A,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pP);CHKERRQ(ierr);
168c4762a1bSJed Brown     ierr = MatNorm(pP,NORM_INFINITY,&norm);CHKERRQ(ierr);
169c20d7725SJed Brown     ierr = MatPtAPMultEqual(A,A,pP,10,&flg);CHKERRQ(ierr);
170*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_MatAIJ");
171c4762a1bSJed Brown 
172c4762a1bSJed Brown     /* MatPtAP_HYPRE_HYPRE -> output is a MatHYPRE */
173c4762a1bSJed Brown     ierr = MatPtAP(C,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&hP);CHKERRQ(ierr);
174c4762a1bSJed Brown     ierr = MatPtAP(C,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&hP);CHKERRQ(ierr);
175c20d7725SJed Brown     ierr = MatPtAPMultEqual(C,B,hP,10,&flg);CHKERRQ(ierr);
176*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_HYPRE_HYPRE");
177c20d7725SJed Brown 
178c20d7725SJed Brown     /* Test MatAXPY_Basic() */
179c4762a1bSJed Brown     ierr = MatAXPY(hP,-1.,pP,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
180c4762a1bSJed Brown     ierr = MatHasOperation(hP,MATOP_NORM,&flg);CHKERRQ(ierr);
181c4762a1bSJed Brown     if (!flg) { /* TODO add MatNorm_HYPRE */
182c4762a1bSJed Brown       ierr = MatConvert(hP,MATAIJ,MAT_INPLACE_MATRIX,&hP);CHKERRQ(ierr);
183c4762a1bSJed Brown     }
184c4762a1bSJed Brown     ierr = MatNorm(hP,NORM_INFINITY,&err);CHKERRQ(ierr);
185*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(err/norm > PETSC_SMALL,PetscObjectComm((PetscObject)hP),PETSC_ERR_PLIB,"Error MatPtAP %g %g",err,norm);
186c20d7725SJed Brown     ierr = MatDestroy(&pP);CHKERRQ(ierr);
187c4762a1bSJed Brown     ierr = MatDestroy(&hP);CHKERRQ(ierr);
188c4762a1bSJed Brown 
189c4762a1bSJed Brown     /* MatPtAP_AIJ_HYPRE -> output can be decided at runtime with -matptap_hypre_outtype */
190c4762a1bSJed Brown     ierr = MatPtAP(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&hP);CHKERRQ(ierr);
191c4762a1bSJed Brown     ierr = MatPtAP(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&hP);CHKERRQ(ierr);
192c20d7725SJed Brown     ierr = MatPtAPMultEqual(A,B,hP,10,&flg);CHKERRQ(ierr);
193*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP_AIJ_HYPRE");
194c4762a1bSJed Brown     ierr = MatDestroy(&hP);CHKERRQ(ierr);
195c4762a1bSJed Brown   }
196c4762a1bSJed Brown   ierr = MatDestroy(&C);CHKERRQ(ierr);
197c4762a1bSJed Brown   ierr = MatDestroy(&B);CHKERRQ(ierr);
198c4762a1bSJed Brown 
199c4762a1bSJed Brown   /* check MatMatMult */
200c4762a1bSJed Brown   if (testmatmatmult) {
201c4762a1bSJed Brown     ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr);
202c4762a1bSJed Brown     ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr);
203c4762a1bSJed Brown     ierr = MatConvert(B,MATHYPRE,MAT_INITIAL_MATRIX,&D);CHKERRQ(ierr);
204c4762a1bSJed Brown 
205c4762a1bSJed Brown     /* PETSc MatMatMult -> output is a MatAIJ
206c4762a1bSJed Brown        It uses HYPRE functions when -matmatmult_via hypre is specified at command line */
207c4762a1bSJed Brown     ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pAB);CHKERRQ(ierr);
208c4762a1bSJed Brown     ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&pAB);CHKERRQ(ierr);
209c4762a1bSJed Brown     ierr = MatNorm(pAB,NORM_INFINITY,&norm);CHKERRQ(ierr);
210c20d7725SJed Brown     ierr = MatMatMultEqual(A,B,pAB,10,&flg);CHKERRQ(ierr);
211*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatMult_AIJ_AIJ");
212c4762a1bSJed Brown 
213c4762a1bSJed Brown     /* MatMatMult_HYPRE_HYPRE -> output is a MatHYPRE */
214c4762a1bSJed Brown     ierr = MatMatMult(C,D,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CD);CHKERRQ(ierr);
215c4762a1bSJed Brown     ierr = MatMatMult(C,D,MAT_REUSE_MATRIX,PETSC_DEFAULT,&CD);CHKERRQ(ierr);
216c20d7725SJed Brown     ierr = MatMatMultEqual(C,D,CD,10,&flg);CHKERRQ(ierr);
217*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!flg,PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatMult_HYPRE_HYPRE");
218c20d7725SJed Brown 
219c20d7725SJed Brown     /* Test MatAXPY_Basic() */
220c4762a1bSJed Brown     ierr = MatAXPY(CD,-1.,pAB,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
221c20d7725SJed Brown 
222c4762a1bSJed Brown     ierr = MatHasOperation(CD,MATOP_NORM,&flg);CHKERRQ(ierr);
223c4762a1bSJed Brown     if (!flg) { /* TODO add MatNorm_HYPRE */
224c4762a1bSJed Brown       ierr = MatConvert(CD,MATAIJ,MAT_INPLACE_MATRIX,&CD);CHKERRQ(ierr);
225c4762a1bSJed Brown     }
226c4762a1bSJed Brown     ierr = MatNorm(CD,NORM_INFINITY,&err);CHKERRQ(ierr);
227*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(err/norm > PETSC_SMALL,PetscObjectComm((PetscObject)CD),PETSC_ERR_PLIB,"Error MatMatMult %g %g",err,norm);
228c20d7725SJed Brown 
229c4762a1bSJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
230c4762a1bSJed Brown     ierr = MatDestroy(&D);CHKERRQ(ierr);
231c4762a1bSJed Brown     ierr = MatDestroy(&pAB);CHKERRQ(ierr);
232c20d7725SJed Brown     ierr = MatDestroy(&CD);CHKERRQ(ierr);
233c4762a1bSJed Brown 
234c4762a1bSJed Brown     /* When configured with HYPRE, MatMatMatMult is available for the triplet transpose(aij)-aij-aij */
235c4762a1bSJed Brown     ierr = MatCreateTranspose(A,&C);CHKERRQ(ierr);
236c4762a1bSJed Brown     ierr = MatMatMatMult(C,A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&CAB);CHKERRQ(ierr);
237c4762a1bSJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
238c4762a1bSJed Brown     ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&C);CHKERRQ(ierr);
239c4762a1bSJed Brown     ierr = MatMatMult(C,A,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&D);CHKERRQ(ierr);
240c4762a1bSJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
241c4762a1bSJed Brown     ierr = MatMatMult(D,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
242c4762a1bSJed Brown     ierr = MatNorm(C,NORM_INFINITY,&norm);CHKERRQ(ierr);
243c4762a1bSJed Brown     ierr = MatAXPY(C,-1.,CAB,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
244c4762a1bSJed Brown     ierr = MatNorm(C,NORM_INFINITY,&err);CHKERRQ(ierr);
245*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(err/norm > PETSC_SMALL,PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatMatMatMult %g %g",err,norm);
246c4762a1bSJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
247c4762a1bSJed Brown     ierr = MatDestroy(&D);CHKERRQ(ierr);
248c4762a1bSJed Brown     ierr = MatDestroy(&CAB);CHKERRQ(ierr);
249c4762a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
250c4762a1bSJed Brown   }
251c4762a1bSJed Brown 
252c4762a1bSJed Brown   /* Check MatView */
253c4762a1bSJed Brown   ierr = MatViewFromOptions(A,NULL,"-view_A");CHKERRQ(ierr);
254c4762a1bSJed Brown   ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr);
255c4762a1bSJed Brown   ierr = MatViewFromOptions(B,NULL,"-view_B");CHKERRQ(ierr);
256c4762a1bSJed Brown 
257c4762a1bSJed Brown   /* Check MatDuplicate/MatCopy */
258c4762a1bSJed Brown   for (j=0;j<3;j++) {
259c4762a1bSJed Brown     MatDuplicateOption dop;
260c4762a1bSJed Brown 
261c4762a1bSJed Brown     dop = MAT_COPY_VALUES;
262c4762a1bSJed Brown     if (j==1) dop = MAT_DO_NOT_COPY_VALUES;
263c4762a1bSJed Brown     if (j==2) dop = MAT_SHARE_NONZERO_PATTERN;
264c4762a1bSJed Brown 
265c4762a1bSJed Brown     for (i=0;i<3;i++) {
266c4762a1bSJed Brown       MatStructure str;
267c4762a1bSJed Brown 
2688fffc762SJacob Faibussowitsch       ierr = PetscPrintf(PETSC_COMM_WORLD,"Dup/Copy tests: %" PetscInt_FMT " %" PetscInt_FMT "\n",j,i);CHKERRQ(ierr);
269c4762a1bSJed Brown 
270c4762a1bSJed Brown       str = DIFFERENT_NONZERO_PATTERN;
271c4762a1bSJed Brown       if (i==1) str = SAME_NONZERO_PATTERN;
272c4762a1bSJed Brown       if (i==2) str = SUBSET_NONZERO_PATTERN;
273c4762a1bSJed Brown 
274c4762a1bSJed Brown       ierr = MatDuplicate(A,dop,&C);CHKERRQ(ierr);
275c4762a1bSJed Brown       ierr = MatDuplicate(B,dop,&D);CHKERRQ(ierr);
276c4762a1bSJed Brown       if (dop != MAT_COPY_VALUES) {
277c4762a1bSJed Brown         ierr = MatCopy(A,C,str);CHKERRQ(ierr);
278c4762a1bSJed Brown         ierr = MatCopy(B,D,str);CHKERRQ(ierr);
279c4762a1bSJed Brown       }
280c4762a1bSJed Brown       /* AXPY with AIJ and HYPRE */
281c4762a1bSJed Brown       ierr = MatAXPY(C,-1.0,D,str);CHKERRQ(ierr);
282c4762a1bSJed Brown       ierr = MatNorm(C,NORM_INFINITY,&err);CHKERRQ(ierr);
283c4762a1bSJed Brown       if (err > PETSC_SMALL) {
284c4762a1bSJed Brown         ierr = MatViewFromOptions(A,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
285c4762a1bSJed Brown         ierr = MatViewFromOptions(B,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
286c4762a1bSJed Brown         ierr = MatViewFromOptions(C,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
28798921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 1 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i);
288c4762a1bSJed Brown       }
289c4762a1bSJed Brown       /* AXPY with HYPRE and HYPRE */
290c4762a1bSJed Brown       ierr = MatAXPY(D,-1.0,B,str);CHKERRQ(ierr);
291c4762a1bSJed Brown       if (err > PETSC_SMALL) {
292c4762a1bSJed Brown         ierr = MatViewFromOptions(A,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
293c4762a1bSJed Brown         ierr = MatViewFromOptions(B,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
294c4762a1bSJed Brown         ierr = MatViewFromOptions(D,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
29598921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 2 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i);
296c4762a1bSJed Brown       }
297c4762a1bSJed Brown       /* Copy from HYPRE to AIJ */
298c4762a1bSJed Brown       ierr = MatCopy(B,C,str);CHKERRQ(ierr);
299c4762a1bSJed Brown       /* Copy from AIJ to HYPRE */
300c4762a1bSJed Brown       ierr = MatCopy(A,D,str);CHKERRQ(ierr);
301c4762a1bSJed Brown       /* AXPY with HYPRE and AIJ */
302c4762a1bSJed Brown       ierr = MatAXPY(D,-1.0,C,str);CHKERRQ(ierr);
303c4762a1bSJed Brown       ierr = MatHasOperation(D,MATOP_NORM,&flg);CHKERRQ(ierr);
304c4762a1bSJed Brown       if (!flg) { /* TODO add MatNorm_HYPRE */
305c4762a1bSJed Brown         ierr = MatConvert(D,MATAIJ,MAT_INPLACE_MATRIX,&D);CHKERRQ(ierr);
306c4762a1bSJed Brown       }
307c4762a1bSJed Brown       ierr = MatNorm(D,NORM_INFINITY,&err);CHKERRQ(ierr);
308c4762a1bSJed Brown       if (err > PETSC_SMALL) {
309c4762a1bSJed Brown         ierr = MatViewFromOptions(A,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
310c4762a1bSJed Brown         ierr = MatViewFromOptions(C,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
311c4762a1bSJed Brown         ierr = MatViewFromOptions(D,NULL,"-view_duplicate_diff");CHKERRQ(ierr);
31298921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error test 3 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")",err,j,i);
313c4762a1bSJed Brown       }
314c4762a1bSJed Brown       ierr = MatDestroy(&C);CHKERRQ(ierr);
315c4762a1bSJed Brown       ierr = MatDestroy(&D);CHKERRQ(ierr);
316c4762a1bSJed Brown     }
317c4762a1bSJed Brown   }
318c4762a1bSJed Brown   ierr = MatDestroy(&B);CHKERRQ(ierr);
319c4762a1bSJed Brown 
320c4762a1bSJed Brown   ierr = MatHasCongruentLayouts(A,&flg);CHKERRQ(ierr);
321c4762a1bSJed Brown   if (flg) {
322c4762a1bSJed Brown     Vec y,y2;
323c4762a1bSJed Brown 
324c4762a1bSJed Brown     ierr = MatConvert(A,MATHYPRE,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr);
325c4762a1bSJed Brown     ierr = MatCreateVecs(A,NULL,&y);CHKERRQ(ierr);
326c4762a1bSJed Brown     ierr = MatCreateVecs(B,NULL,&y2);CHKERRQ(ierr);
327c4762a1bSJed Brown     ierr = MatGetDiagonal(A,y);CHKERRQ(ierr);
328c4762a1bSJed Brown     ierr = MatGetDiagonal(B,y2);CHKERRQ(ierr);
329c4762a1bSJed Brown     ierr = VecAXPY(y2,-1.0,y);CHKERRQ(ierr);
330c4762a1bSJed Brown     ierr = VecNorm(y2,NORM_INFINITY,&err);CHKERRQ(ierr);
331c4762a1bSJed Brown     if (err > PETSC_SMALL) {
332c4762a1bSJed Brown       ierr = VecViewFromOptions(y,NULL,"-view_diagonal_diff");CHKERRQ(ierr);
333c4762a1bSJed Brown       ierr = VecViewFromOptions(y2,NULL,"-view_diagonal_diff");CHKERRQ(ierr);
33498921bdaSJacob Faibussowitsch       SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_PLIB,"Error MatGetDiagonal %g",err);
335c4762a1bSJed Brown     }
336c4762a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
337c4762a1bSJed Brown     ierr = VecDestroy(&y);CHKERRQ(ierr);
338c4762a1bSJed Brown     ierr = VecDestroy(&y2);CHKERRQ(ierr);
339c4762a1bSJed Brown   }
340c4762a1bSJed Brown 
341c4762a1bSJed Brown   ierr = MatDestroy(&A);CHKERRQ(ierr);
342c4762a1bSJed Brown 
343c4762a1bSJed Brown   ierr = PetscFinalize();
344c4762a1bSJed Brown   return ierr;
345c4762a1bSJed Brown }
346c4762a1bSJed Brown 
347c4762a1bSJed Brown /*TEST
348c4762a1bSJed Brown 
349c4762a1bSJed Brown    build:
350c4762a1bSJed Brown       requires: hypre
351c4762a1bSJed Brown 
352c4762a1bSJed Brown    test:
353263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
354c4762a1bSJed Brown       suffix: 1
355c4762a1bSJed Brown       args: -N 11 -M 11
356c4762a1bSJed Brown       output_file: output/ex115_1.out
357c4762a1bSJed Brown 
358c4762a1bSJed Brown    test:
359263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
360c4762a1bSJed Brown       suffix: 2
361c4762a1bSJed Brown       nsize: 3
362c4762a1bSJed Brown       args: -N 13 -M 13 -matmatmult_via hypre
363c4762a1bSJed Brown       output_file: output/ex115_1.out
364c4762a1bSJed Brown 
365c4762a1bSJed Brown    test:
366263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
367c4762a1bSJed Brown       suffix: 3
368c4762a1bSJed Brown       nsize: 4
369c4762a1bSJed Brown       args: -M 13 -N 7 -matmatmult_via hypre
370c4762a1bSJed Brown       output_file: output/ex115_1.out
371c4762a1bSJed Brown 
372c4762a1bSJed Brown    test:
373263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
374c4762a1bSJed Brown       suffix: 4
375c4762a1bSJed Brown       nsize: 2
376c4762a1bSJed Brown       args: -M 12 -N 19
377c4762a1bSJed Brown       output_file: output/ex115_1.out
378c4762a1bSJed Brown 
379c4762a1bSJed Brown    test:
380263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
381c4762a1bSJed Brown       suffix: 5
382c4762a1bSJed Brown       nsize: 3
383c4762a1bSJed Brown       args: -M 13 -N 13 -matptap_via hypre -matptap_hypre_outtype hypre
384c4762a1bSJed Brown       output_file: output/ex115_1.out
385c4762a1bSJed Brown 
386c4762a1bSJed Brown    test:
387263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
388c4762a1bSJed Brown       suffix: 6
389c4762a1bSJed Brown       nsize: 3
390c4762a1bSJed Brown       args: -M 12 -N 19 -test_offproc
391c4762a1bSJed Brown       output_file: output/ex115_1.out
392c4762a1bSJed Brown 
393c4762a1bSJed Brown    test:
394263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
395c4762a1bSJed Brown       suffix: 7
396c4762a1bSJed Brown       nsize: 3
397c4762a1bSJed Brown       args: -M 19 -N 12 -test_offproc -view_B ::ascii_info_detail
398c4762a1bSJed Brown       output_file: output/ex115_7.out
399c4762a1bSJed Brown 
400c4762a1bSJed Brown    test:
401263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
402c4762a1bSJed Brown       suffix: 8
403c4762a1bSJed Brown       nsize: 3
404c4762a1bSJed Brown       args: -M 1 -N 12 -test_offproc
405c4762a1bSJed Brown       output_file: output/ex115_1.out
406c4762a1bSJed Brown 
407c4762a1bSJed Brown    test:
408263f2b91SStefano Zampini       requires: !defined(PETSC_HAVE_HYPRE_DEVICE)
409c4762a1bSJed Brown       suffix: 9
410c4762a1bSJed Brown       nsize: 3
411c4762a1bSJed Brown       args: -M 1 -N 2 -test_offproc
412c4762a1bSJed Brown       output_file: output/ex115_1.out
413c4762a1bSJed Brown 
414c4762a1bSJed Brown TEST*/
415