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(A,alpha);
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(x,rdm);
86: MatMult(B,x,v1);
87: MatMult(A,v1,v2); /* v2 = A*B*x */
88: MatMult(C,x,v1); /* v1 = C*x */
89: VecAXPY(v1,none,v2);
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,&P);
110: MatSetSizes(P,PETSC_DECIDE,PETSC_DECIDE,M,PN);
111: MatSetType(P,MATAIJ);
112: MatSeqAIJSetPreallocation(P,nzp,PETSC_NULL);
113: MatMPIAIJSetPreallocation(P,nzp,PETSC_NULL,nzp,PETSC_NULL);
114: for (i=0; i<nzp; i++){
115: PetscRandomGetValue(rdm,&a[i]);
116: }
117: for (i=0; i<M; i++){
118: for (j=0; j<nzp; j++){
119: PetscRandomGetValue(rdm,&rval);
120: idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
121: }
122: MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);
123: }
124: MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
125: MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);
126:
127: MatMatMultTranspose(P,B,MAT_INITIAL_MATRIX,fill,&C);
129: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
130: alpha=1.0;
131: for (i=0; i<2; i++){
132: alpha -=0.1;
133: MatScale(P,alpha);
134: MatMatMultTranspose(P,B,MAT_REUSE_MATRIX,fill,&C);
135: }
137: /* Create vector x, v5 that are compatible with B */
138: VecCreate(PETSC_COMM_WORLD,&x);
139: MatGetLocalSize(B,&m,&n);
140: VecSetSizes(x,n,PETSC_DECIDE);
141: VecSetFromOptions(x);
143: VecCreate(PETSC_COMM_WORLD,&v5);
144: VecSetSizes(v5,m,PETSC_DECIDE);
145: VecSetFromOptions(v5);
146:
147: MatGetLocalSize(P,PETSC_NULL,&n);
148: VecCreate(PETSC_COMM_WORLD,&v3);
149: VecSetSizes(v3,n,PETSC_DECIDE);
150: VecSetFromOptions(v3);
151: VecDuplicate(v3,&v4);
153: norm = 0.0;
154: for (i=0; i<10; i++) {
155: VecSetRandom(x,rdm);
156: MatMult(B,x,v5); /* v5 = B*x */
157: MatMultTranspose(P,v5,v3); /* v3 = Pt*B*x */
158: MatMult(C,x,v4); /* v4 = C*x */
159: VecAXPY(v4,none,v3);
160: VecNorm(v4,NORM_2,&norm_tmp);
161: if (norm_tmp > norm) norm = norm_tmp;
162: }
163: if (norm >= tol) {
164: PetscPrintf(PETSC_COMM_SELF,"Error: MatMatMultTr(), |v3 - v4|: %g\n",norm);
165: }
166: MatDestroy(P);
167: MatDestroy(C);
168: VecDestroy(v3);
169: VecDestroy(v4);
170: VecDestroy(v5);
171: VecDestroy(x);
172: }
174: /* Test MatPtAP() */
175: /*----------------------*/
176: if (Test_MatPtAP){
177: PetscInt PN;
178: MatDuplicate(A_save,MAT_COPY_VALUES,&A);
179: MatGetSize(A,&M,&N);
180: PN = M/2;
181: nzp = 5;
182: MatCreate(PETSC_COMM_WORLD,&P);
183: MatSetSizes(P,PETSC_DECIDE,PETSC_DECIDE,N,PN);
184: MatSetType(P,MATAIJ);
185: MatSeqAIJSetPreallocation(P,nzp,PETSC_NULL);
186: MatMPIAIJSetPreallocation(P,nzp,PETSC_NULL,nzp,PETSC_NULL);
187: for (i=0; i<nzp; i++){
188: PetscRandomGetValue(rdm,&a[i]);
189: }
190: for (i=0; i<M; i++){
191: for (j=0; j<nzp; j++){
192: PetscRandomGetValue(rdm,&rval);
193: idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
194: }
195: MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);
196: }
197: MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
198: MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);
199:
200: MatPtAP(A,P,MAT_INITIAL_MATRIX,fill,&C);
202: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
203: alpha=1.0;
204: for (i=0; i<2; i++){
205: alpha -=0.1;
206: MatScale(A,alpha);
207: MatPtAP(A,P,MAT_REUSE_MATRIX,fill,&C);
208: }
210: /* Create vector x that is compatible with P */
211: VecCreate(PETSC_COMM_WORLD,&x);
212: MatGetLocalSize(P,&m,&n);
213: VecSetSizes(x,n,PETSC_DECIDE);
214: VecSetFromOptions(x);
215:
216: VecCreate(PETSC_COMM_WORLD,&v3);
217: VecSetSizes(v3,n,PETSC_DECIDE);
218: VecSetFromOptions(v3);
219: VecDuplicate(v3,&v4);
221: norm = 0.0;
222: for (i=0; i<10; i++) {
223: VecSetRandom(x,rdm);
224: MatMult(P,x,v1);
225: MatMult(A,v1,v2); /* v2 = A*P*x */
227: MatMultTranspose(P,v2,v3); /* v3 = Pt*A*P*x */
228: MatMult(C,x,v4); /* v3 = C*x */
229: VecAXPY(v4,none,v3);
230: VecNorm(v4,NORM_2,&norm_tmp);
231: if (norm_tmp > norm) norm = norm_tmp;
232: }
233: if (norm >= tol) {
234: PetscPrintf(PETSC_COMM_SELF,"Error: MatPtAP(), |v1 - v2|: %g\n",norm);
235: }
236:
237: MatDestroy(A);
238: MatDestroy(P);
239: MatDestroy(C);
240: VecDestroy(v3);
241: VecDestroy(v4);
242: VecDestroy(x);
243: } /* if (Test_MatPtAP) */
245: /* Destroy objects */
246: VecDestroy(v1);
247: VecDestroy(v2);
248: PetscRandomDestroy(rdm);
249:
250: MatDestroy(A_save);
251: MatDestroy(B);
253: PreLoadEnd();
254: PetscFinalize();
256: return 0;
257: }