1 static char help[] = "Tests MATPYTHON from C\n\n"; 2 3 #include <petscmat.h> 4 /* MATPYTHON has support for wrapping these operations 5 MatHasOperation_Python inspects the user's Python class and checks 6 if the methods are provided */ 7 MatOperation optenum[] = {MATOP_MULT, MATOP_MULT_ADD, MATOP_MULT_TRANSPOSE, MATOP_MULT_TRANSPOSE_ADD, MATOP_SOLVE, MATOP_SOLVE_ADD, MATOP_SOLVE_TRANSPOSE, MATOP_SOLVE_TRANSPOSE_ADD, MATOP_SOR, MATOP_GET_DIAGONAL, MATOP_DIAGONAL_SCALE, MATOP_NORM, MATOP_ZERO_ENTRIES, MATOP_GET_DIAGONAL_BLOCK, MATOP_DUPLICATE, MATOP_COPY, MATOP_SCALE, MATOP_SHIFT, MATOP_DIAGONAL_SET, MATOP_ZERO_ROWS_COLUMNS, MATOP_CREATE_SUBMATRIX, MATOP_CREATE_VECS, MATOP_CONJUGATE, MATOP_REAL_PART, MATOP_IMAGINARY_PART, MATOP_MULT_DIAGONAL_BLOCK, MATOP_MULT_HERMITIAN_TRANSPOSE, MATOP_MULT_HERMITIAN_TRANS_ADD}; 8 9 /* Name of the methods in the user's Python class */ 10 const char *const optstr[] = {"mult", 11 "multAdd", 12 "multTranspose", 13 "multTransposeAdd", 14 "solve", 15 "solveAdd", 16 "solveTranspose", 17 "solveTransposeAdd", 18 "SOR", 19 "getDiagonal", 20 "diagonalScale", 21 "norm", 22 "zeroEntries", 23 "getDiagonalBlock", 24 "duplicate", 25 "copy", 26 "scale", 27 "shift", 28 "setDiagonal", 29 "zeroRowsColumns", 30 "createSubMatrix", 31 "getVecs", 32 "conjugate", 33 "realPart", 34 "imagPart", 35 "multDiagonalBlock", 36 "multHermitian", 37 "multHermitianAdd"}; 38 39 PetscErrorCode RunHasOperationTest() 40 { 41 Mat A; 42 PetscInt matop, nop = PETSC_STATIC_ARRAY_LENGTH(optenum); 43 44 PetscFunctionBegin; 45 for (matop = 0; matop < nop; matop++) { 46 char opts[256]; 47 PetscBool hasop; 48 PetscInt i; 49 50 PetscCall(PetscSNPrintf(opts, 256, "-enable %s", optstr[matop])); 51 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Testing with %s\n", opts)); 52 PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 53 PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, 0, 0)); 54 PetscCall(MatSetType(A, MATPYTHON)); 55 PetscCall(MatPythonSetType(A, "ex140.py:Matrix")); 56 /* default case, no user implementation */ 57 for (i = 0; i < nop; i++) { 58 PetscCall(MatHasOperation(A, optenum[i], &hasop)); 59 if (hasop) { 60 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Error: %s present\n", optstr[i])); 61 } else { 62 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Pass: %s\n", optstr[i])); 63 } 64 } 65 /* customize Matrix class at a later stage and add support for optenum[matop] */ 66 PetscCall(PetscOptionsInsertString(NULL, opts)); 67 PetscCall(MatSetFromOptions(A)); 68 for (i = 0; i < nop; i++) { 69 PetscCall(MatHasOperation(A, optenum[i], &hasop)); 70 if (hasop && i != matop) { 71 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Error: %s present\n", optstr[i])); 72 } else if (!hasop && i == matop) { 73 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Error: %s not present\n", optstr[i])); 74 } else { 75 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Pass: %s\n", optstr[i])); 76 } 77 } 78 PetscCall(MatDestroy(&A)); 79 PetscCall(PetscOptionsClearValue(NULL, opts)); 80 } 81 PetscFunctionReturn(PETSC_SUCCESS); 82 } 83 84 int main(int argc, char **argv) 85 { 86 PetscFunctionBeginUser; 87 PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 88 PetscCall(PetscPythonInitialize(NULL, NULL)); 89 PetscCall(RunHasOperationTest()); 90 PetscCall(PetscPythonPrintError()); 91 PetscCall(PetscFinalize()); 92 return 0; 93 } 94 95 /*TEST 96 97 test: 98 requires: petsc4py 99 localrunfiles: ex140.py 100 101 TEST*/ 102