Actual source code: ex79.c
1: #include <petsc.h>
3: static char help[] = "Solves a linear system with a block of right-hand sides, apply a preconditioner to the same block.\n\n";
5: PetscErrorCode MatApply(PC pc, Mat X, Mat Y)
6: {
7: PetscFunctionBeginUser;
8: PetscCall(MatCopy(X, Y, SAME_NONZERO_PATTERN));
9: PetscFunctionReturn(PETSC_SUCCESS);
10: }
12: int main(int argc, char **args)
13: {
14: Mat A, X, B; /* computed solutions and RHS */
15: KSP ksp; /* linear solver context */
16: PC pc; /* preconditioner context */
17: PetscInt m = 10;
18: PetscBool flg, transpose = PETSC_FALSE;
19: #if defined(PETSC_USE_LOG)
20: PetscLogEvent event;
21: #endif
22: PetscEventPerfInfo info;
24: PetscFunctionBeginUser;
25: PetscCall(PetscInitialize(&argc, &args, NULL, help));
26: PetscCall(PetscLogDefaultBegin());
27: PetscCall(PetscOptionsGetInt(NULL, NULL, "-m", &m, NULL));
28: PetscCall(MatCreateAIJ(PETSC_COMM_WORLD, m, m, PETSC_DECIDE, PETSC_DECIDE, m, NULL, m, NULL, &A));
29: PetscCall(MatSetRandom(A, NULL));
30: PetscCall(MatSetOption(A, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
31: PetscCall(PetscOptionsGetBool(NULL, NULL, "-transpose", &transpose, NULL));
32: if (transpose) {
33: PetscCall(MatTranspose(A, MAT_INITIAL_MATRIX, &B));
34: PetscCall(MatAXPY(A, 1.0, B, DIFFERENT_NONZERO_PATTERN));
35: PetscCall(MatDestroy(&B));
36: }
37: PetscCall(MatShift(A, 10.0));
38: PetscCall(MatCreateDense(PETSC_COMM_WORLD, m, PETSC_DECIDE, PETSC_DECIDE, m, NULL, &B));
39: PetscCall(MatCreateDense(PETSC_COMM_WORLD, m, PETSC_DECIDE, PETSC_DECIDE, m, NULL, &X));
40: PetscCall(MatSetRandom(B, NULL));
41: PetscCall(MatSetFromOptions(A));
42: PetscCall(PetscObjectTypeCompareAny((PetscObject)A, &flg, MATSEQAIJCUSPARSE, MATMPIAIJCUSPARSE, ""));
43: if (flg) {
44: PetscCall(MatConvert(B, MATDENSECUDA, MAT_INPLACE_MATRIX, &B));
45: PetscCall(MatConvert(X, MATDENSECUDA, MAT_INPLACE_MATRIX, &X));
46: }
47: PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
48: PetscCall(KSPSetOperators(ksp, A, A));
49: PetscCall(KSPSetFromOptions(ksp));
50: PetscCall(KSPGetPC(ksp, &pc));
51: PetscCall(PCShellSetMatApply(pc, MatApply));
52: PetscCall(KSPMatSolve(ksp, B, X));
53: PetscCall(PCMatApply(pc, B, X));
54: if (transpose) {
55: PetscCall(KSPMatSolveTranspose(ksp, B, X));
56: PetscCall(PCMatApply(pc, B, X));
57: PetscCall(KSPMatSolve(ksp, B, X));
58: }
59: PetscCall(MatDestroy(&X));
60: PetscCall(MatDestroy(&B));
61: PetscCall(MatDestroy(&A));
62: PetscCall(KSPDestroy(&ksp));
63: PetscCall(PetscLogEventRegister("PCApply", PC_CLASSID, &event));
64: PetscCall(PetscLogEventGetPerfInfo(PETSC_DETERMINE, event, &info));
65: PetscCheck(!PetscDefined(USE_LOG) || m <= 1 || !info.count, PetscObjectComm((PetscObject)ksp), PETSC_ERR_PLIB, "PCApply() called %d times", info.count);
66: PetscCall(PetscLogEventRegister("PCMatApply", PC_CLASSID, &event));
67: PetscCall(PetscLogEventGetPerfInfo(PETSC_DETERMINE, event, &info));
68: PetscCheck(!PetscDefined(USE_LOG) || m <= 1 || info.count, PetscObjectComm((PetscObject)ksp), PETSC_ERR_PLIB, "PCMatApply() never called");
69: PetscCall(PetscFinalize());
70: return 0;
71: }
73: /*TEST
74: # KSPHPDDM does either pseudo-blocking or "true" blocking, all tests should succeed with other -ksp_hpddm_type
75: testset:
76: nsize: 1
77: args: -pc_type {{bjacobi lu ilu mat cholesky icc none shell asm gasm}shared output}
78: test:
79: suffix: 1
80: output_file: output/ex77_preonly.out
81: args: -ksp_type preonly
82: test:
83: suffix: 1_hpddm
84: output_file: output/ex77_preonly.out
85: requires: hpddm
86: args: -ksp_type hpddm -ksp_hpddm_type preonly
88: testset:
89: nsize: 1
90: args: -pc_type ksp
91: test:
92: suffix: 2
93: output_file: output/ex77_preonly.out
94: args: -ksp_ksp_type preonly -ksp_type preonly
95: test:
96: suffix: 2_hpddm
97: output_file: output/ex77_preonly.out
98: requires: hpddm
99: args: -ksp_ksp_type hpddm -ksp_type hpddm -ksp_hpddm_type preonly -ksp_ksp_hpddm_type preonly
101: testset:
102: nsize: 1
103: requires: h2opus
104: args: -pc_type h2opus -pc_h2opus_init_mat_h2opus_leafsize 10
105: test:
106: suffix: 3
107: output_file: output/ex77_preonly.out
108: args: -ksp_type preonly
109: test:
110: suffix: 3_hpddm
111: output_file: output/ex77_preonly.out
112: requires: hpddm
113: args: -ksp_type hpddm -ksp_hpddm_type preonly
115: testset:
116: nsize: 1
117: requires: spai
118: args: -pc_type spai
119: test:
120: suffix: 4
121: output_file: output/ex77_preonly.out
122: args: -ksp_type preonly
123: test:
124: suffix: 4_hpddm
125: output_file: output/ex77_preonly.out
126: requires: hpddm
127: args: -ksp_type hpddm -ksp_hpddm_type preonly
128: # special code path in PCMatApply() for PCBJACOBI when a block is shared by multiple processes
129: testset:
130: nsize: 2
131: args: -pc_type bjacobi -pc_bjacobi_blocks 1 -sub_pc_type none
132: test:
133: suffix: 5
134: output_file: output/ex77_preonly.out
135: args: -ksp_type preonly -sub_ksp_type preonly
136: test:
137: suffix: 5_hpddm
138: output_file: output/ex77_preonly.out
139: requires: hpddm
140: args: -ksp_type hpddm -ksp_hpddm_type preonly -sub_ksp_type hpddm
141: # special code path in PCMatApply() for PCGASM when a block is shared by multiple processes
142: testset:
143: nsize: 2
144: args: -pc_type gasm -pc_gasm_total_subdomains 1 -sub_pc_type none
145: test:
146: suffix: 6
147: output_file: output/ex77_preonly.out
148: args: -ksp_type preonly -sub_ksp_type preonly
149: test:
150: suffix: 6_hpddm
151: output_file: output/ex77_preonly.out
152: requires: hpddm
153: args: -ksp_type hpddm -ksp_hpddm_type preonly -sub_ksp_type hpddm
155: testset:
156: nsize: 1
157: requires: suitesparse
158: args: -pc_type qr
159: test:
160: suffix: 7
161: output_file: output/ex77_preonly.out
162: args: -ksp_type preonly
163: test:
164: suffix: 7_hpddm
165: output_file: output/ex77_preonly.out
166: requires: hpddm
167: args: -ksp_type hpddm -ksp_hpddm_type preonly
169: testset:
170: nsize: 1
171: requires: hpddm cuda
172: args: -mat_type aijcusparse -ksp_type hpddm
173: test:
174: suffix: 8_hpddm
175: output_file: output/ex77_preonly.out
176: test:
177: suffix: 8_hpddm_transpose
178: output_file: output/ex77_preonly.out
179: args: -pc_type icc -transpose
181: testset:
182: nsize: 1
183: args: -pc_type {{cholesky icc none}shared output} -transpose
184: test:
185: suffix: 1_transpose
186: output_file: output/ex77_preonly.out
187: args: -ksp_type preonly
188: test:
189: suffix: 1_hpddm_transpose
190: output_file: output/ex77_preonly.out
191: requires: hpddm
192: args: -ksp_type hpddm -ksp_hpddm_type preonly
194: TEST*/