1 static char help[] = "Test MatAXPY()\n\n"; 2 3 #include <petscmat.h> 4 5 int main(int argc, char **args) 6 { 7 Mat C, C1, C2, CU; 8 PetscScalar v; 9 PetscInt Ii, J, Istart, Iend; 10 PetscInt i, j, m = 3, n; 11 PetscMPIInt size; 12 PetscBool mat_nonsymmetric = PETSC_FALSE, flg; 13 MatInfo info; 14 15 PetscFunctionBeginUser; 16 PetscCall(PetscInitialize(&argc, &args, (char *)0, help)); 17 PetscCall(PetscOptionsGetInt(NULL, NULL, "-m", &m, NULL)); 18 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 19 n = 2 * size; 20 21 /* Set flag if we are doing a nonsymmetric problem; the default is symmetric. */ 22 PetscCall(PetscOptionsGetBool(NULL, NULL, "-mat_nonsym", &mat_nonsymmetric, NULL)); 23 24 PetscCall(MatCreate(PETSC_COMM_WORLD, &C)); 25 PetscCall(MatSetSizes(C, PETSC_DECIDE, PETSC_DECIDE, m * n, m * n)); 26 PetscCall(MatSetFromOptions(C)); 27 PetscCall(MatSeqAIJSetPreallocation(C, 5, NULL)); 28 PetscCall(MatMPIAIJSetPreallocation(C, 5, NULL, 5, NULL)); 29 30 PetscCall(MatGetOwnershipRange(C, &Istart, &Iend)); 31 for (Ii = Istart; Ii < Iend; Ii++) { 32 v = -1.0; 33 i = Ii / n; 34 j = Ii - i * n; 35 if (i > 0) { 36 J = Ii - n; 37 PetscCall(MatSetValues(C, 1, &Ii, 1, &J, &v, ADD_VALUES)); 38 } 39 if (i < m - 1) { 40 J = Ii + n; 41 PetscCall(MatSetValues(C, 1, &Ii, 1, &J, &v, ADD_VALUES)); 42 } 43 if (j > 0) { 44 J = Ii - 1; 45 PetscCall(MatSetValues(C, 1, &Ii, 1, &J, &v, ADD_VALUES)); 46 } 47 if (j < n - 1) { 48 J = Ii + 1; 49 PetscCall(MatSetValues(C, 1, &Ii, 1, &J, &v, ADD_VALUES)); 50 } 51 v = 4.0; 52 PetscCall(MatSetValues(C, 1, &Ii, 1, &Ii, &v, ADD_VALUES)); 53 } 54 55 /* Make the matrix nonsymmetric if desired */ 56 if (mat_nonsymmetric) { 57 for (Ii = Istart; Ii < Iend; Ii++) { 58 v = -1.5; 59 i = Ii / n; 60 if (i > 1) { 61 J = Ii - n - 1; 62 PetscCall(MatSetValues(C, 1, &Ii, 1, &J, &v, ADD_VALUES)); 63 } 64 } 65 } else { 66 PetscCall(MatSetOption(C, MAT_SYMMETRIC, PETSC_TRUE)); 67 PetscCall(MatSetOption(C, MAT_SYMMETRY_ETERNAL, PETSC_TRUE)); 68 } 69 PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 70 PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 71 PetscCall(PetscObjectSetName((PetscObject)C, "C")); 72 PetscCall(MatViewFromOptions(C, NULL, "-view")); 73 74 /* C1 = 2.0*C1 + C, C1 is anti-diagonal and has different non-zeros than C */ 75 PetscCall(MatCreate(PETSC_COMM_WORLD, &C1)); 76 PetscCall(MatSetSizes(C1, PETSC_DECIDE, PETSC_DECIDE, m * n, m * n)); 77 PetscCall(MatSetFromOptions(C1)); 78 PetscCall(MatSeqAIJSetPreallocation(C1, 1, NULL)); 79 PetscCall(MatMPIAIJSetPreallocation(C1, 1, NULL, 1, NULL)); 80 for (Ii = Istart; Ii < Iend; Ii++) { 81 v = 1.0; 82 i = m * n - Ii - 1; 83 j = Ii; 84 PetscCall(MatSetValues(C1, 1, &i, 1, &j, &v, ADD_VALUES)); 85 } 86 PetscCall(MatAssemblyBegin(C1, MAT_FINAL_ASSEMBLY)); 87 PetscCall(MatAssemblyEnd(C1, MAT_FINAL_ASSEMBLY)); 88 PetscCall(PetscObjectSetName((PetscObject)C1, "C1")); 89 PetscCall(MatViewFromOptions(C1, NULL, "-view")); 90 PetscCall(MatDuplicate(C1, MAT_COPY_VALUES, &CU)); 91 92 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " MatAXPY(C1,2.0,C,DIFFERENT_NONZERO_PATTERN)...\n")); 93 PetscCall(MatAXPY(C1, 2.0, C, DIFFERENT_NONZERO_PATTERN)); 94 PetscCall(MatAXPY(CU, 2.0, C, UNKNOWN_NONZERO_PATTERN)); 95 PetscCall(MatGetInfo(C1, MAT_GLOBAL_SUM, &info)); 96 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " C1: nz_allocated = %g; nz_used = %g; nz_unneeded = %g\n", info.nz_allocated, info.nz_used, info.nz_unneeded)); 97 PetscCall(MatViewFromOptions(C1, NULL, "-view")); 98 PetscCall(MatMultEqual(CU, C1, 10, &flg)); 99 if (!flg) { 100 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error UNKNOWN_NONZERO_PATTERN (supposedly DIFFERENT_NONZERO_PATTERN)\n")); 101 PetscCall(MatViewFromOptions(CU, NULL, "-view")); 102 } 103 PetscCall(MatDestroy(&CU)); 104 105 /* Secondly, compute C1 = 2.0*C2 + C1, C2 has non-zero pattern of C */ 106 PetscCall(MatDuplicate(C, MAT_DO_NOT_COPY_VALUES, &C2)); 107 PetscCall(MatDuplicate(C1, MAT_COPY_VALUES, &CU)); 108 109 for (Ii = Istart; Ii < Iend; Ii++) { 110 v = 1.0; 111 PetscCall(MatSetValues(C2, 1, &Ii, 1, &Ii, &v, ADD_VALUES)); 112 } 113 PetscCall(MatAssemblyBegin(C2, MAT_FINAL_ASSEMBLY)); 114 PetscCall(MatAssemblyEnd(C2, MAT_FINAL_ASSEMBLY)); 115 PetscCall(PetscObjectSetName((PetscObject)C2, "C2")); 116 PetscCall(MatViewFromOptions(C2, NULL, "-view")); 117 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " MatAXPY(C1,2.0,C2,SUBSET_NONZERO_PATTERN)...\n")); 118 PetscCall(MatAXPY(C1, 2.0, C2, SUBSET_NONZERO_PATTERN)); 119 PetscCall(MatAXPY(CU, 2.0, C2, UNKNOWN_NONZERO_PATTERN)); 120 PetscCall(MatGetInfo(C1, MAT_GLOBAL_SUM, &info)); 121 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " C1: nz_allocated = %g; nz_used = %g; nz_unneeded = %g\n", info.nz_allocated, info.nz_used, info.nz_unneeded)); 122 PetscCall(MatViewFromOptions(C1, NULL, "-view")); 123 PetscCall(MatMultEqual(CU, C1, 10, &flg)); 124 if (!flg) { 125 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error UNKNOWN_NONZERO_PATTERN (supposedly SUBSET_NONZERO_PATTERN)\n")); 126 PetscCall(MatViewFromOptions(CU, NULL, "-view")); 127 } 128 PetscCall(MatDestroy(&CU)); 129 130 /* Test SAME_NONZERO_PATTERN computing C2 = C2 + 2.0 * C */ 131 PetscCall(MatDuplicate(C2, MAT_COPY_VALUES, &CU)); 132 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " MatAXPY(C2,2.0,C,SAME_NONZERO_PATTERN)...\n")); 133 PetscCall(MatAXPY(C2, 2.0, C, SAME_NONZERO_PATTERN)); 134 PetscCall(MatAXPY(CU, 2.0, C, UNKNOWN_NONZERO_PATTERN)); 135 PetscCall(MatGetInfo(C2, MAT_GLOBAL_SUM, &info)); 136 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " C2: nz_allocated = %g; nz_used = %g; nz_unneeded = %g\n", info.nz_allocated, info.nz_used, info.nz_unneeded)); 137 PetscCall(MatViewFromOptions(C2, NULL, "-view")); 138 PetscCall(MatMultEqual(CU, C2, 10, &flg)); 139 if (!flg) { 140 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Error UNKNOWN_NONZERO_PATTERN (supposedly SUBSET_NONZERO_PATTERN)\n")); 141 PetscCall(MatViewFromOptions(CU, NULL, "-view")); 142 } 143 PetscCall(MatDestroy(&CU)); 144 145 PetscCall(MatDestroy(&C1)); 146 PetscCall(MatDestroy(&C2)); 147 PetscCall(MatDestroy(&C)); 148 149 PetscCall(PetscFinalize()); 150 return 0; 151 } 152 153 /*TEST 154 155 test: 156 suffix: 1 157 filter: grep -v " type:" | grep -v "Mat Object" 158 args: -view 159 diff_args: -j 160 161 test: 162 output_file: output/ex132_1.out 163 requires: cuda 164 suffix: 1_cuda 165 filter: grep -v " type:" | grep -v "Mat Object" 166 args: -view -mat_type aijcusparse 167 diff_args: -j 168 169 test: 170 output_file: output/ex132_1.out 171 requires: kokkos_kernels 172 suffix: 1_kokkos 173 filter: grep -v " type:" | grep -v "Mat Object" 174 args: -view -mat_type aijkokkos 175 diff_args: -j 176 177 test: 178 suffix: 2 179 filter: grep -v " type:" | grep -v "Mat Object" 180 args: -view -mat_nonsym 181 diff_args: -j 182 183 test: 184 output_file: output/ex132_2.out 185 requires: cuda 186 suffix: 2_cuda 187 filter: grep -v " type:" | grep -v "Mat Object" 188 args: -view -mat_type aijcusparse -mat_nonsym 189 diff_args: -j 190 191 test: 192 output_file: output/ex132_2.out 193 requires: kokkos_kernels 194 suffix: 2_kokkos 195 filter: grep -v " type:" | grep -v "Mat Object" 196 args: -view -mat_type aijkokkos -mat_nonsym 197 diff_args: -j 198 199 test: 200 nsize: 2 201 suffix: 1_par 202 filter: grep -v " type:" | grep -v "Mat Object" 203 args: -view 204 diff_args: -j 205 206 test: 207 nsize: 2 208 output_file: output/ex132_1_par.out 209 requires: cuda 210 suffix: 1_par_cuda 211 filter: grep -v " type:" | grep -v "Mat Object" 212 args: -view -mat_type aijcusparse 213 diff_args: -j 214 215 test: 216 nsize: 2 217 output_file: output/ex132_1_par.out 218 requires: kokkos_kernels 219 suffix: 1_par_kokkos 220 filter: grep -v " type:" | grep -v "Mat Object" 221 args: -view -mat_type aijkokkos 222 diff_args: -j 223 224 test: 225 nsize: 2 226 suffix: 2_par 227 filter: grep -v " type:" | grep -v "Mat Object" 228 args: -view -mat_nonsym 229 diff_args: -j 230 231 test: 232 nsize: 2 233 output_file: output/ex132_2_par.out 234 requires: cuda 235 suffix: 2_par_cuda 236 filter: grep -v " type:" | grep -v "Mat Object" 237 args: -view -mat_type aijcusparse -mat_nonsym 238 diff_args: -j 239 240 testset: 241 nsize: 2 242 output_file: output/ex132_2_par.out 243 requires: kokkos_kernels 244 filter: grep -v " type:" | grep -v "Mat Object" 245 args: -view -mat_type aijkokkos -mat_nonsym 246 diff_args: -j 247 test: 248 suffix: 2_par_kokkos_no_gpu_aware 249 args: -use_gpu_aware_mpi 0 250 test: 251 requires: defined(HAVE_MPI_GPU_AWARE) 252 suffix: 2_par_kokkos_gpu_aware 253 args: -use_gpu_aware_mpi 1 254 255 TEST*/ 256