Actual source code: ex62.c
petsc-3.13.0 2020-03-29
2: static char help[] = "Test Matrix products for AIJ matrices\n\
3: Input arguments are:\n\
4: -fA <input_file> -fB <input_file> -fC <input_file>: file to load\n\n";
5: /* Example of usage:
6: ./ex62 -fA <A_binary> -fB <B_binary>
7: mpiexec -n 3 ./ex62 -fA medium -fB medium
8: */
10: #include <petscmat.h>
12: /*
13: B = A - B
14: norm = norm(B)
15: */
16: PetscErrorCode MatNormDifference(Mat A,Mat B,PetscReal *norm)
17: {
21: MatAXPY(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);
22: MatNorm(B,NORM_FROBENIUS,norm);
23: return(0);
24: }
26: int main(int argc,char **args)
27: {
28: Mat A,A_save,B,C,P,C1,R;
29: PetscViewer viewer;
31: PetscMPIInt size,rank;
32: PetscInt i,j,*idxn,M,N,nzp,PN,rstart,rend;
33: PetscReal norm;
34: PetscRandom rdm;
35: char file[2][128];
36: PetscScalar *a,rval,alpha;
37: PetscBool Test_MatMatMult=PETSC_TRUE,Test_MatTrMat=PETSC_TRUE,Test_MatMatTr=PETSC_TRUE;
38: PetscBool Test_MatPtAP=PETSC_TRUE,Test_MatRARt=PETSC_TRUE,flg,seqaij;
39: MatInfo info;
40: MatType mattype;
42: PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
43: MPI_Comm_size(PETSC_COMM_WORLD,&size);
44: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
46: /* Load the matrices A_save and B */
47: PetscOptionsGetString(NULL,NULL,"-fA",file[0],sizeof(file[0]),&flg);
48: if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate a file name for small matrix A with the -fA option.");
49: PetscOptionsGetString(NULL,NULL,"-fB",file[1],sizeof(file[1]),&flg);
50: if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate a file name for small matrix B with the -fB option.");
52: PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[0],FILE_MODE_READ,&viewer);
53: MatCreate(PETSC_COMM_WORLD,&A_save);
54: MatSetFromOptions(A_save);
55: MatLoad(A_save,viewer);
56: PetscViewerDestroy(&viewer);
58: PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[1],FILE_MODE_READ,&viewer);
59: MatCreate(PETSC_COMM_WORLD,&B);
60: MatSetFromOptions(B);
61: MatLoad(B,viewer);
62: PetscViewerDestroy(&viewer);
64: MatGetType(B,&mattype);
66: MatGetSize(B,&M,&N);
67: nzp = PetscMax((PetscInt)(0.1*M),5);
68: PetscMalloc((nzp+1)*(sizeof(PetscInt)+sizeof(PetscScalar)),&idxn);
69: a = (PetscScalar*)(idxn + nzp);
71: PetscRandomCreate(PETSC_COMM_WORLD,&rdm);
72: PetscRandomSetFromOptions(rdm);
74: /* 1) MatMatMult() */
75: /* ----------------*/
76: if (Test_MatMatMult) {
77: MatDuplicate(A_save,MAT_COPY_VALUES,&A);
79: /* (1.1) Test developer API */
80: MatProductCreate(A,B,NULL,&C);
81: MatProductSetType(C,MATPRODUCT_AB);
82: MatProductSetAlgorithm(C,"default");
83: MatProductSetFill(C,PETSC_DEFAULT);
84: MatProductSetFromOptions(C);
85: MatProductSymbolic(C);
86: MatProductNumeric(C);
88: /* Test reuse symbolic C */
89: alpha = 0.9;
90: MatScale(A,alpha);
91: MatProductNumeric(C);
93: MatMatMultEqual(A,B,C,10,&flg);
94: if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in C=A*B");
95: MatDestroy(&C);
97: /* (1.2) Test user driver */
98: MatMatMult(A,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);
100: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
101: alpha = 1.0;
102: for (i=0; i<2; i++) {
103: alpha -= 0.1;
104: MatScale(A,alpha);
105: MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);
106: }
107: MatMatMultEqual(A,B,C,10,&flg);
108: if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error: MatMatMult()");
109: MatDestroy(&A);
110: MatDestroy(&C);
111: }
113: /* Create P and R = P^T */
114: /* --------------------- */
115: PN = M/2;
116: nzp = 5; /* num of nonzeros in each row of P */
117: MatCreate(PETSC_COMM_WORLD,&P);
118: MatSetSizes(P,PETSC_DECIDE,PETSC_DECIDE,M,PN);
119: MatSetType(P,mattype);
120: MatSeqAIJSetPreallocation(P,nzp,NULL);
121: MatMPIAIJSetPreallocation(P,nzp,NULL,nzp,NULL);
122: MatGetOwnershipRange(P,&rstart,&rend);
123: for (i=0; i<nzp; i++) {
124: PetscRandomGetValue(rdm,&a[i]);
125: }
126: for (i=rstart; i<rend; i++) {
127: for (j=0; j<nzp; j++) {
128: PetscRandomGetValue(rdm,&rval);
129: idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
130: }
131: MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);
132: }
133: MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
134: MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);
136: MatTranspose(P,MAT_INITIAL_MATRIX,&R);
138: /* 2) MatTransposeMatMult() */
139: /* ------------------------ */
140: if (Test_MatTrMat) {
141: /* (2.1) Test developer driver C = P^T*B */
142: MatProductCreate(P,B,NULL,&C);
143: MatProductSetType(C,MATPRODUCT_AtB);
144: MatProductSetAlgorithm(C,"default");
145: MatProductSetFill(C,PETSC_DEFAULT);
146: MatProductSetFromOptions(C);
147: MatProductSymbolic(C);
148: MatProductNumeric(C);
149: MatProductNumeric(C);
150: MatTransposeMatMultEqual(P,B,C,10,&flg);
151: if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error: developer driver C = P^T*B");
152: MatDestroy(&C);
154: /* (2.2) Test user driver C = P^T*B */
155: MatTransposeMatMult(P,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);
156: MatTransposeMatMult(P,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);
157: MatGetInfo(C,MAT_GLOBAL_SUM,&info);
158: MatFreeIntermediateDataStructures(C);
160: /* Compare P^T*B and R*B */
161: MatMatMult(R,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C1);
162: MatNormDifference(C,C1,&norm);
163: if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatTransposeMatMult(): %g",(double)norm);
164: MatDestroy(&C1);
166: /* Test MatDuplicate() of C=P^T*B */
167: MatDuplicate(C,MAT_COPY_VALUES,&C1);
168: MatDestroy(&C1);
169: MatDestroy(&C);
170: }
172: /* 3) MatTransposeMatMult() */
173: /* ------------------------ */
174: if (Test_MatMatTr) {
175: /* C = B*R^T */
176: PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);
177: if (size == 1 && seqaij) {
178: MatMatTransposeMult(B,R,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);
179: MatSetOptionsPrefix(C,"matmatmulttr_"); /* enable '-matmatmulttr_' for matrix C */
180: MatGetInfo(C,MAT_GLOBAL_SUM,&info);
182: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
183: MatMatTransposeMult(B,R,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);
185: /* Check */
186: MatMatMult(B,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C1);
187: MatNormDifference(C,C1,&norm);
188: if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatMatTransposeMult() %g",(double)norm);
189: MatDestroy(&C1);
190: MatDestroy(&C);
191: }
192: }
194: /* 4) Test MatPtAP() */
195: /*-------------------*/
196: if (Test_MatPtAP) {
197: MatDuplicate(A_save,MAT_COPY_VALUES,&A);
199: /* (4.1) Test developer API */
200: MatProductCreate(A,P,NULL,&C);
201: MatProductSetType(C,MATPRODUCT_PtAP);
202: MatProductSetAlgorithm(C,"default");
203: MatProductSetFill(C,PETSC_DEFAULT);
204: MatProductSetFromOptions(C);
205: MatProductSymbolic(C);
206: MatProductNumeric(C);
207: MatProductNumeric(C); /* reuse symbolic C */
209: MatPtAPMultEqual(A,P,C,10,&flg);
210: if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatProduct_PtAP");
211: MatDestroy(&C);
213: /* (4.2) Test user driver */
214: MatPtAP(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&C);
216: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
217: alpha=1.0;
218: for (i=0; i<2; i++) {
219: alpha -= 0.1;
220: MatScale(A,alpha);
221: MatPtAP(A,P,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);
222: }
224: MatPtAPMultEqual(A,P,C,10,&flg);
225: if (!flg) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_PLIB,"Error in MatPtAP");
227: /* 5) Test MatRARt() */
228: /* ----------------- */
229: if (Test_MatRARt) {
230: Mat RARt;
231: MatTranspose(P,MAT_REUSE_MATRIX,&R);
232: MatRARt(A,R,MAT_INITIAL_MATRIX,2.0,&RARt);
233: MatRARt(A,R,MAT_REUSE_MATRIX,2.0,&RARt);
234: MatNormDifference(C,RARt,&norm);
235: if (norm > PETSC_SMALL) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"|PtAP - RARt| = %g",(double)norm);
236: MatDestroy(&RARt);
237: }
239: MatDestroy(&A);
240: MatDestroy(&C);
241: }
243: /* Destroy objects */
244: PetscRandomDestroy(&rdm);
245: PetscFree(idxn);
247: MatDestroy(&A_save);
248: MatDestroy(&B);
249: MatDestroy(&P);
250: MatDestroy(&R);
252: PetscFinalize();
253: return ierr;
254: }
256: /*TEST
257: test:
258: suffix: 1
259: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
260: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
261: output_file: output/ex62_1.out
263: test:
264: suffix: 2_ab_scalable
265: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
266: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via scalable -matmatmult_via scalable -matproduct_atb_via outerproduct -mattransposematmult_via outerproduct
267: output_file: output/ex62_1.out
269: test:
270: suffix: 3_ab_scalable_fast
271: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
272: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via scalable_fast -matmatmult_via scalable_fast -matmattransmult_via color
273: output_file: output/ex62_1.out
275: test:
276: suffix: 4_ab_heap
277: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
278: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via heap -matmatmult_via heap -matproduct_ptap_via rap -matptap_via rap
279: output_file: output/ex62_1.out
281: test:
282: suffix: 5_ab_btheap
283: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
284: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via btheap -matmatmult_via btheap -matrart_via r*art
285: output_file: output/ex62_1.out
287: test:
288: suffix: 6_ab_llcondensed
289: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
290: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via llcondensed -matmatmult_via llcondensed -matrart_via coloring_rart
291: output_file: output/ex62_1.out
293: test:
294: suffix: 7_ab_rowmerge
295: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
296: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via rowmerge -matmatmult_via rowmerge
297: output_file: output/ex62_1.out
299: test:
300: suffix: 8_ab_hypre
301: requires: hypre datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
302: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via hypre -matmatmult_via hypre -matproduct_ptap_via hypre -matptap_via hypre
303: output_file: output/ex62_1.out
305: test:
306: suffix: 10
307: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
308: nsize: 3
309: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium
310: output_file: output/ex62_1.out
312: test:
313: suffix: 11_ab_scalable
314: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
315: nsize: 3
316: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via scalable -matmatmult_via scalable -matproduct_atb_via scalable -mattransposematmult_via scalable
317: output_file: output/ex62_1.out
319: test:
320: suffix: 12_ab_seqmpi
321: requires: datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
322: nsize: 3
323: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via seqmpi -matmatmult_via seqmpi -matproduct_atb_via at*b -mattransposematmult_via at*b
324: output_file: output/ex62_1.out
326: test:
327: suffix: 13_ab_hypre
328: requires: hypre datafilespath !complex double !define(PETSC_USE_64BIT_INDICES)
329: nsize: 3
330: args: -fA ${DATAFILESPATH}/matrices/medium -fB ${DATAFILESPATH}/matrices/medium -matproduct_ab_via hypre -matmatmult_via hypre -matproduct_ptap_via hypre -matptap_via hypre
331: output_file: output/ex62_1.out
333: TEST*/