1c4762a1bSJed Brown static char help[] = "Tests MatCopy() and MatStore/RetrieveValues().\n\n";
2c4762a1bSJed Brown
3c4762a1bSJed Brown #include <petscmat.h>
4c4762a1bSJed Brown
main(int argc,char ** args)5d71ae5a4SJacob Faibussowitsch int main(int argc, char **args)
6d71ae5a4SJacob Faibussowitsch {
7c4762a1bSJed Brown Mat C, A;
8c4762a1bSJed Brown PetscInt i, n = 10, midx[3], bs = 1;
9c4762a1bSJed Brown PetscScalar v[3];
10c4762a1bSJed Brown PetscBool flg, isAIJ;
11c4762a1bSJed Brown MatType type;
12c4762a1bSJed Brown PetscMPIInt size;
13c4762a1bSJed Brown
14327415f7SBarry Smith PetscFunctionBeginUser;
15*c8025a54SPierre Jolivet PetscCall(PetscInitialize(&argc, &args, NULL, help));
169566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
179566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-n", &n, NULL));
189566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, NULL, "-mat_block_size", &bs, NULL));
19c4762a1bSJed Brown
209566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &C));
219566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, PETSC_DECIDE, PETSC_DECIDE, n, n));
229566063dSJacob Faibussowitsch PetscCall(MatSetType(C, MATAIJ));
239566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(C));
249566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)C, "initial"));
25c4762a1bSJed Brown
269566063dSJacob Faibussowitsch PetscCall(MatGetType(C, &type));
27c4762a1bSJed Brown if (size == 1) {
289566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C, MATSEQAIJ, &isAIJ));
29c4762a1bSJed Brown } else {
309566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)C, MATMPIAIJ, &isAIJ));
31c4762a1bSJed Brown }
329566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(C, 3, NULL));
339566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(C, 3, NULL, 3, NULL));
349566063dSJacob Faibussowitsch PetscCall(MatSeqBAIJSetPreallocation(C, bs, 3, NULL));
359566063dSJacob Faibussowitsch PetscCall(MatMPIBAIJSetPreallocation(C, bs, 3, NULL, 3, NULL));
369566063dSJacob Faibussowitsch PetscCall(MatSeqSBAIJSetPreallocation(C, bs, 3, NULL));
379566063dSJacob Faibussowitsch PetscCall(MatMPISBAIJSetPreallocation(C, bs, 3, NULL, 3, NULL));
38c4762a1bSJed Brown
399371c9d4SSatish Balay v[0] = -1.;
409371c9d4SSatish Balay v[1] = 2.;
419371c9d4SSatish Balay v[2] = -1.;
42c4762a1bSJed Brown for (i = 1; i < n - 1; i++) {
439371c9d4SSatish Balay midx[2] = i - 1;
449371c9d4SSatish Balay midx[1] = i;
459371c9d4SSatish Balay midx[0] = i + 1;
469566063dSJacob Faibussowitsch PetscCall(MatSetValues(C, 1, &i, 3, midx, v, INSERT_VALUES));
47c4762a1bSJed Brown }
489371c9d4SSatish Balay i = 0;
499371c9d4SSatish Balay midx[0] = 0;
509371c9d4SSatish Balay midx[1] = 1;
519371c9d4SSatish Balay v[0] = 2.0;
529371c9d4SSatish Balay v[1] = -1.;
539566063dSJacob Faibussowitsch PetscCall(MatSetValues(C, 1, &i, 2, midx, v, INSERT_VALUES));
549371c9d4SSatish Balay i = n - 1;
559371c9d4SSatish Balay midx[0] = n - 2;
569371c9d4SSatish Balay midx[1] = n - 1;
579371c9d4SSatish Balay v[0] = -1.0;
589371c9d4SSatish Balay v[1] = 2.;
599566063dSJacob Faibussowitsch PetscCall(MatSetValues(C, 1, &i, 2, midx, v, INSERT_VALUES));
60c4762a1bSJed Brown
619566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
629566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
639566063dSJacob Faibussowitsch PetscCall(MatView(C, NULL));
649566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(C, NULL, "-view"));
65c4762a1bSJed Brown
66c4762a1bSJed Brown /* test matduplicate */
679566063dSJacob Faibussowitsch PetscCall(MatDuplicate(C, MAT_COPY_VALUES, &A));
689566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "duplicate_copy"));
699566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A, NULL, "-view"));
709566063dSJacob Faibussowitsch PetscCall(MatEqual(A, C, &flg));
7128b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_SUP, "MatDuplicate(C,MAT_COPY_VALUES,): Matrices are NOT equal");
729566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A));
73c4762a1bSJed Brown
74c4762a1bSJed Brown /* test matrices with different nonzero patterns - Note: A is created with different nonzero pattern of C! */
759566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
769566063dSJacob Faibussowitsch PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, n, n));
779566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(A));
789566063dSJacob Faibussowitsch PetscCall(MatSetUp(A));
799566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
809566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
81c4762a1bSJed Brown
829566063dSJacob Faibussowitsch PetscCall(MatCopy(C, A, DIFFERENT_NONZERO_PATTERN));
839566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "copy_diffnnz"));
849566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A, NULL, "-view"));
859566063dSJacob Faibussowitsch PetscCall(MatEqual(A, C, &flg));
8628b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_SUP, "MatCopy(C,A,DIFFERENT_NONZERO_PATTERN): Matrices are NOT equal");
87c4762a1bSJed Brown
88c4762a1bSJed Brown /* test matrices with same nonzero pattern */
899566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A));
909566063dSJacob Faibussowitsch PetscCall(MatDuplicate(C, MAT_DO_NOT_COPY_VALUES, &A));
919566063dSJacob Faibussowitsch PetscCall(MatCopy(C, A, SAME_NONZERO_PATTERN));
929566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "copy_samennz"));
939566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A, NULL, "-view"));
949566063dSJacob Faibussowitsch PetscCall(MatEqual(A, C, &flg));
9528b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_SUP, "MatCopy(C,A,SAME_NONZERO_PATTERN): Matrices are NOT equal");
96c4762a1bSJed Brown
97c4762a1bSJed Brown /* test subset nonzero pattern */
989566063dSJacob Faibussowitsch PetscCall(MatCopy(C, A, SUBSET_NONZERO_PATTERN));
999566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)A, "copy_subnnz"));
1009566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(A, NULL, "-view"));
1019566063dSJacob Faibussowitsch PetscCall(MatEqual(A, C, &flg));
10228b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_SUP, "MatCopy(C,A,SUBSET_NONZERO_PATTERN): Matrices are NOT equal");
103c4762a1bSJed Brown
104c4762a1bSJed Brown /* Test MatCopy on a matrix obtained after MatConvert from AIJ
105c4762a1bSJed Brown see https://lists.mcs.anl.gov/pipermail/petsc-dev/2019-April/024289.html */
1069566063dSJacob Faibussowitsch PetscCall(MatHasCongruentLayouts(C, &flg));
107c4762a1bSJed Brown if (flg) {
108c4762a1bSJed Brown Mat Cs, Cse;
109c4762a1bSJed Brown MatType Ctype, Cstype;
110c4762a1bSJed Brown
1119566063dSJacob Faibussowitsch PetscCall(MatGetType(C, &Ctype));
1129566063dSJacob Faibussowitsch PetscCall(MatTranspose(C, MAT_INITIAL_MATRIX, &Cs));
1139566063dSJacob Faibussowitsch PetscCall(MatAXPY(Cs, 1.0, C, DIFFERENT_NONZERO_PATTERN));
1149566063dSJacob Faibussowitsch PetscCall(MatConvert(Cs, MATAIJ, MAT_INPLACE_MATRIX, &Cs));
1159566063dSJacob Faibussowitsch PetscCall(MatSetOption(Cs, MAT_SYMMETRIC, PETSC_TRUE));
1169566063dSJacob Faibussowitsch PetscCall(MatGetType(Cs, &Cstype));
117c4762a1bSJed Brown
1189566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Cs, "symm_initial"));
1199566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(Cs, NULL, "-view"));
120c4762a1bSJed Brown
1219566063dSJacob Faibussowitsch PetscCall(MatConvert(Cs, Ctype, MAT_INITIAL_MATRIX, &Cse));
1229566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Cse, "symm_conv_init"));
1239566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(Cse, NULL, "-view"));
1249566063dSJacob Faibussowitsch PetscCall(MatMultEqual(Cs, Cse, 5, &flg));
12528b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatConvert MAT_INITIAL_MATRIX %s -> %s: Matrices are NOT multequal", Ctype, Cstype);
126c4762a1bSJed Brown
1279566063dSJacob Faibussowitsch PetscCall(MatConvert(Cs, Ctype, MAT_REUSE_MATRIX, &Cse));
1289566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Cse, "symm_conv_reuse"));
1299566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(Cse, NULL, "-view"));
1309566063dSJacob Faibussowitsch PetscCall(MatMultEqual(Cs, Cse, 5, &flg));
13128b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatConvert MAT_REUSE_MATRIX %s -> %s: Matrices are NOT multequal", Ctype, Cstype);
132c4762a1bSJed Brown
1339566063dSJacob Faibussowitsch PetscCall(MatCopy(Cs, Cse, SAME_NONZERO_PATTERN));
1349566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Cse, "symm_conv_copy_samennz"));
1359566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(Cse, NULL, "-view"));
1369566063dSJacob Faibussowitsch PetscCall(MatMultEqual(Cs, Cse, 5, &flg));
13728b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatCopy(...SAME_NONZERO_PATTERN) %s -> %s: Matrices are NOT multequal", Ctype, Cstype);
138c4762a1bSJed Brown
1399566063dSJacob Faibussowitsch PetscCall(MatCopy(Cs, Cse, SUBSET_NONZERO_PATTERN));
1409566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Cse, "symm_conv_copy_subnnz"));
1419566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(Cse, NULL, "-view"));
1429566063dSJacob Faibussowitsch PetscCall(MatMultEqual(Cs, Cse, 5, &flg));
14328b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatCopy(...SUBSET_NONZERO_PATTERN) %s -> %s: Matrices are NOT multequal", Ctype, Cstype);
144c4762a1bSJed Brown
1459566063dSJacob Faibussowitsch PetscCall(MatCopy(Cs, Cse, DIFFERENT_NONZERO_PATTERN));
1469566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)Cse, "symm_conv_copy_diffnnz"));
1479566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(Cse, NULL, "-view"));
1489566063dSJacob Faibussowitsch PetscCall(MatMultEqual(Cs, Cse, 5, &flg));
14928b400f6SJacob Faibussowitsch PetscCheck(flg, PETSC_COMM_SELF, PETSC_ERR_PLIB, "MatCopy(...DIFFERENT_NONZERO_PATTERN) %s -> %s: Matrices are NOT multequal", Ctype, Cstype);
150c4762a1bSJed Brown
1519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Cse));
1529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Cs));
153c4762a1bSJed Brown }
154c4762a1bSJed Brown
155c4762a1bSJed Brown /* test MatStore/RetrieveValues() */
156c4762a1bSJed Brown if (isAIJ) {
1579566063dSJacob Faibussowitsch PetscCall(MatSetOption(A, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE));
1589566063dSJacob Faibussowitsch PetscCall(MatStoreValues(A));
1599566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(A));
1609566063dSJacob Faibussowitsch PetscCall(MatRetrieveValues(A));
161c4762a1bSJed Brown }
162c4762a1bSJed Brown
1639566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C));
1649566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A));
1659566063dSJacob Faibussowitsch PetscCall(PetscFinalize());
166b122ec5aSJacob Faibussowitsch return 0;
167c4762a1bSJed Brown }
168c4762a1bSJed Brown
169c4762a1bSJed Brown /*TEST
170c4762a1bSJed Brown
171c4762a1bSJed Brown testset:
172c4762a1bSJed Brown nsize: {{1 2}separate output}
173c4762a1bSJed Brown args: -view ::ascii_info -mat_type {{aij baij sbaij mpiaij mpibaij mpisbaij}separate output} -mat_block_size {{1 2}separate output}
174c4762a1bSJed Brown
175c4762a1bSJed Brown TEST*/
176