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,M,N,nzp;
19: PetscReal norm,norm_tmp,tol=1.e-8,fill=4.0;
20: PetscRandom rdm;
21: char file[4][128];
22: PetscTruth flg,preload = PETSC_TRUE;
23: PetscScalar *a,rval,alpha,none = -1.0;
24: PetscTruth Test_MatMatMult=PETSC_TRUE,Test_MatMatMultTr=PETSC_TRUE;
25: Vec v3,v4,v5;
26: PetscInt pm,pn,pM,pN;
27: PetscTruth Test_MatPtAP=PETSC_TRUE;
29: PetscInitialize(&argc,&args,(char *)0,help);
30: MPI_Comm_size(PETSC_COMM_WORLD,&size);
31: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
33: /* Load the matrices A and B */
34: PetscOptionsGetString(PETSC_NULL,"-f0",file[0],127,&flg);
35: if (!flg) SETERRQ(1,"Must indicate a file name for small matrix A with the -f0 option.");
36: PetscOptionsGetString(PETSC_NULL,"-f1",file[1],127,&flg);
37: if (!flg) SETERRQ(1,"Must indicate a file name for small matrix B with the -f1 option.");
38: PetscOptionsGetString(PETSC_NULL,"-f2",file[2],127,&flg);
39: if (!flg) {
40: preload = PETSC_FALSE;
41: } else {
42: PetscOptionsGetString(PETSC_NULL,"-f3",file[3],127,&flg);
43: if (!flg) SETERRQ(1,"Must indicate a file name for test matrix B with the -f3 option.");
44: }
46: PreLoadBegin(preload,"Load system");
47: PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[2*PreLoadIt],FILE_MODE_READ,&viewer);
48: MatLoad(viewer,MATAIJ,&A_save);
49: PetscViewerDestroy(viewer);
51: PetscViewerBinaryOpen(PETSC_COMM_WORLD,file[2*PreLoadIt+1],FILE_MODE_READ,&viewer);
52: MatLoad(viewer,MATAIJ,&B);
53: PetscViewerDestroy(viewer);
55: MatGetSize(B,&M,&N);
56: nzp = (PetscInt)(0.1*M);
57: PetscMalloc((nzp+1)*(sizeof(PetscInt)+sizeof(PetscScalar)),&idxn);
58: a = (PetscScalar*)(idxn + nzp);
59:
60: /* Create vectors v1 and v2 that are compatible with A_save */
61: VecCreate(PETSC_COMM_WORLD,&v1);
62: MatGetLocalSize(A_save,&m,PETSC_NULL);
63: VecSetSizes(v1,m,PETSC_DECIDE);
64: VecSetFromOptions(v1);
65: VecDuplicate(v1,&v2);
67: PetscRandomCreate(PETSC_COMM_WORLD,&rdm);
68: PetscRandomSetFromOptions(rdm);
69: PetscOptionsGetReal(PETSC_NULL,"-fill",&fill,PETSC_NULL);
71: /* Test MatMatMult() */
72: /*-------------------*/
73: if (Test_MatMatMult){
74: MatDuplicate(A_save,MAT_COPY_VALUES,&A);
75: MatMatMult(A,B,MAT_INITIAL_MATRIX,fill,&C);
76:
77: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
78: alpha=1.0;
79: for (i=0; i<2; i++){
80: alpha -=0.1;
81: MatScale(A,alpha);
82: MatMatMult(A,B,MAT_REUSE_MATRIX,fill,&C);
83: }
84:
85: /* Create vector x that is compatible with B */
86: VecCreate(PETSC_COMM_WORLD,&x);
87: MatGetLocalSize(B,PETSC_NULL,&n);
88: VecSetSizes(x,n,PETSC_DECIDE);
89: VecSetFromOptions(x);
91: norm = 0.0;
92: for (i=0; i<10; i++) {
93: VecSetRandom(x,rdm);
94: MatMult(B,x,v1);
95: MatMult(A,v1,v2); /* v2 = A*B*x */
96: MatMult(C,x,v1); /* v1 = C*x */
97: VecAXPY(v1,none,v2);
98: VecNorm(v1,NORM_2,&norm_tmp);
99: if (norm_tmp > norm) norm = norm_tmp;
100: }
101: if (norm >= tol) {
102: PetscPrintf(PETSC_COMM_SELF,"Error: MatMatMult(), |v1 - v2|: %G\n",norm);
103: }
104: MatDestroy(A);
105: MatDestroy(C);
106: VecDestroy(x);
107: } /* if (Test_MatMatMult) */
109: /* Test MatMatMultTranspose() */
110: /*----------------------------*/
111: if (size>1) Test_MatMatMultTr = PETSC_FALSE;
112: if (Test_MatMatMultTr){
113: PetscInt PN;
114: /* MatGetSize(B,&M,&N); */
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,MATAIJ);
120: MatSeqAIJSetPreallocation(P,nzp,PETSC_NULL);
121: MatMPIAIJSetPreallocation(P,nzp,PETSC_NULL,nzp,PETSC_NULL);
122: for (i=0; i<nzp; i++){
123: PetscRandomGetValue(rdm,&a[i]);
124: }
125: for (i=0; i<M; i++){
126: for (j=0; j<nzp; j++){
127: PetscRandomGetValue(rdm,&rval);
128: idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
129: }
130: MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);
131: }
132: MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
133: MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);
134:
135: MatMatMultTranspose(P,B,MAT_INITIAL_MATRIX,fill,&C);
137: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
138: alpha=1.0;
139: for (i=0; i<2; i++){
140: alpha -=0.1;
141: MatScale(P,alpha);
142: MatMatMultTranspose(P,B,MAT_REUSE_MATRIX,fill,&C);
143: }
145: /* Create vector x, v5 that are compatible with B */
146: VecCreate(PETSC_COMM_WORLD,&x);
147: MatGetLocalSize(B,&m,&n);
148: VecSetSizes(x,n,PETSC_DECIDE);
149: VecSetFromOptions(x);
151: VecCreate(PETSC_COMM_WORLD,&v5);
152: VecSetSizes(v5,m,PETSC_DECIDE);
153: VecSetFromOptions(v5);
154:
155: MatGetLocalSize(P,PETSC_NULL,&n);
156: VecCreate(PETSC_COMM_WORLD,&v3);
157: VecSetSizes(v3,n,PETSC_DECIDE);
158: VecSetFromOptions(v3);
159: VecDuplicate(v3,&v4);
161: norm = 0.0;
162: for (i=0; i<10; i++) {
163: VecSetRandom(x,rdm);
164: MatMult(B,x,v5); /* v5 = B*x */
165: MatMultTranspose(P,v5,v3); /* v3 = Pt*B*x */
166: MatMult(C,x,v4); /* v4 = C*x */
167: VecAXPY(v4,none,v3);
168: VecNorm(v4,NORM_2,&norm_tmp);
169: if (norm_tmp > norm) norm = norm_tmp;
170: }
171: if (norm >= tol) {
172: PetscPrintf(PETSC_COMM_SELF,"Error: MatMatMultTr(), |v3 - v4|: %G\n",norm);
173: }
174: MatDestroy(P);
175: MatDestroy(C);
176: VecDestroy(v3);
177: VecDestroy(v4);
178: VecDestroy(v5);
179: VecDestroy(x);
180: }
182: /* Test MatPtAP() */
183: /*----------------------*/
184: if (Test_MatPtAP){
185: PetscInt PN;
186: MatDuplicate(A_save,MAT_COPY_VALUES,&A);
187: MatGetSize(A,&M,&N);
188: MatGetLocalSize(A,&m,&n);
189: /* PetscPrintf(PETSC_COMM_SELF,"[%d] A: %d,%d, %d,%d\n",rank,m,n,M,N); */
191: PN = M/2;
192: nzp = (PetscInt)(0.1*PN); /* num of nozeros in each row of P */
193: MatCreate(PETSC_COMM_WORLD,&P);
194: MatSetSizes(P,PETSC_DECIDE,PETSC_DECIDE,N,PN);
195: MatSetType(P,MATAIJ);
196: MatSeqAIJSetPreallocation(P,nzp,PETSC_NULL);
197: MatMPIAIJSetPreallocation(P,nzp,PETSC_NULL,nzp,PETSC_NULL);
198: for (i=0; i<nzp; i++){
199: PetscRandomGetValue(rdm,&a[i]);
200: }
201: for (i=0; i<M; i++){
202: for (j=0; j<nzp; j++){
203: PetscRandomGetValue(rdm,&rval);
204: idxn[j] = (PetscInt)(PetscRealPart(rval)*PN);
205: }
206: MatSetValues(P,1,&i,nzp,idxn,a,ADD_VALUES);
207: }
208: MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY);
209: MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY);
211: /* MatView(P,PETSC_VIEWER_STDOUT_WORLD); */
212: MatGetSize(P,&pM,&pN);
213: MatGetLocalSize(P,&pm,&pn);
214: /* PetscPrintf(PETSC_COMM_SELF," [%d] P, %d, %d, %d,%d\n",rank,pm,pn,pM,pN); */
215: MatPtAP(A,P,MAT_INITIAL_MATRIX,fill,&C);
217: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
218: alpha=1.0;
219: for (i=0; i<2; i++){
220: alpha -=0.1;
221: MatScale(A,alpha);
222: MatPtAP(A,P,MAT_REUSE_MATRIX,fill,&C);
223: }
225: /* Create vector x that is compatible with P */
226: VecCreate(PETSC_COMM_WORLD,&x);
227: MatGetLocalSize(P,&m,&n);
228: VecSetSizes(x,n,PETSC_DECIDE);
229: VecSetFromOptions(x);
230:
231: VecCreate(PETSC_COMM_WORLD,&v3);
232: VecSetSizes(v3,n,PETSC_DECIDE);
233: VecSetFromOptions(v3);
234: VecDuplicate(v3,&v4);
236: norm = 0.0;
237: for (i=0; i<10; i++) {
238: VecSetRandom(x,rdm);
239: MatMult(P,x,v1);
240: MatMult(A,v1,v2); /* v2 = A*P*x */
242: MatMultTranspose(P,v2,v3); /* v3 = Pt*A*P*x */
243: MatMult(C,x,v4); /* v3 = C*x */
244: VecAXPY(v4,none,v3);
245: VecNorm(v4,NORM_2,&norm_tmp);
246: if (norm_tmp > norm) norm = norm_tmp;
247: }
248: if (norm >= tol) {
249: PetscPrintf(PETSC_COMM_SELF,"Error: MatPtAP(), |v1 - v2|: %G\n",norm);
250: }
251:
252: MatDestroy(A);
253: MatDestroy(P);
254: MatDestroy(C);
255: VecDestroy(v3);
256: VecDestroy(v4);
257: VecDestroy(x);
258: } /* if (Test_MatPtAP) */
260: /* Destroy objects */
261: VecDestroy(v1);
262: VecDestroy(v2);
263: PetscRandomDestroy(rdm);
264: PetscFree(idxn);
265:
266: MatDestroy(A_save);
267: MatDestroy(B);
269: PreLoadEnd();
270: PetscFinalize();
272: return 0;
273: }