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