Actual source code: ex140.c

  1: static char help[] = "Tests MATPYTHON from C\n\n";

  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,
  8:                           MATOP_MULT_ADD,
  9:                           MATOP_MULT_TRANSPOSE,
 10:                           MATOP_MULT_TRANSPOSE_ADD,
 11:                           MATOP_SOLVE,
 12:                           MATOP_SOLVE_ADD,
 13:                           MATOP_SOLVE_TRANSPOSE,
 14:                           MATOP_SOLVE_TRANSPOSE_ADD,
 15:                           MATOP_SOR,
 16:                           MATOP_GET_DIAGONAL,
 17:                           MATOP_DIAGONAL_SCALE,
 18:                           MATOP_NORM,
 19:                           MATOP_ZERO_ENTRIES,
 20:                           MATOP_ZERO_ROWS,
 21:                           MATOP_GET_DIAGONAL_BLOCK,
 22:                           MATOP_DUPLICATE,
 23:                           MATOP_COPY,
 24:                           MATOP_SCALE,
 25:                           MATOP_SHIFT,
 26:                           MATOP_DIAGONAL_SET,
 27:                           MATOP_ZERO_ROWS_COLUMNS,
 28:                           MATOP_CREATE_SUBMATRIX,
 29:                           MATOP_CREATE_VECS,
 30:                           MATOP_CONJUGATE,
 31:                           MATOP_REAL_PART,
 32:                           MATOP_IMAGINARY_PART,
 33: #if PetscDefined(USE_COMPLEX)
 34:                           MATOP_MULT_DIAGONAL_BLOCK,
 35:                           MATOP_MULT_HERMITIAN_TRANSPOSE,
 36:                           MATOP_MULT_HERMITIAN_TRANS_ADD};
 37: #else
 38:                           MATOP_MULT_DIAGONAL_BLOCK};
 39: #endif

 41: /* Name of the methods in the user's Python class */
 42: const char *const optstr[] = {"mult",
 43:                               "multAdd",
 44:                               "multTranspose",
 45:                               "multTransposeAdd",
 46:                               "solve",
 47:                               "solveAdd",
 48:                               "solveTranspose",
 49:                               "solveTransposeAdd",
 50:                               "SOR",
 51:                               "getDiagonal",
 52:                               "diagonalScale",
 53:                               "norm",
 54:                               "zeroEntries",
 55:                               "zeroRows",
 56:                               "getDiagonalBlock",
 57:                               "duplicate",
 58:                               "copy",
 59:                               "scale",
 60:                               "shift",
 61:                               "setDiagonal",
 62:                               "zeroRowsColumns",
 63:                               "createSubMatrix",
 64:                               "createVecs",
 65:                               "conjugate",
 66:                               "realPart",
 67:                               "imagPart",
 68: #if PetscDefined(USE_COMPLEX)
 69:                               "multDiagonalBlock",
 70:                               "multHermitian",
 71:                               "multHermitianAdd"};
 72: #else
 73:                               "multDiagonalBlock"};
 74: #endif

 76: PetscErrorCode RunHasOperationTest(void)
 77: {
 78:   Mat      A;
 79:   PetscInt matop, nop = PETSC_STATIC_ARRAY_LENGTH(optenum);

 81:   PetscFunctionBegin;
 82:   for (matop = 0; matop < nop; matop++) {
 83:     char      opts[256];
 84:     PetscBool hasop;

 86:     PetscCall(PetscSNPrintf(opts, 256, "-enable %s", optstr[matop]));
 87:     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Testing with %s\n", opts));
 88:     PetscCall(MatCreate(PETSC_COMM_WORLD, &A));
 89:     PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, 0, 0));
 90:     PetscCall(MatSetType(A, MATPYTHON));
 91:     PetscCall(MatPythonSetType(A, "ex140.py:Matrix"));
 92:     /* default case, no user implementation */
 93:     for (PetscInt i = 0; i < nop; i++) {
 94:       PetscCall(MatHasOperation(A, optenum[i], &hasop));
 95:       if (hasop) {
 96:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Error: %s present\n", optstr[i]));
 97:       } else {
 98:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Pass: %s\n", optstr[i]));
 99:       }
100:     }
101:     /* customize Matrix class at a later stage and add support for optenum[matop] */
102:     PetscCall(PetscOptionsInsertString(NULL, opts));
103:     PetscCall(MatSetFromOptions(A));
104:     for (PetscInt i = 0; i < nop; i++) {
105:       PetscCall(MatHasOperation(A, optenum[i], &hasop));
106:       if (hasop && i != matop) {
107:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Error: %s present\n", optstr[i]));
108:       } else if (!hasop && i == matop) {
109:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Error: %s not present\n", optstr[i]));
110:       } else {
111:         PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Pass: %s\n", optstr[i]));
112:       }
113:     }
114:     PetscCall(MatDestroy(&A));
115:     PetscCall(PetscOptionsClearValue(NULL, opts));
116:   }
117:   PetscFunctionReturn(PETSC_SUCCESS);
118: }

120: int main(int argc, char **argv)
121: {
122:   PetscFunctionBeginUser;
123:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
124:   PetscCall(PetscPythonInitialize(NULL, NULL));
125:   PetscCall(RunHasOperationTest());
126:   PetscCall(PetscPythonPrintError());
127:   PetscCall(PetscFinalize());
128:   return 0;
129: }

131: /*TEST

133:    test:
134:       suffix: real
135:       requires: petsc4py !complex
136:       localrunfiles: ex140.py
137:       output_file: output/ex140_real.out

139:    test:
140:       suffix: complex
141:       requires: petsc4py complex
142:       localrunfiles: ex140.py
143:       output_file: output/ex140_complex.out

145: TEST*/