xref: /petsc/src/mat/tests/ex23.c (revision 4f58015e5b963ff70f3b7a63a399e8a46849015e)
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 
5c4762a1bSJed Brown PetscErrorCode TestMatZeroRows(Mat, Mat, PetscBool, IS, PetscScalar);
6c4762a1bSJed Brown PetscErrorCode CheckMat(Mat, Mat, PetscBool, const char *);
7c4762a1bSJed Brown 
8d71ae5a4SJacob Faibussowitsch int main(int argc, char **args)
9d71ae5a4SJacob Faibussowitsch {
10c4762a1bSJed Brown   Mat                    A, B, A2, B2, T;
11c4762a1bSJed Brown   Mat                    Aee, Aeo, Aoe, Aoo;
12d0dbe9f7SStefano Zampini   Mat                   *mats, *Asub, *Bsub;
13c4762a1bSJed Brown   Vec                    x, y;
14c4762a1bSJed Brown   MatInfo                info;
15c4762a1bSJed Brown   ISLocalToGlobalMapping cmap, rmap;
16c4762a1bSJed Brown   IS                     is, is2, reven, rodd, ceven, codd;
17c4762a1bSJed Brown   IS                    *rows, *cols;
18d0dbe9f7SStefano Zampini   IS                     irow[2], icol[2];
19d0dbe9f7SStefano Zampini   PetscLayout            rlayout, clayout;
20d0dbe9f7SStefano Zampini   const PetscInt        *rrange, *crange;
21c4762a1bSJed Brown   MatType                lmtype;
22c4762a1bSJed Brown   PetscScalar            diag = 2.;
23e432b41dSStefano Zampini   PetscInt               n, m, i, lm, ln;
24c4762a1bSJed Brown   PetscInt               rst, ren, cst, cen, nr, nc;
25d0dbe9f7SStefano Zampini   PetscMPIInt            rank, size, lrank, rrank;
26c4762a1bSJed Brown   PetscBool              testT, squaretest, isaij;
27*4f58015eSStefano Zampini   PetscBool              permute = PETSC_FALSE, negmap = PETSC_FALSE, repmap = PETSC_FALSE, allow_repeated = PETSC_TRUE;
28e432b41dSStefano Zampini   PetscBool              diffmap = PETSC_TRUE, symmetric = PETSC_FALSE, issymmetric;
29c4762a1bSJed Brown 
30327415f7SBarry Smith   PetscFunctionBeginUser;
319566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &args, (char *)0, help));
329566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
339566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
34c4762a1bSJed Brown   m = n = 2 * size;
359566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-symmetric", &symmetric, NULL));
369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-m", &m, NULL));
379566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL));
389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-negmap", &negmap, NULL));
399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-repmap", &repmap, NULL));
409566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-permmap", &permute, NULL));
419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-diffmap", &diffmap, NULL));
42*4f58015eSStefano Zampini   PetscCall(PetscOptionsGetBool(NULL, NULL, "-allow_repeated", &allow_repeated, NULL));
43e00437b9SBarry 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");
44e00437b9SBarry 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");
45e00437b9SBarry Smith   PetscCheck(n >= 2, PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG, "Number of cols should be larger or equal 2");
46c4762a1bSJed Brown 
47c4762a1bSJed Brown   /* create a MATIS matrix */
489566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
499566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, m, n));
509566063dSJacob Faibussowitsch   PetscCall(MatSetType(A, MATIS));
519566063dSJacob Faibussowitsch   PetscCall(MatSetFromOptions(A));
52e432b41dSStefano Zampini   if (!negmap && !repmap) {
53fc989267SStefano Zampini     /* This is not the proper setting for MATIS for finite elements, it is just used to test the routines
54fc989267SStefano Zampini        Here we use a one-to-one correspondence between local row/column spaces and global row/column spaces
55fc989267SStefano Zampini        Equivalent to passing NULL for the mapping */
569566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, n, 0, 1, &is));
57e432b41dSStefano Zampini   } else if (negmap && !repmap) { /* non repeated but with negative indices */
589566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, n + 2, -2, 1, &is));
59e432b41dSStefano Zampini   } else if (!negmap && repmap) { /* non negative but repeated indices */
60e432b41dSStefano Zampini     IS isl[2];
61e432b41dSStefano Zampini 
629566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, n, 0, 1, &isl[0]));
639566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, n, n - 1, -1, &isl[1]));
649566063dSJacob Faibussowitsch     PetscCall(ISConcatenate(PETSC_COMM_WORLD, 2, isl, &is));
659566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&isl[0]));
669566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&isl[1]));
67e432b41dSStefano Zampini   } else { /* negative and repeated indices */
68e432b41dSStefano Zampini     IS isl[2];
69e432b41dSStefano Zampini 
709566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, n + 1, -1, 1, &isl[0]));
719566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, n + 1, n - 1, -1, &isl[1]));
729566063dSJacob Faibussowitsch     PetscCall(ISConcatenate(PETSC_COMM_WORLD, 2, isl, &is));
739566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&isl[0]));
749566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&isl[1]));
75e432b41dSStefano Zampini   }
769566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingCreateIS(is, &cmap));
779566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&is));
78c4762a1bSJed Brown 
79e432b41dSStefano Zampini   if (m != n || diffmap) {
809566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, m, permute ? m - 1 : 0, permute ? -1 : 1, &is));
819566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingCreateIS(is, &rmap));
829566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&is));
83c4762a1bSJed Brown   } else {
849566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)cmap));
85c4762a1bSJed Brown     rmap = cmap;
86c4762a1bSJed Brown   }
87e432b41dSStefano Zampini 
88*4f58015eSStefano Zampini   PetscCall(MatISSetAllowRepeated(A, allow_repeated));
899566063dSJacob Faibussowitsch   PetscCall(MatSetLocalToGlobalMapping(A, rmap, cmap));
909566063dSJacob Faibussowitsch   PetscCall(MatISStoreL2L(A, PETSC_FALSE));
919566063dSJacob Faibussowitsch   PetscCall(MatISSetPreallocation(A, 3, NULL, 3, NULL));
929566063dSJacob Faibussowitsch   PetscCall(MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, (PetscBool) !(repmap || negmap))); /* I do not want to precompute the pattern */
939566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingGetSize(rmap, &lm));
949566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingGetSize(cmap, &ln));
95e432b41dSStefano Zampini   for (i = 0; i < lm; i++) {
96c4762a1bSJed Brown     PetscScalar v[3];
97c4762a1bSJed Brown     PetscInt    cols[3];
98c4762a1bSJed Brown 
99c4762a1bSJed Brown     cols[0] = (i - 1 + n) % n;
100c4762a1bSJed Brown     cols[1] = i % n;
101c4762a1bSJed Brown     cols[2] = (i + 1) % n;
102c4762a1bSJed Brown     v[0]    = -1. * (symmetric ? PetscMin(i + 1, cols[0] + 1) : i + 1);
103c4762a1bSJed Brown     v[1]    = 2. * (symmetric ? PetscMin(i + 1, cols[1] + 1) : i + 1);
104c4762a1bSJed Brown     v[2]    = -1. * (symmetric ? PetscMin(i + 1, cols[2] + 1) : i + 1);
1059566063dSJacob Faibussowitsch     PetscCall(ISGlobalToLocalMappingApply(cmap, IS_GTOLM_MASK, 3, cols, NULL, cols));
1069566063dSJacob Faibussowitsch     PetscCall(MatSetValuesLocal(A, 1, &i, 3, cols, v, ADD_VALUES));
107c4762a1bSJed Brown   }
1089566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
1099566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
110c4762a1bSJed Brown 
111e432b41dSStefano Zampini   /* activate tests for square matrices with same maps only */
1129566063dSJacob Faibussowitsch   PetscCall(MatHasCongruentLayouts(A, &squaretest));
113e432b41dSStefano Zampini   if (squaretest && rmap != cmap) {
114e432b41dSStefano Zampini     PetscInt nr, nc;
115e432b41dSStefano Zampini 
1169566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetSize(rmap, &nr));
1179566063dSJacob Faibussowitsch     PetscCall(ISLocalToGlobalMappingGetSize(cmap, &nc));
118e432b41dSStefano Zampini     if (nr != nc) squaretest = PETSC_FALSE;
119e432b41dSStefano Zampini     else {
120e432b41dSStefano Zampini       const PetscInt *idxs1, *idxs2;
121e432b41dSStefano Zampini 
1229566063dSJacob Faibussowitsch       PetscCall(ISLocalToGlobalMappingGetIndices(rmap, &idxs1));
1239566063dSJacob Faibussowitsch       PetscCall(ISLocalToGlobalMappingGetIndices(cmap, &idxs2));
1249566063dSJacob Faibussowitsch       PetscCall(PetscArraycmp(idxs1, idxs2, nr, &squaretest));
1259566063dSJacob Faibussowitsch       PetscCall(ISLocalToGlobalMappingRestoreIndices(rmap, &idxs1));
1269566063dSJacob Faibussowitsch       PetscCall(ISLocalToGlobalMappingRestoreIndices(cmap, &idxs2));
127e432b41dSStefano Zampini     }
1281c2dc1cbSBarry Smith     PetscCall(MPIU_Allreduce(MPI_IN_PLACE, &squaretest, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)A)));
129e432b41dSStefano Zampini   }
130*4f58015eSStefano Zampini   if (negmap && repmap) squaretest = PETSC_FALSE;
131e432b41dSStefano Zampini 
132e432b41dSStefano Zampini   /* test MatISGetLocalMat */
1339566063dSJacob Faibussowitsch   PetscCall(MatISGetLocalMat(A, &B));
1349566063dSJacob Faibussowitsch   PetscCall(MatGetType(B, &lmtype));
135c4762a1bSJed Brown 
136c4762a1bSJed Brown   /* test MatGetInfo */
1379566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatGetInfo\n"));
1389566063dSJacob Faibussowitsch   PetscCall(MatGetInfo(A, MAT_LOCAL, &info));
1399566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD));
1409371c9d4SSatish 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,
1419371c9d4SSatish Balay                                                (PetscInt)info.nz_unneeded, (PetscInt)info.assemblies, (PetscInt)info.mallocs));
1429566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD));
1439566063dSJacob Faibussowitsch   PetscCall(MatGetInfo(A, MAT_GLOBAL_MAX, &info));
1449371c9d4SSatish 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,
1459371c9d4SSatish Balay                                    (PetscInt)info.assemblies, (PetscInt)info.mallocs));
1469566063dSJacob Faibussowitsch   PetscCall(MatGetInfo(A, MAT_GLOBAL_SUM, &info));
1479371c9d4SSatish 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,
1489371c9d4SSatish Balay                                    (PetscInt)info.assemblies, (PetscInt)info.mallocs));
149c4762a1bSJed Brown 
150e432b41dSStefano Zampini   /* test MatIsSymmetric */
1519566063dSJacob Faibussowitsch   PetscCall(MatIsSymmetric(A, 0.0, &issymmetric));
1529566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatIsSymmetric: %d\n", issymmetric));
153c4762a1bSJed Brown 
154c4762a1bSJed Brown   /* Create a MPIAIJ matrix, same as A */
1559566063dSJacob Faibussowitsch   PetscCall(MatCreate(PETSC_COMM_WORLD, &B));
1569566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, m, n));
1579566063dSJacob Faibussowitsch   PetscCall(MatSetType(B, MATAIJ));
1589566063dSJacob Faibussowitsch   PetscCall(MatSetFromOptions(B));
1599566063dSJacob Faibussowitsch   PetscCall(MatSetLocalToGlobalMapping(B, rmap, cmap));
1609566063dSJacob Faibussowitsch   PetscCall(MatMPIAIJSetPreallocation(B, 3, NULL, 3, NULL));
1619566063dSJacob Faibussowitsch   PetscCall(MatMPIBAIJSetPreallocation(B, 1, 3, NULL, 3, NULL));
162c4762a1bSJed Brown #if defined(PETSC_HAVE_HYPRE)
1639566063dSJacob Faibussowitsch   PetscCall(MatHYPRESetPreallocation(B, 3, NULL, 3, NULL));
164c4762a1bSJed Brown #endif
1659566063dSJacob Faibussowitsch   PetscCall(MatISSetPreallocation(B, 3, NULL, 3, NULL));
1669566063dSJacob Faibussowitsch   PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, (PetscBool) !(repmap || negmap))); /* I do not want to precompute the pattern */
167e432b41dSStefano Zampini   for (i = 0; i < lm; i++) {
168c4762a1bSJed Brown     PetscScalar v[3];
169c4762a1bSJed Brown     PetscInt    cols[3];
170c4762a1bSJed Brown 
171c4762a1bSJed Brown     cols[0] = (i - 1 + n) % n;
172c4762a1bSJed Brown     cols[1] = i % n;
173c4762a1bSJed Brown     cols[2] = (i + 1) % n;
174c4762a1bSJed Brown     v[0]    = -1. * (symmetric ? PetscMin(i + 1, cols[0] + 1) : i + 1);
175c4762a1bSJed Brown     v[1]    = 2. * (symmetric ? PetscMin(i + 1, cols[1] + 1) : i + 1);
176c4762a1bSJed Brown     v[2]    = -1. * (symmetric ? PetscMin(i + 1, cols[2] + 1) : i + 1);
1779566063dSJacob Faibussowitsch     PetscCall(ISGlobalToLocalMappingApply(cmap, IS_GTOLM_MASK, 3, cols, NULL, cols));
1789566063dSJacob Faibussowitsch     PetscCall(MatSetValuesLocal(B, 1, &i, 3, cols, v, ADD_VALUES));
179c4762a1bSJed Brown   }
1809566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
1819566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
182e432b41dSStefano Zampini 
183e432b41dSStefano Zampini   /* test MatView */
1849566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatView\n"));
1859566063dSJacob Faibussowitsch   PetscCall(MatView(A, NULL));
1869566063dSJacob Faibussowitsch   PetscCall(MatView(B, NULL));
187c4762a1bSJed Brown 
188c4762a1bSJed Brown   /* test CheckMat */
1899566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test CheckMat\n"));
1909566063dSJacob Faibussowitsch   PetscCall(CheckMat(A, B, PETSC_FALSE, "CheckMat"));
191c4762a1bSJed Brown 
192c4762a1bSJed Brown   /* test MatDuplicate and MatAXPY */
1939566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatDuplicate and MatAXPY\n"));
1949566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
1959566063dSJacob Faibussowitsch   PetscCall(CheckMat(A, A2, PETSC_FALSE, "MatDuplicate and MatAXPY"));
196c4762a1bSJed Brown 
197c4762a1bSJed Brown   /* test MatConvert */
1989566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatConvert_IS_XAIJ\n"));
1999566063dSJacob Faibussowitsch   PetscCall(MatConvert(A2, MATAIJ, MAT_INITIAL_MATRIX, &B2));
2009566063dSJacob Faibussowitsch   PetscCall(CheckMat(B, B2, PETSC_TRUE, "MatConvert_IS_XAIJ MAT_INITIAL_MATRIX"));
2019566063dSJacob Faibussowitsch   PetscCall(MatConvert(A2, MATAIJ, MAT_REUSE_MATRIX, &B2));
2029566063dSJacob Faibussowitsch   PetscCall(CheckMat(B, B2, PETSC_TRUE, "MatConvert_IS_XAIJ MAT_REUSE_MATRIX"));
2039566063dSJacob Faibussowitsch   PetscCall(MatConvert(A2, MATAIJ, MAT_INPLACE_MATRIX, &A2));
2049566063dSJacob Faibussowitsch   PetscCall(CheckMat(B, A2, PETSC_TRUE, "MatConvert_IS_XAIJ MAT_INPLACE_MATRIX"));
2059566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
2069566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B2));
2079566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatConvert_XAIJ_IS\n"));
2089566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
2099566063dSJacob Faibussowitsch   PetscCall(MatConvert(B2, MATIS, MAT_INITIAL_MATRIX, &A2));
2109566063dSJacob Faibussowitsch   PetscCall(CheckMat(A, A2, PETSC_TRUE, "MatConvert_XAIJ_IS MAT_INITIAL_MATRIX"));
2119566063dSJacob Faibussowitsch   PetscCall(MatConvert(B2, MATIS, MAT_REUSE_MATRIX, &A2));
2129566063dSJacob Faibussowitsch   PetscCall(CheckMat(A, A2, PETSC_TRUE, "MatConvert_XAIJ_IS MAT_REUSE_MATRIX"));
2139566063dSJacob Faibussowitsch   PetscCall(MatConvert(B2, MATIS, MAT_INPLACE_MATRIX, &B2));
2149566063dSJacob Faibussowitsch   PetscCall(CheckMat(A, B2, PETSC_TRUE, "MatConvert_XAIJ_IS MAT_INPLACE_MATRIX"));
2159566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
2169566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B2));
2179566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(lmtype, MATSEQAIJ, &isaij));
218c4762a1bSJed Brown   if (size == 1 && isaij) { /* tests special code paths in MatConvert_IS_XAIJ */
219c4762a1bSJed 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};
220e432b41dSStefano Zampini     ISLocalToGlobalMapping tcmap, trmap;
221c4762a1bSJed Brown 
222c4762a1bSJed Brown     for (ri = 0; ri < 2; ri++) {
223c4762a1bSJed Brown       PetscInt *r;
224c4762a1bSJed Brown 
225c4762a1bSJed Brown       r = (PetscInt *)(ri == 0 ? rr : rk);
226c4762a1bSJed Brown       for (ci = 0; ci < 2; ci++) {
227c4762a1bSJed Brown         PetscInt *c, rb, cb;
228c4762a1bSJed Brown 
229c4762a1bSJed Brown         c = (PetscInt *)(ci == 0 ? cr : ck);
230c4762a1bSJed Brown         for (rb = 1; rb < 4; rb++) {
2319566063dSJacob Faibussowitsch           PetscCall(ISCreateBlock(PETSC_COMM_SELF, rb, 3, r, PETSC_COPY_VALUES, &is));
2329566063dSJacob Faibussowitsch           PetscCall(ISLocalToGlobalMappingCreateIS(is, &trmap));
2339566063dSJacob Faibussowitsch           PetscCall(ISDestroy(&is));
234c4762a1bSJed Brown           for (cb = 1; cb < 4; cb++) {
235c4762a1bSJed Brown             Mat  T, lT, T2;
236c4762a1bSJed Brown             char testname[256];
237c4762a1bSJed Brown 
2389566063dSJacob Faibussowitsch             PetscCall(PetscSNPrintf(testname, sizeof(testname), "MatConvert_IS_XAIJ special case (%" PetscInt_FMT " %" PetscInt_FMT ", bs %" PetscInt_FMT " %" PetscInt_FMT ")", ri, ci, rb, cb));
2399566063dSJacob Faibussowitsch             PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test %s\n", testname));
240c4762a1bSJed Brown 
2419566063dSJacob Faibussowitsch             PetscCall(ISCreateBlock(PETSC_COMM_SELF, cb, 4, c, PETSC_COPY_VALUES, &is));
2429566063dSJacob Faibussowitsch             PetscCall(ISLocalToGlobalMappingCreateIS(is, &tcmap));
2439566063dSJacob Faibussowitsch             PetscCall(ISDestroy(&is));
244c4762a1bSJed Brown 
2459566063dSJacob Faibussowitsch             PetscCall(MatCreate(PETSC_COMM_SELF, &T));
2469566063dSJacob Faibussowitsch             PetscCall(MatSetSizes(T, PETSC_DECIDE, PETSC_DECIDE, rb * 3, cb * 4));
2479566063dSJacob Faibussowitsch             PetscCall(MatSetType(T, MATIS));
2489566063dSJacob Faibussowitsch             PetscCall(MatSetLocalToGlobalMapping(T, trmap, tcmap));
2499566063dSJacob Faibussowitsch             PetscCall(ISLocalToGlobalMappingDestroy(&tcmap));
2509566063dSJacob Faibussowitsch             PetscCall(MatISGetLocalMat(T, &lT));
2519566063dSJacob Faibussowitsch             PetscCall(MatSetType(lT, MATSEQAIJ));
2529566063dSJacob Faibussowitsch             PetscCall(MatSeqAIJSetPreallocation(lT, cb * 4, NULL));
2539566063dSJacob Faibussowitsch             PetscCall(MatSetRandom(lT, NULL));
2549566063dSJacob Faibussowitsch             PetscCall(MatConvert(lT, lmtype, MAT_INPLACE_MATRIX, &lT));
2559566063dSJacob Faibussowitsch             PetscCall(MatISRestoreLocalMat(T, &lT));
2569566063dSJacob Faibussowitsch             PetscCall(MatAssemblyBegin(T, MAT_FINAL_ASSEMBLY));
2579566063dSJacob Faibussowitsch             PetscCall(MatAssemblyEnd(T, MAT_FINAL_ASSEMBLY));
258c4762a1bSJed Brown 
2599566063dSJacob Faibussowitsch             PetscCall(MatConvert(T, MATAIJ, MAT_INITIAL_MATRIX, &T2));
2609566063dSJacob Faibussowitsch             PetscCall(CheckMat(T, T2, PETSC_TRUE, "MAT_INITIAL_MATRIX"));
2619566063dSJacob Faibussowitsch             PetscCall(MatConvert(T, MATAIJ, MAT_REUSE_MATRIX, &T2));
2629566063dSJacob Faibussowitsch             PetscCall(CheckMat(T, T2, PETSC_TRUE, "MAT_REUSE_MATRIX"));
2639566063dSJacob Faibussowitsch             PetscCall(MatDestroy(&T2));
2649566063dSJacob Faibussowitsch             PetscCall(MatDuplicate(T, MAT_COPY_VALUES, &T2));
2659566063dSJacob Faibussowitsch             PetscCall(MatConvert(T2, MATAIJ, MAT_INPLACE_MATRIX, &T2));
2669566063dSJacob Faibussowitsch             PetscCall(CheckMat(T, T2, PETSC_TRUE, "MAT_INPLACE_MATRIX"));
2679566063dSJacob Faibussowitsch             PetscCall(MatDestroy(&T));
2689566063dSJacob Faibussowitsch             PetscCall(MatDestroy(&T2));
269c4762a1bSJed Brown           }
2709566063dSJacob Faibussowitsch           PetscCall(ISLocalToGlobalMappingDestroy(&trmap));
271c4762a1bSJed Brown         }
272c4762a1bSJed Brown       }
273c4762a1bSJed Brown     }
274c4762a1bSJed Brown   }
275c4762a1bSJed Brown 
276c4762a1bSJed Brown   /* test MatDiagonalScale */
2779566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatDiagonalScale\n"));
2789566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
2799566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
2809566063dSJacob Faibussowitsch   PetscCall(MatCreateVecs(A, &x, &y));
2819566063dSJacob Faibussowitsch   PetscCall(VecSetRandom(x, NULL));
282e432b41dSStefano Zampini   if (issymmetric) {
2839566063dSJacob Faibussowitsch     PetscCall(VecCopy(x, y));
284c4762a1bSJed Brown   } else {
2859566063dSJacob Faibussowitsch     PetscCall(VecSetRandom(y, NULL));
2869566063dSJacob Faibussowitsch     PetscCall(VecScale(y, 8.));
287c4762a1bSJed Brown   }
2889566063dSJacob Faibussowitsch   PetscCall(MatDiagonalScale(A2, y, x));
2899566063dSJacob Faibussowitsch   PetscCall(MatDiagonalScale(B2, y, x));
2909566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatDiagonalScale"));
2919566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
2929566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B2));
2939566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&x));
2949566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&y));
295c4762a1bSJed Brown 
296c4762a1bSJed Brown   /* test MatPtAP (A IS and B AIJ) */
297c4762a1bSJed Brown   if (isaij && m == n) {
2989566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatPtAP\n"));
299*4f58015eSStefano Zampini     /* There's a bug in MatCreateSubMatrices_MPIAIJ I cannot figure out */
300*4f58015eSStefano Zampini     if (!allow_repeated || !repmap || size == 1) {
3019566063dSJacob Faibussowitsch       PetscCall(MatISStoreL2L(A, PETSC_TRUE));
3029566063dSJacob Faibussowitsch       PetscCall(MatPtAP(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A2));
3039566063dSJacob Faibussowitsch       PetscCall(MatPtAP(B, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &B2));
3049566063dSJacob Faibussowitsch       PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatPtAP MAT_INITIAL_MATRIX"));
3059566063dSJacob Faibussowitsch       PetscCall(MatPtAP(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &A2));
3069566063dSJacob Faibussowitsch       PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatPtAP MAT_REUSE_MATRIX"));
3079566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&A2));
3089566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&B2));
309c4762a1bSJed Brown     }
310*4f58015eSStefano Zampini   }
311c4762a1bSJed Brown 
312c4762a1bSJed Brown   /* test MatGetLocalSubMatrix */
3139566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatGetLocalSubMatrix\n"));
3149566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &A2));
3159566063dSJacob Faibussowitsch   PetscCall(ISCreateStride(PETSC_COMM_SELF, lm / 2 + lm % 2, 0, 2, &reven));
3169566063dSJacob Faibussowitsch   PetscCall(ISComplement(reven, 0, lm, &rodd));
3179566063dSJacob Faibussowitsch   PetscCall(ISCreateStride(PETSC_COMM_SELF, ln / 2 + ln % 2, 0, 2, &ceven));
3189566063dSJacob Faibussowitsch   PetscCall(ISComplement(ceven, 0, ln, &codd));
3199566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSubMatrix(A2, reven, ceven, &Aee));
3209566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSubMatrix(A2, reven, codd, &Aeo));
3219566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSubMatrix(A2, rodd, ceven, &Aoe));
3229566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSubMatrix(A2, rodd, codd, &Aoo));
323e432b41dSStefano Zampini   for (i = 0; i < lm; i++) {
324c4762a1bSJed Brown     PetscInt    j, je, jo, colse[3], colso[3];
325c4762a1bSJed Brown     PetscScalar ve[3], vo[3];
326c4762a1bSJed Brown     PetscScalar v[3];
327c4762a1bSJed Brown     PetscInt    cols[3];
328e432b41dSStefano Zampini     PetscInt    row = i / 2;
329c4762a1bSJed Brown 
330c4762a1bSJed Brown     cols[0] = (i - 1 + n) % n;
331c4762a1bSJed Brown     cols[1] = i % n;
332c4762a1bSJed Brown     cols[2] = (i + 1) % n;
333c4762a1bSJed Brown     v[0]    = -1. * (symmetric ? PetscMin(i + 1, cols[0] + 1) : i + 1);
334c4762a1bSJed Brown     v[1]    = 2. * (symmetric ? PetscMin(i + 1, cols[1] + 1) : i + 1);
335c4762a1bSJed Brown     v[2]    = -1. * (symmetric ? PetscMin(i + 1, cols[2] + 1) : i + 1);
3369566063dSJacob Faibussowitsch     PetscCall(ISGlobalToLocalMappingApply(cmap, IS_GTOLM_MASK, 3, cols, NULL, cols));
337c4762a1bSJed Brown     for (j = 0, je = 0, jo = 0; j < 3; j++) {
338c4762a1bSJed Brown       if (cols[j] % 2) {
339c4762a1bSJed Brown         vo[jo]      = v[j];
340c4762a1bSJed Brown         colso[jo++] = cols[j] / 2;
341c4762a1bSJed Brown       } else {
342c4762a1bSJed Brown         ve[je]      = v[j];
343c4762a1bSJed Brown         colse[je++] = cols[j] / 2;
344c4762a1bSJed Brown       }
345c4762a1bSJed Brown     }
346c4762a1bSJed Brown     if (i % 2) {
3479566063dSJacob Faibussowitsch       PetscCall(MatSetValuesLocal(Aoe, 1, &row, je, colse, ve, ADD_VALUES));
3489566063dSJacob Faibussowitsch       PetscCall(MatSetValuesLocal(Aoo, 1, &row, jo, colso, vo, ADD_VALUES));
349c4762a1bSJed Brown     } else {
3509566063dSJacob Faibussowitsch       PetscCall(MatSetValuesLocal(Aee, 1, &row, je, colse, ve, ADD_VALUES));
3519566063dSJacob Faibussowitsch       PetscCall(MatSetValuesLocal(Aeo, 1, &row, jo, colso, vo, ADD_VALUES));
352c4762a1bSJed Brown     }
353c4762a1bSJed Brown   }
3549566063dSJacob Faibussowitsch   PetscCall(MatRestoreLocalSubMatrix(A2, reven, ceven, &Aee));
3559566063dSJacob Faibussowitsch   PetscCall(MatRestoreLocalSubMatrix(A2, reven, codd, &Aeo));
3569566063dSJacob Faibussowitsch   PetscCall(MatRestoreLocalSubMatrix(A2, rodd, ceven, &Aoe));
3579566063dSJacob Faibussowitsch   PetscCall(MatRestoreLocalSubMatrix(A2, rodd, codd, &Aoo));
3589566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&reven));
3599566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&ceven));
3609566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&rodd));
3619566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&codd));
3629566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY));
3639566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY));
3649566063dSJacob Faibussowitsch   PetscCall(MatAXPY(A2, -1., A, SAME_NONZERO_PATTERN));
3659566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, NULL, PETSC_FALSE, "MatGetLocalSubMatrix"));
3669566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
367c4762a1bSJed Brown 
368c4762a1bSJed Brown   /* test MatConvert_Nest_IS */
369c4762a1bSJed Brown   testT = PETSC_FALSE;
3709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_trans", &testT, NULL));
371c4762a1bSJed Brown 
3729566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatConvert_Nest_IS\n"));
373c4762a1bSJed Brown   nr = 2;
374c4762a1bSJed Brown   nc = 2;
3759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-nr", &nr, NULL));
3769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-nc", &nc, NULL));
377c4762a1bSJed Brown   if (testT) {
3789566063dSJacob Faibussowitsch     PetscCall(MatGetOwnershipRange(A, &cst, &cen));
3799566063dSJacob Faibussowitsch     PetscCall(MatGetOwnershipRangeColumn(A, &rst, &ren));
380c4762a1bSJed Brown   } else {
3819566063dSJacob Faibussowitsch     PetscCall(MatGetOwnershipRange(A, &rst, &ren));
3829566063dSJacob Faibussowitsch     PetscCall(MatGetOwnershipRangeColumn(A, &cst, &cen));
383c4762a1bSJed Brown   }
3849566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(nr, &rows, nc, &cols, 2 * nr * nc, &mats));
385c4762a1bSJed Brown   for (i = 0; i < nr * nc; i++) {
386c4762a1bSJed Brown     if (testT) {
3879566063dSJacob Faibussowitsch       PetscCall(MatCreateTranspose(A, &mats[i]));
3889566063dSJacob Faibussowitsch       PetscCall(MatTranspose(B, MAT_INITIAL_MATRIX, &mats[i + nr * nc]));
389c4762a1bSJed Brown     } else {
3909566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &mats[i]));
3919566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &mats[i + nr * nc]));
392c4762a1bSJed Brown     }
393c4762a1bSJed Brown   }
39448a46eb9SPierre Jolivet   for (i = 0; i < nr; i++) PetscCall(ISCreateStride(PETSC_COMM_WORLD, ren - rst, i + rst, nr, &rows[i]));
39548a46eb9SPierre Jolivet   for (i = 0; i < nc; i++) PetscCall(ISCreateStride(PETSC_COMM_WORLD, cen - cst, i + cst, nc, &cols[i]));
3969566063dSJacob Faibussowitsch   PetscCall(MatCreateNest(PETSC_COMM_WORLD, nr, rows, nc, cols, mats, &A2));
3979566063dSJacob Faibussowitsch   PetscCall(MatCreateNest(PETSC_COMM_WORLD, nr, rows, nc, cols, mats + nr * nc, &B2));
39848a46eb9SPierre Jolivet   for (i = 0; i < nr; i++) PetscCall(ISDestroy(&rows[i]));
39948a46eb9SPierre Jolivet   for (i = 0; i < nc; i++) PetscCall(ISDestroy(&cols[i]));
40048a46eb9SPierre Jolivet   for (i = 0; i < 2 * nr * nc; i++) PetscCall(MatDestroy(&mats[i]));
4019566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, cols, mats));
4029566063dSJacob Faibussowitsch   PetscCall(MatConvert(B2, MATAIJ, MAT_INITIAL_MATRIX, &T));
4039566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B2));
4049566063dSJacob Faibussowitsch   PetscCall(MatConvert(A2, MATIS, MAT_INITIAL_MATRIX, &B2));
4059566063dSJacob Faibussowitsch   PetscCall(CheckMat(B2, T, PETSC_TRUE, "MatConvert_Nest_IS MAT_INITIAL_MATRIX"));
4069566063dSJacob Faibussowitsch   PetscCall(MatConvert(A2, MATIS, MAT_REUSE_MATRIX, &B2));
4079566063dSJacob Faibussowitsch   PetscCall(CheckMat(B2, T, PETSC_TRUE, "MatConvert_Nest_IS MAT_REUSE_MATRIX"));
4089566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B2));
4099566063dSJacob Faibussowitsch   PetscCall(MatConvert(A2, MATIS, MAT_INPLACE_MATRIX, &A2));
4109566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, T, PETSC_TRUE, "MatConvert_Nest_IS MAT_INPLACE_MATRIX"));
4119566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&T));
4129566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
413c4762a1bSJed Brown 
414c4762a1bSJed Brown   /* test MatCreateSubMatrix */
4159566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatCreateSubMatrix\n"));
416dd400576SPatrick Sanan   if (rank == 0) {
4179566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, 1, 1, 1, &is));
4189566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, 2, 0, 1, &is2));
419c4762a1bSJed Brown   } else if (rank == 1) {
4209566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, 1, 0, 1, &is));
421c4762a1bSJed Brown     if (n > 3) {
4229566063dSJacob Faibussowitsch       PetscCall(ISCreateStride(PETSC_COMM_WORLD, 1, 3, 1, &is2));
423c4762a1bSJed Brown     } else {
4249566063dSJacob Faibussowitsch       PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is2));
425c4762a1bSJed Brown     }
426c4762a1bSJed Brown   } else if (rank == 2 && n > 4) {
4279566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is));
4289566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, n - 4, 4, 1, &is2));
429c4762a1bSJed Brown   } else {
4309566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is));
4319566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is2));
432c4762a1bSJed Brown   }
4339566063dSJacob Faibussowitsch   PetscCall(MatCreateSubMatrix(A, is, is, MAT_INITIAL_MATRIX, &A2));
4349566063dSJacob Faibussowitsch   PetscCall(MatCreateSubMatrix(B, is, is, MAT_INITIAL_MATRIX, &B2));
4359566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, B2, PETSC_TRUE, "first MatCreateSubMatrix"));
436c4762a1bSJed Brown 
4379566063dSJacob Faibussowitsch   PetscCall(MatCreateSubMatrix(A, is, is, MAT_REUSE_MATRIX, &A2));
4389566063dSJacob Faibussowitsch   PetscCall(MatCreateSubMatrix(B, is, is, MAT_REUSE_MATRIX, &B2));
4399566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, B2, PETSC_FALSE, "reuse MatCreateSubMatrix"));
4409566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
4419566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B2));
442c4762a1bSJed Brown 
443e432b41dSStefano Zampini   if (!issymmetric) {
4449566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix(A, is, is2, MAT_INITIAL_MATRIX, &A2));
4459566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix(B, is, is2, MAT_INITIAL_MATRIX, &B2));
4469566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix(A, is, is2, MAT_REUSE_MATRIX, &A2));
4479566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix(B, is, is2, MAT_REUSE_MATRIX, &B2));
4489566063dSJacob Faibussowitsch     PetscCall(CheckMat(A2, B2, PETSC_FALSE, "second MatCreateSubMatrix"));
449c4762a1bSJed Brown   }
450c4762a1bSJed Brown 
4519566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
4529566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B2));
4539566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&is));
4549566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&is2));
455c4762a1bSJed Brown 
456d0dbe9f7SStefano Zampini   /* test MatCreateSubMatrices */
457d0dbe9f7SStefano Zampini   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatCreateSubMatrices\n"));
458d0dbe9f7SStefano Zampini   PetscCall(MatGetLayouts(A, &rlayout, &clayout));
459d0dbe9f7SStefano Zampini   PetscCall(PetscLayoutGetRanges(rlayout, &rrange));
460d0dbe9f7SStefano Zampini   PetscCall(PetscLayoutGetRanges(clayout, &crange));
461d0dbe9f7SStefano Zampini   lrank = (size + rank - 1) % size;
462d0dbe9f7SStefano Zampini   rrank = (rank + 1) % size;
463d0dbe9f7SStefano Zampini   PetscCall(ISCreateStride(PETSC_COMM_SELF, (rrange[lrank + 1] - rrange[lrank]), rrange[lrank], 1, &irow[0]));
464d0dbe9f7SStefano Zampini   PetscCall(ISCreateStride(PETSC_COMM_SELF, (crange[rrank + 1] - crange[rrank]), crange[rrank], 1, &icol[0]));
465d0dbe9f7SStefano Zampini   PetscCall(ISCreateStride(PETSC_COMM_SELF, (rrange[rrank + 1] - rrange[rrank]), rrange[rrank], 1, &irow[1]));
466d0dbe9f7SStefano Zampini   PetscCall(ISCreateStride(PETSC_COMM_SELF, (crange[lrank + 1] - crange[lrank]), crange[lrank], 1, &icol[1]));
467d0dbe9f7SStefano Zampini   PetscCall(MatCreateSubMatrices(A, 2, irow, icol, MAT_INITIAL_MATRIX, &Asub));
468d0dbe9f7SStefano Zampini   PetscCall(MatCreateSubMatrices(B, 2, irow, icol, MAT_INITIAL_MATRIX, &Bsub));
469d0dbe9f7SStefano Zampini   PetscCall(CheckMat(Asub[0], Bsub[0], PETSC_FALSE, "MatCreateSubMatrices[0]"));
470d0dbe9f7SStefano Zampini   PetscCall(CheckMat(Asub[1], Bsub[1], PETSC_FALSE, "MatCreateSubMatrices[1]"));
471d0dbe9f7SStefano Zampini   PetscCall(MatCreateSubMatrices(A, 2, irow, icol, MAT_REUSE_MATRIX, &Asub));
472d0dbe9f7SStefano Zampini   PetscCall(MatCreateSubMatrices(B, 2, irow, icol, MAT_REUSE_MATRIX, &Bsub));
473d0dbe9f7SStefano Zampini   PetscCall(CheckMat(Asub[0], Bsub[0], PETSC_FALSE, "MatCreateSubMatrices[0]"));
474d0dbe9f7SStefano Zampini   PetscCall(CheckMat(Asub[1], Bsub[1], PETSC_FALSE, "MatCreateSubMatrices[1]"));
475d0dbe9f7SStefano Zampini   PetscCall(MatDestroySubMatrices(2, &Asub));
476d0dbe9f7SStefano Zampini   PetscCall(MatDestroySubMatrices(2, &Bsub));
477d0dbe9f7SStefano Zampini   PetscCall(ISDestroy(&irow[0]));
478d0dbe9f7SStefano Zampini   PetscCall(ISDestroy(&irow[1]));
479d0dbe9f7SStefano Zampini   PetscCall(ISDestroy(&icol[0]));
480d0dbe9f7SStefano Zampini   PetscCall(ISDestroy(&icol[1]));
481d0dbe9f7SStefano Zampini 
482c4762a1bSJed Brown   /* Create an IS required by MatZeroRows(): just rank zero provides the rows to be eliminated */
483c4762a1bSJed Brown   if (size > 1) {
484dd400576SPatrick Sanan     if (rank == 0) {
485c4762a1bSJed Brown       PetscInt st, len;
486c4762a1bSJed Brown 
487c4762a1bSJed Brown       st  = (m + 1) / 2;
488c4762a1bSJed Brown       len = PetscMin(m / 2, PetscMax(m - (m + 1) / 2 - 1, 0));
4899566063dSJacob Faibussowitsch       PetscCall(ISCreateStride(PETSC_COMM_WORLD, len, st, 1, &is));
490c4762a1bSJed Brown     } else {
4919566063dSJacob Faibussowitsch       PetscCall(ISCreateStride(PETSC_COMM_WORLD, 0, 0, 1, &is));
492c4762a1bSJed Brown     }
493c4762a1bSJed Brown   } else {
4949566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PETSC_COMM_WORLD, 1, 0, 1, &is));
495c4762a1bSJed Brown   }
496c4762a1bSJed Brown 
497c4762a1bSJed Brown   if (squaretest) { /* tests for square matrices only, with same maps for rows and columns */
498d0dbe9f7SStefano Zampini     PetscInt *idx0, *idx1, n0, n1;
499d0dbe9f7SStefano Zampini     IS        Ais[2], Bis[2];
500d0dbe9f7SStefano Zampini 
501c4762a1bSJed Brown     /* test MatDiagonalSet */
5029566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatDiagonalSet\n"));
5039566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
5049566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
5059566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(A, NULL, &x));
5069566063dSJacob Faibussowitsch     PetscCall(VecSetRandom(x, NULL));
507*4f58015eSStefano Zampini     PetscCall(MatDiagonalSet(A2, x, allow_repeated ? ADD_VALUES : INSERT_VALUES));
508*4f58015eSStefano Zampini     PetscCall(MatDiagonalSet(B2, x, allow_repeated ? ADD_VALUES : INSERT_VALUES));
5099566063dSJacob Faibussowitsch     PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatDiagonalSet"));
5109566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&x));
5119566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A2));
5129566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B2));
513c4762a1bSJed Brown 
514c4762a1bSJed Brown     /* test MatShift (MatShift_IS internally uses MatDiagonalSet_IS with ADD_VALUES) */
5159566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatShift\n"));
5169566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
5179566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
5189566063dSJacob Faibussowitsch     PetscCall(MatShift(A2, 2.0));
5199566063dSJacob Faibussowitsch     PetscCall(MatShift(B2, 2.0));
5209566063dSJacob Faibussowitsch     PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatShift"));
5219566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A2));
5229566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B2));
523c4762a1bSJed Brown 
524c4762a1bSJed Brown     /* nonzero diag value is supported for square matrices only */
5259566063dSJacob Faibussowitsch     PetscCall(TestMatZeroRows(A, B, PETSC_TRUE, is, diag));
526d0dbe9f7SStefano Zampini 
527d0dbe9f7SStefano Zampini     /* test MatIncreaseOverlap */
528d0dbe9f7SStefano Zampini     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatIncreaseOverlap\n"));
529d0dbe9f7SStefano Zampini     PetscCall(MatGetOwnershipRange(A, &rst, &ren));
530d0dbe9f7SStefano Zampini     n0 = (ren - rst) / 2;
531d0dbe9f7SStefano Zampini     n1 = (ren - rst) / 3;
532d0dbe9f7SStefano Zampini     PetscCall(PetscMalloc1(n0, &idx0));
533d0dbe9f7SStefano Zampini     PetscCall(PetscMalloc1(n1, &idx1));
534d0dbe9f7SStefano Zampini     for (i = 0; i < n0; i++) idx0[i] = ren - i - 1;
535d0dbe9f7SStefano Zampini     for (i = 0; i < n1; i++) idx1[i] = rst + i;
536d0dbe9f7SStefano Zampini     PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n0, idx0, PETSC_OWN_POINTER, &Ais[0]));
537d0dbe9f7SStefano Zampini     PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n1, idx1, PETSC_OWN_POINTER, &Ais[1]));
538d0dbe9f7SStefano Zampini     PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n0, idx0, PETSC_COPY_VALUES, &Bis[0]));
539d0dbe9f7SStefano Zampini     PetscCall(ISCreateGeneral(PETSC_COMM_WORLD, n1, idx1, PETSC_COPY_VALUES, &Bis[1]));
540d0dbe9f7SStefano Zampini     PetscCall(MatIncreaseOverlap(A, 2, Ais, 3));
541d0dbe9f7SStefano Zampini     PetscCall(MatIncreaseOverlap(B, 2, Bis, 3));
542d0dbe9f7SStefano Zampini     /* Non deterministic output! */
543d0dbe9f7SStefano Zampini     PetscCall(ISSort(Ais[0]));
544d0dbe9f7SStefano Zampini     PetscCall(ISSort(Ais[1]));
545d0dbe9f7SStefano Zampini     PetscCall(ISSort(Bis[0]));
546d0dbe9f7SStefano Zampini     PetscCall(ISSort(Bis[1]));
547d0dbe9f7SStefano Zampini     PetscCall(ISView(Ais[0], NULL));
548d0dbe9f7SStefano Zampini     PetscCall(ISView(Bis[0], NULL));
549d0dbe9f7SStefano Zampini     PetscCall(ISView(Ais[1], NULL));
550d0dbe9f7SStefano Zampini     PetscCall(ISView(Bis[1], NULL));
551d0dbe9f7SStefano Zampini     PetscCall(MatCreateSubMatrices(A, 2, Ais, Ais, MAT_INITIAL_MATRIX, &Asub));
552d0dbe9f7SStefano Zampini     PetscCall(MatCreateSubMatrices(B, 2, Bis, Ais, MAT_INITIAL_MATRIX, &Bsub));
553d0dbe9f7SStefano Zampini     PetscCall(CheckMat(Asub[0], Bsub[0], PETSC_FALSE, "MatIncreaseOverlap[0]"));
554d0dbe9f7SStefano Zampini     PetscCall(CheckMat(Asub[1], Bsub[1], PETSC_FALSE, "MatIncreaseOverlap[1]"));
555d0dbe9f7SStefano Zampini     PetscCall(MatDestroySubMatrices(2, &Asub));
556d0dbe9f7SStefano Zampini     PetscCall(MatDestroySubMatrices(2, &Bsub));
557d0dbe9f7SStefano Zampini     PetscCall(ISDestroy(&Ais[0]));
558d0dbe9f7SStefano Zampini     PetscCall(ISDestroy(&Ais[1]));
559d0dbe9f7SStefano Zampini     PetscCall(ISDestroy(&Bis[0]));
560d0dbe9f7SStefano Zampini     PetscCall(ISDestroy(&Bis[1]));
561c4762a1bSJed Brown   }
5629566063dSJacob Faibussowitsch   PetscCall(TestMatZeroRows(A, B, squaretest, is, 0.0));
5639566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&is));
564c4762a1bSJed Brown 
565c4762a1bSJed Brown   /* test MatTranspose */
5669566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatTranspose\n"));
5679566063dSJacob Faibussowitsch   PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &A2));
5689566063dSJacob Faibussowitsch   PetscCall(MatTranspose(B, MAT_INITIAL_MATRIX, &B2));
5699566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, B2, PETSC_FALSE, "initial matrix MatTranspose"));
570c4762a1bSJed Brown 
5719566063dSJacob Faibussowitsch   PetscCall(MatTranspose(A, MAT_REUSE_MATRIX, &A2));
5729566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, B2, PETSC_FALSE, "reuse matrix (not in place) MatTranspose"));
5739566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
574c4762a1bSJed Brown 
5759566063dSJacob Faibussowitsch   PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
5769566063dSJacob Faibussowitsch   PetscCall(MatTranspose(A2, MAT_INPLACE_MATRIX, &A2));
5779566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, B2, PETSC_FALSE, "reuse matrix (in place) MatTranspose"));
5789566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
579c4762a1bSJed Brown 
5809566063dSJacob Faibussowitsch   PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &A2));
5819566063dSJacob Faibussowitsch   PetscCall(CheckMat(A2, B2, PETSC_FALSE, "reuse matrix (different type) MatTranspose"));
5829566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A2));
5839566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B2));
584c4762a1bSJed Brown 
585c4762a1bSJed Brown   /* test MatISFixLocalEmpty */
586c4762a1bSJed Brown   if (isaij) {
587c4762a1bSJed Brown     PetscInt r[2];
588c4762a1bSJed Brown 
589c4762a1bSJed Brown     r[0] = 0;
590c4762a1bSJed Brown     r[1] = PetscMin(m, n) - 1;
5919566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatISFixLocalEmpty\n"));
5929566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
593e432b41dSStefano Zampini 
5949566063dSJacob Faibussowitsch     PetscCall(MatISFixLocalEmpty(A2, PETSC_TRUE));
5959566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY));
5969566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY));
5979566063dSJacob Faibussowitsch     PetscCall(CheckMat(A2, B, PETSC_FALSE, "MatISFixLocalEmpty (null)"));
598c4762a1bSJed Brown 
5999566063dSJacob Faibussowitsch     PetscCall(MatZeroRows(A2, 2, r, 0.0, NULL, NULL));
6009566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view"));
6019566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
6029566063dSJacob Faibussowitsch     PetscCall(MatZeroRows(B2, 2, r, 0.0, NULL, NULL));
6039566063dSJacob Faibussowitsch     PetscCall(MatISFixLocalEmpty(A2, PETSC_TRUE));
6049566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY));
6059566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY));
6069566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view"));
6079566063dSJacob Faibussowitsch     PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatISFixLocalEmpty (rows)"));
6089566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A2));
609c4762a1bSJed Brown 
6109566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
6119566063dSJacob Faibussowitsch     PetscCall(MatZeroRows(A2, 2, r, 0.0, NULL, NULL));
6129566063dSJacob Faibussowitsch     PetscCall(MatTranspose(A2, MAT_INPLACE_MATRIX, &A2));
6139566063dSJacob Faibussowitsch     PetscCall(MatTranspose(B2, MAT_INPLACE_MATRIX, &B2));
6149566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view"));
6159566063dSJacob Faibussowitsch     PetscCall(MatISFixLocalEmpty(A2, PETSC_TRUE));
6169566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY));
6179566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY));
6189566063dSJacob Faibussowitsch     PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view"));
6199566063dSJacob Faibussowitsch     PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatISFixLocalEmpty (cols)"));
620c4762a1bSJed Brown 
6219566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A2));
6229566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B2));
623c4762a1bSJed Brown 
624c4762a1bSJed Brown     if (squaretest) {
6259566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
6269566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
6279566063dSJacob Faibussowitsch       PetscCall(MatZeroRowsColumns(A2, 2, r, 0.0, NULL, NULL));
6289566063dSJacob Faibussowitsch       PetscCall(MatZeroRowsColumns(B2, 2, r, 0.0, NULL, NULL));
6299566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view"));
6309566063dSJacob Faibussowitsch       PetscCall(MatISFixLocalEmpty(A2, PETSC_TRUE));
6319566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(A2, MAT_FINAL_ASSEMBLY));
6329566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(A2, MAT_FINAL_ASSEMBLY));
6339566063dSJacob Faibussowitsch       PetscCall(MatViewFromOptions(A2, NULL, "-fixempty_view"));
6349566063dSJacob Faibussowitsch       PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatISFixLocalEmpty (rows+cols)"));
6359566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&A2));
6369566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&B2));
637c4762a1bSJed Brown     }
638c4762a1bSJed Brown   }
639c4762a1bSJed Brown 
640c4762a1bSJed Brown   /* test MatInvertBlockDiagonal
641c4762a1bSJed Brown        special cases for block-diagonal matrices */
642c4762a1bSJed Brown   if (m == n) {
643c4762a1bSJed Brown     ISLocalToGlobalMapping map;
644c4762a1bSJed Brown     Mat                    Abd, Bbd;
645c4762a1bSJed Brown     IS                     is, bis;
646c4762a1bSJed Brown     const PetscScalar     *isbd, *aijbd;
647c4762a1bSJed Brown     PetscScalar           *vals;
648c4762a1bSJed Brown     const PetscInt        *sts, *idxs;
649c4762a1bSJed Brown     PetscInt              *idxs2, diff, perm, nl, bs, st, en, in;
650c4762a1bSJed Brown     PetscBool              ok;
651c4762a1bSJed Brown 
652c4762a1bSJed Brown     for (diff = 0; diff < 3; diff++) {
653c4762a1bSJed Brown       for (perm = 0; perm < 3; perm++) {
654c4762a1bSJed Brown         for (bs = 1; bs < 4; bs++) {
6559566063dSJacob Faibussowitsch           PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatInvertBlockDiagonal blockdiag %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n", n, diff, perm, bs));
6569566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(bs * bs, &vals));
6579566063dSJacob Faibussowitsch           PetscCall(MatGetOwnershipRanges(A, &sts));
658c4762a1bSJed Brown           switch (diff) {
659c4762a1bSJed Brown           case 1: /* inverted layout by processes */
660c4762a1bSJed Brown             in = 1;
661c4762a1bSJed Brown             st = sts[size - rank - 1];
662c4762a1bSJed Brown             en = sts[size - rank];
663c4762a1bSJed Brown             nl = en - st;
664c4762a1bSJed Brown             break;
665c4762a1bSJed Brown           case 2: /* round-robin layout */
666c4762a1bSJed Brown             in = size;
667c4762a1bSJed Brown             st = rank;
668c4762a1bSJed Brown             nl = n / size;
669c4762a1bSJed Brown             if (rank < n % size) nl++;
670c4762a1bSJed Brown             break;
671c4762a1bSJed Brown           default: /* same layout */
672c4762a1bSJed Brown             in = 1;
673c4762a1bSJed Brown             st = sts[rank];
674c4762a1bSJed Brown             en = sts[rank + 1];
675c4762a1bSJed Brown             nl = en - st;
676c4762a1bSJed Brown             break;
677c4762a1bSJed Brown           }
6789566063dSJacob Faibussowitsch           PetscCall(ISCreateStride(PETSC_COMM_WORLD, nl, st, in, &is));
6799566063dSJacob Faibussowitsch           PetscCall(ISGetLocalSize(is, &nl));
6809566063dSJacob Faibussowitsch           PetscCall(ISGetIndices(is, &idxs));
6819566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(nl, &idxs2));
682c4762a1bSJed Brown           for (i = 0; i < nl; i++) {
683c4762a1bSJed Brown             switch (perm) { /* invert some of the indices */
684d71ae5a4SJacob Faibussowitsch             case 2:
685d71ae5a4SJacob Faibussowitsch               idxs2[i] = rank % 2 ? idxs[i] : idxs[nl - i - 1];
686d71ae5a4SJacob Faibussowitsch               break;
687d71ae5a4SJacob Faibussowitsch             case 1:
688d71ae5a4SJacob Faibussowitsch               idxs2[i] = rank % 2 ? idxs[nl - i - 1] : idxs[i];
689d71ae5a4SJacob Faibussowitsch               break;
690d71ae5a4SJacob Faibussowitsch             default:
691d71ae5a4SJacob Faibussowitsch               idxs2[i] = idxs[i];
692d71ae5a4SJacob Faibussowitsch               break;
693c4762a1bSJed Brown             }
694c4762a1bSJed Brown           }
6959566063dSJacob Faibussowitsch           PetscCall(ISRestoreIndices(is, &idxs));
6969566063dSJacob Faibussowitsch           PetscCall(ISCreateBlock(PETSC_COMM_WORLD, bs, nl, idxs2, PETSC_OWN_POINTER, &bis));
6979566063dSJacob Faibussowitsch           PetscCall(ISLocalToGlobalMappingCreateIS(bis, &map));
6989566063dSJacob Faibussowitsch           PetscCall(MatCreateIS(PETSC_COMM_WORLD, bs, PETSC_DECIDE, PETSC_DECIDE, bs * n, bs * n, map, map, &Abd));
6999566063dSJacob Faibussowitsch           PetscCall(ISLocalToGlobalMappingDestroy(&map));
7009566063dSJacob Faibussowitsch           PetscCall(MatISSetPreallocation(Abd, bs, NULL, 0, NULL));
701c4762a1bSJed Brown           for (i = 0; i < nl; i++) {
702c4762a1bSJed Brown             PetscInt b1, b2;
703c4762a1bSJed Brown 
704c4762a1bSJed Brown             for (b1 = 0; b1 < bs; b1++) {
705ad540459SPierre Jolivet               for (b2 = 0; b2 < bs; b2++) vals[b1 * bs + b2] = i * bs * bs + b1 * bs + b2 + 1 + (b1 == b2 ? 1.0 : 0);
706c4762a1bSJed Brown             }
7079566063dSJacob Faibussowitsch             PetscCall(MatSetValuesBlockedLocal(Abd, 1, &i, 1, &i, vals, INSERT_VALUES));
708c4762a1bSJed Brown           }
7099566063dSJacob Faibussowitsch           PetscCall(MatAssemblyBegin(Abd, MAT_FINAL_ASSEMBLY));
7109566063dSJacob Faibussowitsch           PetscCall(MatAssemblyEnd(Abd, MAT_FINAL_ASSEMBLY));
7119566063dSJacob Faibussowitsch           PetscCall(MatConvert(Abd, MATAIJ, MAT_INITIAL_MATRIX, &Bbd));
7129566063dSJacob Faibussowitsch           PetscCall(MatInvertBlockDiagonal(Abd, &isbd));
7139566063dSJacob Faibussowitsch           PetscCall(MatInvertBlockDiagonal(Bbd, &aijbd));
7149566063dSJacob Faibussowitsch           PetscCall(MatGetLocalSize(Bbd, &nl, NULL));
715c4762a1bSJed Brown           ok = PETSC_TRUE;
716c4762a1bSJed Brown           for (i = 0; i < nl / bs; i++) {
717c4762a1bSJed Brown             PetscInt b1, b2;
718c4762a1bSJed Brown 
719c4762a1bSJed Brown             for (b1 = 0; b1 < bs; b1++) {
720c4762a1bSJed Brown               for (b2 = 0; b2 < bs; b2++) {
721c4762a1bSJed Brown                 if (PetscAbsScalar(isbd[i * bs * bs + b1 * bs + b2] - aijbd[i * bs * bs + b1 * bs + b2]) > PETSC_SMALL) ok = PETSC_FALSE;
722c4762a1bSJed Brown                 if (!ok) {
7239566063dSJacob 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])));
724c4762a1bSJed Brown                   break;
725c4762a1bSJed Brown                 }
726c4762a1bSJed Brown               }
727c4762a1bSJed Brown               if (!ok) break;
728c4762a1bSJed Brown             }
729c4762a1bSJed Brown             if (!ok) break;
730c4762a1bSJed Brown           }
7319566063dSJacob Faibussowitsch           PetscCall(MatDestroy(&Abd));
7329566063dSJacob Faibussowitsch           PetscCall(MatDestroy(&Bbd));
7339566063dSJacob Faibussowitsch           PetscCall(PetscFree(vals));
7349566063dSJacob Faibussowitsch           PetscCall(ISDestroy(&is));
7359566063dSJacob Faibussowitsch           PetscCall(ISDestroy(&bis));
736c4762a1bSJed Brown         }
737c4762a1bSJed Brown       }
738c4762a1bSJed Brown     }
739c4762a1bSJed Brown   }
740d0dbe9f7SStefano Zampini 
741d0dbe9f7SStefano Zampini   /* test MatGetDiagonalBlock */
742d0dbe9f7SStefano Zampini   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatGetDiagonalBlock\n"));
743d0dbe9f7SStefano Zampini   PetscCall(MatGetDiagonalBlock(A, &A2));
744d0dbe9f7SStefano Zampini   PetscCall(MatGetDiagonalBlock(B, &B2));
745d0dbe9f7SStefano Zampini   PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatGetDiagonalBlock"));
746d0dbe9f7SStefano Zampini   PetscCall(MatScale(A, 2.0));
747d0dbe9f7SStefano Zampini   PetscCall(MatScale(B, 2.0));
748d0dbe9f7SStefano Zampini   PetscCall(MatGetDiagonalBlock(A, &A2));
749d0dbe9f7SStefano Zampini   PetscCall(MatGetDiagonalBlock(B, &B2));
750d0dbe9f7SStefano Zampini   PetscCall(CheckMat(A2, B2, PETSC_FALSE, "MatGetDiagonalBlock"));
751d0dbe9f7SStefano Zampini 
752*4f58015eSStefano Zampini   /* test MatISSetAllowRepeated on a MATIS */
753*4f58015eSStefano Zampini   PetscCall(MatISSetAllowRepeated(A, allow_repeated));
754*4f58015eSStefano Zampini   if (allow_repeated) { /* original MATIS maybe with repeated entries, test assembling of local matrices */
755*4f58015eSStefano Zampini     Mat lA, lA2;
756*4f58015eSStefano Zampini 
757*4f58015eSStefano Zampini     for (PetscInt i = 0; i < 1; i++) { /* TODO: make MatScatter inherit from MATSHELL and support MatProducts */
758*4f58015eSStefano Zampini       PetscBool usemult = PETSC_FALSE;
759*4f58015eSStefano Zampini 
760*4f58015eSStefano Zampini       PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
761*4f58015eSStefano Zampini       if (i) {
762*4f58015eSStefano Zampini         Mat tA;
763*4f58015eSStefano Zampini 
764*4f58015eSStefano Zampini         usemult = PETSC_TRUE;
765*4f58015eSStefano Zampini         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatISSetAllowRepeated(false) with possibly repeated entries and local shell matrices\n"));
766*4f58015eSStefano Zampini         PetscCall(MatISGetLocalMat(A2, &lA2));
767*4f58015eSStefano Zampini         PetscCall(MatConvert(lA2, MATSHELL, MAT_INITIAL_MATRIX, &tA));
768*4f58015eSStefano Zampini         PetscCall(MatISRestoreLocalMat(A2, &lA2));
769*4f58015eSStefano Zampini         PetscCall(MatISSetLocalMat(A2, tA));
770*4f58015eSStefano Zampini         PetscCall(MatDestroy(&tA));
771*4f58015eSStefano Zampini       } else {
772*4f58015eSStefano Zampini         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatISSetAllowRepeated(false) with possibly repeated entries\n"));
773*4f58015eSStefano Zampini       }
774*4f58015eSStefano Zampini       PetscCall(MatISSetAllowRepeated(A2, PETSC_FALSE));
775*4f58015eSStefano Zampini       PetscCall(MatISGetLocalMat(A, &lA));
776*4f58015eSStefano Zampini       PetscCall(MatISGetLocalMat(A2, &lA2));
777*4f58015eSStefano Zampini       if (!repmap) PetscCall(CheckMat(lA, lA2, usemult, "MatISSetAllowRepeated(false) with non-repeated entries"));
778*4f58015eSStefano Zampini       PetscCall(MatISRestoreLocalMat(A, &lA));
779*4f58015eSStefano Zampini       PetscCall(MatISRestoreLocalMat(A2, &lA2));
780*4f58015eSStefano Zampini       if (repmap) PetscCall(CheckMat(A2, B, usemult, "MatISSetAllowRepeated(false) with repeated entries"));
781*4f58015eSStefano Zampini       else PetscCall(CheckMat(A2, B, usemult, "MatISSetAllowRepeated(false) with non-repeated entries"));
782*4f58015eSStefano Zampini       PetscCall(MatDestroy(&A2));
783*4f58015eSStefano Zampini     }
784*4f58015eSStefano Zampini   } else { /* original matis with non-repeated entries, this should only recreate the local matrices */
785*4f58015eSStefano Zampini     Mat       lA;
786*4f58015eSStefano Zampini     PetscBool flg;
787*4f58015eSStefano Zampini 
788*4f58015eSStefano Zampini     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatISSetAllowRepeated(true) with non repeated entries\n"));
789*4f58015eSStefano Zampini     PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &A2));
790*4f58015eSStefano Zampini     PetscCall(MatISSetAllowRepeated(A2, PETSC_TRUE));
791*4f58015eSStefano Zampini     PetscCall(MatISGetLocalMat(A2, &lA));
792*4f58015eSStefano Zampini     PetscCall(MatAssembled(lA, &flg));
793*4f58015eSStefano Zampini     PetscCheck(!flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Local mat should be unassembled");
794*4f58015eSStefano Zampini     PetscCall(MatISRestoreLocalMat(A2, &lA));
795*4f58015eSStefano Zampini     PetscCall(MatDestroy(&A2));
796*4f58015eSStefano Zampini   }
797*4f58015eSStefano Zampini 
798c4762a1bSJed Brown   /* free testing matrices */
7999566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingDestroy(&cmap));
8009566063dSJacob Faibussowitsch   PetscCall(ISLocalToGlobalMappingDestroy(&rmap));
8019566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&A));
8029566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B));
8039566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
804b122ec5aSJacob Faibussowitsch   return 0;
805c4762a1bSJed Brown }
806c4762a1bSJed Brown 
807d71ae5a4SJacob Faibussowitsch PetscErrorCode CheckMat(Mat A, Mat B, PetscBool usemult, const char *func)
808d71ae5a4SJacob Faibussowitsch {
809c4762a1bSJed Brown   Mat       Bcheck;
810c4762a1bSJed Brown   PetscReal error;
811c4762a1bSJed Brown 
812c4762a1bSJed Brown   PetscFunctionBeginUser;
813c4762a1bSJed Brown   if (!usemult && B) {
814c4762a1bSJed Brown     PetscBool hasnorm;
815c4762a1bSJed Brown 
8169566063dSJacob Faibussowitsch     PetscCall(MatHasOperation(B, MATOP_NORM, &hasnorm));
817c4762a1bSJed Brown     if (!hasnorm) usemult = PETSC_TRUE;
818c4762a1bSJed Brown   }
819c4762a1bSJed Brown   if (!usemult) {
820c4762a1bSJed Brown     if (B) {
821c4762a1bSJed Brown       MatType Btype;
822c4762a1bSJed Brown 
8239566063dSJacob Faibussowitsch       PetscCall(MatGetType(B, &Btype));
8249566063dSJacob Faibussowitsch       PetscCall(MatConvert(A, Btype, MAT_INITIAL_MATRIX, &Bcheck));
825c4762a1bSJed Brown     } else {
8269566063dSJacob Faibussowitsch       PetscCall(MatConvert(A, MATAIJ, MAT_INITIAL_MATRIX, &Bcheck));
827c4762a1bSJed Brown     }
828c4762a1bSJed Brown     if (B) { /* if B is present, subtract it */
8299566063dSJacob Faibussowitsch       PetscCall(MatAXPY(Bcheck, -1., B, DIFFERENT_NONZERO_PATTERN));
830c4762a1bSJed Brown     }
8319566063dSJacob Faibussowitsch     PetscCall(MatNorm(Bcheck, NORM_INFINITY, &error));
832c4762a1bSJed Brown     if (error > PETSC_SQRT_MACHINE_EPSILON) {
833c4762a1bSJed Brown       ISLocalToGlobalMapping rl2g, cl2g;
834c4762a1bSJed Brown 
835d0dbe9f7SStefano Zampini       PetscCall(PetscObjectSetName((PetscObject)Bcheck, "Bcheck"));
8369566063dSJacob Faibussowitsch       PetscCall(MatView(Bcheck, NULL));
837c4762a1bSJed Brown       if (B) {
838d0dbe9f7SStefano Zampini         PetscCall(PetscObjectSetName((PetscObject)B, "B"));
8399566063dSJacob Faibussowitsch         PetscCall(MatView(B, NULL));
8409566063dSJacob Faibussowitsch         PetscCall(MatDestroy(&Bcheck));
8419566063dSJacob Faibussowitsch         PetscCall(MatConvert(A, MATAIJ, MAT_INITIAL_MATRIX, &Bcheck));
842d0dbe9f7SStefano Zampini         PetscCall(PetscObjectSetName((PetscObject)Bcheck, "Assembled A"));
8439566063dSJacob Faibussowitsch         PetscCall(MatView(Bcheck, NULL));
844c4762a1bSJed Brown       }
8459566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Bcheck));
846d0dbe9f7SStefano Zampini       PetscCall(PetscObjectSetName((PetscObject)A, "A"));
8479566063dSJacob Faibussowitsch       PetscCall(MatView(A, NULL));
8489566063dSJacob Faibussowitsch       PetscCall(MatGetLocalToGlobalMapping(A, &rl2g, &cl2g));
849d0dbe9f7SStefano Zampini       if (rl2g) PetscCall(ISLocalToGlobalMappingView(rl2g, NULL));
850d0dbe9f7SStefano Zampini       if (cl2g) PetscCall(ISLocalToGlobalMappingView(cl2g, NULL));
851d0dbe9f7SStefano Zampini       SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "ERROR ON %s: %g", func, (double)error);
852c4762a1bSJed Brown     }
8539566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&Bcheck));
854c4762a1bSJed Brown   } else {
855c4762a1bSJed Brown     PetscBool ok, okt;
856c4762a1bSJed Brown 
8579566063dSJacob Faibussowitsch     PetscCall(MatMultEqual(A, B, 3, &ok));
8589566063dSJacob Faibussowitsch     PetscCall(MatMultTransposeEqual(A, B, 3, &okt));
859e00437b9SBarry Smith     PetscCheck(ok && okt, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "ERROR ON %s: mult ok ?  %d, multtranspose ok ? %d", func, ok, okt);
860c4762a1bSJed Brown   }
8613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
862c4762a1bSJed Brown }
863c4762a1bSJed Brown 
864d71ae5a4SJacob Faibussowitsch PetscErrorCode TestMatZeroRows(Mat A, Mat Afull, PetscBool squaretest, IS is, PetscScalar diag)
865d71ae5a4SJacob Faibussowitsch {
866c4762a1bSJed Brown   Mat                    B, Bcheck, B2 = NULL, lB;
867c4762a1bSJed Brown   Vec                    x = NULL, b = NULL, b2 = NULL;
868c4762a1bSJed Brown   ISLocalToGlobalMapping l2gr, l2gc;
869c4762a1bSJed Brown   PetscReal              error;
870c4762a1bSJed Brown   char                   diagstr[16];
871c4762a1bSJed Brown   const PetscInt        *idxs;
872c4762a1bSJed Brown   PetscInt               rst, ren, i, n, N, d;
873c4762a1bSJed Brown   PetscMPIInt            rank;
874c4762a1bSJed Brown   PetscBool              miss, haszerorows;
875c4762a1bSJed Brown 
876c4762a1bSJed Brown   PetscFunctionBeginUser;
877c4762a1bSJed Brown   if (diag == 0.) {
878c6a7a370SJeremy L Thompson     PetscCall(PetscStrncpy(diagstr, "zero", sizeof(diagstr)));
879c4762a1bSJed Brown   } else {
880c6a7a370SJeremy L Thompson     PetscCall(PetscStrncpy(diagstr, "nonzero", sizeof(diagstr)));
881c4762a1bSJed Brown   }
8829566063dSJacob Faibussowitsch   PetscCall(ISView(is, NULL));
8839566063dSJacob Faibussowitsch   PetscCall(MatGetLocalToGlobalMapping(A, &l2gr, &l2gc));
884c4762a1bSJed Brown   /* tests MatDuplicate and MatCopy */
885c4762a1bSJed Brown   if (diag == 0.) {
8869566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(A, MAT_COPY_VALUES, &B));
887c4762a1bSJed Brown   } else {
8889566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(A, MAT_DO_NOT_COPY_VALUES, &B));
8899566063dSJacob Faibussowitsch     PetscCall(MatCopy(A, B, SAME_NONZERO_PATTERN));
890c4762a1bSJed Brown   }
8919566063dSJacob Faibussowitsch   PetscCall(MatISGetLocalMat(B, &lB));
8929566063dSJacob Faibussowitsch   PetscCall(MatHasOperation(lB, MATOP_ZERO_ROWS, &haszerorows));
893c4762a1bSJed Brown   if (squaretest && haszerorows) {
8949566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(B, &x, &b));
8959566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &B2));
8969566063dSJacob Faibussowitsch     PetscCall(VecSetLocalToGlobalMapping(b, l2gr));
8979566063dSJacob Faibussowitsch     PetscCall(VecSetLocalToGlobalMapping(x, l2gc));
8989566063dSJacob Faibussowitsch     PetscCall(VecSetRandom(x, NULL));
8999566063dSJacob Faibussowitsch     PetscCall(VecSetRandom(b, NULL));
900c4762a1bSJed Brown     /* mimic b[is] = x[is] */
9019566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(b, &b2));
9029566063dSJacob Faibussowitsch     PetscCall(VecSetLocalToGlobalMapping(b2, l2gr));
9039566063dSJacob Faibussowitsch     PetscCall(VecCopy(b, b2));
9049566063dSJacob Faibussowitsch     PetscCall(ISGetLocalSize(is, &n));
9059566063dSJacob Faibussowitsch     PetscCall(ISGetIndices(is, &idxs));
9069566063dSJacob Faibussowitsch     PetscCall(VecGetSize(x, &N));
907c4762a1bSJed Brown     for (i = 0; i < n; i++) {
908c4762a1bSJed Brown       if (0 <= idxs[i] && idxs[i] < N) {
9099566063dSJacob Faibussowitsch         PetscCall(VecSetValue(b2, idxs[i], diag, INSERT_VALUES));
9109566063dSJacob Faibussowitsch         PetscCall(VecSetValue(x, idxs[i], 1., INSERT_VALUES));
911c4762a1bSJed Brown       }
912c4762a1bSJed Brown     }
9139566063dSJacob Faibussowitsch     PetscCall(VecAssemblyBegin(b2));
9149566063dSJacob Faibussowitsch     PetscCall(VecAssemblyEnd(b2));
9159566063dSJacob Faibussowitsch     PetscCall(VecAssemblyBegin(x));
9169566063dSJacob Faibussowitsch     PetscCall(VecAssemblyEnd(x));
9179566063dSJacob Faibussowitsch     PetscCall(ISRestoreIndices(is, &idxs));
918c4762a1bSJed Brown     /*  test ZeroRows on MATIS */
9199566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRows (diag %s)\n", diagstr));
9209566063dSJacob Faibussowitsch     PetscCall(MatZeroRowsIS(B, is, diag, x, b));
9219566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRowsColumns (diag %s)\n", diagstr));
9229566063dSJacob Faibussowitsch     PetscCall(MatZeroRowsColumnsIS(B2, is, diag, NULL, NULL));
923c4762a1bSJed Brown   } else if (haszerorows) {
924c4762a1bSJed Brown     /*  test ZeroRows on MATIS */
9259566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatZeroRows (diag %s)\n", diagstr));
9269566063dSJacob Faibussowitsch     PetscCall(MatZeroRowsIS(B, is, diag, NULL, NULL));
927c4762a1bSJed Brown     b = b2 = x = NULL;
928c4762a1bSJed Brown   } else {
9299566063dSJacob Faibussowitsch     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Skipping MatZeroRows (diag %s)\n", diagstr));
930c4762a1bSJed Brown     b = b2 = x = NULL;
931c4762a1bSJed Brown   }
932c4762a1bSJed Brown 
933c4762a1bSJed Brown   if (squaretest && haszerorows) {
9349566063dSJacob Faibussowitsch     PetscCall(VecAXPY(b2, -1., b));
9359566063dSJacob Faibussowitsch     PetscCall(VecNorm(b2, NORM_INFINITY, &error));
936e00437b9SBarry Smith     PetscCheck(error <= PETSC_SQRT_MACHINE_EPSILON, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "ERROR IN ZEROROWS ON B %g (diag %s)", (double)error, diagstr);
937c4762a1bSJed Brown   }
938c4762a1bSJed Brown 
939c4762a1bSJed Brown   /* test MatMissingDiagonal */
9409566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Test MatMissingDiagonal\n"));
9419566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
9429566063dSJacob Faibussowitsch   PetscCall(MatMissingDiagonal(B, &miss, &d));
9439566063dSJacob Faibussowitsch   PetscCall(MatGetOwnershipRange(B, &rst, &ren));
9449566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD));
9459566063dSJacob 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));
9469566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(PETSC_VIEWER_STDOUT_WORLD));
9479566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD));
948c4762a1bSJed Brown 
9499566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&x));
9509566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&b));
9519566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&b2));
952c4762a1bSJed Brown 
953c4762a1bSJed Brown   /* check the result of ZeroRows with that from MPIAIJ routines
954c4762a1bSJed Brown      assuming that MatConvert_IS_XAIJ and MatZeroRows_MPIAIJ work fine */
955c4762a1bSJed Brown   if (haszerorows) {
9569566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(Afull, MAT_COPY_VALUES, &Bcheck));
9579566063dSJacob Faibussowitsch     PetscCall(MatSetOption(Bcheck, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
9589566063dSJacob Faibussowitsch     PetscCall(MatZeroRowsIS(Bcheck, is, diag, NULL, NULL));
9599566063dSJacob Faibussowitsch     PetscCall(CheckMat(B, Bcheck, PETSC_FALSE, "Zerorows"));
9609566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&Bcheck));
961c4762a1bSJed Brown   }
9629566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&B));
963c4762a1bSJed Brown 
964c4762a1bSJed Brown   if (B2) { /* test MatZeroRowsColumns */
9659566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(Afull, MAT_COPY_VALUES, &B));
9669566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
9679566063dSJacob Faibussowitsch     PetscCall(MatZeroRowsColumnsIS(B, is, diag, NULL, NULL));
9689566063dSJacob Faibussowitsch     PetscCall(CheckMat(B2, B, PETSC_FALSE, "MatZeroRowsColumns"));
9699566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
9709566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B2));
971c4762a1bSJed Brown   }
9723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
973c4762a1bSJed Brown }
974c4762a1bSJed Brown 
975c4762a1bSJed Brown /*TEST
976c4762a1bSJed Brown 
977c4762a1bSJed Brown    test:
978c4762a1bSJed Brown       args: -test_trans
979c4762a1bSJed Brown 
980c4762a1bSJed Brown    test:
981c4762a1bSJed Brown       suffix: 2
982c4762a1bSJed Brown       nsize: 4
983*4f58015eSStefano Zampini       args: -mat_is_convert_local_nest -nr 3 -nc 4
984c4762a1bSJed Brown 
985c4762a1bSJed Brown    test:
986c4762a1bSJed Brown       suffix: 3
987c4762a1bSJed Brown       nsize: 5
988*4f58015eSStefano Zampini       args: -m 11 -n 10 -mat_is_convert_local_nest -nr 2 -nc 1
989c4762a1bSJed Brown 
990c4762a1bSJed Brown    test:
991c4762a1bSJed Brown       suffix: 4
992c4762a1bSJed Brown       nsize: 6
993c4762a1bSJed Brown       args: -m 9 -n 12 -test_trans -nr 2 -nc 7
994c4762a1bSJed Brown 
995c4762a1bSJed Brown    test:
996c4762a1bSJed Brown       suffix: 5
997c4762a1bSJed Brown       nsize: 6
998c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 3 -nc 1
999c4762a1bSJed Brown 
1000c4762a1bSJed Brown    test:
1001c4762a1bSJed Brown       suffix: 6
1002c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap
1003c4762a1bSJed Brown 
1004c4762a1bSJed Brown    test:
1005c4762a1bSJed Brown       suffix: 7
1006c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap
1007c4762a1bSJed Brown 
1008c4762a1bSJed Brown    test:
1009c4762a1bSJed Brown       suffix: 8
1010c4762a1bSJed Brown       args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap
1011c4762a1bSJed Brown 
1012c4762a1bSJed Brown    test:
1013c4762a1bSJed Brown       suffix: 9
1014c4762a1bSJed Brown       nsize: 5
1015c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap
1016c4762a1bSJed Brown 
1017c4762a1bSJed Brown    test:
1018c4762a1bSJed Brown       suffix: 10
1019c4762a1bSJed Brown       nsize: 5
1020c4762a1bSJed Brown       args: -m 12 -n 12 -test_trans -nr 2 -nc 3 -diffmap -permmap
1021c4762a1bSJed Brown 
1022c20d7725SJed Brown    test:
1023c20d7725SJed Brown       suffix: vscat_default
1024c4762a1bSJed Brown       nsize: 5
1025c4762a1bSJed Brown       args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -permmap
1026c4762a1bSJed Brown       output_file: output/ex23_11.out
1027c4762a1bSJed Brown 
1028c4762a1bSJed Brown    test:
1029c4762a1bSJed Brown       suffix: 12
1030c4762a1bSJed Brown       nsize: 3
1031*4f58015eSStefano Zampini       args: -m 12 -n 12 -symmetric -mat_is_localmat_type sbaij -test_trans -nr 2 -nc 3
1032c4762a1bSJed Brown 
1033c4762a1bSJed Brown    testset:
1034c4762a1bSJed Brown       output_file: output/ex23_13.out
1035c4762a1bSJed Brown       nsize: 3
1036c4762a1bSJed Brown       args: -m 12 -n 17 -test_trans -nr 2 -nc 3 -diffmap -permmap
1037c4762a1bSJed Brown       filter: grep -v "type:"
1038c4762a1bSJed Brown       test:
1039c4762a1bSJed Brown         suffix: baij
1040*4f58015eSStefano Zampini         args: -mat_is_localmat_type baij
1041c4762a1bSJed Brown       test:
1042c4762a1bSJed Brown         requires: viennacl
1043c4762a1bSJed Brown         suffix: viennacl
1044*4f58015eSStefano Zampini         args: -mat_is_localmat_type aijviennacl
1045c4762a1bSJed Brown       test:
1046c4762a1bSJed Brown         requires: cuda
1047c4762a1bSJed Brown         suffix: cusparse
1048*4f58015eSStefano Zampini         args: -mat_is_localmat_type aijcusparse
1049c4762a1bSJed Brown 
1050e432b41dSStefano Zampini    test:
1051e432b41dSStefano Zampini       suffix: negrep
1052e432b41dSStefano Zampini       nsize: {{1 3}separate output}
1053*4f58015eSStefano 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
1054*4f58015eSStefano Zampini 
1055*4f58015eSStefano Zampini    test:
1056*4f58015eSStefano Zampini       suffix: negrep_allowrep
1057*4f58015eSStefano Zampini       nsize: {{1 3}separate output}
1058*4f58015eSStefano 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
1059e432b41dSStefano Zampini 
1060c4762a1bSJed Brown TEST*/
1061