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*/