xref: /petsc/src/mat/tests/ex62.c (revision 910fa13fd89f91836db2ed987f9090e62f6fe0ac)
1c20d7725SJed Brown 
2c20d7725SJed Brown static char help[] = "Test Matrix products for AIJ matrices\n\
3c20d7725SJed Brown Input arguments are:\n\
4c20d7725SJed Brown   -fA <input_file> -fB <input_file> -fC <input_file>: file to load\n\n";
5c20d7725SJed Brown /* Example of usage:
6c20d7725SJed Brown    ./ex62 -fA <A_binary> -fB <B_binary>
7c20d7725SJed Brown    mpiexec -n 3 ./ex62 -fA medium -fB medium
8c20d7725SJed Brown */
9c20d7725SJed Brown 
10c20d7725SJed Brown #include <petscmat.h>
11c20d7725SJed Brown 
12c20d7725SJed Brown /*
13c20d7725SJed Brown      B = A - B
14c20d7725SJed Brown      norm = norm(B)
15c20d7725SJed Brown */
16c20d7725SJed Brown PetscErrorCode MatNormDifference(Mat A,Mat B,PetscReal *norm)
17c20d7725SJed Brown {
18c20d7725SJed Brown   PetscErrorCode ierr;
19c20d7725SJed Brown 
20c20d7725SJed Brown   PetscFunctionBegin;
21c20d7725SJed Brown   ierr = MatAXPY(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
22c20d7725SJed Brown   ierr = MatNorm(B,NORM_FROBENIUS,norm);CHKERRQ(ierr);
23c20d7725SJed Brown   PetscFunctionReturn(0);
24c20d7725SJed Brown }
25c20d7725SJed Brown 
26c20d7725SJed Brown int main(int argc,char **args)
27c20d7725SJed Brown {
28c20d7725SJed Brown   Mat            A,A_save,B,C,P,C1,R;
29c20d7725SJed Brown   PetscViewer    viewer;
30c20d7725SJed Brown   PetscErrorCode ierr;
31c20d7725SJed Brown   PetscMPIInt    size,rank;
32c20d7725SJed Brown   PetscInt       i,j,*idxn,M,N,nzp,PN,rstart,rend;
33c20d7725SJed Brown   PetscReal      norm;
34c20d7725SJed Brown   PetscRandom    rdm;
35c20d7725SJed Brown   char           file[2][128];
36c20d7725SJed Brown   PetscScalar    *a,rval,alpha;
37c20d7725SJed Brown   PetscBool      Test_MatMatMult=PETSC_TRUE,Test_MatTrMat=PETSC_TRUE,Test_MatMatTr=PETSC_TRUE;
38c20d7725SJed Brown   PetscBool      Test_MatPtAP=PETSC_TRUE,Test_MatRARt=PETSC_TRUE,flg,seqaij;
39c20d7725SJed Brown   MatInfo        info;
40c20d7725SJed Brown   MatType        mattype;
41c20d7725SJed Brown 
42c20d7725SJed Brown   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
43c20d7725SJed Brown   ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
44c20d7725SJed Brown   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
45c20d7725SJed Brown 
46c20d7725SJed Brown   /*  Load the matrices A_save and B */
47c20d7725SJed Brown   ierr = PetscOptionsGetString(NULL,NULL,"-fA",file[0],sizeof(file[0]),&flg);CHKERRQ(ierr);
48c20d7725SJed Brown   if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate a file name for small matrix A with the -fA option.");
49c20d7725SJed Brown   ierr = PetscOptionsGetString(NULL,NULL,"-fB",file[1],sizeof(file[1]),&flg);CHKERRQ(ierr);
50c20d7725SJed Brown   if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate a file name for small matrix B with the -fB option.");
51c20d7725SJed Brown 
52c20d7725SJed Brown   ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[0],FILE_MODE_READ,&viewer);CHKERRQ(ierr);
53c20d7725SJed Brown   ierr = MatCreate(PETSC_COMM_WORLD,&A_save);CHKERRQ(ierr);
54c20d7725SJed Brown   ierr = MatSetFromOptions(A_save);CHKERRQ(ierr);
55c20d7725SJed Brown   ierr = MatLoad(A_save,viewer);CHKERRQ(ierr);
56c20d7725SJed Brown   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
57c20d7725SJed Brown 
58c20d7725SJed Brown   ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[1],FILE_MODE_READ,&viewer);CHKERRQ(ierr);
59c20d7725SJed Brown   ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr);
60c20d7725SJed Brown   ierr = MatSetFromOptions(B);CHKERRQ(ierr);
61c20d7725SJed Brown   ierr = MatLoad(B,viewer);CHKERRQ(ierr);
62c20d7725SJed Brown   ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
63c20d7725SJed Brown 
64c20d7725SJed Brown   ierr = MatGetType(B,&mattype);CHKERRQ(ierr);
65c20d7725SJed Brown 
66c20d7725SJed Brown   ierr = MatGetSize(B,&M,&N);CHKERRQ(ierr);
67c20d7725SJed Brown   nzp  = PetscMax((PetscInt)(0.1*M),5);
68c20d7725SJed Brown   ierr = PetscMalloc((nzp+1)*(sizeof(PetscInt)+sizeof(PetscScalar)),&idxn);CHKERRQ(ierr);
69c20d7725SJed Brown   a    = (PetscScalar*)(idxn + nzp);
70c20d7725SJed Brown 
71c20d7725SJed Brown   ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rdm);CHKERRQ(ierr);
72c20d7725SJed Brown   ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr);
73c20d7725SJed Brown 
74c20d7725SJed Brown   /* 1) MatMatMult() */
75c20d7725SJed Brown   /* ----------------*/
76c20d7725SJed Brown   if (Test_MatMatMult) {
77c20d7725SJed Brown     ierr = MatDuplicate(A_save,MAT_COPY_VALUES,&A);CHKERRQ(ierr);
78c20d7725SJed Brown 
79c20d7725SJed Brown     /* (1.1) Test developer API */
80c20d7725SJed Brown     ierr = MatProductCreate(A,B,NULL,&C);CHKERRQ(ierr);
8167b3012eSStefano Zampini     ierr = MatSetOptionsPrefix(C,"AB_");CHKERRQ(ierr);
82c20d7725SJed Brown     ierr = MatProductSetType(C,MATPRODUCT_AB);CHKERRQ(ierr);
83*910fa13fSStefano Zampini     ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
84c20d7725SJed Brown     ierr = MatProductSetFill(C,PETSC_DEFAULT);CHKERRQ(ierr);
85c20d7725SJed Brown     ierr = MatProductSetFromOptions(C);CHKERRQ(ierr);
86*910fa13fSStefano Zampini     /* we can inquire about MATOP_PRODUCTSYMBOLIC even if the destination matrix type has not been set yet */
87*910fa13fSStefano Zampini     ierr = MatHasOperation(C,MATOP_PRODUCTSYMBOLIC,&flg);CHKERRQ(ierr);
88c20d7725SJed Brown     ierr = MatProductSymbolic(C);CHKERRQ(ierr);
89c20d7725SJed Brown     ierr = MatProductNumeric(C);CHKERRQ(ierr);
90c20d7725SJed Brown 
91c20d7725SJed Brown     /* Test reuse symbolic C */
92c20d7725SJed Brown     alpha = 0.9;
93c20d7725SJed Brown     ierr = MatScale(A,alpha);CHKERRQ(ierr);
94c20d7725SJed Brown     ierr = MatProductNumeric(C);CHKERRQ(ierr);
95c20d7725SJed Brown 
96c20d7725SJed Brown     ierr = MatMatMultEqual(A,B,C,10,&flg);CHKERRQ(ierr);
97c20d7725SJed Brown     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in C=A*B");
98c20d7725SJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
99c20d7725SJed Brown 
100c20d7725SJed Brown     /* (1.2) Test user driver */
101c20d7725SJed Brown     ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
102c20d7725SJed Brown 
103c20d7725SJed Brown     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
104c20d7725SJed Brown     alpha = 1.0;
105c20d7725SJed Brown     for (i=0; i<2; i++) {
106c20d7725SJed Brown       alpha -= 0.1;
107c20d7725SJed Brown       ierr   = MatScale(A,alpha);CHKERRQ(ierr);
108c20d7725SJed Brown       ierr   = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
109c20d7725SJed Brown     }
110c20d7725SJed Brown     ierr = MatMatMultEqual(A,B,C,10,&flg);CHKERRQ(ierr);
111c20d7725SJed Brown     if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error: MatMatMult()");
112c20d7725SJed Brown     ierr = MatDestroy(&A);CHKERRQ(ierr);
1134417c5e8SHong Zhang 
1144417c5e8SHong Zhang     /* Test MatProductClear() */
1154417c5e8SHong Zhang     ierr = MatProductClear(C);CHKERRQ(ierr);
116c20d7725SJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
117544a5e07SHong Zhang 
118544a5e07SHong Zhang     /* Test MatMatMult() for dense and aij matrices */
119544a5e07SHong Zhang     ierr = MatConvert(A_save,MATDENSE,MAT_INITIAL_MATRIX,&A);CHKERRQ(ierr);
120544a5e07SHong Zhang     ierr = MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
121544a5e07SHong Zhang     ierr = MatDestroy(&C);CHKERRQ(ierr);
122544a5e07SHong Zhang     ierr = MatDestroy(&A);CHKERRQ(ierr);
123544a5e07SHong Zhang 
124c20d7725SJed Brown   }
125c20d7725SJed Brown 
126c20d7725SJed Brown   /* Create P and R = P^T  */
127c20d7725SJed Brown   /* --------------------- */
128c20d7725SJed Brown   PN   = M/2;
129c20d7725SJed Brown   nzp  = 5; /* num of nonzeros in each row of P */
130c20d7725SJed Brown   ierr = MatCreate(PETSC_COMM_WORLD,&P);CHKERRQ(ierr);
131c20d7725SJed Brown   ierr = MatSetSizes(P,PETSC_DECIDE,PETSC_DECIDE,M,PN);CHKERRQ(ierr);
132c20d7725SJed Brown   ierr = MatSetType(P,mattype);CHKERRQ(ierr);
133c20d7725SJed Brown   ierr = MatSeqAIJSetPreallocation(P,nzp,NULL);CHKERRQ(ierr);
134c20d7725SJed Brown   ierr = MatMPIAIJSetPreallocation(P,nzp,NULL,nzp,NULL);CHKERRQ(ierr);
135c20d7725SJed Brown   ierr = MatGetOwnershipRange(P,&rstart,&rend);CHKERRQ(ierr);
136c20d7725SJed Brown   for (i=0; i<nzp; i++) {
137c20d7725SJed Brown     ierr = PetscRandomGetValue(rdm,&a[i]);CHKERRQ(ierr);
138c20d7725SJed Brown   }
139c20d7725SJed Brown   for (i=rstart; i<rend; i++) {
140c20d7725SJed Brown     for (j=0; j<nzp; j++) {
141c20d7725SJed Brown       ierr    = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr);
142c20d7725SJed Brown       idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
143c20d7725SJed Brown     }
144c20d7725SJed Brown     ierr = MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);CHKERRQ(ierr);
145c20d7725SJed Brown   }
146c20d7725SJed Brown   ierr = MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
147c20d7725SJed Brown   ierr = MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
148c20d7725SJed Brown 
149c20d7725SJed Brown   ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&R);CHKERRQ(ierr);
150c20d7725SJed Brown 
151c20d7725SJed Brown   /* 2) MatTransposeMatMult() */
152c20d7725SJed Brown   /* ------------------------ */
153c20d7725SJed Brown   if (Test_MatTrMat) {
154c20d7725SJed Brown     /* (2.1) Test developer driver C = P^T*B */
155c20d7725SJed Brown     ierr = MatProductCreate(P,B,NULL,&C);CHKERRQ(ierr);
15667b3012eSStefano Zampini     ierr = MatSetOptionsPrefix(C,"AtB_");CHKERRQ(ierr);
157c20d7725SJed Brown     ierr = MatProductSetType(C,MATPRODUCT_AtB);CHKERRQ(ierr);
158*910fa13fSStefano Zampini     ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
159c20d7725SJed Brown     ierr = MatProductSetFill(C,PETSC_DEFAULT);CHKERRQ(ierr);
160c20d7725SJed Brown     ierr = MatProductSetFromOptions(C);CHKERRQ(ierr);
1610e1ed72eSHong Zhang     ierr = MatProductSymbolic(C);CHKERRQ(ierr); /* equivalent to MatSetUp() */
1620ad02fcaSStefano Zampini     ierr = MatSetOption(C,MAT_USE_INODES,PETSC_FALSE);CHKERRQ(ierr); /* illustrate how to call MatSetOption() */
163c20d7725SJed Brown     ierr = MatProductNumeric(C);CHKERRQ(ierr);
16467b3012eSStefano Zampini     ierr = MatProductNumeric(C);CHKERRQ(ierr); /* test reuse symbolic C */
16567b3012eSStefano Zampini 
166c20d7725SJed Brown     ierr = MatTransposeMatMultEqual(P,B,C,10,&flg);CHKERRQ(ierr);
167c20d7725SJed Brown     if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error: developer driver C = P^T*B");
168c20d7725SJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
169c20d7725SJed Brown 
170c20d7725SJed Brown     /* (2.2) Test user driver C = P^T*B */
171c20d7725SJed Brown     ierr = MatTransposeMatMult(P,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
172c20d7725SJed Brown     ierr = MatTransposeMatMult(P,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
173c20d7725SJed Brown     ierr = MatGetInfo(C,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
174c20d7725SJed Brown     ierr = MatFreeIntermediateDataStructures(C);CHKERRQ(ierr);
175c20d7725SJed Brown 
176c20d7725SJed Brown     /* Compare P^T*B and R*B */
177c20d7725SJed Brown     ierr = MatMatMult(R,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C1);CHKERRQ(ierr);
178c20d7725SJed Brown     ierr = MatNormDifference(C,C1,&norm);CHKERRQ(ierr);
179c20d7725SJed Brown     if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatTransposeMatMult(): %g",(double)norm);
180c20d7725SJed Brown     ierr = MatDestroy(&C1);CHKERRQ(ierr);
181c20d7725SJed Brown 
182c20d7725SJed Brown     /* Test MatDuplicate() of C=P^T*B */
183c20d7725SJed Brown     ierr = MatDuplicate(C,MAT_COPY_VALUES,&C1);CHKERRQ(ierr);
184c20d7725SJed Brown     ierr = MatDestroy(&C1);CHKERRQ(ierr);
185c20d7725SJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
186c20d7725SJed Brown   }
187c20d7725SJed Brown 
18867b3012eSStefano Zampini   /* 3) MatMatTransposeMult() */
189c20d7725SJed Brown   /* ------------------------ */
190c20d7725SJed Brown   if (Test_MatMatTr) {
191c20d7725SJed Brown     /* C = B*R^T */
192c20d7725SJed Brown     ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
193c20d7725SJed Brown     if (size == 1 && seqaij) {
194c20d7725SJed Brown       ierr = MatMatTransposeMult(B,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
19567b3012eSStefano Zampini       ierr = MatSetOptionsPrefix(C,"ABt_");CHKERRQ(ierr); /* enable '-ABt_' for matrix C */
196c20d7725SJed Brown       ierr = MatGetInfo(C,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr);
197c20d7725SJed Brown 
198c20d7725SJed Brown       /* Test MAT_REUSE_MATRIX - reuse symbolic C */
199c20d7725SJed Brown       ierr = MatMatTransposeMult(B,R,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
200c20d7725SJed Brown 
201c20d7725SJed Brown       /* Check */
202c20d7725SJed Brown       ierr = MatMatMult(B,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C1);CHKERRQ(ierr);
203c20d7725SJed Brown       ierr = MatNormDifference(C,C1,&norm);CHKERRQ(ierr);
204c20d7725SJed Brown       if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatTransposeMult() %g",(double)norm);
205c20d7725SJed Brown       ierr = MatDestroy(&C1);CHKERRQ(ierr);
206c20d7725SJed Brown       ierr = MatDestroy(&C);CHKERRQ(ierr);
207c20d7725SJed Brown     }
208c20d7725SJed Brown   }
209c20d7725SJed Brown 
210c20d7725SJed Brown   /* 4) Test MatPtAP() */
211c20d7725SJed Brown   /*-------------------*/
212c20d7725SJed Brown   if (Test_MatPtAP) {
213c20d7725SJed Brown     ierr = MatDuplicate(A_save,MAT_COPY_VALUES,&A);CHKERRQ(ierr);
214c20d7725SJed Brown 
215c20d7725SJed Brown     /* (4.1) Test developer API */
216c20d7725SJed Brown     ierr = MatProductCreate(A,P,NULL,&C);CHKERRQ(ierr);
21767b3012eSStefano Zampini     ierr = MatSetOptionsPrefix(C,"PtAP_");CHKERRQ(ierr);
218c20d7725SJed Brown     ierr = MatProductSetType(C,MATPRODUCT_PtAP);CHKERRQ(ierr);
219*910fa13fSStefano Zampini     ierr = MatProductSetAlgorithm(C,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
220c20d7725SJed Brown     ierr = MatProductSetFill(C,PETSC_DEFAULT);CHKERRQ(ierr);
221c20d7725SJed Brown     ierr = MatProductSetFromOptions(C);CHKERRQ(ierr);
222c20d7725SJed Brown     ierr = MatProductSymbolic(C);CHKERRQ(ierr);
223c20d7725SJed Brown     ierr = MatProductNumeric(C);CHKERRQ(ierr);
224c20d7725SJed Brown     ierr = MatProductNumeric(C);CHKERRQ(ierr); /* reuse symbolic C */
225c20d7725SJed Brown 
226c20d7725SJed Brown     ierr = MatPtAPMultEqual(A,P,C,10,&flg);CHKERRQ(ierr);
227c20d7725SJed Brown     if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatProduct_PtAP");
228c20d7725SJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
229c20d7725SJed Brown 
230c20d7725SJed Brown     /* (4.2) Test user driver */
231c20d7725SJed Brown     ierr = MatPtAP(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
232c20d7725SJed Brown 
233c20d7725SJed Brown     /* Test MAT_REUSE_MATRIX - reuse symbolic C */
234c20d7725SJed Brown     alpha=1.0;
235c20d7725SJed Brown     for (i=0; i<2; i++) {
236c20d7725SJed Brown       alpha -= 0.1;
237c20d7725SJed Brown       ierr   = MatScale(A,alpha);CHKERRQ(ierr);
238c20d7725SJed Brown       ierr   = MatPtAP(A,P,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
239c20d7725SJed Brown     }
240c20d7725SJed Brown 
241c20d7725SJed Brown     ierr = MatPtAPMultEqual(A,P,C,10,&flg);CHKERRQ(ierr);
242c20d7725SJed Brown     if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP");
243c20d7725SJed Brown 
244c20d7725SJed Brown     /* 5) Test MatRARt() */
245c20d7725SJed Brown     /* ----------------- */
246c20d7725SJed Brown     if (Test_MatRARt) {
247c20d7725SJed Brown       Mat RARt;
248c20d7725SJed Brown       ierr = MatTranspose(P,MAT_REUSE_MATRIX,&R);CHKERRQ(ierr);
24967b3012eSStefano Zampini 
25067b3012eSStefano Zampini       /* (5.1) Test developer driver RARt = R*A*Rt */
25167b3012eSStefano Zampini       ierr = MatProductCreate(A,R,NULL,&RARt);CHKERRQ(ierr);
25267b3012eSStefano Zampini       ierr = MatSetOptionsPrefix(RARt,"RARt_");CHKERRQ(ierr);
25367b3012eSStefano Zampini       ierr = MatProductSetType(RARt,MATPRODUCT_RARt);CHKERRQ(ierr);
254*910fa13fSStefano Zampini       ierr = MatProductSetAlgorithm(RARt,MATPRODUCTALGORITHM_DEFAULT);CHKERRQ(ierr);
25567b3012eSStefano Zampini       ierr = MatProductSetFill(RARt,PETSC_DEFAULT);CHKERRQ(ierr);
25667b3012eSStefano Zampini       ierr = MatProductSetFromOptions(RARt);CHKERRQ(ierr);
25767b3012eSStefano Zampini       ierr = MatProductSymbolic(RARt);CHKERRQ(ierr); /* equivalent to MatSetUp() */
25867b3012eSStefano Zampini       ierr = MatSetOption(RARt,MAT_USE_INODES,PETSC_FALSE);CHKERRQ(ierr); /* illustrate how to call MatSetOption() */
25967b3012eSStefano Zampini       ierr = MatProductNumeric(RARt);CHKERRQ(ierr);
26067b3012eSStefano Zampini       ierr = MatProductNumeric(RARt);CHKERRQ(ierr); /* test reuse symbolic RARt */
26167b3012eSStefano Zampini       ierr = MatDestroy(&RARt);CHKERRQ(ierr);
26267b3012eSStefano Zampini 
26367b3012eSStefano Zampini       /* (2.2) Test user driver RARt = R*A*Rt */
264c20d7725SJed Brown       ierr = MatRARt(A,R,MAT_INITIAL_MATRIX,2.0,&RARt);CHKERRQ(ierr);
265c20d7725SJed Brown       ierr = MatRARt(A,R,MAT_REUSE_MATRIX,2.0,&RARt);CHKERRQ(ierr);
26667b3012eSStefano Zampini 
267c20d7725SJed Brown       ierr = MatNormDifference(C,RARt,&norm);CHKERRQ(ierr);
268c20d7725SJed Brown       if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"|PtAP - RARt| = %g",(double)norm);
269c20d7725SJed Brown       ierr = MatDestroy(&RARt);CHKERRQ(ierr);
270c20d7725SJed Brown     }
271c20d7725SJed Brown 
272c20d7725SJed Brown     ierr = MatDestroy(&A);CHKERRQ(ierr);
273c20d7725SJed Brown     ierr = MatDestroy(&C);CHKERRQ(ierr);
274c20d7725SJed Brown   }
275c20d7725SJed Brown 
276c20d7725SJed Brown   /* Destroy objects */
277c20d7725SJed Brown   ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr);
278c20d7725SJed Brown   ierr = PetscFree(idxn);CHKERRQ(ierr);
279c20d7725SJed Brown 
280c20d7725SJed Brown   ierr = MatDestroy(&A_save);CHKERRQ(ierr);
281c20d7725SJed Brown   ierr = MatDestroy(&B);CHKERRQ(ierr);
282c20d7725SJed Brown   ierr = MatDestroy(&P);CHKERRQ(ierr);
283c20d7725SJed Brown   ierr = MatDestroy(&R);CHKERRQ(ierr);
284c20d7725SJed Brown 
285c20d7725SJed Brown   PetscFinalize();
286c20d7725SJed Brown   return ierr;
287c20d7725SJed Brown }
288c20d7725SJed Brown 
289c20d7725SJed Brown /*TEST
290c20d7725SJed Brown    test:
291c20d7725SJed Brown      suffix: 1
292c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
293c20d7725SJed Brown      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
294c20d7725SJed Brown      output_file: output/ex62_1.out
295c20d7725SJed Brown 
296c20d7725SJed Brown    test:
297c20d7725SJed Brown      suffix: 2_ab_scalable
298c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
29967b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via scalable -matmatmult_via scalable -AtB_matproduct_atb_via outerproduct -mattransposematmult_via outerproduct
300c20d7725SJed Brown      output_file: output/ex62_1.out
301c20d7725SJed Brown 
302c20d7725SJed Brown    test:
303c20d7725SJed Brown      suffix: 3_ab_scalable_fast
304c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
30567b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via scalable_fast -matmatmult_via scalable_fast -matmattransmult_via color
306c20d7725SJed Brown      output_file: output/ex62_1.out
307c20d7725SJed Brown 
308c20d7725SJed Brown    test:
309c20d7725SJed Brown      suffix: 4_ab_heap
310c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
31167b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via heap -matmatmult_via heap -PtAP_matproduct_ptap_via rap -matptap_via rap
312c20d7725SJed Brown      output_file: output/ex62_1.out
313c20d7725SJed Brown 
314c20d7725SJed Brown    test:
315c20d7725SJed Brown      suffix: 5_ab_btheap
316c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
31767b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via btheap -matmatmult_via btheap -matrart_via r*art
318c20d7725SJed Brown      output_file: output/ex62_1.out
319c20d7725SJed Brown 
320c20d7725SJed Brown    test:
321c20d7725SJed Brown      suffix: 6_ab_llcondensed
322c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
32367b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via llcondensed -matmatmult_via llcondensed -matrart_via coloring_rart
324c20d7725SJed Brown      output_file: output/ex62_1.out
325c20d7725SJed Brown 
326c20d7725SJed Brown    test:
327c20d7725SJed Brown      suffix: 7_ab_rowmerge
328c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
32967b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via rowmerge -matmatmult_via rowmerge
330c20d7725SJed Brown      output_file: output/ex62_1.out
331c20d7725SJed Brown 
332c20d7725SJed Brown    test:
333c20d7725SJed Brown      suffix: 8_ab_hypre
334c20d7725SJed Brown      requires: hypre datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
33567b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via hypre -matmatmult_via hypre -PtAP_matproduct_ptap_via hypre -matptap_via hypre
336c20d7725SJed Brown      output_file: output/ex62_1.out
337c20d7725SJed Brown 
338c20d7725SJed Brown    test:
339c20d7725SJed Brown      suffix: 10
340c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
341c20d7725SJed Brown      nsize: 3
342c20d7725SJed Brown      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
343c20d7725SJed Brown      output_file: output/ex62_1.out
344c20d7725SJed Brown 
345c20d7725SJed Brown    test:
346c20d7725SJed Brown      suffix: 11_ab_scalable
347c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
348c20d7725SJed Brown      nsize: 3
34967b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via scalable -matmatmult_via scalable -AtB_matproduct_atb_via scalable -mattransposematmult_via scalable
350c20d7725SJed Brown      output_file: output/ex62_1.out
351c20d7725SJed Brown 
352c20d7725SJed Brown    test:
353c20d7725SJed Brown      suffix: 12_ab_seqmpi
354c20d7725SJed Brown      requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
355c20d7725SJed Brown      nsize: 3
35667b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via seqmpi -matmatmult_via seqmpi -AtB_matproduct_atb_via at*b -mattransposematmult_via at*b
357c20d7725SJed Brown      output_file: output/ex62_1.out
358c20d7725SJed Brown 
359c20d7725SJed Brown    test:
360c20d7725SJed Brown      suffix: 13_ab_hypre
361c20d7725SJed Brown      requires: hypre datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
362c20d7725SJed Brown      nsize: 3
36367b3012eSStefano Zampini      args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -AB_matproduct_ab_via hypre -matmatmult_via hypre -PtAP_matproduct_ptap_via hypre -matptap_via hypre
364c20d7725SJed Brown      output_file: output/ex62_1.out
365c20d7725SJed Brown 
366c20d7725SJed Brown TEST*/
367