1d0dbe9f7SStefano Zampini static char help[] = "Tests the use of interface functions for MATIS matrices and conversion routines.\n"; 2c4762a1bSJed Brown 3c4762a1bSJed Brown #include <petscmat.h> 4c4762a1bSJed Brown 50d2733adSStefano Zampini PetscErrorCode TestMatZeroRows(Mat, Mat, PetscBool, IS, PetscScalar, PetscBool); 6c4762a1bSJed Brown PetscErrorCode CheckMat(Mat, Mat, PetscBool, const char *); 70d2733adSStefano Zampini PetscErrorCode ISL2GMapNoNeg(ISLocalToGlobalMapping, IS, IS *); 8c4762a1bSJed Brown 9d71ae5a4SJacob Faibussowitsch int main(int argc, char **args) 10d71ae5a4SJacob Faibussowitsch { 11c4762a1bSJed Brown Mat A, B, A2, B2, T; 12c4762a1bSJed Brown Mat Aee, Aeo, Aoe, Aoo; 13d0dbe9f7SStefano Zampini Mat *mats, *Asub, *Bsub; 14c4762a1bSJed Brown Vec x, y; 15c4762a1bSJed Brown MatInfo info; 16c4762a1bSJed Brown ISLocalToGlobalMapping cmap, rmap; 170d2733adSStefano Zampini IS is, lis, is2, reven, rodd, ceven, codd; 18c4762a1bSJed Brown IS *rows, *cols; 19d0dbe9f7SStefano Zampini IS irow[2], icol[2]; 20d0dbe9f7SStefano Zampini PetscLayout rlayout, clayout; 2184a95373SStefano Zampini const PetscInt *rrange, *crange, *idxs1, *idxs2; 22c4762a1bSJed Brown MatType lmtype; 2384a95373SStefano Zampini PetscScalar diag = 2., *vals; 24e432b41dSStefano Zampini PetscInt n, m, i, lm, ln; 25a50ef18cSStefano Zampini PetscInt rst, ren, cst, cen, nr, nc, rbs = 1, cbs = 1; 26d0dbe9f7SStefano Zampini PetscMPIInt rank, size, lrank, rrank; 27c4762a1bSJed Brown PetscBool testT, squaretest, isaij; 284f58015eSStefano Zampini PetscBool permute = PETSC_FALSE, negmap = PETSC_FALSE, repmap = PETSC_FALSE, allow_repeated = PETSC_TRUE; 2984a95373SStefano Zampini PetscBool diffmap = PETSC_TRUE, symmetric = PETSC_FALSE, issymmetric, test_matlab = PETSC_FALSE, test_setvalues = PETSC_TRUE; 30c4762a1bSJed Brown 31327415f7SBarry Smith PetscFunctionBeginUser; 32c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &args, NULL, help)); 339566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 349566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 35c4762a1bSJed Brown m = n = 2 * size; 369566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-symmetric", &symmetric, NULL)); 379566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-m", &m, NULL)); 389566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL)); 399566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-negmap", &negmap, NULL)); 409566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-repmap", &repmap, NULL)); 419566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-permmap", &permute, NULL)); 429566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-diffmap", &diffmap, NULL)); 434f58015eSStefano Zampini PetscCall(PetscOptionsGetBool(NULL, NULL, "-allow_repeated", &allow_repeated, NULL)); 445042aa92SStefano Zampini PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_matlab", &test_matlab, NULL)); 4584a95373SStefano Zampini PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_setvalues", &test_setvalues, NULL)); 46a50ef18cSStefano Zampini PetscCall(PetscOptionsGetInt(NULL, NULL, "-rbs", &rbs, NULL)); 47a50ef18cSStefano Zampini PetscCall(PetscOptionsGetInt(NULL, NULL, "-cbs", &cbs, NULL)); 48e00437b9SBarry Smith PetscCheck(size == 1 || m >= 4, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Number of rows should be larger or equal 4 for parallel runs"); 49e00437b9SBarry Smith PetscCheck(size != 1 || m >= 2, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Number of rows should be larger or equal 2 for uniprocessor runs"); 50e00437b9SBarry Smith PetscCheck(n >= 2, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Number of cols should be larger or equal 2"); 51c4762a1bSJed Brown 52c4762a1bSJed Brown /* create a MATIS matrix */ 539566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 549566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, m, n)); 559566063dSJacob Faibussowitsch PetscCall(MatSetType(A, MATIS)); 569566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A)); 57e432b41dSStefano Zampini if (!negmap && !repmap) { 58fc989267SStefano Zampini /* This is not the proper setting for MATIS for finite elements, it is just used to test the routines 59fc989267SStefano Zampini Here we use a one-to-one correspondence between local row/column spaces and global row/column spaces 60fc989267SStefano Zampini Equivalent to passing NULL for the mapping */ 619566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, n, 0, 1, &is)); 62e432b41dSStefano Zampini } else if (negmap && !repmap) { /* non repeated but with negative indices */ 639566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, n + 2, -2, 1, &is)); 64e432b41dSStefano Zampini } else if (!negmap && repmap) { /* non negative but repeated indices */ 65e432b41dSStefano Zampini IS isl[2]; 66e432b41dSStefano Zampini 679566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, n, 0, 1, &isl[0])); 689566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, n, n - 1, -1, &isl[1])); 699566063dSJacob Faibussowitsch PetscCall(ISConcatenate(PETSC_COMM_WORLD, 2, isl, &is)); 709566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isl[0])); 719566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isl[1])); 72e432b41dSStefano Zampini } else { /* negative and repeated indices */ 73e432b41dSStefano Zampini IS isl[2]; 74e432b41dSStefano Zampini 759566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, n + 1, -1, 1, &isl[0])); 769566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, n + 1, n - 1, -1, &isl[1])); 779566063dSJacob Faibussowitsch PetscCall(ISConcatenate(PETSC_COMM_WORLD, 2, isl, &is)); 789566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isl[0])); 799566063dSJacob Faibussowitsch PetscCall(ISDestroy(&isl[1])); 80e432b41dSStefano Zampini } 819566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(is, &cmap)); 829566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 83c4762a1bSJed Brown 84e432b41dSStefano Zampini if (m != n || diffmap) { 859566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, m, permute ? m - 1 : 0, permute ? -1 : 1, &is)); 869566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(is, &rmap)); 879566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 88c4762a1bSJed Brown } else { 899566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)cmap)); 90c4762a1bSJed Brown rmap = cmap; 91c4762a1bSJed Brown } 92e432b41dSStefano Zampini 934f58015eSStefano Zampini PetscCall(MatISSetAllowRepeated(A, allow_repeated)); 949566063dSJacob Faibussowitsch PetscCall(MatSetLocalToGlobalMapping(A, rmap, cmap)); 95a50ef18cSStefano Zampini PetscCall(MatSetBlockSizes(A, rbs, cbs)); 969566063dSJacob Faibussowitsch PetscCall(MatISStoreL2L(A, PETSC_FALSE)); 979566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 3, NULL, 3, NULL)); 989566063dSJacob Faibussowitsch PetscCall(MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, (PetscBool)!(repmap || negmap))); /* I do not want to precompute the pattern */ 999566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetSize(rmap, &lm)); 1009566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetSize(cmap, &ln)); 101e432b41dSStefano Zampini for (i = 0; i < lm; i++) { 102c4762a1bSJed Brown PetscScalar v[3]; 103c4762a1bSJed Brown PetscInt cols[3]; 104c4762a1bSJed Brown 105c4762a1bSJed Brown cols[0] = (i - 1 + n) % n; 106c4762a1bSJed Brown cols[1] = i % n; 107c4762a1bSJed Brown cols[2] = (i + 1) % n; 108c4762a1bSJed Brown v[0] = -1. * (symmetric ? PetscMin(i + 1, cols[0] + 1) : i + 1); 109c4762a1bSJed Brown v[1] = 2. * (symmetric ? PetscMin(i + 1, cols[1] + 1) : i + 1); 110c4762a1bSJed Brown v[2] = -1. * (symmetric ? PetscMin(i + 1, cols[2] + 1) : i + 1); 1119566063dSJacob Faibussowitsch PetscCall(ISGlobalToLocalMappingApply(cmap, IS_GTOLM_MASK, 3, cols, NULL, cols)); 1129566063dSJacob Faibussowitsch PetscCall(MatSetValuesLocal(A, 1, &i, 3, cols, v, ADD_VALUES)); 113c4762a1bSJed Brown } 1149566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 1159566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 116c4762a1bSJed Brown 117e432b41dSStefano Zampini /* activate tests for square matrices with same maps only */ 1189566063dSJacob Faibussowitsch PetscCall(MatHasCongruentLayouts(A, &squaretest)); 119e432b41dSStefano Zampini if (squaretest && rmap != cmap) { 120e432b41dSStefano Zampini PetscInt nr, nc; 121e432b41dSStefano Zampini 1229566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetSize(rmap, &nr)); 1239566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetSize(cmap, &nc)); 124e432b41dSStefano Zampini if (nr != nc) squaretest = PETSC_FALSE; 125e432b41dSStefano Zampini else { 1269566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetIndices(rmap, &idxs1)); 1279566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingGetIndices(cmap, &idxs2)); 1289566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(idxs1, idxs2, nr, &squaretest)); 1299566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingRestoreIndices(rmap, &idxs1)); 1309566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingRestoreIndices(cmap, &idxs2)); 131e432b41dSStefano Zampini } 1325440e5dcSBarry Smith PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, &squaretest, 1, MPI_C_BOOL, MPI_LAND, PetscObjectComm((PetscObject)A))); 133e432b41dSStefano Zampini } 1344f58015eSStefano Zampini if (negmap && repmap) squaretest = PETSC_FALSE; 135e432b41dSStefano Zampini 136e432b41dSStefano Zampini /* test MatISGetLocalMat */ 1379566063dSJacob Faibussowitsch PetscCall(MatISGetLocalMat(A, &B)); 1389566063dSJacob Faibussowitsch PetscCall(MatGetType(B, &lmtype)); 139c4762a1bSJed Brown 140c4762a1bSJed Brown /* test MatGetInfo */ 1419566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatGetInfo\n")); 1429566063dSJacob Faibussowitsch PetscCall(MatGetInfo(A, MAT_LOCAL, &info)); 1439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD)); 1449371c9d4SSatish Balay PetscCall(PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD, "Process %2d: %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n", PetscGlobalRank, (PetscInt)info.nz_used, (PetscInt)info.nz_allocated, 1459371c9d4SSatish Balay (PetscInt)info.nz_unneeded, (PetscInt)info.assemblies, (PetscInt)info.mallocs)); 1469566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD)); 1479566063dSJacob Faibussowitsch PetscCall(MatGetInfo(A, MAT_GLOBAL_MAX, &info)); 1489371c9d4SSatish Balay PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "GlobalMax : %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n", (PetscInt)info.nz_used, (PetscInt)info.nz_allocated, (PetscInt)info.nz_unneeded, 1499371c9d4SSatish Balay (PetscInt)info.assemblies, (PetscInt)info.mallocs)); 1509566063dSJacob Faibussowitsch PetscCall(MatGetInfo(A, MAT_GLOBAL_SUM, &info)); 1519371c9d4SSatish Balay PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "GlobalSum : %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n", (PetscInt)info.nz_used, (PetscInt)info.nz_allocated, (PetscInt)info.nz_unneeded, 1529371c9d4SSatish Balay (PetscInt)info.assemblies, (PetscInt)info.mallocs)); 153c4762a1bSJed Brown 154e432b41dSStefano Zampini /* test MatIsSymmetric */ 1559566063dSJacob Faibussowitsch PetscCall(MatIsSymmetric(A, 0.0, &issymmetric)); 1569566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatIsSymmetric: %d\n", issymmetric)); 157c4762a1bSJed Brown 158c4762a1bSJed Brown /* Create a MPIAIJ matrix, same as A */ 1599566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &B)); 1609566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, m, n)); 161a50ef18cSStefano Zampini PetscCall(MatSetBlockSizes(B, rbs, cbs)); 1629566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATAIJ)); 1639566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(B)); 1649566063dSJacob Faibussowitsch PetscCall(MatSetLocalToGlobalMapping(B, rmap, cmap)); 1659566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(B, 3, NULL, 3, NULL)); 1669566063dSJacob Faibussowitsch PetscCall(MatMPIBAIJSetPreallocation(B, 1, 3, NULL, 3, NULL)); 167c4762a1bSJed Brown #if defined(PETSC_HAVE_HYPRE) 1689566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(B, 3, NULL, 3, NULL)); 169c4762a1bSJed Brown #endif 1709566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(B, 3, NULL, 3, NULL)); 1719566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, (PetscBool)!(repmap || negmap))); /* I do not want to precompute the pattern */ 172e432b41dSStefano Zampini for (i = 0; i < lm; i++) { 173c4762a1bSJed Brown PetscScalar v[3]; 174c4762a1bSJed Brown PetscInt cols[3]; 175c4762a1bSJed Brown 176c4762a1bSJed Brown cols[0] = (i - 1 + n) % n; 177c4762a1bSJed Brown cols[1] = i % n; 178c4762a1bSJed Brown cols[2] = (i + 1) % n; 179c4762a1bSJed Brown v[0] = -1. * (symmetric ? PetscMin(i + 1, cols[0] + 1) : i + 1); 180c4762a1bSJed Brown v[1] = 2. * (symmetric ? PetscMin(i + 1, cols[1] + 1) : i + 1); 181c4762a1bSJed Brown v[2] = -1. * (symmetric ? PetscMin(i + 1, cols[2] + 1) : i + 1); 1829566063dSJacob Faibussowitsch PetscCall(ISGlobalToLocalMappingApply(cmap, IS_GTOLM_MASK, 3, cols, NULL, cols)); 1839566063dSJacob Faibussowitsch PetscCall(MatSetValuesLocal(B, 1, &i, 3, cols, v, ADD_VALUES)); 184c4762a1bSJed Brown } 1859566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 1869566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 187e432b41dSStefano Zampini 188e432b41dSStefano Zampini /* test MatView */ 1899566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatView\n")); 1909566063dSJacob Faibussowitsch PetscCall(MatView(A, NULL)); 1919566063dSJacob Faibussowitsch PetscCall(MatView(B, NULL)); 192c4762a1bSJed Brown 1935042aa92SStefano Zampini /* test MATLAB ASCII view */ 1945042aa92SStefano Zampini if (test_matlab) { /* output is different when using real or complex numbers */ 1955042aa92SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatView ASCII MATLAB\n")); 1965042aa92SStefano Zampini PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_MATLAB)); 1975042aa92SStefano Zampini PetscCall(MatView(A, PETSC_VIEWER_STDOUT_WORLD)); 1985042aa92SStefano Zampini PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD)); 1995042aa92SStefano Zampini } 2005042aa92SStefano Zampini 201c4762a1bSJed Brown /* test CheckMat */ 2029566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test CheckMat\n")); 2039566063dSJacob Faibussowitsch PetscCall(CheckMat(A, B, PETSC_FALSE, "CheckMat")); 204c4762a1bSJed Brown 2055042aa92SStefano Zampini /* test binary MatView/MatLoad */ 2065042aa92SStefano Zampini { 2075042aa92SStefano Zampini PetscMPIInt color = rank % 2; 2085042aa92SStefano Zampini MPI_Comm comm; 2095042aa92SStefano Zampini char name[PETSC_MAX_PATH_LEN]; 2105042aa92SStefano Zampini PetscViewer wview, cview, sview, view; 2115042aa92SStefano Zampini Mat A2; 2125042aa92SStefano Zampini 2135042aa92SStefano Zampini PetscCallMPI(MPI_Comm_split(PETSC_COMM_WORLD, color, rank, &comm)); 2145042aa92SStefano Zampini 2155042aa92SStefano Zampini PetscCall(PetscSNPrintf(name, PETSC_STATIC_ARRAY_LENGTH(name), "world_is")); 2165042aa92SStefano Zampini PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, name, FILE_MODE_WRITE, &wview)); 2175042aa92SStefano Zampini PetscCall(PetscSNPrintf(name, PETSC_STATIC_ARRAY_LENGTH(name), "seq_is_%d", rank)); 2185042aa92SStefano Zampini PetscCall(PetscViewerBinaryOpen(PETSC_COMM_SELF, name, FILE_MODE_WRITE, &sview)); 2195042aa92SStefano Zampini PetscCall(PetscSNPrintf(name, PETSC_STATIC_ARRAY_LENGTH(name), "color_is_%d", color)); 2205042aa92SStefano Zampini PetscCall(PetscViewerBinaryOpen(comm, name, FILE_MODE_WRITE, &cview)); 2215042aa92SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatView on binary world\n")); 2225042aa92SStefano Zampini PetscCall(MatView(A, wview)); 2235042aa92SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatView on binary self\n")); 2245042aa92SStefano Zampini PetscCall(MatView(A, sview)); 2255042aa92SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatView on binary subcomm\n")); 2265042aa92SStefano Zampini PetscCall(MatView(A, cview)); 2275042aa92SStefano Zampini PetscCall(PetscViewerDestroy(&wview)); 2285042aa92SStefano Zampini PetscCall(PetscViewerDestroy(&cview)); 2295042aa92SStefano Zampini PetscCall(PetscViewerDestroy(&sview)); 2305042aa92SStefano Zampini 2315042aa92SStefano Zampini /* Load a world matrix */ 2325042aa92SStefano Zampini PetscCall(MatCreate(PETSC_COMM_WORLD, &A2)); 2335042aa92SStefano Zampini PetscCall(MatSetType(A2, MATIS)); 2345042aa92SStefano Zampini PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_INFO_DETAIL)); 2355042aa92SStefano Zampini 2365042aa92SStefano Zampini /* Read back the same matrix and check */ 2375042aa92SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatLoad from world\n")); 2385042aa92SStefano Zampini PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, "world_is", FILE_MODE_READ, &view)); 2395042aa92SStefano Zampini PetscCall(MatLoad(A2, view)); 2405042aa92SStefano Zampini PetscCall(CheckMat(A, A2, PETSC_TRUE, "Load")); 2415042aa92SStefano Zampini PetscCall(MatView(A2, PETSC_VIEWER_STDOUT_WORLD)); 2425042aa92SStefano Zampini PetscCall(PetscViewerDestroy(&view)); 2435042aa92SStefano Zampini 2445042aa92SStefano Zampini /* Read the matrix from rank 0 only */ 2455042aa92SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatLoad from self\n")); 2465042aa92SStefano Zampini PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, "seq_is_0", FILE_MODE_READ, &view)); 2475042aa92SStefano Zampini PetscCall(MatLoad(A2, view)); 2485042aa92SStefano Zampini PetscCall(MatView(A2, PETSC_VIEWER_STDOUT_WORLD)); 2495042aa92SStefano Zampini PetscCall(PetscViewerDestroy(&view)); 2505042aa92SStefano Zampini 2515042aa92SStefano Zampini /* Read the matrix from subcomm */ 2525042aa92SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatLoad from subcomm\n")); 2535042aa92SStefano Zampini PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, "color_is_0", FILE_MODE_READ, &view)); 2545042aa92SStefano Zampini PetscCall(MatLoad(A2, view)); 2555042aa92SStefano Zampini PetscCall(MatView(A2, PETSC_VIEWER_STDOUT_WORLD)); 2565042aa92SStefano Zampini PetscCall(PetscViewerDestroy(&view)); 2575042aa92SStefano Zampini 2585042aa92SStefano Zampini PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD)); 2595042aa92SStefano Zampini PetscCall(MatDestroy(&A2)); 2605042aa92SStefano Zampini 2615042aa92SStefano Zampini /* now load the original matrix from color 0 only processes */ 2625042aa92SStefano Zampini if (!color) { 2635042aa92SStefano Zampini PetscCall(PetscPrintf(comm, "Test subcomm MatLoad from world\n")); 2645042aa92SStefano Zampini PetscCall(MatCreate(comm, &A2)); 2655042aa92SStefano Zampini PetscCall(MatSetType(A2, MATIS)); 2665042aa92SStefano Zampini PetscCall(PetscViewerPushFormat(PETSC_VIEWER_STDOUT_(comm), PETSC_VIEWER_ASCII_INFO_DETAIL)); 2675042aa92SStefano Zampini PetscCall(PetscViewerBinaryOpen(comm, "world_is", FILE_MODE_READ, &view)); 2685042aa92SStefano Zampini PetscCall(MatLoad(A2, view)); 2695042aa92SStefano Zampini PetscCall(MatView(A2, PETSC_VIEWER_STDOUT_(comm))); 2705042aa92SStefano Zampini PetscCall(PetscViewerDestroy(&view)); 2715042aa92SStefano Zampini PetscCall(PetscViewerPopFormat(PETSC_VIEWER_STDOUT_(comm))); 2725042aa92SStefano Zampini PetscCall(MatDestroy(&A2)); 2735042aa92SStefano Zampini } 2745042aa92SStefano Zampini 2755042aa92SStefano Zampini PetscCallMPI(MPI_Comm_free(&comm)); 2765042aa92SStefano Zampini } 2775042aa92SStefano Zampini 278c4762a1bSJed Brown /* test MatDuplicate and MatAXPY */ 2799566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatDuplicate and MatAXPY\n")); 2809566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 2819566063dSJacob Faibussowitsch PetscCall(CheckMat(A, A2, PETSC_FALSE, "MatDuplicate and MatAXPY")); 282c4762a1bSJed Brown 283c4762a1bSJed Brown /* test MatConvert */ 2849566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatConvert_IS_XAIJ\n")); 2859566063dSJacob Faibussowitsch PetscCall(MatConvert(A2, MATAIJ, MAT_INITIAL_MATRIX, &B2)); 2869566063dSJacob Faibussowitsch PetscCall(CheckMat(B, B2, PETSC_TRUE, "MatConvert_IS_XAIJ MAT_INITIAL_MATRIX")); 2879566063dSJacob Faibussowitsch PetscCall(MatConvert(A2, MATAIJ, MAT_REUSE_MATRIX, &B2)); 2889566063dSJacob Faibussowitsch PetscCall(CheckMat(B, B2, PETSC_TRUE, "MatConvert_IS_XAIJ MAT_REUSE_MATRIX")); 2899566063dSJacob Faibussowitsch PetscCall(MatConvert(A2, MATAIJ, MAT_INPLACE_MATRIX, &A2)); 2909566063dSJacob Faibussowitsch PetscCall(CheckMat(B, A2, PETSC_TRUE, "MatConvert_IS_XAIJ MAT_INPLACE_MATRIX")); 2919566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 2929566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 2939566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatConvert_XAIJ_IS\n")); 2949566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2)); 2959566063dSJacob Faibussowitsch PetscCall(MatConvert(B2, MATIS, MAT_INITIAL_MATRIX, &A2)); 2969566063dSJacob Faibussowitsch PetscCall(CheckMat(A, A2, PETSC_TRUE, "MatConvert_XAIJ_IS MAT_INITIAL_MATRIX")); 2979566063dSJacob Faibussowitsch PetscCall(MatConvert(B2, MATIS, MAT_REUSE_MATRIX, &A2)); 2989566063dSJacob Faibussowitsch PetscCall(CheckMat(A, A2, PETSC_TRUE, "MatConvert_XAIJ_IS MAT_REUSE_MATRIX")); 2999566063dSJacob Faibussowitsch PetscCall(MatConvert(B2, MATIS, MAT_INPLACE_MATRIX, &B2)); 3009566063dSJacob Faibussowitsch PetscCall(CheckMat(A, B2, PETSC_TRUE, "MatConvert_XAIJ_IS MAT_INPLACE_MATRIX")); 3019566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 3029566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 3039566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(lmtype, MATSEQAIJ, &isaij)); 304c4762a1bSJed Brown if (size == 1 && isaij) { /* tests special code paths in MatConvert_IS_XAIJ */ 305c4762a1bSJed Brown PetscInt ri, ci, rr[3] = {0, 1, 0}, cr[4] = {1, 2, 0, 1}, rk[3] = {0, 2, 1}, ck[4] = {1, 0, 3, 2}; 306e432b41dSStefano Zampini ISLocalToGlobalMapping tcmap, trmap; 307c4762a1bSJed Brown 308c4762a1bSJed Brown for (ri = 0; ri < 2; ri++) { 309c4762a1bSJed Brown PetscInt *r; 310c4762a1bSJed Brown 311c4762a1bSJed Brown r = (PetscInt *)(ri == 0 ? rr : rk); 312c4762a1bSJed Brown for (ci = 0; ci < 2; ci++) { 313c4762a1bSJed Brown PetscInt *c, rb, cb; 314c4762a1bSJed Brown 315c4762a1bSJed Brown c = (PetscInt *)(ci == 0 ? cr : ck); 316c4762a1bSJed Brown for (rb = 1; rb < 4; rb++) { 3179566063dSJacob Faibussowitsch PetscCall(ISCreateBlock(PETSC_COMM_SELF, rb, 3, r, PETSC_COPY_VALUES, &is)); 3189566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(is, &trmap)); 3199566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 320c4762a1bSJed Brown for (cb = 1; cb < 4; cb++) { 321c4762a1bSJed Brown Mat T, lT, T2; 322c4762a1bSJed Brown char testname[256]; 323c4762a1bSJed Brown 3249566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(testname, sizeof(testname), "MatConvert_IS_XAIJ special case (%" PetscInt_FMT " %" PetscInt_FMT ", bs %" PetscInt_FMT " %" PetscInt_FMT ")", ri, ci, rb, cb)); 3259566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test %s\n", testname)); 326c4762a1bSJed Brown 3279566063dSJacob Faibussowitsch PetscCall(ISCreateBlock(PETSC_COMM_SELF, cb, 4, c, PETSC_COPY_VALUES, &is)); 3289566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(is, &tcmap)); 3299566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 330c4762a1bSJed Brown 3319566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_SELF, &T)); 3329566063dSJacob Faibussowitsch PetscCall(MatSetSizes(T, PETSC_DECIDE, PETSC_DECIDE, rb * 3, cb * 4)); 3339566063dSJacob Faibussowitsch PetscCall(MatSetType(T, MATIS)); 3349566063dSJacob Faibussowitsch PetscCall(MatSetLocalToGlobalMapping(T, trmap, tcmap)); 3359566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&tcmap)); 3369566063dSJacob Faibussowitsch PetscCall(MatISGetLocalMat(T, &lT)); 3379566063dSJacob Faibussowitsch PetscCall(MatSetType(lT, MATSEQAIJ)); 3389566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(lT, cb * 4, NULL)); 3399566063dSJacob Faibussowitsch PetscCall(MatSetRandom(lT, NULL)); 3409566063dSJacob Faibussowitsch PetscCall(MatConvert(lT, lmtype, MAT_INPLACE_MATRIX, &lT)); 3419566063dSJacob Faibussowitsch PetscCall(MatISRestoreLocalMat(T, &lT)); 3429566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(T, MAT_FINAL_ASSEMBLY)); 3439566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(T, MAT_FINAL_ASSEMBLY)); 344c4762a1bSJed Brown 3459566063dSJacob Faibussowitsch PetscCall(MatConvert(T, MATAIJ, MAT_INITIAL_MATRIX, &T2)); 3469566063dSJacob Faibussowitsch PetscCall(CheckMat(T, T2, PETSC_TRUE, "MAT_INITIAL_MATRIX")); 3479566063dSJacob Faibussowitsch PetscCall(MatConvert(T, MATAIJ, MAT_REUSE_MATRIX, &T2)); 3489566063dSJacob Faibussowitsch PetscCall(CheckMat(T, T2, PETSC_TRUE, "MAT_REUSE_MATRIX")); 3499566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T2)); 3509566063dSJacob Faibussowitsch PetscCall(MatDuplicate(T, MAT_COPY_VALUES, &T2)); 3519566063dSJacob Faibussowitsch PetscCall(MatConvert(T2, MATAIJ, MAT_INPLACE_MATRIX, &T2)); 3529566063dSJacob Faibussowitsch PetscCall(CheckMat(T, T2, PETSC_TRUE, "MAT_INPLACE_MATRIX")); 3539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T)); 3549566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T2)); 355c4762a1bSJed Brown } 3569566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&trmap)); 357c4762a1bSJed Brown } 358c4762a1bSJed Brown } 359c4762a1bSJed Brown } 360c4762a1bSJed Brown } 361c4762a1bSJed Brown 362c4762a1bSJed Brown /* test MatDiagonalScale */ 3639566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatDiagonalScale\n")); 3649566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 3659566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2)); 3669566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, &x, &y)); 3679566063dSJacob Faibussowitsch PetscCall(VecSetRandom(x, NULL)); 368e432b41dSStefano Zampini if (issymmetric) { 3699566063dSJacob Faibussowitsch PetscCall(VecCopy(x, y)); 370c4762a1bSJed Brown } else { 3719566063dSJacob Faibussowitsch PetscCall(VecSetRandom(y, NULL)); 3729566063dSJacob Faibussowitsch PetscCall(VecScale(y, 8.)); 373c4762a1bSJed Brown } 3749566063dSJacob Faibussowitsch PetscCall(MatDiagonalScale(A2, y, x)); 3759566063dSJacob Faibussowitsch PetscCall(MatDiagonalScale(B2, y, x)); 3769566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatDiagonalScale")); 3779566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 3789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 3799566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 3809566063dSJacob Faibussowitsch PetscCall(VecDestroy(&y)); 381c4762a1bSJed Brown 382c4762a1bSJed Brown /* test MatPtAP (A IS and B AIJ) */ 383c4762a1bSJed Brown if (isaij && m == n) { 3849566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatPtAP\n")); 3854f58015eSStefano Zampini /* There's a bug in MatCreateSubMatrices_MPIAIJ I cannot figure out */ 3864f58015eSStefano Zampini if (!allow_repeated || !repmap || size == 1) { 3879566063dSJacob Faibussowitsch PetscCall(MatISStoreL2L(A, PETSC_TRUE)); 388fb842aefSJose E. Roman PetscCall(MatPtAP(A, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &A2)); 389fb842aefSJose E. Roman PetscCall(MatPtAP(B, B, MAT_INITIAL_MATRIX, PETSC_DETERMINE, &B2)); 3909566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatPtAP MAT_INITIAL_MATRIX")); 391fb842aefSJose E. Roman PetscCall(MatPtAP(A, B, MAT_REUSE_MATRIX, PETSC_DETERMINE, &A2)); 3929566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatPtAP MAT_REUSE_MATRIX")); 3939566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 3949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 395c4762a1bSJed Brown } 3964f58015eSStefano Zampini } 397c4762a1bSJed Brown 398c4762a1bSJed Brown /* test MatGetLocalSubMatrix */ 3999566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatGetLocalSubMatrix\n")); 4009566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &A2)); 4019566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, lm / 2 + lm % 2, 0, 2, &reven)); 4029566063dSJacob Faibussowitsch PetscCall(ISComplement(reven, 0, lm, &rodd)); 4039566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_SELF, ln / 2 + ln % 2, 0, 2, &ceven)); 4049566063dSJacob Faibussowitsch PetscCall(ISComplement(ceven, 0, ln, &codd)); 4059566063dSJacob Faibussowitsch PetscCall(MatGetLocalSubMatrix(A2, reven, ceven, &Aee)); 4069566063dSJacob Faibussowitsch PetscCall(MatGetLocalSubMatrix(A2, reven, codd, &Aeo)); 4079566063dSJacob Faibussowitsch PetscCall(MatGetLocalSubMatrix(A2, rodd, ceven, &Aoe)); 4089566063dSJacob Faibussowitsch PetscCall(MatGetLocalSubMatrix(A2, rodd, codd, &Aoo)); 409e432b41dSStefano Zampini for (i = 0; i < lm; i++) { 410c4762a1bSJed Brown PetscInt j, je, jo, colse[3], colso[3]; 411c4762a1bSJed Brown PetscScalar ve[3], vo[3]; 412c4762a1bSJed Brown PetscScalar v[3]; 413c4762a1bSJed Brown PetscInt cols[3]; 414e432b41dSStefano Zampini PetscInt row = i / 2; 415c4762a1bSJed Brown 416c4762a1bSJed Brown cols[0] = (i - 1 + n) % n; 417c4762a1bSJed Brown cols[1] = i % n; 418c4762a1bSJed Brown cols[2] = (i + 1) % n; 419c4762a1bSJed Brown v[0] = -1. * (symmetric ? PetscMin(i + 1, cols[0] + 1) : i + 1); 420c4762a1bSJed Brown v[1] = 2. * (symmetric ? PetscMin(i + 1, cols[1] + 1) : i + 1); 421c4762a1bSJed Brown v[2] = -1. * (symmetric ? PetscMin(i + 1, cols[2] + 1) : i + 1); 4229566063dSJacob Faibussowitsch PetscCall(ISGlobalToLocalMappingApply(cmap, IS_GTOLM_MASK, 3, cols, NULL, cols)); 423c4762a1bSJed Brown for (j = 0, je = 0, jo = 0; j < 3; j++) { 424c4762a1bSJed Brown if (cols[j] % 2) { 425c4762a1bSJed Brown vo[jo] = v[j]; 426c4762a1bSJed Brown colso[jo++] = cols[j] / 2; 427c4762a1bSJed Brown } else { 428c4762a1bSJed Brown ve[je] = v[j]; 429c4762a1bSJed Brown colse[je++] = cols[j] / 2; 430c4762a1bSJed Brown } 431c4762a1bSJed Brown } 432c4762a1bSJed Brown if (i % 2) { 4339566063dSJacob Faibussowitsch PetscCall(MatSetValuesLocal(Aoe, 1, &row, je, colse, ve, ADD_VALUES)); 434*076fee34SStefano Zampini PetscCall(MatSetValuesBlockedLocal(Aoo, 1, &row, jo, colso, vo, ADD_VALUES)); 435c4762a1bSJed Brown } else { 4369566063dSJacob Faibussowitsch PetscCall(MatSetValuesLocal(Aee, 1, &row, je, colse, ve, ADD_VALUES)); 437*076fee34SStefano Zampini PetscCall(MatSetValuesBlockedLocal(Aeo, 1, &row, jo, colso, vo, ADD_VALUES)); 438c4762a1bSJed Brown } 439c4762a1bSJed Brown } 4409566063dSJacob Faibussowitsch PetscCall(MatRestoreLocalSubMatrix(A2, reven, ceven, &Aee)); 4419566063dSJacob Faibussowitsch PetscCall(MatRestoreLocalSubMatrix(A2, reven, codd, &Aeo)); 4429566063dSJacob Faibussowitsch PetscCall(MatRestoreLocalSubMatrix(A2, rodd, ceven, &Aoe)); 4439566063dSJacob Faibussowitsch PetscCall(MatRestoreLocalSubMatrix(A2, rodd, codd, &Aoo)); 4449566063dSJacob Faibussowitsch PetscCall(ISDestroy(&reven)); 4459566063dSJacob Faibussowitsch PetscCall(ISDestroy(&ceven)); 4469566063dSJacob Faibussowitsch PetscCall(ISDestroy(&rodd)); 4479566063dSJacob Faibussowitsch PetscCall(ISDestroy(&codd)); 4489566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY)); 4499566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY)); 4509566063dSJacob Faibussowitsch PetscCall(MatAXPY(A2, -1., A, SAME_NONZERO_PATTERN)); 4519566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, NULL, PETSC_FALSE, "MatGetLocalSubMatrix")); 4529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 453c4762a1bSJed Brown 454c4762a1bSJed Brown /* test MatConvert_Nest_IS */ 455c4762a1bSJed Brown testT = PETSC_FALSE; 4569566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_trans", &testT, NULL)); 457c4762a1bSJed Brown 4589566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatConvert_Nest_IS\n")); 459c4762a1bSJed Brown nr = 2; 460c4762a1bSJed Brown nc = 2; 4619566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-nr", &nr, NULL)); 4629566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-nc", &nc, NULL)); 463c4762a1bSJed Brown if (testT) { 4649566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &cst, &cen)); 4659566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRangeColumn(A, &rst, &ren)); 466c4762a1bSJed Brown } else { 4679566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(A, &rst, &ren)); 4689566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRangeColumn(A, &cst, &cen)); 469c4762a1bSJed Brown } 4709566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(nr, &rows, nc, &cols, 2 * nr * nc, &mats)); 471c4762a1bSJed Brown for (i = 0; i < nr * nc; i++) { 472c4762a1bSJed Brown if (testT) { 4739566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(A, &mats[i])); 4749566063dSJacob Faibussowitsch PetscCall(MatTranspose(B, MAT_INITIAL_MATRIX, &mats[i + nr * nc])); 475c4762a1bSJed Brown } else { 4769566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &mats[i])); 4779566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &mats[i + nr * nc])); 478c4762a1bSJed Brown } 479c4762a1bSJed Brown } 48048a46eb9SPierre Jolivet for (i = 0; i < nr; i++) PetscCall(ISCreateStride(PETSC_COMM_WORLD, ren - rst, i + rst, nr, &rows[i])); 48148a46eb9SPierre Jolivet for (i = 0; i < nc; i++) PetscCall(ISCreateStride(PETSC_COMM_WORLD, cen - cst, i + cst, nc, &cols[i])); 4829566063dSJacob Faibussowitsch PetscCall(MatCreateNest(PETSC_COMM_WORLD, nr, rows, nc, cols, mats, &A2)); 4839566063dSJacob Faibussowitsch PetscCall(MatCreateNest(PETSC_COMM_WORLD, nr, rows, nc, cols, mats + nr * nc, &B2)); 48448a46eb9SPierre Jolivet for (i = 0; i < nr; i++) PetscCall(ISDestroy(&rows[i])); 48548a46eb9SPierre Jolivet for (i = 0; i < nc; i++) PetscCall(ISDestroy(&cols[i])); 48648a46eb9SPierre Jolivet for (i = 0; i < 2 * nr * nc; i++) PetscCall(MatDestroy(&mats[i])); 4879566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, cols, mats)); 4889566063dSJacob Faibussowitsch PetscCall(MatConvert(B2, MATAIJ, MAT_INITIAL_MATRIX, &T)); 4899566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 4909566063dSJacob Faibussowitsch PetscCall(MatConvert(A2, MATIS, MAT_INITIAL_MATRIX, &B2)); 4919566063dSJacob Faibussowitsch PetscCall(CheckMat(B2, T, PETSC_TRUE, "MatConvert_Nest_IS MAT_INITIAL_MATRIX")); 4929566063dSJacob Faibussowitsch PetscCall(MatConvert(A2, MATIS, MAT_REUSE_MATRIX, &B2)); 4939566063dSJacob Faibussowitsch PetscCall(CheckMat(B2, T, PETSC_TRUE, "MatConvert_Nest_IS MAT_REUSE_MATRIX")); 4949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 4959566063dSJacob Faibussowitsch PetscCall(MatConvert(A2, MATIS, MAT_INPLACE_MATRIX, &A2)); 4969566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, T, PETSC_TRUE, "MatConvert_Nest_IS MAT_INPLACE_MATRIX")); 4979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&T)); 4989566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 499c4762a1bSJed Brown 500c4762a1bSJed Brown /* test MatCreateSubMatrix */ 5019566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatCreateSubMatrix\n")); 502dd400576SPatrick Sanan if (rank == 0) { 5039566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 1, 1, 1, &is)); 5049566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 2, 0, 1, &is2)); 505c4762a1bSJed Brown } else if (rank == 1) { 5069566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 1, 0, 1, &is)); 507c4762a1bSJed Brown if (n > 3) { 5089566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 1, 3, 1, &is2)); 509c4762a1bSJed Brown } else { 5109566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is2)); 511c4762a1bSJed Brown } 512c4762a1bSJed Brown } else if (rank == 2 && n > 4) { 5139566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is)); 5149566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, n - 4, 4, 1, &is2)); 515c4762a1bSJed Brown } else { 5169566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is)); 5179566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is2)); 518c4762a1bSJed Brown } 5199566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(A, is, is, MAT_INITIAL_MATRIX, &A2)); 5209566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(B, is, is, MAT_INITIAL_MATRIX, &B2)); 5219566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_TRUE, "first MatCreateSubMatrix")); 522c4762a1bSJed Brown 5239566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(A, is, is, MAT_REUSE_MATRIX, &A2)); 5249566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(B, is, is, MAT_REUSE_MATRIX, &B2)); 5259566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "reuse MatCreateSubMatrix")); 5269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 5279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 528c4762a1bSJed Brown 529e432b41dSStefano Zampini if (!issymmetric) { 5309566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(A, is, is2, MAT_INITIAL_MATRIX, &A2)); 5319566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(B, is, is2, MAT_INITIAL_MATRIX, &B2)); 5329566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(A, is, is2, MAT_REUSE_MATRIX, &A2)); 5339566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix(B, is, is2, MAT_REUSE_MATRIX, &B2)); 5349566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "second MatCreateSubMatrix")); 535c4762a1bSJed Brown } 536c4762a1bSJed Brown 5379566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 5389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 5399566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 5409566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is2)); 541c4762a1bSJed Brown 542d0dbe9f7SStefano Zampini /* test MatCreateSubMatrices */ 543d0dbe9f7SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatCreateSubMatrices\n")); 544d0dbe9f7SStefano Zampini PetscCall(MatGetLayouts(A, &rlayout, &clayout)); 545d0dbe9f7SStefano Zampini PetscCall(PetscLayoutGetRanges(rlayout, &rrange)); 546d0dbe9f7SStefano Zampini PetscCall(PetscLayoutGetRanges(clayout, &crange)); 547d0dbe9f7SStefano Zampini lrank = (size + rank - 1) % size; 548d0dbe9f7SStefano Zampini rrank = (rank + 1) % size; 54957508eceSPierre Jolivet PetscCall(ISCreateStride(PETSC_COMM_SELF, rrange[lrank + 1] - rrange[lrank], rrange[lrank], 1, &irow[0])); 55057508eceSPierre Jolivet PetscCall(ISCreateStride(PETSC_COMM_SELF, crange[rrank + 1] - crange[rrank], crange[rrank], 1, &icol[0])); 55157508eceSPierre Jolivet PetscCall(ISCreateStride(PETSC_COMM_SELF, rrange[rrank + 1] - rrange[rrank], rrange[rrank], 1, &irow[1])); 55257508eceSPierre Jolivet PetscCall(ISCreateStride(PETSC_COMM_SELF, crange[lrank + 1] - crange[lrank], crange[lrank], 1, &icol[1])); 553d0dbe9f7SStefano Zampini PetscCall(MatCreateSubMatrices(A, 2, irow, icol, MAT_INITIAL_MATRIX, &Asub)); 554d0dbe9f7SStefano Zampini PetscCall(MatCreateSubMatrices(B, 2, irow, icol, MAT_INITIAL_MATRIX, &Bsub)); 555d0dbe9f7SStefano Zampini PetscCall(CheckMat(Asub[0], Bsub[0], PETSC_FALSE, "MatCreateSubMatrices[0]")); 556d0dbe9f7SStefano Zampini PetscCall(CheckMat(Asub[1], Bsub[1], PETSC_FALSE, "MatCreateSubMatrices[1]")); 557d0dbe9f7SStefano Zampini PetscCall(MatCreateSubMatrices(A, 2, irow, icol, MAT_REUSE_MATRIX, &Asub)); 558d0dbe9f7SStefano Zampini PetscCall(MatCreateSubMatrices(B, 2, irow, icol, MAT_REUSE_MATRIX, &Bsub)); 559d0dbe9f7SStefano Zampini PetscCall(CheckMat(Asub[0], Bsub[0], PETSC_FALSE, "MatCreateSubMatrices[0]")); 560d0dbe9f7SStefano Zampini PetscCall(CheckMat(Asub[1], Bsub[1], PETSC_FALSE, "MatCreateSubMatrices[1]")); 561d0dbe9f7SStefano Zampini PetscCall(MatDestroySubMatrices(2, &Asub)); 562d0dbe9f7SStefano Zampini PetscCall(MatDestroySubMatrices(2, &Bsub)); 563d0dbe9f7SStefano Zampini PetscCall(ISDestroy(&irow[0])); 564d0dbe9f7SStefano Zampini PetscCall(ISDestroy(&irow[1])); 565d0dbe9f7SStefano Zampini PetscCall(ISDestroy(&icol[0])); 566d0dbe9f7SStefano Zampini PetscCall(ISDestroy(&icol[1])); 567d0dbe9f7SStefano Zampini 568c4762a1bSJed Brown /* Create an IS required by MatZeroRows(): just rank zero provides the rows to be eliminated */ 569c4762a1bSJed Brown if (size > 1) { 570dd400576SPatrick Sanan if (rank == 0) { 571c4762a1bSJed Brown PetscInt st, len; 572c4762a1bSJed Brown 573c4762a1bSJed Brown st = (m + 1) / 2; 574c4762a1bSJed Brown len = PetscMin(m / 2, PetscMax(m - (m + 1) / 2 - 1, 0)); 5759566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, len, st, 1, &is)); 576c4762a1bSJed Brown } else { 5779566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is)); 578c4762a1bSJed Brown } 579c4762a1bSJed Brown } else { 5809566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, 1, 0, 1, &is)); 581c4762a1bSJed Brown } 5820d2733adSStefano Zampini /* local IS for local zero operations */ 5830d2733adSStefano Zampini PetscCall(ISLocalToGlobalMappingGetSize(rmap, &lm)); 5840d2733adSStefano Zampini PetscCall(ISCreateStride(PETSC_COMM_WORLD, lm ? 1 : 0, 0, 1, &lis)); 585c4762a1bSJed Brown 586c4762a1bSJed Brown if (squaretest) { /* tests for square matrices only, with same maps for rows and columns */ 587d0dbe9f7SStefano Zampini PetscInt *idx0, *idx1, n0, n1; 588d0dbe9f7SStefano Zampini IS Ais[2], Bis[2]; 589d0dbe9f7SStefano Zampini 590c4762a1bSJed Brown /* test MatDiagonalSet */ 5919566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatDiagonalSet\n")); 5929566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 5939566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2)); 5949566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, NULL, &x)); 5959566063dSJacob Faibussowitsch PetscCall(VecSetRandom(x, NULL)); 5964f58015eSStefano Zampini PetscCall(MatDiagonalSet(A2, x, allow_repeated ? ADD_VALUES : INSERT_VALUES)); 5974f58015eSStefano Zampini PetscCall(MatDiagonalSet(B2, x, allow_repeated ? ADD_VALUES : INSERT_VALUES)); 5989566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatDiagonalSet")); 5999566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 6009566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 6019566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 602c4762a1bSJed Brown 603c4762a1bSJed Brown /* test MatShift (MatShift_IS internally uses MatDiagonalSet_IS with ADD_VALUES) */ 6049566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatShift\n")); 6059566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 6069566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2)); 6079566063dSJacob Faibussowitsch PetscCall(MatShift(A2, 2.0)); 6089566063dSJacob Faibussowitsch PetscCall(MatShift(B2, 2.0)); 6099566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatShift")); 6109566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 6119566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 612c4762a1bSJed Brown 613c4762a1bSJed Brown /* nonzero diag value is supported for square matrices only */ 6140d2733adSStefano Zampini PetscCall(TestMatZeroRows(A, B, PETSC_TRUE, is, diag, PETSC_FALSE)); 6150d2733adSStefano Zampini PetscCall(TestMatZeroRows(A, B, PETSC_TRUE, lis, diag, PETSC_TRUE)); 616d0dbe9f7SStefano Zampini 617d0dbe9f7SStefano Zampini /* test MatIncreaseOverlap */ 618d0dbe9f7SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatIncreaseOverlap\n")); 619d0dbe9f7SStefano Zampini PetscCall(MatGetOwnershipRange(A, &rst, &ren)); 620d0dbe9f7SStefano Zampini n0 = (ren - rst) / 2; 621d0dbe9f7SStefano Zampini n1 = (ren - rst) / 3; 622d0dbe9f7SStefano Zampini PetscCall(PetscMalloc1(n0, &idx0)); 623d0dbe9f7SStefano Zampini PetscCall(PetscMalloc1(n1, &idx1)); 624d0dbe9f7SStefano Zampini for (i = 0; i < n0; i++) idx0[i] = ren - i - 1; 625d0dbe9f7SStefano Zampini for (i = 0; i < n1; i++) idx1[i] = rst + i; 626d0dbe9f7SStefano Zampini PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n0, idx0, PETSC_OWN_POINTER, &Ais[0])); 627d0dbe9f7SStefano Zampini PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n1, idx1, PETSC_OWN_POINTER, &Ais[1])); 628d0dbe9f7SStefano Zampini PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n0, idx0, PETSC_COPY_VALUES, &Bis[0])); 629d0dbe9f7SStefano Zampini PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n1, idx1, PETSC_COPY_VALUES, &Bis[1])); 630d0dbe9f7SStefano Zampini PetscCall(MatIncreaseOverlap(A, 2, Ais, 3)); 631d0dbe9f7SStefano Zampini PetscCall(MatIncreaseOverlap(B, 2, Bis, 3)); 632d0dbe9f7SStefano Zampini /* Non deterministic output! */ 633d0dbe9f7SStefano Zampini PetscCall(ISSort(Ais[0])); 634d0dbe9f7SStefano Zampini PetscCall(ISSort(Ais[1])); 635d0dbe9f7SStefano Zampini PetscCall(ISSort(Bis[0])); 636d0dbe9f7SStefano Zampini PetscCall(ISSort(Bis[1])); 637d0dbe9f7SStefano Zampini PetscCall(ISView(Ais[0], NULL)); 638d0dbe9f7SStefano Zampini PetscCall(ISView(Bis[0], NULL)); 639d0dbe9f7SStefano Zampini PetscCall(ISView(Ais[1], NULL)); 640d0dbe9f7SStefano Zampini PetscCall(ISView(Bis[1], NULL)); 641d0dbe9f7SStefano Zampini PetscCall(MatCreateSubMatrices(A, 2, Ais, Ais, MAT_INITIAL_MATRIX, &Asub)); 642d0dbe9f7SStefano Zampini PetscCall(MatCreateSubMatrices(B, 2, Bis, Ais, MAT_INITIAL_MATRIX, &Bsub)); 643d0dbe9f7SStefano Zampini PetscCall(CheckMat(Asub[0], Bsub[0], PETSC_FALSE, "MatIncreaseOverlap[0]")); 644d0dbe9f7SStefano Zampini PetscCall(CheckMat(Asub[1], Bsub[1], PETSC_FALSE, "MatIncreaseOverlap[1]")); 645d0dbe9f7SStefano Zampini PetscCall(MatDestroySubMatrices(2, &Asub)); 646d0dbe9f7SStefano Zampini PetscCall(MatDestroySubMatrices(2, &Bsub)); 647d0dbe9f7SStefano Zampini PetscCall(ISDestroy(&Ais[0])); 648d0dbe9f7SStefano Zampini PetscCall(ISDestroy(&Ais[1])); 649d0dbe9f7SStefano Zampini PetscCall(ISDestroy(&Bis[0])); 650d0dbe9f7SStefano Zampini PetscCall(ISDestroy(&Bis[1])); 651c4762a1bSJed Brown } 6520d2733adSStefano Zampini PetscCall(TestMatZeroRows(A, B, squaretest, is, 0.0, PETSC_FALSE)); 6530d2733adSStefano Zampini PetscCall(TestMatZeroRows(A, B, squaretest, lis, 0.0, PETSC_TRUE)); 6549566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 6550d2733adSStefano Zampini PetscCall(ISDestroy(&lis)); 656c4762a1bSJed Brown 657c4762a1bSJed Brown /* test MatTranspose */ 6589566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatTranspose\n")); 6599566063dSJacob Faibussowitsch PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &A2)); 6609566063dSJacob Faibussowitsch PetscCall(MatTranspose(B, MAT_INITIAL_MATRIX, &B2)); 6619566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "initial matrix MatTranspose")); 662c4762a1bSJed Brown 6639566063dSJacob Faibussowitsch PetscCall(MatTranspose(A, MAT_REUSE_MATRIX, &A2)); 6649566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "reuse matrix (not in place) MatTranspose")); 6659566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 666c4762a1bSJed Brown 6679566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 6689566063dSJacob Faibussowitsch PetscCall(MatTranspose(A2, MAT_INPLACE_MATRIX, &A2)); 6699566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "reuse matrix (in place) MatTranspose")); 6709566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 671c4762a1bSJed Brown 6729566063dSJacob Faibussowitsch PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &A2)); 6739566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "reuse matrix (different type) MatTranspose")); 6749566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 6759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 676c4762a1bSJed Brown 677c4762a1bSJed Brown /* test MatISFixLocalEmpty */ 678c4762a1bSJed Brown if (isaij) { 679c4762a1bSJed Brown PetscInt r[2]; 680c4762a1bSJed Brown 681c4762a1bSJed Brown r[0] = 0; 682c4762a1bSJed Brown r[1] = PetscMin(m, n) - 1; 6839566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatISFixLocalEmpty\n")); 6849566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 685e432b41dSStefano Zampini 6869566063dSJacob Faibussowitsch PetscCall(MatISFixLocalEmpty(A2, PETSC_TRUE)); 6879566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY)); 6889566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY)); 6899566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B, PETSC_FALSE, "MatISFixLocalEmpty (null)")); 690c4762a1bSJed Brown 6919566063dSJacob Faibussowitsch PetscCall(MatZeroRows(A2, 2, r, 0.0, NULL, NULL)); 6929566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view")); 6939566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2)); 6949566063dSJacob Faibussowitsch PetscCall(MatZeroRows(B2, 2, r, 0.0, NULL, NULL)); 6959566063dSJacob Faibussowitsch PetscCall(MatISFixLocalEmpty(A2, PETSC_TRUE)); 6969566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY)); 6979566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY)); 6989566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view")); 6999566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatISFixLocalEmpty (rows)")); 7009566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 701c4762a1bSJed Brown 7029566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 7039566063dSJacob Faibussowitsch PetscCall(MatZeroRows(A2, 2, r, 0.0, NULL, NULL)); 7049566063dSJacob Faibussowitsch PetscCall(MatTranspose(A2, MAT_INPLACE_MATRIX, &A2)); 7059566063dSJacob Faibussowitsch PetscCall(MatTranspose(B2, MAT_INPLACE_MATRIX, &B2)); 7069566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view")); 7079566063dSJacob Faibussowitsch PetscCall(MatISFixLocalEmpty(A2, PETSC_TRUE)); 7089566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY)); 7099566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY)); 7109566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view")); 7119566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatISFixLocalEmpty (cols)")); 712c4762a1bSJed Brown 7139566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 7149566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 715c4762a1bSJed Brown 716c4762a1bSJed Brown if (squaretest) { 7179566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 7189566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2)); 7199566063dSJacob Faibussowitsch PetscCall(MatZeroRowsColumns(A2, 2, r, 0.0, NULL, NULL)); 7209566063dSJacob Faibussowitsch PetscCall(MatZeroRowsColumns(B2, 2, r, 0.0, NULL, NULL)); 7219566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view")); 7229566063dSJacob Faibussowitsch PetscCall(MatISFixLocalEmpty(A2, PETSC_TRUE)); 7239566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY)); 7249566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY)); 7259566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view")); 7269566063dSJacob Faibussowitsch PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatISFixLocalEmpty (rows+cols)")); 7279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A2)); 7289566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 729c4762a1bSJed Brown } 730c4762a1bSJed Brown } 731c4762a1bSJed Brown 732c4762a1bSJed Brown /* test MatInvertBlockDiagonal 733c4762a1bSJed Brown special cases for block-diagonal matrices */ 734c4762a1bSJed Brown if (m == n) { 735c4762a1bSJed Brown ISLocalToGlobalMapping map; 736c4762a1bSJed Brown Mat Abd, Bbd; 737c4762a1bSJed Brown IS is, bis; 738c4762a1bSJed Brown const PetscScalar *isbd, *aijbd; 739c4762a1bSJed Brown const PetscInt *sts, *idxs; 740c4762a1bSJed Brown PetscInt *idxs2, diff, perm, nl, bs, st, en, in; 741c4762a1bSJed Brown PetscBool ok; 742c4762a1bSJed Brown 743c4762a1bSJed Brown for (diff = 0; diff < 3; diff++) { 744c4762a1bSJed Brown for (perm = 0; perm < 3; perm++) { 745c4762a1bSJed Brown for (bs = 1; bs < 4; bs++) { 7469566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatInvertBlockDiagonal blockdiag %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n", n, diff, perm, bs)); 7479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bs * bs, &vals)); 7489566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRanges(A, &sts)); 749c4762a1bSJed Brown switch (diff) { 750c4762a1bSJed Brown case 1: /* inverted layout by processes */ 751c4762a1bSJed Brown in = 1; 752c4762a1bSJed Brown st = sts[size - rank - 1]; 753c4762a1bSJed Brown en = sts[size - rank]; 754c4762a1bSJed Brown nl = en - st; 755c4762a1bSJed Brown break; 756c4762a1bSJed Brown case 2: /* round-robin layout */ 757c4762a1bSJed Brown in = size; 758c4762a1bSJed Brown st = rank; 759c4762a1bSJed Brown nl = n / size; 760c4762a1bSJed Brown if (rank < n % size) nl++; 761c4762a1bSJed Brown break; 762c4762a1bSJed Brown default: /* same layout */ 763c4762a1bSJed Brown in = 1; 764c4762a1bSJed Brown st = sts[rank]; 765c4762a1bSJed Brown en = sts[rank + 1]; 766c4762a1bSJed Brown nl = en - st; 767c4762a1bSJed Brown break; 768c4762a1bSJed Brown } 7699566063dSJacob Faibussowitsch PetscCall(ISCreateStride(PETSC_COMM_WORLD, nl, st, in, &is)); 7709566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &nl)); 7719566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &idxs)); 7729566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nl, &idxs2)); 773c4762a1bSJed Brown for (i = 0; i < nl; i++) { 774c4762a1bSJed Brown switch (perm) { /* invert some of the indices */ 775d71ae5a4SJacob Faibussowitsch case 2: 776d71ae5a4SJacob Faibussowitsch idxs2[i] = rank % 2 ? idxs[i] : idxs[nl - i - 1]; 777d71ae5a4SJacob Faibussowitsch break; 778d71ae5a4SJacob Faibussowitsch case 1: 779d71ae5a4SJacob Faibussowitsch idxs2[i] = rank % 2 ? idxs[nl - i - 1] : idxs[i]; 780d71ae5a4SJacob Faibussowitsch break; 781d71ae5a4SJacob Faibussowitsch default: 782d71ae5a4SJacob Faibussowitsch idxs2[i] = idxs[i]; 783d71ae5a4SJacob Faibussowitsch break; 784c4762a1bSJed Brown } 785c4762a1bSJed Brown } 7869566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is, &idxs)); 7879566063dSJacob Faibussowitsch PetscCall(ISCreateBlock(PETSC_COMM_WORLD, bs, nl, idxs2, PETSC_OWN_POINTER, &bis)); 7889566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingCreateIS(bis, &map)); 7899566063dSJacob Faibussowitsch PetscCall(MatCreateIS(PETSC_COMM_WORLD, bs, PETSC_DECIDE, PETSC_DECIDE, bs * n, bs * n, map, map, &Abd)); 7909566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&map)); 7919566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(Abd, bs, NULL, 0, NULL)); 792c4762a1bSJed Brown for (i = 0; i < nl; i++) { 793c4762a1bSJed Brown PetscInt b1, b2; 794c4762a1bSJed Brown 795c4762a1bSJed Brown for (b1 = 0; b1 < bs; b1++) { 796ad540459SPierre Jolivet for (b2 = 0; b2 < bs; b2++) vals[b1 * bs + b2] = i * bs * bs + b1 * bs + b2 + 1 + (b1 == b2 ? 1.0 : 0); 797c4762a1bSJed Brown } 7989566063dSJacob Faibussowitsch PetscCall(MatSetValuesBlockedLocal(Abd, 1, &i, 1, &i, vals, INSERT_VALUES)); 799c4762a1bSJed Brown } 8009566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(Abd, MAT_FINAL_ASSEMBLY)); 8019566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(Abd, MAT_FINAL_ASSEMBLY)); 8029566063dSJacob Faibussowitsch PetscCall(MatConvert(Abd, MATAIJ, MAT_INITIAL_MATRIX, &Bbd)); 8039566063dSJacob Faibussowitsch PetscCall(MatInvertBlockDiagonal(Abd, &isbd)); 8049566063dSJacob Faibussowitsch PetscCall(MatInvertBlockDiagonal(Bbd, &aijbd)); 8059566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(Bbd, &nl, NULL)); 806c4762a1bSJed Brown ok = PETSC_TRUE; 807c4762a1bSJed Brown for (i = 0; i < nl / bs; i++) { 808c4762a1bSJed Brown PetscInt b1, b2; 809c4762a1bSJed Brown 810c4762a1bSJed Brown for (b1 = 0; b1 < bs; b1++) { 811c4762a1bSJed Brown for (b2 = 0; b2 < bs; b2++) { 812c4762a1bSJed Brown if (PetscAbsScalar(isbd[i * bs * bs + b1 * bs + b2] - aijbd[i * bs * bs + b1 * bs + b2]) > PETSC_SMALL) ok = PETSC_FALSE; 813c4762a1bSJed Brown if (!ok) { 8149566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] ERROR block %" PetscInt_FMT ", entry %" PetscInt_FMT " %" PetscInt_FMT ": %g %g\n", rank, i, b1, b2, (double)PetscAbsScalar(isbd[i * bs * bs + b1 * bs + b2]), (double)PetscAbsScalar(aijbd[i * bs * bs + b1 * bs + b2]))); 815c4762a1bSJed Brown break; 816c4762a1bSJed Brown } 817c4762a1bSJed Brown } 818c4762a1bSJed Brown if (!ok) break; 819c4762a1bSJed Brown } 820c4762a1bSJed Brown if (!ok) break; 821c4762a1bSJed Brown } 8229566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Abd)); 8239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bbd)); 8249566063dSJacob Faibussowitsch PetscCall(PetscFree(vals)); 8259566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is)); 8269566063dSJacob Faibussowitsch PetscCall(ISDestroy(&bis)); 827c4762a1bSJed Brown } 828c4762a1bSJed Brown } 829c4762a1bSJed Brown } 830c4762a1bSJed Brown } 831d0dbe9f7SStefano Zampini 832d0dbe9f7SStefano Zampini /* test MatGetDiagonalBlock */ 833d0dbe9f7SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatGetDiagonalBlock\n")); 834d0dbe9f7SStefano Zampini PetscCall(MatGetDiagonalBlock(A, &A2)); 835d0dbe9f7SStefano Zampini PetscCall(MatGetDiagonalBlock(B, &B2)); 836d0dbe9f7SStefano Zampini PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatGetDiagonalBlock")); 837d0dbe9f7SStefano Zampini PetscCall(MatScale(A, 2.0)); 838d0dbe9f7SStefano Zampini PetscCall(MatScale(B, 2.0)); 839d0dbe9f7SStefano Zampini PetscCall(MatGetDiagonalBlock(A, &A2)); 840d0dbe9f7SStefano Zampini PetscCall(MatGetDiagonalBlock(B, &B2)); 841d0dbe9f7SStefano Zampini PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatGetDiagonalBlock")); 842d0dbe9f7SStefano Zampini 8434f58015eSStefano Zampini /* test MatISSetAllowRepeated on a MATIS */ 8444f58015eSStefano Zampini PetscCall(MatISSetAllowRepeated(A, allow_repeated)); 8454f58015eSStefano Zampini if (allow_repeated) { /* original MATIS maybe with repeated entries, test assembling of local matrices */ 8464f58015eSStefano Zampini Mat lA, lA2; 8474f58015eSStefano Zampini 8484f58015eSStefano Zampini for (PetscInt i = 0; i < 1; i++) { /* TODO: make MatScatter inherit from MATSHELL and support MatProducts */ 8494f58015eSStefano Zampini PetscBool usemult = PETSC_FALSE; 8504f58015eSStefano Zampini 8514f58015eSStefano Zampini PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 8524f58015eSStefano Zampini if (i) { 8534f58015eSStefano Zampini Mat tA; 8544f58015eSStefano Zampini 8554f58015eSStefano Zampini usemult = PETSC_TRUE; 8564f58015eSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatISSetAllowRepeated(false) with possibly repeated entries and local shell matrices\n")); 8574f58015eSStefano Zampini PetscCall(MatISGetLocalMat(A2, &lA2)); 8584f58015eSStefano Zampini PetscCall(MatConvert(lA2, MATSHELL, MAT_INITIAL_MATRIX, &tA)); 8594f58015eSStefano Zampini PetscCall(MatISRestoreLocalMat(A2, &lA2)); 8604f58015eSStefano Zampini PetscCall(MatISSetLocalMat(A2, tA)); 8614f58015eSStefano Zampini PetscCall(MatDestroy(&tA)); 8624f58015eSStefano Zampini } else { 8634f58015eSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatISSetAllowRepeated(false) with possibly repeated entries\n")); 8644f58015eSStefano Zampini } 8654f58015eSStefano Zampini PetscCall(MatISSetAllowRepeated(A2, PETSC_FALSE)); 8664f58015eSStefano Zampini PetscCall(MatISGetLocalMat(A, &lA)); 8674f58015eSStefano Zampini PetscCall(MatISGetLocalMat(A2, &lA2)); 8684f58015eSStefano Zampini if (!repmap) PetscCall(CheckMat(lA, lA2, usemult, "MatISSetAllowRepeated(false) with non-repeated entries")); 8694f58015eSStefano Zampini PetscCall(MatISRestoreLocalMat(A, &lA)); 8704f58015eSStefano Zampini PetscCall(MatISRestoreLocalMat(A2, &lA2)); 8714f58015eSStefano Zampini if (repmap) PetscCall(CheckMat(A2, B, usemult, "MatISSetAllowRepeated(false) with repeated entries")); 8724f58015eSStefano Zampini else PetscCall(CheckMat(A2, B, usemult, "MatISSetAllowRepeated(false) with non-repeated entries")); 8734f58015eSStefano Zampini PetscCall(MatDestroy(&A2)); 8744f58015eSStefano Zampini } 8754f58015eSStefano Zampini } else { /* original matis with non-repeated entries, this should only recreate the local matrices */ 8764f58015eSStefano Zampini Mat lA; 8774f58015eSStefano Zampini PetscBool flg; 8784f58015eSStefano Zampini 8794f58015eSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatISSetAllowRepeated(true) with non repeated entries\n")); 8804f58015eSStefano Zampini PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2)); 8814f58015eSStefano Zampini PetscCall(MatISSetAllowRepeated(A2, PETSC_TRUE)); 8824f58015eSStefano Zampini PetscCall(MatISGetLocalMat(A2, &lA)); 8834f58015eSStefano Zampini PetscCall(MatAssembled(lA, &flg)); 8844f58015eSStefano Zampini PetscCheck(!flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local mat should be unassembled"); 8854f58015eSStefano Zampini PetscCall(MatISRestoreLocalMat(A2, &lA)); 8864f58015eSStefano Zampini PetscCall(MatDestroy(&A2)); 8874f58015eSStefano Zampini } 8884f58015eSStefano Zampini 88984a95373SStefano Zampini /* Test MatZeroEntries */ 89084a95373SStefano Zampini PetscCall(MatZeroEntries(A)); 89184a95373SStefano Zampini PetscCall(MatZeroEntries(B)); 89284a95373SStefano Zampini PetscCall(CheckMat(A, B, PETSC_FALSE, "MatZeroEntries")); 89384a95373SStefano Zampini 89484a95373SStefano Zampini /* Test MatSetValues and MatSetValuesBlocked */ 89584a95373SStefano Zampini if (test_setvalues) { 89684a95373SStefano Zampini PetscCall(PetscMalloc1(lm * ln, &vals)); 89784a95373SStefano Zampini for (i = 0; i < lm * ln; i++) vals[i] = i + 1.0; 89884a95373SStefano Zampini PetscCall(MatGetLocalSize(A, NULL, &ln)); 89984a95373SStefano Zampini PetscCall(MatISSetPreallocation(A, ln, NULL, n - ln, NULL)); 90084a95373SStefano Zampini PetscCall(MatSeqAIJSetPreallocation(B, ln, NULL)); 90184a95373SStefano Zampini PetscCall(MatMPIAIJSetPreallocation(B, ln, NULL, n - ln, NULL)); 90284a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingGetSize(rmap, &lm)); 90384a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingGetSize(cmap, &ln)); 90484a95373SStefano Zampini 90584a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingGetIndices(rmap, &idxs1)); 90684a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingGetIndices(cmap, &idxs2)); 90784a95373SStefano Zampini PetscCall(MatSetValues(A, lm, idxs1, ln, idxs2, vals, ADD_VALUES)); 90884a95373SStefano Zampini PetscCall(MatSetValues(B, lm, idxs1, ln, idxs2, vals, ADD_VALUES)); 90984a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingRestoreIndices(rmap, &idxs1)); 91084a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingRestoreIndices(cmap, &idxs2)); 91184a95373SStefano Zampini PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 91284a95373SStefano Zampini PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 91384a95373SStefano Zampini PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 91484a95373SStefano Zampini PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 91584a95373SStefano Zampini PetscCall(CheckMat(A, B, PETSC_FALSE, "MatSetValues")); 91684a95373SStefano Zampini 91784a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingGetBlockIndices(rmap, &idxs1)); 91884a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingGetBlockIndices(cmap, &idxs2)); 91984a95373SStefano Zampini PetscCall(MatSetValuesBlocked(A, lm / rbs, idxs1, ln / cbs, idxs2, vals, ADD_VALUES)); 92084a95373SStefano Zampini PetscCall(MatSetValuesBlocked(B, lm / rbs, idxs1, ln / cbs, idxs2, vals, ADD_VALUES)); 92184a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingRestoreBlockIndices(rmap, &idxs1)); 92284a95373SStefano Zampini PetscCall(ISLocalToGlobalMappingRestoreBlockIndices(cmap, &idxs2)); 92384a95373SStefano Zampini PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 92484a95373SStefano Zampini PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 92584a95373SStefano Zampini PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 92684a95373SStefano Zampini PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 92784a95373SStefano Zampini PetscCall(CheckMat(A, B, PETSC_FALSE, "MatSetValuesBlocked")); 92884a95373SStefano Zampini PetscCall(PetscFree(vals)); 92984a95373SStefano Zampini } 93084a95373SStefano Zampini 931c4762a1bSJed Brown /* free testing matrices */ 9329566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&cmap)); 9339566063dSJacob Faibussowitsch PetscCall(ISLocalToGlobalMappingDestroy(&rmap)); 9349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 9359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 9369566063dSJacob Faibussowitsch PetscCall(PetscFinalize()); 937b122ec5aSJacob Faibussowitsch return 0; 938c4762a1bSJed Brown } 939c4762a1bSJed Brown 940d71ae5a4SJacob Faibussowitsch PetscErrorCode CheckMat(Mat A, Mat B, PetscBool usemult, const char *func) 941d71ae5a4SJacob Faibussowitsch { 942c4762a1bSJed Brown Mat Bcheck; 943c4762a1bSJed Brown PetscReal error; 944c4762a1bSJed Brown 945c4762a1bSJed Brown PetscFunctionBeginUser; 946c4762a1bSJed Brown if (!usemult && B) { 947c4762a1bSJed Brown PetscBool hasnorm; 948c4762a1bSJed Brown 9499566063dSJacob Faibussowitsch PetscCall(MatHasOperation(B, MATOP_NORM, &hasnorm)); 950c4762a1bSJed Brown if (!hasnorm) usemult = PETSC_TRUE; 951c4762a1bSJed Brown } 952c4762a1bSJed Brown if (!usemult) { 953c4762a1bSJed Brown if (B) { 954c4762a1bSJed Brown MatType Btype; 955c4762a1bSJed Brown 9569566063dSJacob Faibussowitsch PetscCall(MatGetType(B, &Btype)); 9579566063dSJacob Faibussowitsch PetscCall(MatConvert(A, Btype, MAT_INITIAL_MATRIX, &Bcheck)); 958c4762a1bSJed Brown } else { 9599566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATAIJ, MAT_INITIAL_MATRIX, &Bcheck)); 960c4762a1bSJed Brown } 961c4762a1bSJed Brown if (B) { /* if B is present, subtract it */ 9629566063dSJacob Faibussowitsch PetscCall(MatAXPY(Bcheck, -1., B, DIFFERENT_NONZERO_PATTERN)); 963c4762a1bSJed Brown } 9649566063dSJacob Faibussowitsch PetscCall(MatNorm(Bcheck, NORM_INFINITY, &error)); 965c4762a1bSJed Brown if (error > PETSC_SQRT_MACHINE_EPSILON) { 966c4762a1bSJed Brown ISLocalToGlobalMapping rl2g, cl2g; 967c4762a1bSJed Brown 968d0dbe9f7SStefano Zampini PetscCall(PetscObjectSetName((PetscObject)Bcheck, "Bcheck")); 9699566063dSJacob Faibussowitsch PetscCall(MatView(Bcheck, NULL)); 970c4762a1bSJed Brown if (B) { 971d0dbe9f7SStefano Zampini PetscCall(PetscObjectSetName((PetscObject)B, "B")); 9729566063dSJacob Faibussowitsch PetscCall(MatView(B, NULL)); 9739566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bcheck)); 9749566063dSJacob Faibussowitsch PetscCall(MatConvert(A, MATAIJ, MAT_INITIAL_MATRIX, &Bcheck)); 975d0dbe9f7SStefano Zampini PetscCall(PetscObjectSetName((PetscObject)Bcheck, "Assembled A")); 9769566063dSJacob Faibussowitsch PetscCall(MatView(Bcheck, NULL)); 977c4762a1bSJed Brown } 9789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bcheck)); 979d0dbe9f7SStefano Zampini PetscCall(PetscObjectSetName((PetscObject)A, "A")); 9809566063dSJacob Faibussowitsch PetscCall(MatView(A, NULL)); 9819566063dSJacob Faibussowitsch PetscCall(MatGetLocalToGlobalMapping(A, &rl2g, &cl2g)); 982d0dbe9f7SStefano Zampini if (rl2g) PetscCall(ISLocalToGlobalMappingView(rl2g, NULL)); 983d0dbe9f7SStefano Zampini if (cl2g) PetscCall(ISLocalToGlobalMappingView(cl2g, NULL)); 984d0dbe9f7SStefano Zampini SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "ERROR ON %s: %g", func, (double)error); 985c4762a1bSJed Brown } 9869566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bcheck)); 987c4762a1bSJed Brown } else { 988c4762a1bSJed Brown PetscBool ok, okt; 989c4762a1bSJed Brown 9909566063dSJacob Faibussowitsch PetscCall(MatMultEqual(A, B, 3, &ok)); 9919566063dSJacob Faibussowitsch PetscCall(MatMultTransposeEqual(A, B, 3, &okt)); 992e00437b9SBarry Smith PetscCheck(ok && okt, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "ERROR ON %s: mult ok ? %d, multtranspose ok ? %d", func, ok, okt); 993c4762a1bSJed Brown } 9943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 995c4762a1bSJed Brown } 996c4762a1bSJed Brown 9970d2733adSStefano Zampini PetscErrorCode TestMatZeroRows(Mat A, Mat Afull, PetscBool squaretest, IS is, PetscScalar diag, PetscBool local) 998d71ae5a4SJacob Faibussowitsch { 999c4762a1bSJed Brown Mat B, Bcheck, B2 = NULL, lB; 1000c4762a1bSJed Brown Vec x = NULL, b = NULL, b2 = NULL; 1001c4762a1bSJed Brown ISLocalToGlobalMapping l2gr, l2gc; 1002c4762a1bSJed Brown PetscReal error; 1003c4762a1bSJed Brown char diagstr[16]; 1004c4762a1bSJed Brown const PetscInt *idxs; 1005c4762a1bSJed Brown PetscInt rst, ren, i, n, N, d; 1006c4762a1bSJed Brown PetscMPIInt rank; 1007c4762a1bSJed Brown PetscBool miss, haszerorows; 10080d2733adSStefano Zampini IS gis; 1009c4762a1bSJed Brown 1010c4762a1bSJed Brown PetscFunctionBeginUser; 1011c4762a1bSJed Brown if (diag == 0.) { 1012c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(diagstr, "zero", sizeof(diagstr))); 1013c4762a1bSJed Brown } else { 1014c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(diagstr, "nonzero", sizeof(diagstr))); 1015c4762a1bSJed Brown } 10169566063dSJacob Faibussowitsch PetscCall(ISView(is, NULL)); 10179566063dSJacob Faibussowitsch PetscCall(MatGetLocalToGlobalMapping(A, &l2gr, &l2gc)); 1018c4762a1bSJed Brown /* tests MatDuplicate and MatCopy */ 1019c4762a1bSJed Brown if (diag == 0.) { 10209566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B)); 1021c4762a1bSJed Brown } else { 10229566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &B)); 10239566063dSJacob Faibussowitsch PetscCall(MatCopy(A, B, SAME_NONZERO_PATTERN)); 1024c4762a1bSJed Brown } 10259566063dSJacob Faibussowitsch PetscCall(MatISGetLocalMat(B, &lB)); 10269566063dSJacob Faibussowitsch PetscCall(MatHasOperation(lB, MATOP_ZERO_ROWS, &haszerorows)); 1027c4762a1bSJed Brown if (squaretest && haszerorows) { 10289566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(B, &x, &b)); 10299566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2)); 10309566063dSJacob Faibussowitsch PetscCall(VecSetLocalToGlobalMapping(b, l2gr)); 10319566063dSJacob Faibussowitsch PetscCall(VecSetLocalToGlobalMapping(x, l2gc)); 10329566063dSJacob Faibussowitsch PetscCall(VecSetRandom(x, NULL)); 10339566063dSJacob Faibussowitsch PetscCall(VecSetRandom(b, NULL)); 1034c4762a1bSJed Brown /* mimic b[is] = x[is] */ 10359566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &b2)); 10369566063dSJacob Faibussowitsch PetscCall(VecSetLocalToGlobalMapping(b2, l2gr)); 10379566063dSJacob Faibussowitsch PetscCall(VecCopy(b, b2)); 10380d2733adSStefano Zampini if (local) { 10390d2733adSStefano Zampini PetscCall(ISL2GMapNoNeg(l2gr, is, &gis)); 10400d2733adSStefano Zampini PetscCall(ISGetLocalSize(gis, &n)); 10410d2733adSStefano Zampini PetscCall(ISGetIndices(gis, &idxs)); 10420d2733adSStefano Zampini } else { 10439566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n)); 10449566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &idxs)); 10450d2733adSStefano Zampini } 10469566063dSJacob Faibussowitsch PetscCall(VecGetSize(x, &N)); 1047c4762a1bSJed Brown for (i = 0; i < n; i++) { 1048c4762a1bSJed Brown if (0 <= idxs[i] && idxs[i] < N) { 10499566063dSJacob Faibussowitsch PetscCall(VecSetValue(b2, idxs[i], diag, INSERT_VALUES)); 10509566063dSJacob Faibussowitsch PetscCall(VecSetValue(x, idxs[i], 1., INSERT_VALUES)); 1051c4762a1bSJed Brown } 1052c4762a1bSJed Brown } 10530d2733adSStefano Zampini if (local) { 10540d2733adSStefano Zampini PetscCall(ISRestoreIndices(gis, &idxs)); 10550d2733adSStefano Zampini PetscCall(ISDestroy(&gis)); 10560d2733adSStefano Zampini } else { 10570d2733adSStefano Zampini PetscCall(ISRestoreIndices(is, &idxs)); 10580d2733adSStefano Zampini } 10599566063dSJacob Faibussowitsch PetscCall(VecAssemblyBegin(b2)); 10609566063dSJacob Faibussowitsch PetscCall(VecAssemblyEnd(b2)); 10619566063dSJacob Faibussowitsch PetscCall(VecAssemblyBegin(x)); 10629566063dSJacob Faibussowitsch PetscCall(VecAssemblyEnd(x)); 1063c4762a1bSJed Brown /* test ZeroRows on MATIS */ 10640d2733adSStefano Zampini if (local) { 10650d2733adSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsLocal (diag %s)\n", diagstr)); 10660d2733adSStefano Zampini PetscCall(MatZeroRowsLocalIS(B, is, diag, x, b)); 10670d2733adSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsColumnsLocal (diag %s)\n", diagstr)); 10680d2733adSStefano Zampini PetscCall(MatZeroRowsColumnsLocalIS(B2, is, diag, NULL, NULL)); 10690d2733adSStefano Zampini } else { 10709566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRows (diag %s)\n", diagstr)); 10719566063dSJacob Faibussowitsch PetscCall(MatZeroRowsIS(B, is, diag, x, b)); 10729566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsColumns (diag %s)\n", diagstr)); 10739566063dSJacob Faibussowitsch PetscCall(MatZeroRowsColumnsIS(B2, is, diag, NULL, NULL)); 10740d2733adSStefano Zampini } 1075c4762a1bSJed Brown } else if (haszerorows) { 1076c4762a1bSJed Brown /* test ZeroRows on MATIS */ 10770d2733adSStefano Zampini if (local) { 10780d2733adSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsLocal (diag %s)\n", diagstr)); 10790d2733adSStefano Zampini PetscCall(MatZeroRowsLocalIS(B, is, diag, NULL, NULL)); 10800d2733adSStefano Zampini } else { 10819566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRows (diag %s)\n", diagstr)); 10829566063dSJacob Faibussowitsch PetscCall(MatZeroRowsIS(B, is, diag, NULL, NULL)); 10830d2733adSStefano Zampini } 1084c4762a1bSJed Brown b = b2 = x = NULL; 1085c4762a1bSJed Brown } else { 10869566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Skipping MatZeroRows (diag %s)\n", diagstr)); 1087c4762a1bSJed Brown b = b2 = x = NULL; 1088c4762a1bSJed Brown } 1089c4762a1bSJed Brown 1090c4762a1bSJed Brown if (squaretest && haszerorows) { 10919566063dSJacob Faibussowitsch PetscCall(VecAXPY(b2, -1., b)); 10929566063dSJacob Faibussowitsch PetscCall(VecNorm(b2, NORM_INFINITY, &error)); 1093e00437b9SBarry Smith PetscCheck(error <= PETSC_SQRT_MACHINE_EPSILON, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "ERROR IN ZEROROWS ON B %g (diag %s)", (double)error, diagstr); 1094c4762a1bSJed Brown } 1095c4762a1bSJed Brown 1096c4762a1bSJed Brown /* test MatMissingDiagonal */ 10979566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatMissingDiagonal\n")); 10989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 10999566063dSJacob Faibussowitsch PetscCall(MatMissingDiagonal(B, &miss, &d)); 11009566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &rst, &ren)); 11019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD)); 11029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISynchronizedPrintf(PETSC_VIEWER_STDOUT_WORLD, "[%d] [%" PetscInt_FMT ",%" PetscInt_FMT ") Missing %d, row %" PetscInt_FMT " (diag %s)\n", rank, rst, ren, (int)miss, d, diagstr)); 11039566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD)); 11049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD)); 1105c4762a1bSJed Brown 11069566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 11079566063dSJacob Faibussowitsch PetscCall(VecDestroy(&b)); 11089566063dSJacob Faibussowitsch PetscCall(VecDestroy(&b2)); 1109c4762a1bSJed Brown 1110c4762a1bSJed Brown /* check the result of ZeroRows with that from MPIAIJ routines 1111c4762a1bSJed Brown assuming that MatConvert_IS_XAIJ and MatZeroRows_MPIAIJ work fine */ 1112c4762a1bSJed Brown if (haszerorows) { 11139566063dSJacob Faibussowitsch PetscCall(MatDuplicate(Afull, MAT_COPY_VALUES, &Bcheck)); 11149566063dSJacob Faibussowitsch PetscCall(MatSetOption(Bcheck, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 11150d2733adSStefano Zampini if (local) { 11160d2733adSStefano Zampini PetscCall(ISL2GMapNoNeg(l2gr, is, &gis)); 11170d2733adSStefano Zampini PetscCall(MatZeroRowsIS(Bcheck, gis, diag, NULL, NULL)); 11180d2733adSStefano Zampini PetscCall(ISDestroy(&gis)); 11190d2733adSStefano Zampini } else { 11209566063dSJacob Faibussowitsch PetscCall(MatZeroRowsIS(Bcheck, is, diag, NULL, NULL)); 11210d2733adSStefano Zampini } 11229566063dSJacob Faibussowitsch PetscCall(CheckMat(B, Bcheck, PETSC_FALSE, "Zerorows")); 11239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bcheck)); 1124c4762a1bSJed Brown } 11259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 1126c4762a1bSJed Brown 1127c4762a1bSJed Brown if (B2) { /* test MatZeroRowsColumns */ 11289566063dSJacob Faibussowitsch PetscCall(MatDuplicate(Afull, MAT_COPY_VALUES, &B)); 11299566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 11300d2733adSStefano Zampini if (local) { 11310d2733adSStefano Zampini PetscCall(ISL2GMapNoNeg(l2gr, is, &gis)); 11320d2733adSStefano Zampini PetscCall(MatZeroRowsColumnsIS(B, gis, diag, NULL, NULL)); 11330d2733adSStefano Zampini PetscCall(ISDestroy(&gis)); 11340d2733adSStefano Zampini } else { 11359566063dSJacob Faibussowitsch PetscCall(MatZeroRowsColumnsIS(B, is, diag, NULL, NULL)); 11360d2733adSStefano Zampini } 11379566063dSJacob Faibussowitsch PetscCall(CheckMat(B2, B, PETSC_FALSE, "MatZeroRowsColumns")); 11389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 11399566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2)); 1140c4762a1bSJed Brown } 11413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1142c4762a1bSJed Brown } 1143c4762a1bSJed Brown 11440d2733adSStefano Zampini PetscErrorCode ISL2GMapNoNeg(ISLocalToGlobalMapping mapping, IS is, IS *newis) 11450d2733adSStefano Zampini { 11460d2733adSStefano Zampini PetscInt n, *idxout, nn = 0; 11470d2733adSStefano Zampini const PetscInt *idxin; 11480d2733adSStefano Zampini 11490d2733adSStefano Zampini PetscFunctionBegin; 11500d2733adSStefano Zampini PetscCall(ISGetLocalSize(is, &n)); 11510d2733adSStefano Zampini PetscCall(ISGetIndices(is, &idxin)); 11520d2733adSStefano Zampini PetscCall(PetscMalloc1(n, &idxout)); 11530d2733adSStefano Zampini PetscCall(ISLocalToGlobalMappingApply(mapping, n, idxin, idxout)); 11540d2733adSStefano Zampini PetscCall(ISRestoreIndices(is, &idxin)); 11550d2733adSStefano Zampini for (PetscInt i = 0; i < n; i++) 11560d2733adSStefano Zampini if (idxout[i] > -1) idxout[nn++] = idxout[i]; 11570d2733adSStefano Zampini PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)is), nn, idxout, PETSC_OWN_POINTER, newis)); 11580d2733adSStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 11590d2733adSStefano Zampini } 11600d2733adSStefano Zampini 1161c4762a1bSJed Brown /*TEST 1162c4762a1bSJed Brown 1163c4762a1bSJed Brown test: 11645042aa92SStefano Zampini requires: !complex 11655042aa92SStefano Zampini args: -test_matlab -test_trans 1166c4762a1bSJed Brown 1167c4762a1bSJed Brown test: 1168c4762a1bSJed Brown suffix: 2 1169c4762a1bSJed Brown nsize: 4 11704f58015eSStefano Zampini args: -mat_is_convert_local_nest -nr 3 -nc 4 1171c4762a1bSJed Brown 1172c4762a1bSJed Brown test: 1173c4762a1bSJed Brown suffix: 3 1174c4762a1bSJed Brown nsize: 5 1175a50ef18cSStefano Zampini args: -m 11 -n 10 -mat_is_convert_local_nest -nr 2 -nc 1 -cbs 2 1176c4762a1bSJed Brown 1177c4762a1bSJed Brown test: 1178c4762a1bSJed Brown suffix: 4 1179c4762a1bSJed Brown nsize: 6 1180c4762a1bSJed Brown args: -m 9 -n 12 -test_trans -nr 2 -nc 7 1181c4762a1bSJed Brown 1182c4762a1bSJed Brown test: 1183c4762a1bSJed Brown suffix: 5 1184c4762a1bSJed Brown nsize: 6 1185a50ef18cSStefano Zampini args: -m 12 -n 12 -test_trans -nr 3 -nc 1 -rbs 2 1186c4762a1bSJed Brown 1187c4762a1bSJed Brown test: 1188c4762a1bSJed Brown suffix: 6 1189a50ef18cSStefano Zampini args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -rbs 6 -cbs 3 1190c4762a1bSJed Brown 1191c4762a1bSJed Brown test: 1192c4762a1bSJed Brown suffix: 7 1193c4762a1bSJed Brown args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap 1194c4762a1bSJed Brown 1195c4762a1bSJed Brown test: 1196c4762a1bSJed Brown suffix: 8 1197c4762a1bSJed Brown args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap 1198c4762a1bSJed Brown 1199c4762a1bSJed Brown test: 1200c4762a1bSJed Brown suffix: 9 1201c4762a1bSJed Brown nsize: 5 1202c4762a1bSJed Brown args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap 1203c4762a1bSJed Brown 1204c4762a1bSJed Brown test: 1205c4762a1bSJed Brown suffix: 10 1206c4762a1bSJed Brown nsize: 5 1207c4762a1bSJed Brown args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap 1208c4762a1bSJed Brown 1209c20d7725SJed Brown test: 1210c20d7725SJed Brown suffix: vscat_default 1211c4762a1bSJed Brown nsize: 5 1212c4762a1bSJed Brown args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap 1213c4762a1bSJed Brown output_file: output/ex23_11.out 1214c4762a1bSJed Brown 1215c4762a1bSJed Brown test: 1216c4762a1bSJed Brown suffix: 12 1217c4762a1bSJed Brown nsize: 3 121884a95373SStefano Zampini args: -m 12 -n 12 -symmetric -mat_is_localmat_type sbaij -test_trans -nr 2 -nc 3 -test_setvalues 0 1219c4762a1bSJed Brown 1220c4762a1bSJed Brown testset: 1221c4762a1bSJed Brown output_file: output/ex23_13.out 1222c4762a1bSJed Brown nsize: 3 1223c4762a1bSJed Brown args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -diffmap -permmap 12245042aa92SStefano Zampini filter: grep -v "type:" | grep -v "block size is 1" | grep -v "not using I-node routines" 1225c4762a1bSJed Brown test: 1226c4762a1bSJed Brown suffix: baij 12274f58015eSStefano Zampini args: -mat_is_localmat_type baij 1228c4762a1bSJed Brown test: 1229c4762a1bSJed Brown requires: viennacl 1230c4762a1bSJed Brown suffix: viennacl 12314f58015eSStefano Zampini args: -mat_is_localmat_type aijviennacl 1232c4762a1bSJed Brown test: 1233c4762a1bSJed Brown requires: cuda 1234c4762a1bSJed Brown suffix: cusparse 12354f58015eSStefano Zampini args: -mat_is_localmat_type aijcusparse 12365042aa92SStefano Zampini test: 12375042aa92SStefano Zampini requires: kokkos_kernels 12385042aa92SStefano Zampini suffix: kokkos 12395042aa92SStefano Zampini args: -mat_is_localmat_type aijkokkos 1240c4762a1bSJed Brown 1241e432b41dSStefano Zampini test: 1242e432b41dSStefano Zampini suffix: negrep 1243e432b41dSStefano Zampini nsize: {{1 3}separate output} 12444f58015eSStefano Zampini args: -m {{5 7}separate output} -n {{5 7}separate output} -test_trans -nr 2 -nc 3 -negmap {{0 1}separate output} -repmap {{0 1}separate output} -permmap -diffmap {{0 1}separate output} -allow_repeated 0 12454f58015eSStefano Zampini 12464f58015eSStefano Zampini test: 12474f58015eSStefano Zampini suffix: negrep_allowrep 12484f58015eSStefano Zampini nsize: {{1 3}separate output} 12494f58015eSStefano Zampini args: -m {{5 7}separate output} -n {{5 7}separate output} -test_trans -nr 2 -nc 3 -negmap {{0 1}separate output} -repmap {{0 1}separate output} -permmap -diffmap {{0 1}separate output} -allow_repeated 1250e432b41dSStefano Zampini 1251c4762a1bSJed Brown TEST*/ 1252