Actual source code: ex94.c
2: static char help[] = "Tests sequential and parallel MatMatMult() and MatPtAP(), sequential MatMatMultTranspose()\n\
3: Input arguments are:\n\
4: -f0 <input_file> -f1 <input_file> -f2 <input_file> -f3 <input_file> : file to load\n\n";
5: /* e.g., ex94 -f0 $D/small -f1 $D/small -f2 $D/arco1 -f3 $D/arco1 */
7: #include petscmat.h
11: int main(int argc,char **args)
12: {
13: Mat A,A_save,B,P,C;
14: Vec x,v1,v2;
15: PetscViewer viewer;
17: PetscMPIInt size,rank;
18: PetscInt i,m,n,j,idxn[10],M,N,nzp;
19: PetscReal norm,norm_tmp,tol=1.e-10,fill=4.0;
20: PetscRandom rdm;
21: char file[4][128];
22: PetscTruth flg,preload = PETSC_TRUE;
23: PetscScalar a[10],rval,alpha,none = -1.0;
24: PetscTruth Test_MatMatMult=PETSC_TRUE,Test_MatMatMultTr=PETSC_TRUE,Test_MatPtAP=PETSC_TRUE;
25: Vec v3,v4,v5;
27: PetscInitialize(&argc,&args,(char *)0,help);
28: MPI_Comm_size(PETSC_COMM_WORLD,&size);
29: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
31: /* Load the matrices A and B */
32: PetscOptionsGetString(PETSC_NULL,"-f0",file[0],127,&flg);
33: if (!flg) SETERRQ(1,"Must indicate a file name for small matrix A with the -f0 option.");
34: PetscOptionsGetString(PETSC_NULL,"-f1",file[1],127,&flg);
35: if (!flg) SETERRQ(1,"Must indicate a file name for small matrix B with the -f1 option.");
36: PetscOptionsGetString(PETSC_NULL,"-f2",file[2],127,&flg);
37: if (!flg) {
38: preload = PETSC_FALSE;
39: } else {
40: PetscOptionsGetString(PETSC_NULL,"-f3",file[3],127,&flg);
41: if (!flg) SETERRQ(1,"Must indicate a file name for test matrix B with the -f3 option.");
42: }
44: PreLoadBegin(preload,"Load system");
45: PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[2*PreLoadIt],PETSC_FILE_RDONLY,&viewer);
46: MatLoad(viewer,MATAIJ,&A_save);
47: PetscViewerDestroy(viewer);
49: PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[2*PreLoadIt+1],PETSC_FILE_RDONLY,&viewer);
50: MatLoad(viewer,MATAIJ,&B);
51: PetscViewerDestroy(viewer);
52:
53: /* Create vectors v1 and v2 that are compatible with A_save */
54: VecCreate(PETSC_COMM_WORLD,&v1);
55: MatGetLocalSize(A_save,&m,PETSC_NULL);
56: VecSetSizes(v1,m,PETSC_DECIDE);
57: VecSetFromOptions(v1);
58: VecDuplicate(v1,&v2);
60: PetscRandomCreate(PETSC_COMM_WORLD,RANDOM_DEFAULT,&rdm);
61: PetscOptionsGetReal(PETSC_NULL,"-fill",&fill,PETSC_NULL);
63: /* Test MatMatMult() */
64: /*-------------------*/
65: if (Test_MatMatMult){
66: MatDuplicate(A_save,MAT_COPY_VALUES,&A);
67: MatMatMult(A,B,MAT_INITIAL_MATRIX,fill,&C);
68:
69: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
70: alpha=1.0;
71: for (i=0; i<2; i++){
72: alpha -=0.1;
73: MatScale(&alpha,A);
74: MatMatMult(A,B,MAT_REUSE_MATRIX,fill,&C);
75: }
76:
77: /* Create vector x that is compatible with B */
78: VecCreate(PETSC_COMM_WORLD,&x);
79: MatGetLocalSize(B,PETSC_NULL,&n);
80: VecSetSizes(x,n,PETSC_DECIDE);
81: VecSetFromOptions(x);
83: norm = 0.0;
84: for (i=0; i<10; i++) {
85: VecSetRandom(rdm,x);
86: MatMult(B,x,v1);
87: MatMult(A,v1,v2); /* v2 = A*B*x */
88: MatMult(C,x,v1); /* v1 = C*x */
89: VecAXPY(&none,v2,v1);
90: VecNorm(v1,NORM_2,&norm_tmp);
91: if (norm_tmp > norm) norm = norm_tmp;
92: }
93: if (norm >= tol) {
94: PetscPrintf(PETSC_COMM_SELF,"Error: MatMatMult(), |v1 - v2|: %g\n",norm);
95: }
96: MatDestroy(A);
97: MatDestroy(C);
98: VecDestroy(x);
99: } /* if (Test_MatMatMult) */
101: /* Test MatMatMultTranspose() */
102: /*----------------------------*/
103: if (size>1) Test_MatMatMultTr = PETSC_FALSE;
104: if (Test_MatMatMultTr){
105: PetscInt PN;
106: MatGetSize(B,&M,&N);
107: PN = M/2;
108: nzp = 5;
109: MatCreate(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,M,PN,&P);
110: MatSetType(P,MATAIJ);
111: MatSeqAIJSetPreallocation(P,nzp,PETSC_NULL);
112: MatMPIAIJSetPreallocation(P,nzp,PETSC_NULL,nzp,PETSC_NULL);
113: for (i=0; i<nzp; i++){
114: PetscRandomGetValue(rdm,&a[i]);
115: }
116: for (i=0; i<M; i++){
117: for (j=0; j<nzp; j++){
118: PetscRandomGetValue(rdm,&rval);
119: idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
120: }
121: MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);
122: }
123: MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
124: MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);
125:
126: MatMatMultTranspose(P,B,MAT_INITIAL_MATRIX,fill,&C);
128: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
129: alpha=1.0;
130: for (i=0; i<2; i++){
131: alpha -=0.1;
132: MatScale(&alpha,P);
133: MatMatMultTranspose(P,B,MAT_REUSE_MATRIX,fill,&C);
134: }
136: /* Create vector x, v5 that are compatible with B */
137: VecCreate(PETSC_COMM_WORLD,&x);
138: MatGetLocalSize(B,&m,&n);
139: VecSetSizes(x,n,PETSC_DECIDE);
140: VecSetFromOptions(x);
142: VecCreate(PETSC_COMM_WORLD,&v5);
143: VecSetSizes(v5,m,PETSC_DECIDE);
144: VecSetFromOptions(v5);
145:
146: MatGetLocalSize(P,PETSC_NULL,&n);
147: VecCreate(PETSC_COMM_WORLD,&v3);
148: VecSetSizes(v3,n,PETSC_DECIDE);
149: VecSetFromOptions(v3);
150: VecDuplicate(v3,&v4);
152: norm = 0.0;
153: for (i=0; i<10; i++) {
154: VecSetRandom(rdm,x);
155: MatMult(B,x,v5); /* v5 = B*x */
156: MatMultTranspose(P,v5,v3); /* v3 = Pt*B*x */
157: MatMult(C,x,v4); /* v4 = C*x */
158: VecAXPY(&none,v3,v4);
159: VecNorm(v4,NORM_2,&norm_tmp);
160: if (norm_tmp > norm) norm = norm_tmp;
161: }
162: if (norm >= tol) {
163: PetscPrintf(PETSC_COMM_SELF,"Error: MatMatMultTr(), |v3 - v4|: %g\n",norm);
164: }
165: MatDestroy(P);
166: MatDestroy(C);
167: VecDestroy(v3);
168: VecDestroy(v4);
169: VecDestroy(v5);
170: VecDestroy(x);
171: }
173: /* Test MatPtAP() */
174: /*----------------------*/
175: if (Test_MatPtAP){
176: PetscInt PN;
177: MatDuplicate(A_save,MAT_COPY_VALUES,&A);
178: MatGetSize(A,&M,&N);
179: PN = M/2;
180: nzp = 5;
181: MatCreate(PETSC_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,N,PN,&P);
182: MatSetType(P,MATAIJ);
183: MatSeqAIJSetPreallocation(P,nzp,PETSC_NULL);
184: MatMPIAIJSetPreallocation(P,nzp,PETSC_NULL,nzp,PETSC_NULL);
185: for (i=0; i<nzp; i++){
186: PetscRandomGetValue(rdm,&a[i]);
187: }
188: for (i=0; i<M; i++){
189: for (j=0; j<nzp; j++){
190: PetscRandomGetValue(rdm,&rval);
191: idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
192: }
193: MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);
194: }
195: MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
196: MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);
197:
198: MatPtAP(A,P,MAT_INITIAL_MATRIX,fill,&C);
200: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
201: alpha=1.0;
202: for (i=0; i<2; i++){
203: alpha -=0.1;
204: MatScale(&alpha,A);
205: MatPtAP(A,P,MAT_REUSE_MATRIX,fill,&C);
206: }
208: /* Create vector x that is compatible with P */
209: VecCreate(PETSC_COMM_WORLD,&x);
210: MatGetLocalSize(P,&m,&n);
211: VecSetSizes(x,n,PETSC_DECIDE);
212: VecSetFromOptions(x);
213:
214: VecCreate(PETSC_COMM_WORLD,&v3);
215: VecSetSizes(v3,n,PETSC_DECIDE);
216: VecSetFromOptions(v3);
217: VecDuplicate(v3,&v4);
219: norm = 0.0;
220: for (i=0; i<10; i++) {
221: VecSetRandom(rdm,x);
222: MatMult(P,x,v1);
223: MatMult(A,v1,v2); /* v2 = A*P*x */
225: MatMultTranspose(P,v2,v3); /* v3 = Pt*A*P*x */
226: MatMult(C,x,v4); /* v3 = C*x */
227: VecAXPY(&none,v3,v4);
228: VecNorm(v4,NORM_2,&norm_tmp);
229: if (norm_tmp > norm) norm = norm_tmp;
230: }
231: if (norm >= tol) {
232: PetscPrintf(PETSC_COMM_SELF,"Error: MatPtAP(), |v1 - v2|: %g\n",norm);
233: }
234:
235: MatDestroy(A);
236: MatDestroy(P);
237: MatDestroy(C);
238: VecDestroy(v3);
239: VecDestroy(v4);
240: VecDestroy(x);
241: } /* if (Test_MatPtAP) */
243: /* Destroy objects */
244: VecDestroy(v1);
245: VecDestroy(v2);
246: PetscRandomDestroy(rdm);
247:
248: MatDestroy(A_save);
249: MatDestroy(B);
251: PreLoadEnd();
252: PetscFinalize();
254: return 0;
255: }