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
main(int argc,char ** args)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));
434076fee34SStefano 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));
437076fee34SStefano 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
CheckMat(Mat A,Mat B,PetscBool usemult,const char * func)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
TestMatZeroRows(Mat A,Mat Afull,PetscBool squaretest,IS is,PetscScalar diag,PetscBool local)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;
1005421480d9SBarry Smith PetscInt i, n, N;
1006421480d9SBarry Smith PetscBool haszerorows;
10070d2733adSStefano Zampini IS gis;
1008c4762a1bSJed Brown
1009c4762a1bSJed Brown PetscFunctionBeginUser;
1010c4762a1bSJed Brown if (diag == 0.) {
1011c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(diagstr, "zero", sizeof(diagstr)));
1012c4762a1bSJed Brown } else {
1013c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(diagstr, "nonzero", sizeof(diagstr)));
1014c4762a1bSJed Brown }
10159566063dSJacob Faibussowitsch PetscCall(ISView(is, NULL));
10169566063dSJacob Faibussowitsch PetscCall(MatGetLocalToGlobalMapping(A, &l2gr, &l2gc));
1017c4762a1bSJed Brown /* tests MatDuplicate and MatCopy */
1018c4762a1bSJed Brown if (diag == 0.) {
10199566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B));
1020c4762a1bSJed Brown } else {
10219566063dSJacob Faibussowitsch PetscCall(MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &B));
10229566063dSJacob Faibussowitsch PetscCall(MatCopy(A, B, SAME_NONZERO_PATTERN));
1023c4762a1bSJed Brown }
10249566063dSJacob Faibussowitsch PetscCall(MatISGetLocalMat(B, &lB));
10259566063dSJacob Faibussowitsch PetscCall(MatHasOperation(lB, MATOP_ZERO_ROWS, &haszerorows));
1026c4762a1bSJed Brown if (squaretest && haszerorows) {
10279566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(B, &x, &b));
10289566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
10299566063dSJacob Faibussowitsch PetscCall(VecSetLocalToGlobalMapping(b, l2gr));
10309566063dSJacob Faibussowitsch PetscCall(VecSetLocalToGlobalMapping(x, l2gc));
10319566063dSJacob Faibussowitsch PetscCall(VecSetRandom(x, NULL));
10329566063dSJacob Faibussowitsch PetscCall(VecSetRandom(b, NULL));
1033c4762a1bSJed Brown /* mimic b[is] = x[is] */
10349566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &b2));
10359566063dSJacob Faibussowitsch PetscCall(VecSetLocalToGlobalMapping(b2, l2gr));
10369566063dSJacob Faibussowitsch PetscCall(VecCopy(b, b2));
10370d2733adSStefano Zampini if (local) {
10380d2733adSStefano Zampini PetscCall(ISL2GMapNoNeg(l2gr, is, &gis));
10390d2733adSStefano Zampini PetscCall(ISGetLocalSize(gis, &n));
10400d2733adSStefano Zampini PetscCall(ISGetIndices(gis, &idxs));
10410d2733adSStefano Zampini } else {
10429566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is, &n));
10439566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is, &idxs));
10440d2733adSStefano Zampini }
10459566063dSJacob Faibussowitsch PetscCall(VecGetSize(x, &N));
1046c4762a1bSJed Brown for (i = 0; i < n; i++) {
1047c4762a1bSJed Brown if (0 <= idxs[i] && idxs[i] < N) {
10489566063dSJacob Faibussowitsch PetscCall(VecSetValue(b2, idxs[i], diag, INSERT_VALUES));
10499566063dSJacob Faibussowitsch PetscCall(VecSetValue(x, idxs[i], 1., INSERT_VALUES));
1050c4762a1bSJed Brown }
1051c4762a1bSJed Brown }
10520d2733adSStefano Zampini if (local) {
10530d2733adSStefano Zampini PetscCall(ISRestoreIndices(gis, &idxs));
10540d2733adSStefano Zampini PetscCall(ISDestroy(&gis));
10550d2733adSStefano Zampini } else {
10560d2733adSStefano Zampini PetscCall(ISRestoreIndices(is, &idxs));
10570d2733adSStefano Zampini }
10589566063dSJacob Faibussowitsch PetscCall(VecAssemblyBegin(b2));
10599566063dSJacob Faibussowitsch PetscCall(VecAssemblyEnd(b2));
10609566063dSJacob Faibussowitsch PetscCall(VecAssemblyBegin(x));
10619566063dSJacob Faibussowitsch PetscCall(VecAssemblyEnd(x));
1062c4762a1bSJed Brown /* test ZeroRows on MATIS */
10630d2733adSStefano Zampini if (local) {
10640d2733adSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsLocal (diag %s)\n", diagstr));
10650d2733adSStefano Zampini PetscCall(MatZeroRowsLocalIS(B, is, diag, x, b));
10660d2733adSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsColumnsLocal (diag %s)\n", diagstr));
10670d2733adSStefano Zampini PetscCall(MatZeroRowsColumnsLocalIS(B2, is, diag, NULL, NULL));
10680d2733adSStefano Zampini } else {
10699566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRows (diag %s)\n", diagstr));
10709566063dSJacob Faibussowitsch PetscCall(MatZeroRowsIS(B, is, diag, x, b));
10719566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsColumns (diag %s)\n", diagstr));
10729566063dSJacob Faibussowitsch PetscCall(MatZeroRowsColumnsIS(B2, is, diag, NULL, NULL));
10730d2733adSStefano Zampini }
1074c4762a1bSJed Brown } else if (haszerorows) {
1075c4762a1bSJed Brown /* test ZeroRows on MATIS */
10760d2733adSStefano Zampini if (local) {
10770d2733adSStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsLocal (diag %s)\n", diagstr));
10780d2733adSStefano Zampini PetscCall(MatZeroRowsLocalIS(B, is, diag, NULL, NULL));
10790d2733adSStefano Zampini } else {
10809566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRows (diag %s)\n", diagstr));
10819566063dSJacob Faibussowitsch PetscCall(MatZeroRowsIS(B, is, diag, NULL, NULL));
10820d2733adSStefano Zampini }
1083c4762a1bSJed Brown b = b2 = x = NULL;
1084c4762a1bSJed Brown } else {
10859566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Skipping MatZeroRows (diag %s)\n", diagstr));
1086c4762a1bSJed Brown b = b2 = x = NULL;
1087c4762a1bSJed Brown }
1088c4762a1bSJed Brown
1089c4762a1bSJed Brown if (squaretest && haszerorows) {
10909566063dSJacob Faibussowitsch PetscCall(VecAXPY(b2, -1., b));
10919566063dSJacob Faibussowitsch PetscCall(VecNorm(b2, NORM_INFINITY, &error));
1092e00437b9SBarry Smith PetscCheck(error <= PETSC_SQRT_MACHINE_EPSILON, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "ERROR IN ZEROROWS ON B %g (diag %s)", (double)error, diagstr);
1093c4762a1bSJed Brown }
10949566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x));
10959566063dSJacob Faibussowitsch PetscCall(VecDestroy(&b));
10969566063dSJacob Faibussowitsch PetscCall(VecDestroy(&b2));
1097c4762a1bSJed Brown
1098c4762a1bSJed Brown /* check the result of ZeroRows with that from MPIAIJ routines
1099c4762a1bSJed Brown assuming that MatConvert_IS_XAIJ and MatZeroRows_MPIAIJ work fine */
1100c4762a1bSJed Brown if (haszerorows) {
11019566063dSJacob Faibussowitsch PetscCall(MatDuplicate(Afull, MAT_COPY_VALUES, &Bcheck));
11029566063dSJacob Faibussowitsch PetscCall(MatSetOption(Bcheck, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
11030d2733adSStefano Zampini if (local) {
11040d2733adSStefano Zampini PetscCall(ISL2GMapNoNeg(l2gr, is, &gis));
11050d2733adSStefano Zampini PetscCall(MatZeroRowsIS(Bcheck, gis, diag, NULL, NULL));
11060d2733adSStefano Zampini PetscCall(ISDestroy(&gis));
11070d2733adSStefano Zampini } else {
11089566063dSJacob Faibussowitsch PetscCall(MatZeroRowsIS(Bcheck, is, diag, NULL, NULL));
11090d2733adSStefano Zampini }
11109566063dSJacob Faibussowitsch PetscCall(CheckMat(B, Bcheck, PETSC_FALSE, "Zerorows"));
11119566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bcheck));
1112c4762a1bSJed Brown }
11139566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B));
1114c4762a1bSJed Brown
1115c4762a1bSJed Brown if (B2) { /* test MatZeroRowsColumns */
11169566063dSJacob Faibussowitsch PetscCall(MatDuplicate(Afull, MAT_COPY_VALUES, &B));
11179566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
11180d2733adSStefano Zampini if (local) {
11190d2733adSStefano Zampini PetscCall(ISL2GMapNoNeg(l2gr, is, &gis));
11200d2733adSStefano Zampini PetscCall(MatZeroRowsColumnsIS(B, gis, diag, NULL, NULL));
11210d2733adSStefano Zampini PetscCall(ISDestroy(&gis));
11220d2733adSStefano Zampini } else {
11239566063dSJacob Faibussowitsch PetscCall(MatZeroRowsColumnsIS(B, is, diag, NULL, NULL));
11240d2733adSStefano Zampini }
11259566063dSJacob Faibussowitsch PetscCall(CheckMat(B2, B, PETSC_FALSE, "MatZeroRowsColumns"));
11269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B));
11279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B2));
1128c4762a1bSJed Brown }
11293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1130c4762a1bSJed Brown }
1131c4762a1bSJed Brown
ISL2GMapNoNeg(ISLocalToGlobalMapping mapping,IS is,IS * newis)11320d2733adSStefano Zampini PetscErrorCode ISL2GMapNoNeg(ISLocalToGlobalMapping mapping, IS is, IS *newis)
11330d2733adSStefano Zampini {
11340d2733adSStefano Zampini PetscInt n, *idxout, nn = 0;
11350d2733adSStefano Zampini const PetscInt *idxin;
11360d2733adSStefano Zampini
11370d2733adSStefano Zampini PetscFunctionBegin;
11380d2733adSStefano Zampini PetscCall(ISGetLocalSize(is, &n));
11390d2733adSStefano Zampini PetscCall(ISGetIndices(is, &idxin));
11400d2733adSStefano Zampini PetscCall(PetscMalloc1(n, &idxout));
11410d2733adSStefano Zampini PetscCall(ISLocalToGlobalMappingApply(mapping, n, idxin, idxout));
11420d2733adSStefano Zampini PetscCall(ISRestoreIndices(is, &idxin));
11430d2733adSStefano Zampini for (PetscInt i = 0; i < n; i++)
11440d2733adSStefano Zampini if (idxout[i] > -1) idxout[nn++] = idxout[i];
11450d2733adSStefano Zampini PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)is), nn, idxout, PETSC_OWN_POINTER, newis));
11460d2733adSStefano Zampini PetscFunctionReturn(PETSC_SUCCESS);
11470d2733adSStefano Zampini }
11480d2733adSStefano Zampini
1149c4762a1bSJed Brown /*TEST
1150c4762a1bSJed Brown
1151c4762a1bSJed Brown test:
11525042aa92SStefano Zampini requires: !complex
11535042aa92SStefano Zampini args: -test_matlab -test_trans
1154c4762a1bSJed Brown
1155c4762a1bSJed Brown test:
1156c4762a1bSJed Brown suffix: 2
1157c4762a1bSJed Brown nsize: 4
11584f58015eSStefano Zampini args: -mat_is_convert_local_nest -nr 3 -nc 4
1159c4762a1bSJed Brown
1160c4762a1bSJed Brown test:
1161c4762a1bSJed Brown suffix: 3
1162c4762a1bSJed Brown nsize: 5
1163a50ef18cSStefano Zampini args: -m 11 -n 10 -mat_is_convert_local_nest -nr 2 -nc 1 -cbs 2
1164c4762a1bSJed Brown
1165c4762a1bSJed Brown test:
1166c4762a1bSJed Brown suffix: 4
1167c4762a1bSJed Brown nsize: 6
1168c4762a1bSJed Brown args: -m 9 -n 12 -test_trans -nr 2 -nc 7
1169c4762a1bSJed Brown
1170c4762a1bSJed Brown test:
1171c4762a1bSJed Brown suffix: 5
1172c4762a1bSJed Brown nsize: 6
1173a50ef18cSStefano Zampini args: -m 12 -n 12 -test_trans -nr 3 -nc 1 -rbs 2
1174c4762a1bSJed Brown
1175c4762a1bSJed Brown test:
1176c4762a1bSJed Brown suffix: 6
1177a50ef18cSStefano Zampini args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -rbs 6 -cbs 3
1178c4762a1bSJed Brown
1179c4762a1bSJed Brown test:
1180c4762a1bSJed Brown suffix: 7
1181c4762a1bSJed Brown args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap
1182c4762a1bSJed Brown
1183c4762a1bSJed Brown test:
1184c4762a1bSJed Brown suffix: 8
1185c4762a1bSJed Brown args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap
1186c4762a1bSJed Brown
1187c4762a1bSJed Brown test:
1188c4762a1bSJed Brown suffix: 9
1189c4762a1bSJed Brown nsize: 5
1190c4762a1bSJed Brown args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap
1191c4762a1bSJed Brown
1192c4762a1bSJed Brown test:
1193c4762a1bSJed Brown suffix: 10
1194c4762a1bSJed Brown nsize: 5
1195c4762a1bSJed Brown args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap
1196c4762a1bSJed Brown
1197c20d7725SJed Brown test:
1198c20d7725SJed Brown suffix: vscat_default
1199c4762a1bSJed Brown nsize: 5
1200c4762a1bSJed Brown args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap
1201c4762a1bSJed Brown output_file: output/ex23_11.out
1202c4762a1bSJed Brown
1203c4762a1bSJed Brown test:
1204c4762a1bSJed Brown suffix: 12
1205c4762a1bSJed Brown nsize: 3
120684a95373SStefano Zampini args: -m 12 -n 12 -symmetric -mat_is_localmat_type sbaij -test_trans -nr 2 -nc 3 -test_setvalues 0
1207c4762a1bSJed Brown
1208c4762a1bSJed Brown testset:
1209c4762a1bSJed Brown output_file: output/ex23_13.out
1210c4762a1bSJed Brown nsize: 3
1211c4762a1bSJed Brown args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -diffmap -permmap
1212*e363090eSPierre Jolivet filter: grep -v "type:" | grep -v "not using I-node routines"
1213c4762a1bSJed Brown test:
1214c4762a1bSJed Brown suffix: baij
12154f58015eSStefano Zampini args: -mat_is_localmat_type baij
1216c4762a1bSJed Brown test:
1217c4762a1bSJed Brown requires: viennacl
1218c4762a1bSJed Brown suffix: viennacl
12194f58015eSStefano Zampini args: -mat_is_localmat_type aijviennacl
1220c4762a1bSJed Brown test:
1221c4762a1bSJed Brown requires: cuda
1222c4762a1bSJed Brown suffix: cusparse
12234f58015eSStefano Zampini args: -mat_is_localmat_type aijcusparse
12245042aa92SStefano Zampini test:
12255042aa92SStefano Zampini requires: kokkos_kernels
12265042aa92SStefano Zampini suffix: kokkos
12275042aa92SStefano Zampini args: -mat_is_localmat_type aijkokkos
1228c4762a1bSJed Brown
1229e432b41dSStefano Zampini test:
1230e432b41dSStefano Zampini suffix: negrep
1231e432b41dSStefano Zampini nsize: {{1 3}separate output}
12324f58015eSStefano 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
12334f58015eSStefano Zampini
12344f58015eSStefano Zampini test:
12354f58015eSStefano Zampini suffix: negrep_allowrep
12364f58015eSStefano Zampini nsize: {{1 3}separate output}
12374f58015eSStefano 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
1238e432b41dSStefano Zampini
1239c4762a1bSJed Brown TEST*/
1240