xref: /petsc/src/mat/tests/ex55.c (revision 2ce66baa5cf960b8d2a50678a0474f346227b7ca)
1c4762a1bSJed Brown 
2c4762a1bSJed Brown static char help[] = "Tests converting a matrix to another format with MatConvert().\n\n";
3c4762a1bSJed Brown 
4c4762a1bSJed Brown #include <petscmat.h>
5c4762a1bSJed Brown /* Usage: mpiexec -n <np> ex55 -verbose <0 or 1> */
6c4762a1bSJed Brown 
7d71ae5a4SJacob Faibussowitsch int main(int argc, char **args)
8d71ae5a4SJacob Faibussowitsch {
9c4762a1bSJed Brown   Mat         C, A, B, D;
10c4762a1bSJed Brown   PetscInt    i, j, ntypes, bs, mbs, m, block, d_nz = 6, o_nz = 3, col[3], row, verbose = 0;
11c4762a1bSJed Brown   PetscMPIInt size, rank;
12c4762a1bSJed Brown   MatType     type[9];
13c4762a1bSJed Brown   char        file[PETSC_MAX_PATH_LEN];
14c4762a1bSJed Brown   PetscViewer fd;
15c4762a1bSJed Brown   PetscBool   equal, flg_loadmat, flg, issymmetric;
16c4762a1bSJed Brown   PetscScalar value[3];
17c4762a1bSJed Brown 
18327415f7SBarry Smith   PetscFunctionBeginUser;
199566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &args, (char *)0, help));
209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-verbose", &verbose, NULL));
219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(NULL, NULL, "-f", file, sizeof(file), &flg_loadmat));
229566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
239566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
24c4762a1bSJed Brown 
259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(NULL, NULL, "-testseqaij", &flg));
26c4762a1bSJed Brown   if (flg) {
27c4762a1bSJed Brown     if (size == 1) {
28c4762a1bSJed Brown       type[0] = MATSEQAIJ;
29c4762a1bSJed Brown     } else {
30c4762a1bSJed Brown       type[0] = MATMPIAIJ;
31c4762a1bSJed Brown     }
32c4762a1bSJed Brown   } else {
33c4762a1bSJed Brown     type[0] = MATAIJ;
34c4762a1bSJed Brown   }
35c4762a1bSJed Brown   if (size == 1) {
36c4762a1bSJed Brown     ntypes  = 3;
37c4762a1bSJed Brown     type[1] = MATSEQBAIJ;
38c4762a1bSJed Brown     type[2] = MATSEQSBAIJ;
39c4762a1bSJed Brown   } else {
40c4762a1bSJed Brown     ntypes  = 3;
41c4762a1bSJed Brown     type[1] = MATMPIBAIJ;
42c4762a1bSJed Brown     type[2] = MATMPISBAIJ;
43c4762a1bSJed Brown   }
44c4762a1bSJed Brown 
45c4762a1bSJed Brown   /* input matrix C */
46c4762a1bSJed Brown   if (flg_loadmat) {
47c4762a1bSJed Brown     /* Open binary file. */
489566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file, FILE_MODE_READ, &fd));
49c4762a1bSJed Brown 
50c4762a1bSJed Brown     /* Load a baij matrix, then destroy the viewer. */
519566063dSJacob Faibussowitsch     PetscCall(MatCreate(PETSC_COMM_WORLD, &C));
52c4762a1bSJed Brown     if (size == 1) {
539566063dSJacob Faibussowitsch       PetscCall(MatSetType(C, MATSEQBAIJ));
54c4762a1bSJed Brown     } else {
559566063dSJacob Faibussowitsch       PetscCall(MatSetType(C, MATMPIBAIJ));
56c4762a1bSJed Brown     }
579566063dSJacob Faibussowitsch     PetscCall(MatSetFromOptions(C));
589566063dSJacob Faibussowitsch     PetscCall(MatLoad(C, fd));
599566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&fd));
60c4762a1bSJed Brown   } else { /* Create a baij mat with bs>1  */
619371c9d4SSatish Balay     bs  = 2;
629371c9d4SSatish Balay     mbs = 8;
639566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetInt(NULL, NULL, "-mbs", &mbs, NULL));
649566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetInt(NULL, NULL, "-bs", &bs, NULL));
6508401ef6SPierre Jolivet     PetscCheck(bs > 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, " bs must be >1 in this case");
66c4762a1bSJed Brown     m = mbs * bs;
679566063dSJacob Faibussowitsch     PetscCall(MatCreateBAIJ(PETSC_COMM_WORLD, bs, PETSC_DECIDE, PETSC_DECIDE, m, m, d_nz, NULL, o_nz, NULL, &C));
68c4762a1bSJed Brown     for (block = 0; block < mbs; block++) {
69c4762a1bSJed Brown       /* diagonal blocks */
709371c9d4SSatish Balay       value[0] = -1.0;
719371c9d4SSatish Balay       value[1] = 4.0;
729371c9d4SSatish Balay       value[2] = -1.0;
73c4762a1bSJed Brown       for (i = 1 + block * bs; i < bs - 1 + block * bs; i++) {
749371c9d4SSatish Balay         col[0] = i - 1;
759371c9d4SSatish Balay         col[1] = i;
769371c9d4SSatish Balay         col[2] = i + 1;
779566063dSJacob Faibussowitsch         PetscCall(MatSetValues(C, 1, &i, 3, col, value, INSERT_VALUES));
78c4762a1bSJed Brown       }
799371c9d4SSatish Balay       i        = bs - 1 + block * bs;
809371c9d4SSatish Balay       col[0]   = bs - 2 + block * bs;
819371c9d4SSatish Balay       col[1]   = bs - 1 + block * bs;
829371c9d4SSatish Balay       value[0] = -1.0;
839371c9d4SSatish Balay       value[1] = 4.0;
849566063dSJacob Faibussowitsch       PetscCall(MatSetValues(C, 1, &i, 2, col, value, INSERT_VALUES));
85c4762a1bSJed Brown 
869371c9d4SSatish Balay       i        = 0 + block * bs;
879371c9d4SSatish Balay       col[0]   = 0 + block * bs;
889371c9d4SSatish Balay       col[1]   = 1 + block * bs;
899371c9d4SSatish Balay       value[0] = 4.0;
909371c9d4SSatish Balay       value[1] = -1.0;
919566063dSJacob Faibussowitsch       PetscCall(MatSetValues(C, 1, &i, 2, col, value, INSERT_VALUES));
92c4762a1bSJed Brown     }
93c4762a1bSJed Brown     /* off-diagonal blocks */
94c4762a1bSJed Brown     value[0] = -1.0;
95c4762a1bSJed Brown     for (i = 0; i < (mbs - 1) * bs; i++) {
96c4762a1bSJed Brown       col[0] = i + bs;
979566063dSJacob Faibussowitsch       PetscCall(MatSetValues(C, 1, &i, 1, col, value, INSERT_VALUES));
989371c9d4SSatish Balay       col[0] = i;
999371c9d4SSatish Balay       row    = i + bs;
1009566063dSJacob Faibussowitsch       PetscCall(MatSetValues(C, 1, &row, 1, col, value, INSERT_VALUES));
101c4762a1bSJed Brown     }
1029566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
1039566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
104c4762a1bSJed Brown   }
105c4762a1bSJed Brown   {
106c4762a1bSJed Brown     /* Check the symmetry of C because it will be converted to a sbaij matrix */
107c4762a1bSJed Brown     Mat Ctrans;
1089566063dSJacob Faibussowitsch     PetscCall(MatTranspose(C, MAT_INITIAL_MATRIX, &Ctrans));
1099566063dSJacob Faibussowitsch     PetscCall(MatEqual(C, Ctrans, &flg));
110c4762a1bSJed Brown     /*
111c4762a1bSJed Brown     {
1129566063dSJacob Faibussowitsch       PetscCall(MatAXPY(C,1.,Ctrans,DIFFERENT_NONZERO_PATTERN));
113c4762a1bSJed Brown       flg  = PETSC_TRUE;
114c4762a1bSJed Brown     }
115c4762a1bSJed Brown */
1169566063dSJacob Faibussowitsch     PetscCall(MatSetOption(C, MAT_SYMMETRIC, flg));
1179566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&Ctrans));
118c4762a1bSJed Brown   }
1199566063dSJacob Faibussowitsch   PetscCall(MatIsSymmetric(C, 0.0, &issymmetric));
1209566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(C, NULL, "-view_mat"));
121c4762a1bSJed Brown 
122c4762a1bSJed Brown   /* convert C to other formats */
123c4762a1bSJed Brown   for (i = 0; i < ntypes; i++) {
124c4762a1bSJed Brown     PetscBool ismpisbaij, isseqsbaij;
125c4762a1bSJed Brown 
1269566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(type[i], MATMPISBAIJ, &ismpisbaij));
1279566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(type[i], MATMPISBAIJ, &isseqsbaij));
128c4762a1bSJed Brown     if (!issymmetric && (ismpisbaij || isseqsbaij)) continue;
1299566063dSJacob Faibussowitsch     PetscCall(MatConvert(C, type[i], MAT_INITIAL_MATRIX, &A));
1309566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(A, C, 10, &equal));
13128b400f6SJacob Faibussowitsch     PetscCheck(equal, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMETYPE, "Error in conversion from BAIJ to %s", type[i]);
132c4762a1bSJed Brown     for (j = i + 1; j < ntypes; j++) {
1339566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(type[j], MATMPISBAIJ, &ismpisbaij));
1349566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(type[j], MATMPISBAIJ, &isseqsbaij));
135c4762a1bSJed Brown       if (!issymmetric && (ismpisbaij || isseqsbaij)) continue;
13648a46eb9SPierre Jolivet       if (verbose > 0) PetscCall(PetscPrintf(PETSC_COMM_WORLD, " \n[%d] test conversion between %s and %s\n", rank, type[i], type[j]));
137c4762a1bSJed Brown 
138dd400576SPatrick Sanan       if (rank == 0 && verbose) printf("Convert %s A to %s B\n", type[i], type[j]);
1399566063dSJacob Faibussowitsch       PetscCall(MatConvert(A, type[j], MAT_INITIAL_MATRIX, &B));
140c4762a1bSJed Brown       /*
141c4762a1bSJed Brown       if (j == 2) {
1429566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_SELF," A: %s\n",type[i]));
1439566063dSJacob Faibussowitsch         PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD));
1449566063dSJacob Faibussowitsch         PetscCall(PetscPrintf(PETSC_COMM_SELF," B: %s\n",type[j]));
1459566063dSJacob Faibussowitsch         PetscCall(MatView(B,PETSC_VIEWER_STDOUT_WORLD));
146c4762a1bSJed Brown       }
147c4762a1bSJed Brown        */
1489566063dSJacob Faibussowitsch       PetscCall(MatMultEqual(A, B, 10, &equal));
14928b400f6SJacob Faibussowitsch       PetscCheck(equal, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMETYPE, "Error in conversion from %s to %s", type[i], type[j]);
150c4762a1bSJed Brown 
151c4762a1bSJed Brown       if (size == 1 || j != 2) { /* Matconvert from mpisbaij mat to other formats are not supported */
152dd400576SPatrick Sanan         if (rank == 0 && verbose) printf("Convert %s B to %s D\n", type[j], type[i]);
1539566063dSJacob Faibussowitsch         PetscCall(MatConvert(B, type[i], MAT_INITIAL_MATRIX, &D));
1549566063dSJacob Faibussowitsch         PetscCall(MatMultEqual(B, D, 10, &equal));
15528b400f6SJacob Faibussowitsch         PetscCheck(equal, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMETYPE, "Error in conversion from %s to %s", type[j], type[i]);
156c4762a1bSJed Brown 
1579566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&D));
158c4762a1bSJed Brown       }
1599566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&B));
1609566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&D));
161c4762a1bSJed Brown     }
162c4762a1bSJed Brown 
163c4762a1bSJed Brown     /* Test in-place convert */
164c4762a1bSJed Brown     if (size == 1) { /* size > 1 is not working yet! */
165c4762a1bSJed Brown       j = (i + 1) % ntypes;
1669566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(type[j], MATMPISBAIJ, &ismpisbaij));
1679566063dSJacob Faibussowitsch       PetscCall(PetscStrcmp(type[j], MATMPISBAIJ, &isseqsbaij));
168c4762a1bSJed Brown       if (!issymmetric && (ismpisbaij || isseqsbaij)) continue;
169c4762a1bSJed Brown       /* printf("[%d] i: %d, j: %d\n",rank,i,j); */
1709566063dSJacob Faibussowitsch       PetscCall(MatConvert(A, type[j], MAT_INPLACE_MATRIX, &A));
171c4762a1bSJed Brown     }
172c4762a1bSJed Brown 
1739566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
174c4762a1bSJed Brown   }
175c4762a1bSJed Brown 
176c4762a1bSJed Brown   /* test BAIJ to MATIS */
177c4762a1bSJed Brown   if (size > 1) {
178c4762a1bSJed Brown     MatType ctype;
179c4762a1bSJed Brown 
1809566063dSJacob Faibussowitsch     PetscCall(MatGetType(C, &ctype));
1819566063dSJacob Faibussowitsch     PetscCall(MatConvert(C, MATIS, MAT_INITIAL_MATRIX, &A));
1829566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(A, C, 10, &equal));
1839566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(A, NULL, "-view_conv"));
184c4762a1bSJed Brown     if (!equal) {
185c4762a1bSJed Brown       Mat C2;
186c4762a1bSJed Brown 
1879566063dSJacob Faibussowitsch       PetscCall(MatConvert(A, ctype, MAT_INITIAL_MATRIX, &C2));
1889566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(C2, NULL, "-view_conv_assembled"));
1899566063dSJacob Faibussowitsch       PetscCall(MatAXPY(C2, -1., C, DIFFERENT_NONZERO_PATTERN));
190*2ce66baaSPierre Jolivet       PetscCall(MatFilter(C2, PETSC_SMALL, PETSC_FALSE, PETSC_FALSE));
1919566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(C2, NULL, "-view_err"));
1929566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C2));
193c4762a1bSJed Brown       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Error in conversion from BAIJ to MATIS");
194c4762a1bSJed Brown     }
1959566063dSJacob Faibussowitsch     PetscCall(MatConvert(C, MATIS, MAT_REUSE_MATRIX, &A));
1969566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(A, C, 10, &equal));
1979566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(A, NULL, "-view_conv"));
198c4762a1bSJed Brown     if (!equal) {
199c4762a1bSJed Brown       Mat C2;
200c4762a1bSJed Brown 
2019566063dSJacob Faibussowitsch       PetscCall(MatConvert(A, ctype, MAT_INITIAL_MATRIX, &C2));
2029566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(C2, NULL, "-view_conv_assembled"));
2039566063dSJacob Faibussowitsch       PetscCall(MatAXPY(C2, -1., C, DIFFERENT_NONZERO_PATTERN));
204*2ce66baaSPierre Jolivet       PetscCall(MatFilter(C2, PETSC_SMALL, PETSC_FALSE, PETSC_FALSE));
2059566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(C2, NULL, "-view_err"));
2069566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C2));
207c4762a1bSJed Brown       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Error in conversion from BAIJ to MATIS");
208c4762a1bSJed Brown     }
2099566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
2109566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(C, MAT_COPY_VALUES, &A));
2119566063dSJacob Faibussowitsch     PetscCall(MatConvert(A, MATIS, MAT_INPLACE_MATRIX, &A));
2129566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(A, NULL, "-view_conv"));
2139566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(A, C, 10, &equal));
214c4762a1bSJed Brown     if (!equal) {
215c4762a1bSJed Brown       Mat C2;
216c4762a1bSJed Brown 
2179566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(A, NULL, "-view_conv"));
2189566063dSJacob Faibussowitsch       PetscCall(MatConvert(A, ctype, MAT_INITIAL_MATRIX, &C2));
2199566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(C2, NULL, "-view_conv_assembled"));
2209566063dSJacob Faibussowitsch       PetscCall(MatAXPY(C2, -1., C, DIFFERENT_NONZERO_PATTERN));
221*2ce66baaSPierre Jolivet       PetscCall(MatFilter(C2, PETSC_SMALL, PETSC_FALSE, PETSC_FALSE));
2229566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(C2, NULL, "-view_err"));
2239566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C2));
224c4762a1bSJed Brown       SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Error in conversion from BAIJ to MATIS");
225c4762a1bSJed Brown     }
2269566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
227c4762a1bSJed Brown   }
2289566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&C));
229c4762a1bSJed Brown 
2309566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
231b122ec5aSJacob Faibussowitsch   return 0;
232c4762a1bSJed Brown }
233c4762a1bSJed Brown 
234c4762a1bSJed Brown /*TEST
235c4762a1bSJed Brown 
236c4762a1bSJed Brown    test:
237c4762a1bSJed Brown 
238c4762a1bSJed Brown    test:
239c4762a1bSJed Brown       suffix: 2
240c4762a1bSJed Brown       nsize: 3
241c4762a1bSJed Brown 
242c4762a1bSJed Brown    testset:
243c4762a1bSJed Brown       requires: parmetis
244c4762a1bSJed Brown       output_file: output/ex55_1.out
245c4762a1bSJed Brown       nsize: 3
246c4762a1bSJed Brown       args: -mat_is_disassemble_l2g_type nd -mat_partitioning_type parmetis
247c4762a1bSJed Brown       test:
248c4762a1bSJed Brown         suffix: matis_baij_parmetis_nd
249c4762a1bSJed Brown       test:
250c4762a1bSJed Brown         suffix: matis_aij_parmetis_nd
251c4762a1bSJed Brown         args: -testseqaij
252c4762a1bSJed Brown       test:
253dfd57a17SPierre Jolivet         requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
254c4762a1bSJed Brown         suffix: matis_poisson1_parmetis_nd
255c4762a1bSJed Brown         args: -f ${DATAFILESPATH}/matrices/poisson1
256c4762a1bSJed Brown 
257c4762a1bSJed Brown    testset:
258dfd57a17SPierre Jolivet       requires: ptscotch defined(PETSC_HAVE_SCOTCH_PARMETIS_V3_NODEND)
259c4762a1bSJed Brown       output_file: output/ex55_1.out
260c4762a1bSJed Brown       nsize: 4
261c4762a1bSJed Brown       args: -mat_is_disassemble_l2g_type nd -mat_partitioning_type ptscotch
262c4762a1bSJed Brown       test:
263c4762a1bSJed Brown         suffix: matis_baij_ptscotch_nd
264c4762a1bSJed Brown       test:
265c4762a1bSJed Brown         suffix: matis_aij_ptscotch_nd
266c4762a1bSJed Brown         args: -testseqaij
267c4762a1bSJed Brown       test:
268dfd57a17SPierre Jolivet         requires: datafilespath !complex double !defined(PETSC_USE_64BIT_INDICES)
269c4762a1bSJed Brown         suffix: matis_poisson1_ptscotch_nd
270c4762a1bSJed Brown         args: -f ${DATAFILESPATH}/matrices/poisson1
271c4762a1bSJed Brown 
272c4762a1bSJed Brown TEST*/
273