1 2 static char help[] = "Tests MatHYPRE\n"; 3 4 #include <petscmathypre.h> 5 6 int main(int argc, char **args) { 7 Mat A, B, C, D; 8 Mat pAB, CD, CAB; 9 hypre_ParCSRMatrix *parcsr; 10 PetscReal err; 11 PetscInt i, j, N = 6, M = 6; 12 PetscBool flg, testptap = PETSC_TRUE, testmatmatmult = PETSC_TRUE; 13 PetscReal norm; 14 char file[256]; 15 16 PetscFunctionBeginUser; 17 PetscCall(PetscInitialize(&argc, &args, (char *)0, help)); 18 PetscCall(PetscOptionsGetString(NULL, NULL, "-f", file, sizeof(file), &flg)); 19 #if defined(PETSC_USE_COMPLEX) 20 testptap = PETSC_FALSE; 21 testmatmatmult = PETSC_FALSE; 22 PetscCall(PetscOptionsInsertString(NULL, "-options_left 0")); 23 #endif 24 PetscCall(PetscOptionsGetBool(NULL, NULL, "-ptap", &testptap, NULL)); 25 PetscCall(PetscOptionsGetBool(NULL, NULL, "-matmatmult", &testmatmatmult, NULL)); 26 PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 27 if (!flg) { /* Create a matrix and test MatSetValues */ 28 PetscMPIInt size; 29 30 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); 31 PetscCall(PetscOptionsGetInt(NULL, NULL, "-M", &M, NULL)); 32 PetscCall(PetscOptionsGetInt(NULL, NULL, "-N", &N, NULL)); 33 PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, M, N)); 34 PetscCall(MatSetType(A, MATAIJ)); 35 PetscCall(MatSeqAIJSetPreallocation(A, 9, NULL)); 36 PetscCall(MatMPIAIJSetPreallocation(A, 9, NULL, 9, NULL)); 37 PetscCall(MatCreate(PETSC_COMM_WORLD, &B)); 38 PetscCall(MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, M, N)); 39 PetscCall(MatSetType(B, MATHYPRE)); 40 if (M == N) { 41 PetscCall(MatHYPRESetPreallocation(B, 9, NULL, 9, NULL)); 42 } else { 43 PetscCall(MatHYPRESetPreallocation(B, 6, NULL, 6, NULL)); 44 } 45 if (M == N) { 46 for (i = 0; i < M; i++) { 47 PetscInt cols[] = {0, 1, 2, 3, 4, 5}; 48 PetscScalar vals[] = {0, 1. / size, 2. / size, 3. / size, 4. / size, 5. / size}; 49 for (j = i - 2; j < i + 1; j++) { 50 if (j >= N) { 51 PetscCall(MatSetValue(A, i, N - 1, (1. * j * N + i) / (3. * N * size), ADD_VALUES)); 52 PetscCall(MatSetValue(B, i, N - 1, (1. * j * N + i) / (3. * N * size), ADD_VALUES)); 53 } else if (i > j) { 54 PetscCall(MatSetValue(A, i, PetscMin(j, N - 1), (1. * j * N + i) / (2. * N * size), ADD_VALUES)); 55 PetscCall(MatSetValue(B, i, PetscMin(j, N - 1), (1. * j * N + i) / (2. * N * size), ADD_VALUES)); 56 } else { 57 PetscCall(MatSetValue(A, i, PetscMin(j, N - 1), -1. - (1. * j * N + i) / (4. * N * size), ADD_VALUES)); 58 PetscCall(MatSetValue(B, i, PetscMin(j, N - 1), -1. - (1. * j * N + i) / (4. * N * size), ADD_VALUES)); 59 } 60 } 61 PetscCall(MatSetValues(A, 1, &i, PetscMin(6, N), cols, vals, ADD_VALUES)); 62 PetscCall(MatSetValues(B, 1, &i, PetscMin(6, N), cols, vals, ADD_VALUES)); 63 } 64 } else { 65 PetscInt rows[2]; 66 PetscBool test_offproc = PETSC_FALSE; 67 68 PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_offproc", &test_offproc, NULL)); 69 if (test_offproc) { 70 const PetscInt *ranges; 71 PetscMPIInt rank; 72 73 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 74 PetscCall(MatGetOwnershipRanges(A, &ranges)); 75 rows[0] = ranges[(rank + 1) % size]; 76 rows[1] = ranges[(rank + 1) % size + 1]; 77 } else { 78 PetscCall(MatGetOwnershipRange(A, &rows[0], &rows[1])); 79 } 80 for (i = rows[0]; i < rows[1]; i++) { 81 PetscInt cols[] = {0, 1, 2, 3, 4, 5}; 82 PetscScalar vals[] = {-1, 1, -2, 2, -3, 3}; 83 84 PetscCall(MatSetValues(A, 1, &i, PetscMin(6, N), cols, vals, INSERT_VALUES)); 85 PetscCall(MatSetValues(B, 1, &i, PetscMin(6, N), cols, vals, INSERT_VALUES)); 86 } 87 } 88 /* MAT_FLUSH_ASSEMBLY currently not supported */ 89 PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 90 PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 91 PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 92 PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 93 94 #if defined(PETSC_USE_COMPLEX) 95 /* make the matrix imaginary */ 96 PetscCall(MatScale(A, PETSC_i)); 97 PetscCall(MatScale(B, PETSC_i)); 98 #endif 99 100 /* MatAXPY further exercises MatSetValues_HYPRE */ 101 PetscCall(MatAXPY(B, -1., A, DIFFERENT_NONZERO_PATTERN)); 102 PetscCall(MatConvert(B, MATMPIAIJ, MAT_INITIAL_MATRIX, &C)); 103 PetscCall(MatNorm(C, NORM_INFINITY, &err)); 104 PetscCheck(err <= PETSC_SMALL, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatSetValues %g", err); 105 PetscCall(MatDestroy(&B)); 106 PetscCall(MatDestroy(&C)); 107 } else { 108 PetscViewer viewer; 109 110 PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, file, FILE_MODE_READ, &viewer)); 111 PetscCall(MatSetFromOptions(A)); 112 PetscCall(MatLoad(A, viewer)); 113 PetscCall(PetscViewerDestroy(&viewer)); 114 PetscCall(MatGetSize(A, &M, &N)); 115 } 116 117 /* check conversion routines */ 118 PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &B)); 119 PetscCall(MatConvert(A, MATHYPRE, MAT_REUSE_MATRIX, &B)); 120 PetscCall(MatMultEqual(B, A, 4, &flg)); 121 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat HYPRE"); 122 PetscCall(MatConvert(B, MATIS, MAT_INITIAL_MATRIX, &D)); 123 PetscCall(MatConvert(B, MATIS, MAT_REUSE_MATRIX, &D)); 124 PetscCall(MatMultEqual(D, A, 4, &flg)); 125 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat IS"); 126 PetscCall(MatConvert(B, MATAIJ, MAT_INITIAL_MATRIX, &C)); 127 PetscCall(MatConvert(B, MATAIJ, MAT_REUSE_MATRIX, &C)); 128 PetscCall(MatMultEqual(C, A, 4, &flg)); 129 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat AIJ"); 130 PetscCall(MatAXPY(C, -1., A, SAME_NONZERO_PATTERN)); 131 PetscCall(MatNorm(C, NORM_INFINITY, &err)); 132 PetscCheck(err <= PETSC_SMALL, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat AIJ %g", err); 133 PetscCall(MatDestroy(&C)); 134 PetscCall(MatConvert(D, MATAIJ, MAT_INITIAL_MATRIX, &C)); 135 PetscCall(MatAXPY(C, -1., A, SAME_NONZERO_PATTERN)); 136 PetscCall(MatNorm(C, NORM_INFINITY, &err)); 137 PetscCheck(err <= PETSC_SMALL, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error Mat IS %g", err); 138 PetscCall(MatDestroy(&C)); 139 PetscCall(MatDestroy(&D)); 140 141 /* check MatCreateFromParCSR */ 142 PetscCall(MatHYPREGetParCSR(B, &parcsr)); 143 PetscCall(MatCreateFromParCSR(parcsr, MATAIJ, PETSC_COPY_VALUES, &D)); 144 PetscCall(MatDestroy(&D)); 145 PetscCall(MatCreateFromParCSR(parcsr, MATHYPRE, PETSC_USE_POINTER, &C)); 146 147 /* check MatMult operations */ 148 PetscCall(MatMultEqual(A, B, 4, &flg)); 149 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMult B"); 150 PetscCall(MatMultEqual(A, C, 4, &flg)); 151 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMult C"); 152 PetscCall(MatMultAddEqual(A, B, 4, &flg)); 153 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultAdd B"); 154 PetscCall(MatMultAddEqual(A, C, 4, &flg)); 155 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultAdd C"); 156 PetscCall(MatMultTransposeEqual(A, B, 4, &flg)); 157 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultTranspose B"); 158 PetscCall(MatMultTransposeEqual(A, C, 4, &flg)); 159 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultTranspose C"); 160 PetscCall(MatMultTransposeAddEqual(A, B, 4, &flg)); 161 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultTransposeAdd B"); 162 PetscCall(MatMultTransposeAddEqual(A, C, 4, &flg)); 163 PetscCheck(flg, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMultTransposeAdd C"); 164 165 /* check PtAP */ 166 if (testptap && M == N) { 167 Mat pP, hP; 168 169 /* PETSc MatPtAP -> output is a MatAIJ 170 It uses HYPRE functions when -matptap_via hypre is specified at command line */ 171 PetscCall(MatPtAP(A, A, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &pP)); 172 PetscCall(MatPtAP(A, A, MAT_REUSE_MATRIX, PETSC_DEFAULT, &pP)); 173 PetscCall(MatNorm(pP, NORM_INFINITY, &norm)); 174 PetscCall(MatPtAPMultEqual(A, A, pP, 10, &flg)); 175 PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatPtAP_MatAIJ"); 176 177 /* MatPtAP_HYPRE_HYPRE -> output is a MatHYPRE */ 178 PetscCall(MatPtAP(C, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &hP)); 179 PetscCall(MatPtAP(C, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &hP)); 180 PetscCall(MatPtAPMultEqual(C, B, hP, 10, &flg)); 181 PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatPtAP_HYPRE_HYPRE"); 182 183 /* Test MatAXPY_Basic() */ 184 PetscCall(MatAXPY(hP, -1., pP, DIFFERENT_NONZERO_PATTERN)); 185 PetscCall(MatHasOperation(hP, MATOP_NORM, &flg)); 186 if (!flg) { /* TODO add MatNorm_HYPRE */ 187 PetscCall(MatConvert(hP, MATAIJ, MAT_INPLACE_MATRIX, &hP)); 188 } 189 PetscCall(MatNorm(hP, NORM_INFINITY, &err)); 190 PetscCheck(err / norm <= PETSC_SMALL, PetscObjectComm((PetscObject)hP), PETSC_ERR_PLIB, "Error MatPtAP %g %g", err, norm); 191 PetscCall(MatDestroy(&pP)); 192 PetscCall(MatDestroy(&hP)); 193 194 /* MatPtAP_AIJ_HYPRE -> output can be decided at runtime with -matptap_hypre_outtype */ 195 PetscCall(MatPtAP(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &hP)); 196 PetscCall(MatPtAP(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &hP)); 197 PetscCall(MatPtAPMultEqual(A, B, hP, 10, &flg)); 198 PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatPtAP_AIJ_HYPRE"); 199 PetscCall(MatDestroy(&hP)); 200 } 201 PetscCall(MatDestroy(&C)); 202 PetscCall(MatDestroy(&B)); 203 204 /* check MatMatMult */ 205 if (testmatmatmult) { 206 PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &B)); 207 PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &C)); 208 PetscCall(MatConvert(B, MATHYPRE, MAT_INITIAL_MATRIX, &D)); 209 210 /* PETSc MatMatMult -> output is a MatAIJ 211 It uses HYPRE functions when -matmatmult_via hypre is specified at command line */ 212 PetscCall(MatMatMult(A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &pAB)); 213 PetscCall(MatMatMult(A, B, MAT_REUSE_MATRIX, PETSC_DEFAULT, &pAB)); 214 PetscCall(MatNorm(pAB, NORM_INFINITY, &norm)); 215 PetscCall(MatMatMultEqual(A, B, pAB, 10, &flg)); 216 PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatMatMult_AIJ_AIJ"); 217 218 /* MatMatMult_HYPRE_HYPRE -> output is a MatHYPRE */ 219 PetscCall(MatMatMult(C, D, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &CD)); 220 PetscCall(MatMatMult(C, D, MAT_REUSE_MATRIX, PETSC_DEFAULT, &CD)); 221 PetscCall(MatMatMultEqual(C, D, CD, 10, &flg)); 222 PetscCheck(flg, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Error in MatMatMult_HYPRE_HYPRE"); 223 224 /* Test MatAXPY_Basic() */ 225 PetscCall(MatAXPY(CD, -1., pAB, DIFFERENT_NONZERO_PATTERN)); 226 227 PetscCall(MatHasOperation(CD, MATOP_NORM, &flg)); 228 if (!flg) { /* TODO add MatNorm_HYPRE */ 229 PetscCall(MatConvert(CD, MATAIJ, MAT_INPLACE_MATRIX, &CD)); 230 } 231 PetscCall(MatNorm(CD, NORM_INFINITY, &err)); 232 PetscCheck((err / norm) <= PETSC_SMALL, PetscObjectComm((PetscObject)CD), PETSC_ERR_PLIB, "Error MatMatMult %g %g", err, norm); 233 234 PetscCall(MatDestroy(&C)); 235 PetscCall(MatDestroy(&D)); 236 PetscCall(MatDestroy(&pAB)); 237 PetscCall(MatDestroy(&CD)); 238 239 /* When configured with HYPRE, MatMatMatMult is available for the triplet transpose(aij)-aij-aij */ 240 PetscCall(MatCreateTranspose(A, &C)); 241 PetscCall(MatMatMatMult(C, A, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &CAB)); 242 PetscCall(MatDestroy(&C)); 243 PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &C)); 244 PetscCall(MatMatMult(C, A, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &D)); 245 PetscCall(MatDestroy(&C)); 246 PetscCall(MatMatMult(D, B, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &C)); 247 PetscCall(MatNorm(C, NORM_INFINITY, &norm)); 248 PetscCall(MatAXPY(C, -1., CAB, DIFFERENT_NONZERO_PATTERN)); 249 PetscCall(MatNorm(C, NORM_INFINITY, &err)); 250 PetscCheck((err / norm) <= PETSC_SMALL, PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatMatMatMult %g %g", err, norm); 251 PetscCall(MatDestroy(&C)); 252 PetscCall(MatDestroy(&D)); 253 PetscCall(MatDestroy(&CAB)); 254 PetscCall(MatDestroy(&B)); 255 } 256 257 /* Check MatView */ 258 PetscCall(MatViewFromOptions(A, NULL, "-view_A")); 259 PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &B)); 260 PetscCall(MatViewFromOptions(B, NULL, "-view_B")); 261 262 /* Check MatDuplicate/MatCopy */ 263 for (j = 0; j < 3; j++) { 264 MatDuplicateOption dop; 265 266 dop = MAT_COPY_VALUES; 267 if (j == 1) dop = MAT_DO_NOT_COPY_VALUES; 268 if (j == 2) dop = MAT_SHARE_NONZERO_PATTERN; 269 270 for (i = 0; i < 3; i++) { 271 MatStructure str; 272 273 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Dup/Copy tests: %" PetscInt_FMT " %" PetscInt_FMT "\n", j, i)); 274 275 str = DIFFERENT_NONZERO_PATTERN; 276 if (i == 1) str = SAME_NONZERO_PATTERN; 277 if (i == 2) str = SUBSET_NONZERO_PATTERN; 278 279 PetscCall(MatDuplicate(A, dop, &C)); 280 PetscCall(MatDuplicate(B, dop, &D)); 281 if (dop != MAT_COPY_VALUES) { 282 PetscCall(MatCopy(A, C, str)); 283 PetscCall(MatCopy(B, D, str)); 284 } 285 /* AXPY with AIJ and HYPRE */ 286 PetscCall(MatAXPY(C, -1.0, D, str)); 287 PetscCall(MatNorm(C, NORM_INFINITY, &err)); 288 if (err > PETSC_SMALL) { 289 PetscCall(MatViewFromOptions(A, NULL, "-view_duplicate_diff")); 290 PetscCall(MatViewFromOptions(B, NULL, "-view_duplicate_diff")); 291 PetscCall(MatViewFromOptions(C, NULL, "-view_duplicate_diff")); 292 SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error test 1 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")", err, j, i); 293 } 294 /* AXPY with HYPRE and HYPRE */ 295 PetscCall(MatAXPY(D, -1.0, B, str)); 296 if (err > PETSC_SMALL) { 297 PetscCall(MatViewFromOptions(A, NULL, "-view_duplicate_diff")); 298 PetscCall(MatViewFromOptions(B, NULL, "-view_duplicate_diff")); 299 PetscCall(MatViewFromOptions(D, NULL, "-view_duplicate_diff")); 300 SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error test 2 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")", err, j, i); 301 } 302 /* Copy from HYPRE to AIJ */ 303 PetscCall(MatCopy(B, C, str)); 304 /* Copy from AIJ to HYPRE */ 305 PetscCall(MatCopy(A, D, str)); 306 /* AXPY with HYPRE and AIJ */ 307 PetscCall(MatAXPY(D, -1.0, C, str)); 308 PetscCall(MatHasOperation(D, MATOP_NORM, &flg)); 309 if (!flg) { /* TODO add MatNorm_HYPRE */ 310 PetscCall(MatConvert(D, MATAIJ, MAT_INPLACE_MATRIX, &D)); 311 } 312 PetscCall(MatNorm(D, NORM_INFINITY, &err)); 313 if (err > PETSC_SMALL) { 314 PetscCall(MatViewFromOptions(A, NULL, "-view_duplicate_diff")); 315 PetscCall(MatViewFromOptions(C, NULL, "-view_duplicate_diff")); 316 PetscCall(MatViewFromOptions(D, NULL, "-view_duplicate_diff")); 317 SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error test 3 MatDuplicate/MatCopy %g (%" PetscInt_FMT ",%" PetscInt_FMT ")", err, j, i); 318 } 319 PetscCall(MatDestroy(&C)); 320 PetscCall(MatDestroy(&D)); 321 } 322 } 323 PetscCall(MatDestroy(&B)); 324 325 PetscCall(MatHasCongruentLayouts(A, &flg)); 326 if (flg) { 327 Vec y, y2; 328 329 PetscCall(MatConvert(A, MATHYPRE, MAT_INITIAL_MATRIX, &B)); 330 PetscCall(MatCreateVecs(A, NULL, &y)); 331 PetscCall(MatCreateVecs(B, NULL, &y2)); 332 PetscCall(MatGetDiagonal(A, y)); 333 PetscCall(MatGetDiagonal(B, y2)); 334 PetscCall(VecAXPY(y2, -1.0, y)); 335 PetscCall(VecNorm(y2, NORM_INFINITY, &err)); 336 if (err > PETSC_SMALL) { 337 PetscCall(VecViewFromOptions(y, NULL, "-view_diagonal_diff")); 338 PetscCall(VecViewFromOptions(y2, NULL, "-view_diagonal_diff")); 339 SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_PLIB, "Error MatGetDiagonal %g", err); 340 } 341 PetscCall(MatDestroy(&B)); 342 PetscCall(VecDestroy(&y)); 343 PetscCall(VecDestroy(&y2)); 344 } 345 346 PetscCall(MatDestroy(&A)); 347 348 PetscCall(PetscFinalize()); 349 return 0; 350 } 351 352 /*TEST 353 354 build: 355 requires: hypre 356 357 test: 358 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 359 suffix: 1 360 args: -N 11 -M 11 361 output_file: output/ex115_1.out 362 363 test: 364 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 365 suffix: 2 366 nsize: 3 367 args: -N 13 -M 13 -matmatmult_via hypre 368 output_file: output/ex115_1.out 369 370 test: 371 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 372 suffix: 3 373 nsize: 4 374 args: -M 13 -N 7 -matmatmult_via hypre 375 output_file: output/ex115_1.out 376 377 test: 378 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 379 suffix: 4 380 nsize: 2 381 args: -M 12 -N 19 382 output_file: output/ex115_1.out 383 384 test: 385 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 386 suffix: 5 387 nsize: 3 388 args: -M 13 -N 13 -matptap_via hypre -matptap_hypre_outtype hypre 389 output_file: output/ex115_1.out 390 391 test: 392 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 393 suffix: 6 394 nsize: 3 395 args: -M 12 -N 19 -test_offproc 396 output_file: output/ex115_1.out 397 398 test: 399 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 400 suffix: 7 401 nsize: 3 402 args: -M 19 -N 12 -test_offproc -view_B ::ascii_info_detail 403 output_file: output/ex115_7.out 404 405 test: 406 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 407 suffix: 8 408 nsize: 3 409 args: -M 1 -N 12 -test_offproc 410 output_file: output/ex115_1.out 411 412 test: 413 requires: !defined(PETSC_HAVE_HYPRE_DEVICE) 414 suffix: 9 415 nsize: 3 416 args: -M 1 -N 2 -test_offproc 417 output_file: output/ex115_1.out 418 419 TEST*/ 420