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: }