Actual source code: ex3.c

  1: const char help[] = "Test validity of different approaches to specifying a MatLMVM";

  3: #include <petscksp.h>

  5: enum {
  6:   TEST_INIT_NONE,
  7:   TEST_INIT_VECS,
  8:   TEST_INIT_DIAG,
  9:   TEST_INIT_MAT,
 10:   TEST_INIT_PC,
 11:   TEST_INIT_KSP,
 12:   TEST_INIT_COUNT
 13: };

 15: typedef PetscInt TestInitType;

 17: enum {
 18:   TEST_SIZE_NONE,
 19:   TEST_SIZE_LOCAL,
 20:   TEST_SIZE_GLOBAL,
 21:   TEST_SIZE_BOTH,
 22:   TEST_SIZE_COUNT
 23: };

 25: typedef PetscInt TestSizeType;

 27: static PetscErrorCode CreateMatWithTestSizes(MPI_Comm comm, MatType mat_type, PetscInt n, PetscInt N, TestSizeType size_type, PetscBool call_setup, Mat *B)
 28: {
 29:   PetscFunctionBegin;
 30:   PetscCall(MatCreate(comm, B));
 31:   switch (size_type) {
 32:   case TEST_SIZE_LOCAL:
 33:     PetscCall(MatSetSizes(*B, n, n, PETSC_DETERMINE, PETSC_DETERMINE));
 34:     break;
 35:   case TEST_SIZE_GLOBAL:
 36:     PetscCall(MatSetSizes(*B, PETSC_DECIDE, PETSC_DECIDE, N, N));
 37:     break;
 38:   case TEST_SIZE_BOTH:
 39:     PetscCall(MatSetSizes(*B, n, n, N, N));
 40:     break;
 41:   default:
 42:     break;
 43:   }
 44:   PetscCall(MatSetType(*B, mat_type));
 45:   if (call_setup) PetscCall(MatSetUp(*B));
 46:   PetscFunctionReturn(PETSC_SUCCESS);
 47: }

 49: static PetscErrorCode TestUsability(Mat B, Vec pattern, PetscRandom rand, PetscBool test_pre)
 50: {
 51:   Vec dx, df;

 53:   PetscFunctionBegin;
 54:   PetscCall(VecDuplicate(pattern, &dx));
 55:   PetscCall(VecDuplicate(pattern, &df));
 56:   PetscCall(VecSetRandom(dx, rand));

 58:   if (test_pre) {
 59:     // Mult and Solve should work before any updates
 60:     PetscCall(MatMult(B, dx, df));
 61:     PetscCall(MatSolve(B, dx, df));
 62:   }

 64:   for (PetscInt i = 0; i < 2; i++) {
 65:     PetscCall(VecCopy(dx, df));
 66:     PetscCall(MatLMVMUpdate(B, dx, df));
 67:     PetscCall(MatMult(B, dx, df));
 68:     PetscCall(MatSolve(B, dx, df));
 69:   }

 71:   PetscCall(VecDestroy(&df));
 72:   PetscCall(VecDestroy(&dx));
 73:   PetscFunctionReturn(PETSC_SUCCESS);
 74: }

 76: int main(int argc, char **argv)
 77: {
 78:   MPI_Comm    comm;
 79:   PetscRandom rand;
 80:   PetscInt    N = 9;
 81:   PetscInt    n = PETSC_DETERMINE;
 82:   Vec         pattern;

 84:   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
 85:   PetscCall(KSPInitializePackage());
 86:   comm = PETSC_COMM_WORLD;
 87:   PetscCall(PetscRandomCreate(comm, &rand));
 88:   PetscCall(VecCreate(comm, &pattern));
 89:   PetscCall(PetscSplitOwnership(comm, &n, &N));
 90:   PetscCall(VecSetSizes(pattern, n, N));
 91:   PetscCall(VecSetType(pattern, VECSTANDARD));
 92:   for (TestInitType init = TEST_INIT_NONE; init < TEST_INIT_COUNT; init++) {
 93:     for (PetscInt call_setup = 0; call_setup < 2; call_setup++) {
 94:       for (TestSizeType size = (call_setup ? TEST_SIZE_NONE : TEST_SIZE_LOCAL); size < TEST_SIZE_COUNT; size++) {
 95:         Mat B;

 97:         // skip invalid case
 98:         if (init == TEST_INIT_NONE && size == TEST_SIZE_NONE) continue;
 99:         if (size == TEST_SIZE_NONE && call_setup) continue;

101:         PetscCall(CreateMatWithTestSizes(comm, MATLMVMBFGS, n, N, size, call_setup ? PETSC_TRUE : PETSC_FALSE, &B));

103:         switch (init) {
104:         case TEST_INIT_NONE:
105:           PetscCall(TestUsability(B, pattern, rand, call_setup ? PETSC_TRUE : PETSC_FALSE));
106:           break;
107:         case TEST_INIT_VECS: {
108:           Vec x, f;

110:           PetscCall(VecDuplicate(pattern, &x));
111:           PetscCall(VecDuplicate(pattern, &f));
112:           PetscCall(MatLMVMAllocate(B, x, f));
113:           PetscCall(VecDestroy(&x));
114:           PetscCall(VecDestroy(&f));
115:           PetscCall(TestUsability(B, pattern, rand, PETSC_TRUE));
116:           break;
117:         }
118:         case TEST_INIT_DIAG: {
119:           Vec d;

121:           PetscCall(VecDuplicate(pattern, &d));
122:           PetscCall(VecSet(d, 1.0));
123:           PetscCall(MatLMVMSetJ0Diag(B, d));
124:           PetscCall(VecDestroy(&d));
125:           PetscCall(TestUsability(B, pattern, rand, PETSC_TRUE));
126:           break;
127:         }
128:         case TEST_INIT_MAT: {
129:           for (PetscInt j0_call_setup = 0; j0_call_setup < 2; j0_call_setup++) {
130:             for (TestSizeType j0_size = TEST_SIZE_LOCAL; j0_size < TEST_SIZE_COUNT; j0_size++) {
131:               Mat J0;

133:               PetscCall(CreateMatWithTestSizes(comm, MATDENSE, n, N, j0_size, j0_call_setup ? PETSC_TRUE : PETSC_FALSE, &J0));
134:               PetscCall(MatLMVMSetJ0(B, J0));
135:               PetscCall(MatZeroEntries(J0));
136:               PetscCall(MatShift(J0, 1.0));
137:               PetscCall(MatDestroy(&J0));
138:               PetscCall(TestUsability(B, pattern, rand, PETSC_TRUE));
139:             }
140:           }
141:           break;
142:         }
143:         case TEST_INIT_PC: {
144:           for (PetscInt j0_call_setup = 0; j0_call_setup < 2; j0_call_setup++) {
145:             for (TestSizeType j0_size = TEST_SIZE_LOCAL; j0_size < TEST_SIZE_COUNT; j0_size++) {
146:               PC  J0pc;
147:               Mat J0;

149:               PetscCall(CreateMatWithTestSizes(comm, MATCONSTANTDIAGONAL, n, N, j0_size, j0_call_setup ? PETSC_TRUE : PETSC_FALSE, &J0));
150:               PetscCall(PCCreate(comm, &J0pc));
151:               PetscCall(PCSetType(J0pc, PCMAT));
152:               PetscCall(PCMatSetApplyOperation(J0pc, MATOP_SOLVE));
153:               PetscCall(PCSetOperators(J0pc, J0, J0));
154:               PetscCall(MatLMVMSetJ0PC(B, J0pc));
155:               PetscCall(MatZeroEntries(J0));
156:               PetscCall(MatShift(J0, 1.0));
157:               PetscCall(MatDestroy(&J0));
158:               PetscCall(PCDestroy(&J0pc));
159:               PetscCall(TestUsability(B, pattern, rand, PETSC_TRUE));
160:             }
161:           }
162:           break;
163:         }
164:         case TEST_INIT_KSP: {
165:           for (PetscInt j0_call_setup = 0; j0_call_setup < 2; j0_call_setup++) {
166:             for (TestSizeType j0_size = TEST_SIZE_LOCAL; j0_size < TEST_SIZE_COUNT; j0_size++) {
167:               KSP J0ksp;
168:               PC  J0pc;
169:               Mat J0;

171:               PetscCall(CreateMatWithTestSizes(comm, MATCONSTANTDIAGONAL, n, N, j0_size, j0_call_setup ? PETSC_TRUE : PETSC_FALSE, &J0));
172:               PetscCall(KSPCreate(comm, &J0ksp));
173:               PetscCall(KSPSetOperators(J0ksp, J0, J0));
174:               PetscCall(KSPGetPC(J0ksp, &J0pc));
175:               PetscCall(PCSetType(J0pc, PCNONE));
176:               PetscCall(MatLMVMSetJ0KSP(B, J0ksp));
177:               PetscCall(MatZeroEntries(J0));
178:               PetscCall(MatShift(J0, 1.0));
179:               PetscCall(MatDestroy(&J0));
180:               PetscCall(KSPDestroy(&J0ksp));
181:               PetscCall(TestUsability(B, pattern, rand, PETSC_TRUE));
182:             }
183:           }
184:           break;
185:         }
186:         default:
187:           break;
188:         }
189:         PetscCall(MatDestroy(&B));
190:       }
191:     }
192:   }

194:   PetscCall(VecDestroy(&pattern));
195:   PetscCall(PetscRandomDestroy(&rand));
196:   PetscCall(PetscFinalize());
197:   return 0;
198: }

200: /*TEST

202:   test:
203:     suffix: 0
204:     nsize: 2
205:     output_file: output/empty.out

207: TEST*/