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_MISSING_DIAGONAL, 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", "multAdd", "multTranspose", "multTransposeAdd", "solve", "solveAdd", "solveTranspose", "solveTransposeAdd", "SOR", "getDiagonal", "diagonalScale", "norm", "zeroEntries", "getDiagonalBlock", "duplicate", "copy", "scale", "shift", "setDiagonal", "zeroRowsColumns", "createSubMatrix", "getVecs", "conjugate", "realPart", "imagPart", "missingDiagonal", "multDiagonalBlock", "multHermitian", "multHermitianAdd"}; 11 12 PetscErrorCode RunHasOperationTest() 13 { 14 Mat A; 15 PetscInt matop, nop = PETSC_STATIC_ARRAY_LENGTH(optenum); 16 17 PetscFunctionBegin; 18 for (matop = 0; matop < nop; matop++) { 19 char opts[256]; 20 PetscBool hasop; 21 PetscInt i; 22 23 PetscCall(PetscSNPrintf(opts, 256, "-enable %s", optstr[matop])); 24 PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Testing with %s\n", opts)); 25 PetscCall(MatCreate(PETSC_COMM_WORLD, &A)); 26 PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, 0, 0)); 27 PetscCall(MatSetType(A, MATPYTHON)); 28 PetscCall(MatPythonSetType(A, "ex140.py:Matrix")); 29 /* default case, no user implementation */ 30 for (i = 0; i < nop; i++) { 31 PetscCall(MatHasOperation(A, optenum[i], &hasop)); 32 if (hasop) { 33 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Error: %s present\n", optstr[i])); 34 } else { 35 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Pass: %s\n", optstr[i])); 36 } 37 } 38 /* customize Matrix class at a later stage and add support for optenum[matop] */ 39 PetscCall(PetscOptionsInsertString(NULL, opts)); 40 PetscCall(MatSetFromOptions(A)); 41 for (i = 0; i < nop; i++) { 42 PetscCall(MatHasOperation(A, optenum[i], &hasop)); 43 if (hasop && i != matop) { 44 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Error: %s present\n", optstr[i])); 45 } else if (!hasop && i == matop) { 46 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Error: %s not present\n", optstr[i])); 47 } else { 48 PetscCall(PetscPrintf(PETSC_COMM_WORLD, " Pass: %s\n", optstr[i])); 49 } 50 } 51 PetscCall(MatDestroy(&A)); 52 PetscCall(PetscOptionsClearValue(NULL, opts)); 53 } 54 PetscFunctionReturn(PETSC_SUCCESS); 55 } 56 57 int main(int argc, char **argv) 58 { 59 PetscFunctionBeginUser; 60 PetscCall(PetscInitialize(&argc, &argv, (char *)0, help)); 61 PetscCall(PetscPythonInitialize(NULL, NULL)); 62 PetscCall(RunHasOperationTest()); 63 PetscCall(PetscPythonPrintError()); 64 PetscCall(PetscFinalize()); 65 return 0; 66 } 67 68 /*TEST 69 70 test: 71 requires: petsc4py 72 localrunfiles: ex140.py 73 74 TEST*/ 75