Actual source code: ex94.c
2: static char help[] = "Tests sequential and parallel MatMatMult() and MatPtAP(), MatTransposeMatMult(), sequential MatMatTransposeMult(), MatRARt()\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: /* Example of usage:
6: ./ex94 -f0 <A_binary> -f1 <B_binary> -matmatmult_mat_view ascii::ascii_info -matmatmulttr_mat_view
7: mpiexec -n 3 ./ex94 -f0 medium -f1 medium -f2 arco1 -f3 arco1 -matmatmult_mat_view
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: {
18: MatAXPY(B, -1.0, A, DIFFERENT_NONZERO_PATTERN);
19: MatNorm(B, NORM_FROBENIUS, norm);
20: return 0;
21: }
23: int main(int argc, char **args)
24: {
25: Mat A, A_save, B, AT, ATT, BT, BTT, P, R, C, C1;
26: Vec x, v1, v2, v3, v4;
27: PetscViewer viewer;
28: PetscMPIInt size, rank;
29: PetscInt i, m, n, j, *idxn, M, N, nzp, rstart, rend;
30: PetscReal norm, norm_abs, norm_tmp, fill = 4.0;
31: PetscRandom rdm;
32: char file[4][128];
33: PetscBool flg, preload = PETSC_TRUE;
34: PetscScalar *a, rval, alpha, none = -1.0;
35: PetscBool Test_MatMatMult = PETSC_TRUE, Test_MatMatTr = PETSC_TRUE, Test_MatPtAP = PETSC_TRUE, Test_MatRARt = PETSC_TRUE, Test_MatMatMatMult = PETSC_TRUE;
36: PetscBool Test_MatAXPY = PETSC_FALSE, view = PETSC_FALSE;
37: PetscInt pm, pn, pM, pN;
38: MatInfo info;
39: PetscBool seqaij;
40: MatType mattype;
41: Mat Cdensetest, Pdense, Cdense, Adense;
44: PetscInitialize(&argc, &args, (char *)0, help);
45: MPI_Comm_size(PETSC_COMM_WORLD, &size);
46: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
48: PetscOptionsGetReal(NULL, NULL, "-fill", &fill, NULL);
49: PetscOptionsGetBool(NULL, NULL, "-matops_view", &view, NULL);
50: if (view) PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_INFO);
52: /* Load the matrices A_save and B */
53: PetscOptionsGetString(NULL, NULL, "-f0", file[0], sizeof(file[0]), &flg);
55: PetscOptionsGetString(NULL, NULL, "-f1", file[1], sizeof(file[1]), &flg);
57: PetscOptionsGetString(NULL, NULL, "-f2", file[2], sizeof(file[2]), &flg);
58: if (!flg) {
59: preload = PETSC_FALSE;
60: } else {
61: PetscOptionsGetString(NULL, NULL, "-f3", file[3], sizeof(file[3]), &flg);
63: }
65: PetscPreLoadBegin(preload, "Load system");
66: PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[2 * PetscPreLoadIt], FILE_MODE_READ, &viewer);
67: MatCreate(PETSC_COMM_WORLD, &A_save);
68: MatSetFromOptions(A_save);
69: MatLoad(A_save, viewer);
70: PetscViewerDestroy(&viewer);
72: PetscViewerBinaryOpen(PETSC_COMM_WORLD, file[2 * PetscPreLoadIt + 1], FILE_MODE_READ, &viewer);
73: MatCreate(PETSC_COMM_WORLD, &B);
74: MatSetFromOptions(B);
75: MatLoad(B, viewer);
76: PetscViewerDestroy(&viewer);
78: MatGetType(B, &mattype);
80: MatGetSize(B, &M, &N);
81: nzp = PetscMax((PetscInt)(0.1 * M), 5);
82: PetscMalloc((nzp + 1) * (sizeof(PetscInt) + sizeof(PetscScalar)), &idxn);
83: a = (PetscScalar *)(idxn + nzp);
85: /* Create vectors v1 and v2 that are compatible with A_save */
86: VecCreate(PETSC_COMM_WORLD, &v1);
87: MatGetLocalSize(A_save, &m, NULL);
88: VecSetSizes(v1, m, PETSC_DECIDE);
89: VecSetFromOptions(v1);
90: VecDuplicate(v1, &v2);
92: PetscRandomCreate(PETSC_COMM_WORLD, &rdm);
93: PetscRandomSetFromOptions(rdm);
94: PetscOptionsGetReal(NULL, NULL, "-fill", &fill, NULL);
96: /* Test MatAXPY() */
97: /*-------------------*/
98: PetscOptionsHasName(NULL, NULL, "-test_MatAXPY", &Test_MatAXPY);
99: if (Test_MatAXPY) {
100: Mat Btmp;
101: MatDuplicate(A_save, MAT_COPY_VALUES, &A);
102: MatDuplicate(B, MAT_COPY_VALUES, &Btmp);
103: MatAXPY(A, -1.0, B, DIFFERENT_NONZERO_PATTERN); /* A = -B + A_save */
105: MatScale(A, -1.0); /* A = -A = B - A_save */
106: MatAXPY(Btmp, -1.0, A, DIFFERENT_NONZERO_PATTERN); /* Btmp = -A + B = A_save */
107: MatMultEqual(A_save, Btmp, 10, &flg);
109: MatDestroy(&A);
110: MatDestroy(&Btmp);
112: Test_MatMatMult = PETSC_FALSE;
113: Test_MatMatTr = PETSC_FALSE;
114: Test_MatPtAP = PETSC_FALSE;
115: Test_MatRARt = PETSC_FALSE;
116: Test_MatMatMatMult = PETSC_FALSE;
117: }
119: /* 1) Test MatMatMult() */
120: /* ---------------------*/
121: if (Test_MatMatMult) {
122: MatDuplicate(A_save, MAT_COPY_VALUES, &A);
123: MatCreateTranspose(A, &AT);
124: MatCreateTranspose(AT, &ATT);
125: MatCreateTranspose(B, &BT);
126: MatCreateTranspose(BT, &BTT);
128: MatMatMult(AT, B, MAT_INITIAL_MATRIX, fill, &C);
129: MatMatMultEqual(AT, B, C, 10, &flg);
131: MatDestroy(&C);
133: MatMatMult(ATT, B, MAT_INITIAL_MATRIX, fill, &C);
134: MatMatMultEqual(ATT, B, C, 10, &flg);
136: MatDestroy(&C);
138: MatMatMult(A, B, MAT_INITIAL_MATRIX, fill, &C);
139: MatMatMultEqual(A, B, C, 10, &flg);
141: /* ATT has different matrix type as A (although they have same internal data structure),
142: we cannot call MatProductReplaceMats(ATT,NULL,NULL,C) and MatMatMult(ATT,B,MAT_REUSE_MATRIX,fill,&C) */
143: MatDestroy(&C);
145: MatMatMult(A, BTT, MAT_INITIAL_MATRIX, fill, &C);
146: MatMatMultEqual(A, BTT, C, 10, &flg);
148: MatDestroy(&C);
150: MatMatMult(ATT, BTT, MAT_INITIAL_MATRIX, fill, &C);
151: MatMatMultEqual(A, B, C, 10, &flg);
153: MatDestroy(&C);
155: MatDestroy(&BTT);
156: MatDestroy(&BT);
157: MatDestroy(&ATT);
158: MatDestroy(&AT);
160: MatMatMult(A, B, MAT_INITIAL_MATRIX, fill, &C);
161: MatSetOptionsPrefix(C, "matmatmult_"); /* enable option '-matmatmult_' for matrix C */
162: MatGetInfo(C, MAT_GLOBAL_SUM, &info);
164: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
165: alpha = 1.0;
166: for (i = 0; i < 2; i++) {
167: alpha -= 0.1;
168: MatScale(A, alpha);
169: MatMatMult(A, B, MAT_REUSE_MATRIX, fill, &C);
170: }
171: MatMatMultEqual(A, B, C, 10, &flg);
173: MatDestroy(&A);
175: /* Test MatDuplicate() of C=A*B */
176: MatDuplicate(C, MAT_COPY_VALUES, &C1);
177: MatDestroy(&C1);
178: MatDestroy(&C);
179: } /* if (Test_MatMatMult) */
181: /* 2) Test MatTransposeMatMult() and MatMatTransposeMult() */
182: /* ------------------------------------------------------- */
183: if (Test_MatMatTr) {
184: /* Create P */
185: PetscInt PN, rstart, rend;
186: PN = M / 2;
187: nzp = 5; /* num of nonzeros in each row of P */
188: MatCreate(PETSC_COMM_WORLD, &P);
189: MatSetSizes(P, PETSC_DECIDE, PETSC_DECIDE, M, PN);
190: MatSetType(P, mattype);
191: MatSeqAIJSetPreallocation(P, nzp, NULL);
192: MatMPIAIJSetPreallocation(P, nzp, NULL, nzp, NULL);
193: MatGetOwnershipRange(P, &rstart, &rend);
194: for (i = 0; i < nzp; i++) PetscRandomGetValue(rdm, &a[i]);
195: for (i = rstart; i < rend; i++) {
196: for (j = 0; j < nzp; j++) {
197: PetscRandomGetValue(rdm, &rval);
198: idxn[j] = (PetscInt)(PetscRealPart(rval) * PN);
199: }
200: MatSetValues(P, 1, &i, nzp, idxn, a, ADD_VALUES);
201: }
202: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
203: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
205: /* Create R = P^T */
206: MatTranspose(P, MAT_INITIAL_MATRIX, &R);
208: { /* Test R = P^T, C1 = R*B */
209: MatMatMult(R, B, MAT_INITIAL_MATRIX, fill, &C1);
210: MatTranspose(P, MAT_REUSE_MATRIX, &R);
211: MatMatMult(R, B, MAT_REUSE_MATRIX, fill, &C1);
212: MatDestroy(&C1);
213: }
215: /* C = P^T*B */
216: MatTransposeMatMult(P, B, MAT_INITIAL_MATRIX, fill, &C);
217: MatGetInfo(C, MAT_GLOBAL_SUM, &info);
219: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
220: MatTransposeMatMult(P, B, MAT_REUSE_MATRIX, fill, &C);
221: if (view) {
222: PetscPrintf(PETSC_COMM_WORLD, "C = P^T * B:\n");
223: MatView(C, PETSC_VIEWER_STDOUT_WORLD);
224: }
225: MatProductClear(C);
226: if (view) {
227: PetscPrintf(PETSC_COMM_WORLD, "\nC = P^T * B after MatProductClear():\n");
228: MatView(C, PETSC_VIEWER_STDOUT_WORLD);
229: }
231: /* Compare P^T*B and R*B */
232: MatMatMult(R, B, MAT_INITIAL_MATRIX, fill, &C1);
233: MatNormDifference(C, C1, &norm);
235: MatDestroy(&C1);
237: /* Test MatDuplicate() of C=P^T*B */
238: MatDuplicate(C, MAT_COPY_VALUES, &C1);
239: MatDestroy(&C1);
240: MatDestroy(&C);
242: /* C = B*R^T */
243: PetscObjectTypeCompare((PetscObject)B, MATSEQAIJ, &seqaij);
244: if (size == 1 && seqaij) {
245: MatMatTransposeMult(B, R, MAT_INITIAL_MATRIX, fill, &C);
246: MatSetOptionsPrefix(C, "matmatmulttr_"); /* enable '-matmatmulttr_' for matrix C */
247: MatGetInfo(C, MAT_GLOBAL_SUM, &info);
249: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
250: MatMatTransposeMult(B, R, MAT_REUSE_MATRIX, fill, &C);
252: /* Check */
253: MatMatMult(B, P, MAT_INITIAL_MATRIX, fill, &C1);
254: MatNormDifference(C, C1, &norm);
256: MatDestroy(&C1);
257: MatDestroy(&C);
258: }
259: MatDestroy(&P);
260: MatDestroy(&R);
261: }
263: /* 3) Test MatPtAP() */
264: /*-------------------*/
265: if (Test_MatPtAP) {
266: PetscInt PN;
267: Mat Cdup;
269: MatDuplicate(A_save, MAT_COPY_VALUES, &A);
270: MatGetSize(A, &M, &N);
271: MatGetLocalSize(A, &m, &n);
273: PN = M / 2;
274: nzp = (PetscInt)(0.1 * PN + 1); /* num of nozeros in each row of P */
275: MatCreate(PETSC_COMM_WORLD, &P);
276: MatSetSizes(P, PETSC_DECIDE, PETSC_DECIDE, N, PN);
277: MatSetType(P, mattype);
278: MatSeqAIJSetPreallocation(P, nzp, NULL);
279: MatMPIAIJSetPreallocation(P, nzp, NULL, nzp, NULL);
280: for (i = 0; i < nzp; i++) PetscRandomGetValue(rdm, &a[i]);
281: MatGetOwnershipRange(P, &rstart, &rend);
282: for (i = rstart; i < rend; i++) {
283: for (j = 0; j < nzp; j++) {
284: PetscRandomGetValue(rdm, &rval);
285: idxn[j] = (PetscInt)(PetscRealPart(rval) * PN);
286: }
287: MatSetValues(P, 1, &i, nzp, idxn, a, ADD_VALUES);
288: }
289: MatAssemblyBegin(P, MAT_FINAL_ASSEMBLY);
290: MatAssemblyEnd(P, MAT_FINAL_ASSEMBLY);
292: /* MatView(P,PETSC_VIEWER_STDOUT_WORLD); */
293: MatGetSize(P, &pM, &pN);
294: MatGetLocalSize(P, &pm, &pn);
295: MatPtAP(A, P, MAT_INITIAL_MATRIX, fill, &C);
297: /* Test MAT_REUSE_MATRIX - reuse symbolic C */
298: alpha = 1.0;
299: for (i = 0; i < 2; i++) {
300: alpha -= 0.1;
301: MatScale(A, alpha);
302: MatPtAP(A, P, MAT_REUSE_MATRIX, fill, &C);
303: }
305: /* Test PtAP ops with P Dense and A either AIJ or SeqDense (it assumes MatPtAP_XAIJ_XAIJ is fine) */
306: PetscObjectTypeCompare((PetscObject)A, MATSEQAIJ, &seqaij);
307: if (seqaij) {
308: MatConvert(C, MATSEQDENSE, MAT_INITIAL_MATRIX, &Cdensetest);
309: MatConvert(P, MATSEQDENSE, MAT_INITIAL_MATRIX, &Pdense);
310: } else {
311: MatConvert(C, MATMPIDENSE, MAT_INITIAL_MATRIX, &Cdensetest);
312: MatConvert(P, MATMPIDENSE, MAT_INITIAL_MATRIX, &Pdense);
313: }
315: /* test with A(AIJ), Pdense -- call MatPtAP_Basic() when np>1 */
316: MatPtAP(A, Pdense, MAT_INITIAL_MATRIX, fill, &Cdense);
317: MatPtAP(A, Pdense, MAT_REUSE_MATRIX, fill, &Cdense);
318: MatPtAPMultEqual(A, Pdense, Cdense, 10, &flg);
320: MatDestroy(&Cdense);
322: /* test with A SeqDense */
323: if (seqaij) {
324: MatConvert(A, MATSEQDENSE, MAT_INITIAL_MATRIX, &Adense);
325: MatPtAP(Adense, Pdense, MAT_INITIAL_MATRIX, fill, &Cdense);
326: MatPtAP(Adense, Pdense, MAT_REUSE_MATRIX, fill, &Cdense);
327: MatPtAPMultEqual(Adense, Pdense, Cdense, 10, &flg);
329: MatDestroy(&Cdense);
330: MatDestroy(&Adense);
331: }
332: MatDestroy(&Cdensetest);
333: MatDestroy(&Pdense);
335: /* Test MatDuplicate() of C=PtAP and MatView(Cdup,...) */
336: MatDuplicate(C, MAT_COPY_VALUES, &Cdup);
337: if (view) {
338: PetscPrintf(PETSC_COMM_WORLD, "\nC = P^T * A * P:\n");
339: MatView(C, PETSC_VIEWER_STDOUT_WORLD);
341: MatProductClear(C);
342: PetscPrintf(PETSC_COMM_WORLD, "\nC = P^T * A * P after MatProductClear():\n");
343: MatView(C, PETSC_VIEWER_STDOUT_WORLD);
345: PetscPrintf(PETSC_COMM_WORLD, "\nCdup:\n");
346: MatView(Cdup, PETSC_VIEWER_STDOUT_WORLD);
347: }
348: MatDestroy(&Cdup);
350: if (size > 1 || !seqaij) Test_MatRARt = PETSC_FALSE;
351: /* 4) Test MatRARt() */
352: /* ----------------- */
353: if (Test_MatRARt) {
354: Mat R, RARt, Rdense, RARtdense;
355: MatTranspose(P, MAT_INITIAL_MATRIX, &R);
357: /* Test MatRARt_Basic(), MatMatMatMult_Basic() */
358: MatConvert(R, MATDENSE, MAT_INITIAL_MATRIX, &Rdense);
359: MatRARt(A, Rdense, MAT_INITIAL_MATRIX, 2.0, &RARtdense);
360: MatRARt(A, Rdense, MAT_REUSE_MATRIX, 2.0, &RARtdense);
362: MatConvert(RARtdense, MATAIJ, MAT_INITIAL_MATRIX, &RARt);
363: MatNormDifference(C, RARt, &norm);
365: MatDestroy(&Rdense);
366: MatDestroy(&RARtdense);
367: MatDestroy(&RARt);
369: /* Test MatRARt() for aij matrices */
370: MatRARt(A, R, MAT_INITIAL_MATRIX, 2.0, &RARt);
371: MatRARt(A, R, MAT_REUSE_MATRIX, 2.0, &RARt);
372: MatNormDifference(C, RARt, &norm);
374: MatDestroy(&R);
375: MatDestroy(&RARt);
376: }
378: if (Test_MatMatMatMult && size == 1) {
379: Mat R, RAP;
380: MatTranspose(P, MAT_INITIAL_MATRIX, &R);
381: MatMatMatMult(R, A, P, MAT_INITIAL_MATRIX, 2.0, &RAP);
382: MatMatMatMult(R, A, P, MAT_REUSE_MATRIX, 2.0, &RAP);
383: MatNormDifference(C, RAP, &norm);
385: MatDestroy(&R);
386: MatDestroy(&RAP);
387: }
389: /* Create vector x that is compatible with P */
390: VecCreate(PETSC_COMM_WORLD, &x);
391: MatGetLocalSize(P, &m, &n);
392: VecSetSizes(x, n, PETSC_DECIDE);
393: VecSetFromOptions(x);
395: VecCreate(PETSC_COMM_WORLD, &v3);
396: VecSetSizes(v3, n, PETSC_DECIDE);
397: VecSetFromOptions(v3);
398: VecDuplicate(v3, &v4);
400: norm = 0.0;
401: for (i = 0; i < 10; i++) {
402: VecSetRandom(x, rdm);
403: MatMult(P, x, v1);
404: MatMult(A, v1, v2); /* v2 = A*P*x */
406: MatMultTranspose(P, v2, v3); /* v3 = Pt*A*P*x */
407: MatMult(C, x, v4); /* v3 = C*x */
408: VecNorm(v4, NORM_2, &norm_abs);
409: VecAXPY(v4, none, v3);
410: VecNorm(v4, NORM_2, &norm_tmp);
412: norm_tmp /= norm_abs;
413: if (norm_tmp > norm) norm = norm_tmp;
414: }
417: MatDestroy(&A);
418: MatDestroy(&P);
419: MatDestroy(&C);
420: VecDestroy(&v3);
421: VecDestroy(&v4);
422: VecDestroy(&x);
423: }
425: /* Destroy objects */
426: VecDestroy(&v1);
427: VecDestroy(&v2);
428: PetscRandomDestroy(&rdm);
429: PetscFree(idxn);
431: MatDestroy(&A_save);
432: MatDestroy(&B);
434: PetscPreLoadEnd();
435: PetscFinalize();
436: return 0;
437: }
439: /*TEST
441: test:
442: suffix: 2_mattransposematmult_matmatmult
443: nsize: 3
444: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
445: args: -f0 ${DATAFILESPATH}/matrices/medium -f1 ${DATAFILESPATH}/matrices/medium -mattransposematmult_via at*b> ex94_2.tmp 2>&1
447: test:
448: suffix: 2_mattransposematmult_scalable
449: nsize: 3
450: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
451: args: -f0 ${DATAFILESPATH}/matrices/medium -f1 ${DATAFILESPATH}/matrices/medium -mattransposematmult_via scalable> ex94_2.tmp 2>&1
452: output_file: output/ex94_1.out
454: test:
455: suffix: axpy_mpiaij
456: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
457: nsize: 8
458: args: -f0 ${DATAFILESPATH}/matrices/poisson_2d5p -f1 ${DATAFILESPATH}/matrices/poisson_2d13p -test_MatAXPY
459: output_file: output/ex94_1.out
461: test:
462: suffix: axpy_mpibaij
463: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
464: nsize: 8
465: args: -f0 ${DATAFILESPATH}/matrices/poisson_2d5p -f1 ${DATAFILESPATH}/matrices/poisson_2d13p -test_MatAXPY -mat_type baij
466: output_file: output/ex94_1.out
468: test:
469: suffix: axpy_mpisbaij
470: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
471: nsize: 8
472: args: -f0 ${DATAFILESPATH}/matrices/poisson_2d5p -f1 ${DATAFILESPATH}/matrices/poisson_2d13p -test_MatAXPY -mat_type sbaij
473: output_file: output/ex94_1.out
475: test:
476: suffix: matmatmult
477: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
478: args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -viewer_binary_skip_info
479: output_file: output/ex94_1.out
481: test:
482: suffix: matmatmult_2
483: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
484: args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -mat_type mpiaij -viewer_binary_skip_info
485: output_file: output/ex94_1.out
487: test:
488: suffix: matmatmult_scalable
489: nsize: 4
490: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
491: args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -matmatmult_via scalable
492: output_file: output/ex94_1.out
494: test:
495: suffix: ptap
496: nsize: 3
497: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
498: args: -f0 ${DATAFILESPATH}/matrices/medium -f1 ${DATAFILESPATH}/matrices/medium -matptap_via scalable
499: output_file: output/ex94_1.out
501: test:
502: suffix: rap
503: nsize: 3
504: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
505: args: -f0 ${DATAFILESPATH}/matrices/medium -f1 ${DATAFILESPATH}/matrices/medium
506: output_file: output/ex94_1.out
508: test:
509: suffix: scalable0
510: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
511: args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -viewer_binary_skip_info
512: output_file: output/ex94_1.out
514: test:
515: suffix: scalable1
516: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
517: args: -f0 ${DATAFILESPATH}/matrices/arco1 -f1 ${DATAFILESPATH}/matrices/arco1 -viewer_binary_skip_info -matptap_via scalable
518: output_file: output/ex94_1.out
520: test:
521: suffix: view
522: nsize: 2
523: requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
524: args: -f0 ${DATAFILESPATH}/matrices/tiny -f1 ${DATAFILESPATH}/matrices/tiny -viewer_binary_skip_info -matops_view
525: output_file: output/ex94_2.out
527: TEST*/