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