19a53571cSHong Zhang #include <petsc/private/tsimpl.h> /*I "petscts.h" I*/
29a53571cSHong Zhang #include <petscsys.h>
32f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
40cae4918SHong Zhang #include <revolve_c.h>
5e43ad619SHong Zhang
6e43ad619SHong Zhang /* Limit Revolve to 32-bits */
7e43ad619SHong Zhang #define PETSC_REVOLVE_INT_MAX 2147483647
8e43ad619SHong Zhang
9e43ad619SHong Zhang typedef int PetscRevolveInt;
10e43ad619SHong Zhang
PetscRevolveIntCast(PetscInt a,PetscRevolveInt * b)11d71ae5a4SJacob Faibussowitsch static inline PetscErrorCode PetscRevolveIntCast(PetscInt a, PetscRevolveInt *b)
12d71ae5a4SJacob Faibussowitsch {
13e43ad619SHong Zhang PetscFunctionBegin;
14e43ad619SHong Zhang #if defined(PETSC_USE_64BIT_INDICES)
15e43ad619SHong Zhang *b = 0;
167de69702SBarry Smith PetscCheck(a <= PETSC_REVOLVE_INT_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Parameter is too large for Revolve, which is restricted to 32-bit integers");
17e43ad619SHong Zhang #endif
1857508eceSPierre Jolivet *b = (PetscRevolveInt)a;
193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
20e43ad619SHong Zhang }
214d4d444eSHong Zhang #endif
22cc4f23bcSHong Zhang #if defined(PETSC_HAVE_CAMS)
23cc4f23bcSHong Zhang #include <offline_schedule.h>
24cc4f23bcSHong Zhang #endif
25fd16c3b4SHong Zhang
264c820ef5SHong Zhang PetscLogEvent TSTrajectory_DiskWrite, TSTrajectory_DiskRead;
27ac73474cSStefano Zampini static PetscErrorCode TSTrajectorySet_Memory(TSTrajectory, TS, PetscInt, PetscReal, Vec);
285a3ef282SHong Zhang
299371c9d4SSatish Balay typedef enum {
309371c9d4SSatish Balay NONE,
319371c9d4SSatish Balay TWO_LEVEL_NOREVOLVE,
329371c9d4SSatish Balay TWO_LEVEL_REVOLVE,
339371c9d4SSatish Balay TWO_LEVEL_TWO_REVOLVE,
349371c9d4SSatish Balay REVOLVE_OFFLINE,
359371c9d4SSatish Balay REVOLVE_ONLINE,
369371c9d4SSatish Balay REVOLVE_MULTISTAGE,
379371c9d4SSatish Balay CAMS_OFFLINE
389371c9d4SSatish Balay } SchedulerType;
39cc4f23bcSHong Zhang
409371c9d4SSatish Balay typedef enum {
419371c9d4SSatish Balay UNSET = -1,
429371c9d4SSatish Balay SOLUTIONONLY = 0,
439371c9d4SSatish Balay STAGESONLY = 1,
449371c9d4SSatish Balay SOLUTION_STAGES = 2
459371c9d4SSatish Balay } CheckpointType;
46cc4f23bcSHong Zhang
47ba38deedSJacob Faibussowitsch const char *const TSTrajectoryMemoryTypes[] = {"REVOLVE", "CAMS", "PETSC", "TSTrajectoryMemoryType", "TJ_", NULL};
48533251d3SHong Zhang
49cc4f23bcSHong Zhang #define HaveSolution(m) ((m) == SOLUTIONONLY || (m) == SOLUTION_STAGES)
50cc4f23bcSHong Zhang #define HaveStages(m) ((m) == STAGESONLY || (m) == SOLUTION_STAGES)
510cae4918SHong Zhang
529a53571cSHong Zhang typedef struct _StackElement {
539a53571cSHong Zhang PetscInt stepnum;
549a53571cSHong Zhang Vec X;
559a53571cSHong Zhang Vec *Y;
5693d756bdSHong Zhang PetscReal time;
57cf2e76e0SHong Zhang PetscReal timeprev; /* for no solution_only mode */
58cf2e76e0SHong Zhang PetscReal timenext; /* for solution_only mode */
59cc4f23bcSHong Zhang CheckpointType cptype;
609a53571cSHong Zhang } *StackElement;
619a53571cSHong Zhang
622f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
630708eeb8SHong Zhang typedef struct _RevolveCTX {
64fd16c3b4SHong Zhang PetscBool reverseonestep;
65e43ad619SHong Zhang PetscRevolveInt where;
66e43ad619SHong Zhang PetscRevolveInt snaps_in;
67e43ad619SHong Zhang PetscRevolveInt stepsleft;
68e43ad619SHong Zhang PetscRevolveInt check;
69e43ad619SHong Zhang PetscRevolveInt oldcapo;
70e43ad619SHong Zhang PetscRevolveInt capo;
71e43ad619SHong Zhang PetscRevolveInt fine;
72e43ad619SHong Zhang PetscRevolveInt info;
730708eeb8SHong Zhang } RevolveCTX;
748f4fbd80SHong Zhang #endif
750708eeb8SHong Zhang
76cc4f23bcSHong Zhang #if defined(PETSC_HAVE_CAMS)
77cc4f23bcSHong Zhang typedef struct _CAMSCTX {
78cc4f23bcSHong Zhang PetscInt lastcheckpointstep;
79cc4f23bcSHong Zhang PetscInt lastcheckpointtype;
80cc4f23bcSHong Zhang PetscInt num_units_avail;
81cc4f23bcSHong Zhang PetscInt endstep;
82cc4f23bcSHong Zhang PetscInt num_stages;
83cc4f23bcSHong Zhang PetscInt nextcheckpointstep;
84cc4f23bcSHong Zhang PetscInt nextcheckpointtype; /* (0) solution only (1) stages (2) solution+stages */
85cc4f23bcSHong Zhang PetscInt info;
86cc4f23bcSHong Zhang } CAMSCTX;
87cc4f23bcSHong Zhang #endif
88cc4f23bcSHong Zhang
890708eeb8SHong Zhang typedef struct _Stack {
900c393656SHong Zhang PetscInt stacksize;
910c393656SHong Zhang PetscInt top;
920c393656SHong Zhang StackElement *container;
9372e62aceSHong Zhang PetscInt nallocated;
940c393656SHong Zhang PetscInt numY;
950c393656SHong Zhang PetscBool solution_only;
96c1706be6SHong Zhang PetscBool use_dram;
970c393656SHong Zhang } Stack;
980c393656SHong Zhang
990c393656SHong Zhang typedef struct _DiskStack {
1000c393656SHong Zhang PetscInt stacksize;
1010c393656SHong Zhang PetscInt top;
1020c393656SHong Zhang PetscInt *container;
1030c393656SHong Zhang } DiskStack;
1040c393656SHong Zhang
1050c393656SHong Zhang typedef struct _TJScheduler {
1060cae4918SHong Zhang SchedulerType stype;
107533251d3SHong Zhang TSTrajectoryMemoryType tj_memory_type;
1082f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
1090c393656SHong Zhang RevolveCTX *rctx, *rctx2;
1105a3ef282SHong Zhang PetscBool use_online;
1119ef973d6SHong Zhang PetscInt store_stride;
1128f4fbd80SHong Zhang #endif
113cc4f23bcSHong Zhang #if defined(PETSC_HAVE_CAMS)
114cc4f23bcSHong Zhang CAMSCTX *actx;
115cc4f23bcSHong Zhang #endif
116d8b09a0eSHong Zhang PetscBool recompute;
1175d284f90SHong Zhang PetscBool skip_trajectory;
118f6dac7d6SHong Zhang PetscBool save_stack;
119cc4f23bcSHong Zhang PetscInt max_units_ram; /* maximum checkpointing units in RAM */
120cc4f23bcSHong Zhang PetscInt max_units_disk; /* maximum checkpointing units on disk */
1210cae4918SHong Zhang PetscInt max_cps_ram; /* maximum checkpoints in RAM */
1220cae4918SHong Zhang PetscInt max_cps_disk; /* maximum checkpoints on disk */
12346c2e3beSHong Zhang PetscInt stride;
124f5ed801bSHong Zhang PetscInt total_steps; /* total number of steps */
1250c393656SHong Zhang Stack stack;
1260c393656SHong Zhang DiskStack diskstack;
1278a10d460SHong Zhang PetscViewer viewer;
1280c393656SHong Zhang } TJScheduler;
1299a53571cSHong Zhang
TurnForwardWithStepsize(TS ts,PetscReal nextstepsize)130d71ae5a4SJacob Faibussowitsch static PetscErrorCode TurnForwardWithStepsize(TS ts, PetscReal nextstepsize)
131d71ae5a4SJacob Faibussowitsch {
132cf2e76e0SHong Zhang PetscFunctionBegin;
133cf2e76e0SHong Zhang /* reverse the direction */
1349566063dSJacob Faibussowitsch PetscCall(TSSetTimeStep(ts, nextstepsize));
1353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
136cf2e76e0SHong Zhang }
137cf2e76e0SHong Zhang
TurnForward(TS ts)138d71ae5a4SJacob Faibussowitsch static PetscErrorCode TurnForward(TS ts)
139d71ae5a4SJacob Faibussowitsch {
14086d8549aSHong Zhang PetscReal stepsize;
14186d8549aSHong Zhang
14286d8549aSHong Zhang PetscFunctionBegin;
14386d8549aSHong Zhang /* reverse the direction */
1449566063dSJacob Faibussowitsch PetscCall(TSGetTimeStep(ts, &stepsize));
1459566063dSJacob Faibussowitsch PetscCall(TSSetTimeStep(ts, -stepsize));
1463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
14786d8549aSHong Zhang }
14886d8549aSHong Zhang
TurnBackward(TS ts)149d71ae5a4SJacob Faibussowitsch static PetscErrorCode TurnBackward(TS ts)
150d71ae5a4SJacob Faibussowitsch {
151cf2e76e0SHong Zhang PetscReal stepsize;
152cf2e76e0SHong Zhang
153cf2e76e0SHong Zhang PetscFunctionBegin;
1543ba16761SJacob Faibussowitsch if (!ts->trajectory->adjoint_solve_mode) PetscFunctionReturn(PETSC_SUCCESS);
155cf2e76e0SHong Zhang /* reverse the direction */
156cf2e76e0SHong Zhang stepsize = ts->ptime_prev - ts->ptime;
1579566063dSJacob Faibussowitsch PetscCall(TSSetTimeStep(ts, stepsize));
1583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
159cf2e76e0SHong Zhang }
160cf2e76e0SHong Zhang
ElementCreate(TS ts,CheckpointType cptype,Stack * stack,StackElement * e)161d71ae5a4SJacob Faibussowitsch static PetscErrorCode ElementCreate(TS ts, CheckpointType cptype, Stack *stack, StackElement *e)
162d71ae5a4SJacob Faibussowitsch {
1632f21b5c6SHong Zhang Vec X;
1642f21b5c6SHong Zhang Vec *Y;
1659a53571cSHong Zhang
16645a28ef8SHong Zhang PetscFunctionBegin;
16772e62aceSHong Zhang if (stack->top < stack->stacksize - 1 && stack->container[stack->top + 1]) {
16872e62aceSHong Zhang *e = stack->container[stack->top + 1];
169cc4f23bcSHong Zhang if (HaveSolution(cptype) && !(*e)->X) {
1709566063dSJacob Faibussowitsch PetscCall(TSGetSolution(ts, &X));
1719566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &(*e)->X));
172cc4f23bcSHong Zhang }
17348a46eb9SPierre Jolivet if (cptype == 1 && (*e)->X) PetscCall(VecDestroy(&(*e)->X));
174cc4f23bcSHong Zhang if (HaveStages(cptype) && !(*e)->Y) {
1759566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
17648a46eb9SPierre Jolivet if (stack->numY) PetscCall(VecDuplicateVecs(Y[0], stack->numY, &(*e)->Y));
177cc4f23bcSHong Zhang }
17848a46eb9SPierre Jolivet if (cptype == 0 && (*e)->Y) PetscCall(VecDestroyVecs(stack->numY, &(*e)->Y));
179cc4f23bcSHong Zhang (*e)->cptype = cptype;
1803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
18172e62aceSHong Zhang }
1821baa6e33SBarry Smith if (stack->use_dram) PetscCall(PetscMallocSetDRAM());
1839566063dSJacob Faibussowitsch PetscCall(PetscNew(e));
184cc4f23bcSHong Zhang if (HaveSolution(cptype)) {
1859566063dSJacob Faibussowitsch PetscCall(TSGetSolution(ts, &X));
1869566063dSJacob Faibussowitsch PetscCall(VecDuplicate(X, &(*e)->X));
187cc4f23bcSHong Zhang }
188cc4f23bcSHong Zhang if (HaveStages(cptype)) {
1899566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
19048a46eb9SPierre Jolivet if (stack->numY) PetscCall(VecDuplicateVecs(Y[0], stack->numY, &(*e)->Y));
1914dbe3957SHong Zhang }
1921baa6e33SBarry Smith if (stack->use_dram) PetscCall(PetscMallocResetDRAM());
19372e62aceSHong Zhang stack->nallocated++;
194cc4f23bcSHong Zhang (*e)->cptype = cptype;
1953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1969a53571cSHong Zhang }
1979a53571cSHong Zhang
ElementSet(TS ts,Stack * stack,StackElement * e,PetscInt stepnum,PetscReal time,Vec X)198d71ae5a4SJacob Faibussowitsch static PetscErrorCode ElementSet(TS ts, Stack *stack, StackElement *e, PetscInt stepnum, PetscReal time, Vec X)
199d71ae5a4SJacob Faibussowitsch {
2002f21b5c6SHong Zhang Vec *Y;
2019a53571cSHong Zhang PetscInt i;
2022f21b5c6SHong Zhang PetscReal timeprev;
2039a53571cSHong Zhang
20445a28ef8SHong Zhang PetscFunctionBegin;
20548a46eb9SPierre Jolivet if (HaveSolution((*e)->cptype)) PetscCall(VecCopy(X, (*e)->X));
206cc4f23bcSHong Zhang if (HaveStages((*e)->cptype)) {
2079566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
20848a46eb9SPierre Jolivet for (i = 0; i < stack->numY; i++) PetscCall(VecCopy(Y[i], (*e)->Y[i]));
2099a53571cSHong Zhang }
2102f21b5c6SHong Zhang (*e)->stepnum = stepnum;
2112f21b5c6SHong Zhang (*e)->time = time;
2122f21b5c6SHong Zhang /* for consistency */
2132f21b5c6SHong Zhang if (stepnum == 0) {
2142f21b5c6SHong Zhang (*e)->timeprev = (*e)->time - ts->time_step;
2152f21b5c6SHong Zhang } else {
2169566063dSJacob Faibussowitsch PetscCall(TSGetPrevTime(ts, &timeprev));
2172f21b5c6SHong Zhang (*e)->timeprev = timeprev;
2182f21b5c6SHong Zhang }
2193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2202f21b5c6SHong Zhang }
2212f21b5c6SHong Zhang
ElementDestroy(Stack * stack,StackElement e)222d71ae5a4SJacob Faibussowitsch static PetscErrorCode ElementDestroy(Stack *stack, StackElement e)
223d71ae5a4SJacob Faibussowitsch {
2242f21b5c6SHong Zhang PetscFunctionBegin;
2251baa6e33SBarry Smith if (stack->use_dram) PetscCall(PetscMallocSetDRAM());
2269566063dSJacob Faibussowitsch PetscCall(VecDestroy(&e->X));
22748a46eb9SPierre Jolivet if (e->Y) PetscCall(VecDestroyVecs(stack->numY, &e->Y));
2289566063dSJacob Faibussowitsch PetscCall(PetscFree(e));
2291baa6e33SBarry Smith if (stack->use_dram) PetscCall(PetscMallocResetDRAM());
23072e62aceSHong Zhang stack->nallocated--;
2313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2329a53571cSHong Zhang }
2339a53571cSHong Zhang
StackResize(Stack * stack,PetscInt newsize)234d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackResize(Stack *stack, PetscInt newsize)
235d71ae5a4SJacob Faibussowitsch {
236cf2e76e0SHong Zhang StackElement *newcontainer;
237cf2e76e0SHong Zhang PetscInt i;
238cf2e76e0SHong Zhang
239cf2e76e0SHong Zhang PetscFunctionBegin;
2409566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(newsize * sizeof(StackElement), &newcontainer));
241ad540459SPierre Jolivet for (i = 0; i < stack->stacksize; i++) newcontainer[i] = stack->container[i];
2429566063dSJacob Faibussowitsch PetscCall(PetscFree(stack->container));
243cf2e76e0SHong Zhang stack->container = newcontainer;
244cf2e76e0SHong Zhang stack->stacksize = newsize;
2453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
246cf2e76e0SHong Zhang }
247cf2e76e0SHong Zhang
StackPush(Stack * stack,StackElement e)248d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackPush(Stack *stack, StackElement e)
249d71ae5a4SJacob Faibussowitsch {
25045a28ef8SHong Zhang PetscFunctionBegin;
25163a3b9bcSJacob Faibussowitsch PetscCheck(stack->top + 1 < stack->stacksize, PETSC_COMM_SELF, PETSC_ERR_MEMC, "Maximum stack size (%" PetscInt_FMT ") exceeded", stack->stacksize);
2520c393656SHong Zhang stack->container[++stack->top] = e;
2533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2549a53571cSHong Zhang }
2559a53571cSHong Zhang
StackPop(Stack * stack,StackElement * e)256d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackPop(Stack *stack, StackElement *e)
257d71ae5a4SJacob Faibussowitsch {
25845a28ef8SHong Zhang PetscFunctionBegin;
259aab5bcd8SJed Brown *e = NULL;
2605f80ce2aSJacob Faibussowitsch PetscCheck(stack->top != -1, PETSC_COMM_SELF, PETSC_ERR_MEMC, "Empty stack");
2610c393656SHong Zhang *e = stack->container[stack->top--];
2623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2639a53571cSHong Zhang }
2649a53571cSHong Zhang
StackTop(Stack * stack,StackElement * e)265d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackTop(Stack *stack, StackElement *e)
266d71ae5a4SJacob Faibussowitsch {
26745a28ef8SHong Zhang PetscFunctionBegin;
2680c393656SHong Zhang *e = stack->container[stack->top];
2693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
27045a28ef8SHong Zhang }
27145a28ef8SHong Zhang
StackInit(Stack * stack,PetscInt size,PetscInt ny)272d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackInit(Stack *stack, PetscInt size, PetscInt ny)
273d71ae5a4SJacob Faibussowitsch {
2742f21b5c6SHong Zhang PetscFunctionBegin;
2752f21b5c6SHong Zhang stack->top = -1;
2762f21b5c6SHong Zhang stack->numY = ny;
2772f21b5c6SHong Zhang
27848a46eb9SPierre Jolivet if (!stack->container) PetscCall(PetscCalloc1(size, &stack->container));
2793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2802f21b5c6SHong Zhang }
2812f21b5c6SHong Zhang
StackDestroy(Stack * stack)282d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackDestroy(Stack *stack)
283d71ae5a4SJacob Faibussowitsch {
2845f80ce2aSJacob Faibussowitsch const PetscInt n = stack->nallocated;
2852f21b5c6SHong Zhang
2862f21b5c6SHong Zhang PetscFunctionBegin;
2873ba16761SJacob Faibussowitsch if (!stack->container) PetscFunctionReturn(PETSC_SUCCESS);
28863a3b9bcSJacob Faibussowitsch PetscCheck(stack->top + 1 <= n, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Stack size does not match element counter %" PetscInt_FMT, n);
2899566063dSJacob Faibussowitsch for (PetscInt i = 0; i < n; i++) PetscCall(ElementDestroy(stack, stack->container[i]));
2909566063dSJacob Faibussowitsch PetscCall(PetscFree(stack->container));
2913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2922f21b5c6SHong Zhang }
2932f21b5c6SHong Zhang
StackFind(Stack * stack,StackElement * e,PetscInt index)294d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackFind(Stack *stack, StackElement *e, PetscInt index)
295d71ae5a4SJacob Faibussowitsch {
2965a3ef282SHong Zhang PetscFunctionBegin;
297ac73474cSStefano Zampini *e = NULL;
29863a3b9bcSJacob Faibussowitsch PetscCheck(index >= 0 && index <= stack->top, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Invalid index %" PetscInt_FMT, index);
2990c393656SHong Zhang *e = stack->container[index];
3003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3015a3ef282SHong Zhang }
3025a3ef282SHong Zhang
WriteToDisk(PetscBool stifflyaccurate,PetscInt stepnum,PetscReal time,PetscReal timeprev,Vec X,Vec * Y,PetscInt numY,CheckpointType cptype,PetscViewer viewer)303d71ae5a4SJacob Faibussowitsch static PetscErrorCode WriteToDisk(PetscBool stifflyaccurate, PetscInt stepnum, PetscReal time, PetscReal timeprev, Vec X, Vec *Y, PetscInt numY, CheckpointType cptype, PetscViewer viewer)
304d71ae5a4SJacob Faibussowitsch {
305b2124117SHong Zhang PetscFunctionBegin;
3069566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &stepnum, 1, PETSC_INT));
3079566063dSJacob Faibussowitsch if (HaveSolution(cptype)) PetscCall(VecView(X, viewer));
3084dbe3957SHong Zhang if (HaveStages(cptype)) {
3095f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < numY; i++) {
310533251d3SHong Zhang /* For stiffly accurate TS methods, the last stage Y[ns-1] is the same as the solution X, thus does not need to be saved again. */
311533251d3SHong Zhang if (stifflyaccurate && i == numY - 1 && HaveSolution(cptype)) continue;
3129566063dSJacob Faibussowitsch PetscCall(VecView(Y[i], viewer));
313b2124117SHong Zhang }
3144dbe3957SHong Zhang }
3159566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &time, 1, PETSC_REAL));
3169566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &timeprev, 1, PETSC_REAL));
3173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
318b2124117SHong Zhang }
319b2124117SHong Zhang
ReadFromDisk(PetscBool stifflyaccurate,PetscInt * stepnum,PetscReal * time,PetscReal * timeprev,Vec X,Vec * Y,PetscInt numY,CheckpointType cptype,PetscViewer viewer)320d71ae5a4SJacob Faibussowitsch static PetscErrorCode ReadFromDisk(PetscBool stifflyaccurate, PetscInt *stepnum, PetscReal *time, PetscReal *timeprev, Vec X, Vec *Y, PetscInt numY, CheckpointType cptype, PetscViewer viewer)
321d71ae5a4SJacob Faibussowitsch {
322b2124117SHong Zhang PetscFunctionBegin;
3239566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, stepnum, 1, NULL, PETSC_INT));
3249566063dSJacob Faibussowitsch if (HaveSolution(cptype)) PetscCall(VecLoad(X, viewer));
3254dbe3957SHong Zhang if (HaveStages(cptype)) {
3265f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < numY; i++) {
327533251d3SHong Zhang /* For stiffly accurate TS methods, the last stage Y[ns-1] is the same as the solution X, thus does not need to be loaded again. */
328533251d3SHong Zhang if (stifflyaccurate && i == numY - 1 && HaveSolution(cptype)) continue;
3299566063dSJacob Faibussowitsch PetscCall(VecLoad(Y[i], viewer));
330b2124117SHong Zhang }
3314dbe3957SHong Zhang }
3329566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, time, 1, NULL, PETSC_REAL));
3339566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, timeprev, 1, NULL, PETSC_REAL));
3343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
335b2124117SHong Zhang }
336b2124117SHong Zhang
StackDumpAll(TSTrajectory tj,TS ts,Stack * stack,PetscInt id)337d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackDumpAll(TSTrajectory tj, TS ts, Stack *stack, PetscInt id)
338d71ae5a4SJacob Faibussowitsch {
339b2124117SHong Zhang Vec *Y;
3405f80ce2aSJacob Faibussowitsch PetscInt ndumped, cptype_int;
341137d0469SJed Brown StackElement e = NULL;
3428a10d460SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
34346c2e3beSHong Zhang char filename[PETSC_MAX_PATH_LEN];
34478fbdcc8SBarry Smith MPI_Comm comm;
34546c2e3beSHong Zhang
34646c2e3beSHong Zhang PetscFunctionBegin;
3479566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
348aced365eSHong Zhang if (tj->monitor) {
3499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(tj->monitor));
35063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Dump stack id %" PetscInt_FMT " to file\n", id));
3519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(tj->monitor));
352aced365eSHong Zhang }
35363a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, sizeof(filename), "%s/TS-STACK%06" PetscInt_FMT ".bin", tj->dirname, id));
3549566063dSJacob Faibussowitsch PetscCall(PetscViewerFileSetName(tjsch->viewer, filename));
3559566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(tjsch->viewer));
3564dbe3957SHong Zhang ndumped = stack->top + 1;
3579566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(tjsch->viewer, &ndumped, 1, PETSC_INT));
3585f80ce2aSJacob Faibussowitsch for (PetscInt i = 0; i < ndumped; i++) {
3590c393656SHong Zhang e = stack->container[i];
3604dbe3957SHong Zhang cptype_int = (PetscInt)e->cptype;
3619566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(tjsch->viewer, &cptype_int, 1, PETSC_INT));
3629566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TSTrajectory_DiskWrite, tj, ts, 0, 0));
3639566063dSJacob Faibussowitsch PetscCall(WriteToDisk(ts->stifflyaccurate, e->stepnum, e->time, e->timeprev, e->X, e->Y, stack->numY, e->cptype, tjsch->viewer));
3649566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TSTrajectory_DiskWrite, tj, ts, 0, 0));
36553b27ddbSHong Zhang ts->trajectory->diskwrites++;
3669566063dSJacob Faibussowitsch PetscCall(StackPop(stack, &e));
36746c2e3beSHong Zhang }
3685a3ef282SHong Zhang /* save the last step for restart, the last step is in memory when using single level schemes, but not necessarily the case for multi level schemes */
3699566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
3709566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TSTrajectory_DiskWrite, tj, ts, 0, 0));
3719566063dSJacob Faibussowitsch PetscCall(WriteToDisk(ts->stifflyaccurate, ts->steps, ts->ptime, ts->ptime_prev, ts->vec_sol, Y, stack->numY, SOLUTION_STAGES, tjsch->viewer));
3729566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TSTrajectory_DiskWrite, tj, ts, 0, 0));
37353b27ddbSHong Zhang ts->trajectory->diskwrites++;
3743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
37546c2e3beSHong Zhang }
37646c2e3beSHong Zhang
StackLoadAll(TSTrajectory tj,TS ts,Stack * stack,PetscInt id)377d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackLoadAll(TSTrajectory tj, TS ts, Stack *stack, PetscInt id)
378d71ae5a4SJacob Faibussowitsch {
37946c2e3beSHong Zhang Vec *Y;
3804dbe3957SHong Zhang PetscInt i, nloaded, cptype_int;
38146c2e3beSHong Zhang StackElement e;
38246c2e3beSHong Zhang PetscViewer viewer;
38346c2e3beSHong Zhang char filename[PETSC_MAX_PATH_LEN];
38446c2e3beSHong Zhang
38546c2e3beSHong Zhang PetscFunctionBegin;
386aced365eSHong Zhang if (tj->monitor) {
3879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
3889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Load stack from file\n"));
3899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
390aced365eSHong Zhang }
39163a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, sizeof filename, "%s/TS-STACK%06" PetscInt_FMT ".bin", tj->dirname, id));
3929566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PetscObjectComm((PetscObject)tj), filename, FILE_MODE_READ, &viewer));
3939566063dSJacob Faibussowitsch PetscCall(PetscViewerBinarySetSkipInfo(viewer, PETSC_TRUE));
3949566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, PETSC_VIEWER_NATIVE));
3959566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &nloaded, 1, NULL, PETSC_INT));
3964dbe3957SHong Zhang for (i = 0; i < nloaded; i++) {
3979566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &cptype_int, 1, NULL, PETSC_INT));
3989566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, (CheckpointType)cptype_int, stack, &e));
3999566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
4009566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TSTrajectory_DiskRead, tj, ts, 0, 0));
4019566063dSJacob Faibussowitsch PetscCall(ReadFromDisk(ts->stifflyaccurate, &e->stepnum, &e->time, &e->timeprev, e->X, e->Y, stack->numY, e->cptype, viewer));
4029566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TSTrajectory_DiskRead, tj, ts, 0, 0));
40353b27ddbSHong Zhang ts->trajectory->diskreads++;
40446c2e3beSHong Zhang }
4055a3ef282SHong Zhang /* load the last step into TS */
4069566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
4079566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TSTrajectory_DiskRead, tj, ts, 0, 0));
4089566063dSJacob Faibussowitsch PetscCall(ReadFromDisk(ts->stifflyaccurate, &ts->steps, &ts->ptime, &ts->ptime_prev, ts->vec_sol, Y, stack->numY, SOLUTION_STAGES, viewer));
4099566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TSTrajectory_DiskRead, tj, ts, 0, 0));
41053b27ddbSHong Zhang ts->trajectory->diskreads++;
4119566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
4129566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer));
4133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
41446c2e3beSHong Zhang }
41546c2e3beSHong Zhang
4162f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
StackLoadLast(TSTrajectory tj,TS ts,Stack * stack,PetscInt id)417d71ae5a4SJacob Faibussowitsch static PetscErrorCode StackLoadLast(TSTrajectory tj, TS ts, Stack *stack, PetscInt id)
418d71ae5a4SJacob Faibussowitsch {
419d40cae4fSHong Zhang Vec *Y;
420d40cae4fSHong Zhang PetscInt size;
421d40cae4fSHong Zhang PetscViewer viewer;
422d40cae4fSHong Zhang char filename[PETSC_MAX_PATH_LEN];
4235e703940SHong Zhang #if defined(PETSC_HAVE_MPIIO)
424d40cae4fSHong Zhang PetscBool usempiio;
4255e703940SHong Zhang #endif
426d40cae4fSHong Zhang int fd;
427d40cae4fSHong Zhang off_t off, offset;
428d40cae4fSHong Zhang
429d40cae4fSHong Zhang PetscFunctionBegin;
430aced365eSHong Zhang if (tj->monitor) {
4319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
4329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Load last stack element from file\n"));
4339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
434aced365eSHong Zhang }
4359566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
4369566063dSJacob Faibussowitsch PetscCall(VecGetSize(Y[0], &size));
43733cb2c6aSHong Zhang /* VecView writes to file two extra int's for class id and number of rows */
43894645148SHong Zhang off = -((stack->solution_only ? 0 : stack->numY) + 1) * (size * PETSC_BINARY_SCALAR_SIZE + 2 * PETSC_BINARY_INT_SIZE) - PETSC_BINARY_INT_SIZE - 2 * PETSC_BINARY_SCALAR_SIZE;
439d40cae4fSHong Zhang
44063a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, sizeof filename, "%s/TS-STACK%06" PetscInt_FMT ".bin", tj->dirname, id));
4419566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PetscObjectComm((PetscObject)tj), filename, FILE_MODE_READ, &viewer));
4429566063dSJacob Faibussowitsch PetscCall(PetscViewerBinarySetSkipInfo(viewer, PETSC_TRUE));
4439566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, PETSC_VIEWER_NATIVE));
4445e703940SHong Zhang #if defined(PETSC_HAVE_MPIIO)
4459566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetUseMPIIO(viewer, &usempiio));
446d40cae4fSHong Zhang if (usempiio) {
4479566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetMPIIODescriptor(viewer, (MPI_File *)&fd));
4489566063dSJacob Faibussowitsch PetscCall(PetscBinarySynchronizedSeek(PetscObjectComm((PetscObject)tj), fd, off, PETSC_BINARY_SEEK_END, &offset));
449d40cae4fSHong Zhang } else {
4505e703940SHong Zhang #endif
4519566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetDescriptor(viewer, &fd));
4529566063dSJacob Faibussowitsch PetscCall(PetscBinarySeek(fd, off, PETSC_BINARY_SEEK_END, &offset));
4535e703940SHong Zhang #if defined(PETSC_HAVE_MPIIO)
454d40cae4fSHong Zhang }
4555e703940SHong Zhang #endif
456d40cae4fSHong Zhang /* load the last step into TS */
4579566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TSTrajectory_DiskRead, tj, ts, 0, 0));
4589566063dSJacob Faibussowitsch PetscCall(ReadFromDisk(ts->stifflyaccurate, &ts->steps, &ts->ptime, &ts->ptime_prev, ts->vec_sol, Y, stack->numY, SOLUTION_STAGES, viewer));
4599566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TSTrajectory_DiskRead, tj, ts, 0, 0));
46053b27ddbSHong Zhang ts->trajectory->diskreads++;
4619566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer));
4629566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
4633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
464d40cae4fSHong Zhang }
4655e703940SHong Zhang #endif
466d40cae4fSHong Zhang
DumpSingle(TSTrajectory tj,TS ts,Stack * stack,PetscInt id)467d71ae5a4SJacob Faibussowitsch static PetscErrorCode DumpSingle(TSTrajectory tj, TS ts, Stack *stack, PetscInt id)
468d71ae5a4SJacob Faibussowitsch {
469b2124117SHong Zhang Vec *Y;
4705a3ef282SHong Zhang PetscInt stepnum;
4718a10d460SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
4725a3ef282SHong Zhang char filename[PETSC_MAX_PATH_LEN];
47378fbdcc8SBarry Smith MPI_Comm comm;
4745a3ef282SHong Zhang
4755a3ef282SHong Zhang PetscFunctionBegin;
4769566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)ts, &comm));
477aced365eSHong Zhang if (tj->monitor) {
4789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
4799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Dump a single point from file\n"));
4809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
481aced365eSHong Zhang }
4829566063dSJacob Faibussowitsch PetscCall(TSGetStepNumber(ts, &stepnum));
48363a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, sizeof(filename), "%s/TS-CPS%06" PetscInt_FMT ".bin", tj->dirname, id));
4849566063dSJacob Faibussowitsch PetscCall(PetscViewerFileSetName(tjsch->viewer, filename));
4859566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(tjsch->viewer));
4865a3ef282SHong Zhang
4879566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
4889566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TSTrajectory_DiskWrite, tj, ts, 0, 0));
4899566063dSJacob Faibussowitsch PetscCall(WriteToDisk(ts->stifflyaccurate, stepnum, ts->ptime, ts->ptime_prev, ts->vec_sol, Y, stack->numY, SOLUTION_STAGES, tjsch->viewer));
4909566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TSTrajectory_DiskWrite, tj, ts, 0, 0));
49153b27ddbSHong Zhang ts->trajectory->diskwrites++;
4923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4935a3ef282SHong Zhang }
4945a3ef282SHong Zhang
LoadSingle(TSTrajectory tj,TS ts,Stack * stack,PetscInt id)495d71ae5a4SJacob Faibussowitsch static PetscErrorCode LoadSingle(TSTrajectory tj, TS ts, Stack *stack, PetscInt id)
496d71ae5a4SJacob Faibussowitsch {
497b2124117SHong Zhang Vec *Y;
4985a3ef282SHong Zhang PetscViewer viewer;
4995a3ef282SHong Zhang char filename[PETSC_MAX_PATH_LEN];
5005a3ef282SHong Zhang
5015a3ef282SHong Zhang PetscFunctionBegin;
502aced365eSHong Zhang if (tj->monitor) {
5039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
5049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Load a single point from file\n"));
5059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
506aced365eSHong Zhang }
50763a3b9bcSJacob Faibussowitsch PetscCall(PetscSNPrintf(filename, sizeof filename, "%s/TS-CPS%06" PetscInt_FMT ".bin", tj->dirname, id));
5089566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryOpen(PetscObjectComm((PetscObject)tj), filename, FILE_MODE_READ, &viewer));
5099566063dSJacob Faibussowitsch PetscCall(PetscViewerBinarySetSkipInfo(viewer, PETSC_TRUE));
5109566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, PETSC_VIEWER_NATIVE));
5119566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
5129566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(TSTrajectory_DiskRead, tj, ts, 0, 0));
5139566063dSJacob Faibussowitsch PetscCall(ReadFromDisk(ts->stifflyaccurate, &ts->steps, &ts->ptime, &ts->ptime_prev, ts->vec_sol, Y, stack->numY, SOLUTION_STAGES, viewer));
5149566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(TSTrajectory_DiskRead, tj, ts, 0, 0));
51553b27ddbSHong Zhang ts->trajectory->diskreads++;
5169566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer));
5173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5185a3ef282SHong Zhang }
5195a3ef282SHong Zhang
UpdateTS(TS ts,Stack * stack,StackElement e,PetscInt stepnum,PetscBool adjoint_mode)520d71ae5a4SJacob Faibussowitsch static PetscErrorCode UpdateTS(TS ts, Stack *stack, StackElement e, PetscInt stepnum, PetscBool adjoint_mode)
521d71ae5a4SJacob Faibussowitsch {
5228f4fbd80SHong Zhang Vec *Y;
5238f4fbd80SHong Zhang PetscInt i;
5248f4fbd80SHong Zhang
5258f4fbd80SHong Zhang PetscFunctionBegin;
526017827d1SHong Zhang /* In adjoint mode we do not need to copy solution if the stepnum is the same */
52748a46eb9SPierre Jolivet if (!adjoint_mode || (HaveSolution(e->cptype) && e->stepnum != stepnum)) PetscCall(VecCopy(e->X, ts->vec_sol));
528cc4f23bcSHong Zhang if (HaveStages(e->cptype)) {
5299566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
530cc4f23bcSHong Zhang if (e->stepnum && e->stepnum == stepnum) {
53148a46eb9SPierre Jolivet for (i = 0; i < stack->numY; i++) PetscCall(VecCopy(e->Y[i], Y[i]));
532cc4f23bcSHong Zhang } else if (ts->stifflyaccurate) {
5339566063dSJacob Faibussowitsch PetscCall(VecCopy(e->Y[stack->numY - 1], ts->vec_sol));
534cc4f23bcSHong Zhang }
5358f4fbd80SHong Zhang }
536ac73474cSStefano Zampini if (adjoint_mode) {
5379566063dSJacob Faibussowitsch PetscCall(TSSetTimeStep(ts, e->timeprev - e->time)); /* stepsize will be negative */
538ac73474cSStefano Zampini } else {
5399566063dSJacob Faibussowitsch PetscCall(TSSetTimeStep(ts, e->time - e->timeprev)); /* stepsize will be positive */
540ac73474cSStefano Zampini }
5418f4fbd80SHong Zhang ts->ptime = e->time;
5428f4fbd80SHong Zhang ts->ptime_prev = e->timeprev;
54314d3d187SHong Zhang ts->steprestart = PETSC_TRUE; /* prevent methods with FSAL using information from the previous time step which is not available when current checkpoint is restored */
5443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5458f4fbd80SHong Zhang }
5468f4fbd80SHong Zhang
ReCompute(TS ts,TJScheduler * tjsch,PetscInt stepnumbegin,PetscInt stepnumend)547d71ae5a4SJacob Faibussowitsch static PetscErrorCode ReCompute(TS ts, TJScheduler *tjsch, PetscInt stepnumbegin, PetscInt stepnumend)
548d71ae5a4SJacob Faibussowitsch {
5490c393656SHong Zhang Stack *stack = &tjsch->stack;
5502808aa04SLisandro Dalcin PetscInt i;
5518f4fbd80SHong Zhang
5528f4fbd80SHong Zhang PetscFunctionBegin;
553b552121cSHong Zhang tjsch->recompute = PETSC_TRUE; /* hints TSTrajectorySet() that it is in recompute mode */
5549566063dSJacob Faibussowitsch PetscCall(TSSetStepNumber(ts, stepnumbegin)); /* global step number */
5551a5a771fSHong Zhang for (i = stepnumbegin; i < stepnumend; i++) { /* assume fixed step size */
5560c393656SHong Zhang if (stack->solution_only && !tjsch->skip_trajectory) { /* revolve online need this */
557ac73474cSStefano Zampini /* don't use the public interface as it will update the TSHistory: this need a better fix */
5589566063dSJacob Faibussowitsch PetscCall(TSTrajectorySet_Memory(ts->trajectory, ts, ts->steps, ts->ptime, ts->vec_sol));
5598f4fbd80SHong Zhang }
5609566063dSJacob Faibussowitsch PetscCall(TSMonitor(ts, ts->steps, ts->ptime, ts->vec_sol));
5619566063dSJacob Faibussowitsch PetscCall(TSStep(ts));
5620c393656SHong Zhang if (!stack->solution_only && !tjsch->skip_trajectory) {
563ac73474cSStefano Zampini /* don't use the public interface as it will update the TSHistory: this need a better fix */
5649566063dSJacob Faibussowitsch PetscCall(TSTrajectorySet_Memory(ts->trajectory, ts, ts->steps, ts->ptime, ts->vec_sol));
5658f4fbd80SHong Zhang }
5669566063dSJacob Faibussowitsch PetscCall(TSEventHandler(ts));
56748a46eb9SPierre Jolivet if (!ts->steprollback) PetscCall(TSPostStep(ts));
5688f4fbd80SHong Zhang }
5699566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
57053b27ddbSHong Zhang ts->trajectory->recomps += stepnumend - stepnumbegin; /* recomputation counter */
5719566063dSJacob Faibussowitsch PetscCall(TSSetStepNumber(ts, stepnumend));
572b552121cSHong Zhang tjsch->recompute = PETSC_FALSE; /* reset the flag for recompute mode */
5733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5748f4fbd80SHong Zhang }
5758f4fbd80SHong Zhang
TopLevelStore(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscInt localstepnum,PetscInt laststridesize,PetscBool * done)576d71ae5a4SJacob Faibussowitsch static PetscErrorCode TopLevelStore(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscInt localstepnum, PetscInt laststridesize, PetscBool *done)
577d71ae5a4SJacob Faibussowitsch {
57869aec5caSHong Zhang Stack *stack = &tjsch->stack;
5799fbd8902SHong Zhang DiskStack *diskstack = &tjsch->diskstack;
58069aec5caSHong Zhang PetscInt stridenum;
58169aec5caSHong Zhang
58269aec5caSHong Zhang PetscFunctionBegin;
5839ef973d6SHong Zhang *done = PETSC_FALSE;
58469aec5caSHong Zhang stridenum = stepnum / tjsch->stride;
585fc1d53bdSHong Zhang /* make sure saved checkpoint id starts from 1
586fc1d53bdSHong Zhang skip last stride when using stridenum+1
587fc1d53bdSHong Zhang skip first stride when using stridenum */
58869aec5caSHong Zhang if (stack->solution_only) {
58969aec5caSHong Zhang if (tjsch->save_stack) {
59069aec5caSHong Zhang if (localstepnum == tjsch->stride - 1 && stepnum < tjsch->total_steps - laststridesize) { /* current step will be saved without going through stack */
5919566063dSJacob Faibussowitsch PetscCall(StackDumpAll(tj, ts, stack, stridenum + 1));
5922336627cSHong Zhang if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) diskstack->container[++diskstack->top] = stridenum + 1;
5939ef973d6SHong Zhang *done = PETSC_TRUE;
59469aec5caSHong Zhang }
59569aec5caSHong Zhang } else {
5962336627cSHong Zhang if (localstepnum == 0 && stepnum < tjsch->total_steps - laststridesize) {
5979566063dSJacob Faibussowitsch PetscCall(DumpSingle(tj, ts, stack, stridenum + 1));
5982336627cSHong Zhang if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) diskstack->container[++diskstack->top] = stridenum + 1;
5999ef973d6SHong Zhang *done = PETSC_TRUE;
60069aec5caSHong Zhang }
60169aec5caSHong Zhang }
60269aec5caSHong Zhang } else {
60369aec5caSHong Zhang if (tjsch->save_stack) {
6049ef973d6SHong Zhang if (localstepnum == 0 && stepnum < tjsch->total_steps && stepnum != 0) { /* skip the first stride */
6059566063dSJacob Faibussowitsch PetscCall(StackDumpAll(tj, ts, stack, stridenum));
6062336627cSHong Zhang if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) diskstack->container[++diskstack->top] = stridenum;
6079ef973d6SHong Zhang *done = PETSC_TRUE;
60869aec5caSHong Zhang }
60969aec5caSHong Zhang } else {
6102336627cSHong Zhang if (localstepnum == 1 && stepnum < tjsch->total_steps - laststridesize) {
6119566063dSJacob Faibussowitsch PetscCall(DumpSingle(tj, ts, stack, stridenum + 1));
6122336627cSHong Zhang if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) diskstack->container[++diskstack->top] = stridenum + 1;
6139ef973d6SHong Zhang *done = PETSC_TRUE;
61469aec5caSHong Zhang }
61569aec5caSHong Zhang }
61669aec5caSHong Zhang }
6173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
61869aec5caSHong Zhang }
61969aec5caSHong Zhang
TSTrajectoryMemorySet_N(TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)620d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_N(TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
621d71ae5a4SJacob Faibussowitsch {
6220c393656SHong Zhang Stack *stack = &tjsch->stack;
6238f4fbd80SHong Zhang StackElement e;
624cc4f23bcSHong Zhang CheckpointType cptype;
6258f4fbd80SHong Zhang
6268f4fbd80SHong Zhang PetscFunctionBegin;
627cf2e76e0SHong Zhang /* skip the last step */
628cf2e76e0SHong Zhang if (ts->reason) { /* only affect the forward run */
629cf2e76e0SHong Zhang /* update total_steps in the end of forward run */
630cf2e76e0SHong Zhang if (stepnum != tjsch->total_steps) tjsch->total_steps = stepnum;
631cf2e76e0SHong Zhang if (stack->solution_only) {
632cf2e76e0SHong Zhang /* get rid of the solution at second last step */
6339566063dSJacob Faibussowitsch PetscCall(StackPop(stack, &e));
634cf2e76e0SHong Zhang }
6353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
636cf2e76e0SHong Zhang }
637cf2e76e0SHong Zhang /* do not save trajectory at the recompute stage for solution_only mode */
6383ba16761SJacob Faibussowitsch if (stack->solution_only && tjsch->recompute) PetscFunctionReturn(PETSC_SUCCESS);
639cf2e76e0SHong Zhang /* skip the first step for no_solution_only mode */
6403ba16761SJacob Faibussowitsch if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(PETSC_SUCCESS);
6410c393656SHong Zhang
642cf2e76e0SHong Zhang /* resize the stack */
64348a46eb9SPierre Jolivet if (stack->top + 1 == stack->stacksize) PetscCall(StackResize(stack, 2 * stack->stacksize));
644cf2e76e0SHong Zhang /* update timenext for the previous step; necessary for step adaptivity */
645cf2e76e0SHong Zhang if (stack->top > -1) {
6469566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
647cf2e76e0SHong Zhang e->timenext = ts->ptime;
648cf2e76e0SHong Zhang }
6497a46b595SBarry Smith PetscCheck(stepnum >= stack->top, PetscObjectComm((PetscObject)ts), PETSC_ERR_MEMC, "Illegal modification of a non-top stack element");
65084675038SHong Zhang cptype = stack->solution_only ? SOLUTIONONLY : STAGESONLY;
6519566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
6529566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
6539566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
6543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
6558f4fbd80SHong Zhang }
6568f4fbd80SHong Zhang
TSTrajectoryMemorySet_N_2(TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)657d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_N_2(TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
658d71ae5a4SJacob Faibussowitsch {
659ac73474cSStefano Zampini Stack *stack = &tjsch->stack;
660ac73474cSStefano Zampini StackElement e;
661cc4f23bcSHong Zhang CheckpointType cptype;
662ac73474cSStefano Zampini
663ac73474cSStefano Zampini PetscFunctionBegin;
66448a46eb9SPierre Jolivet if (stack->top + 1 == stack->stacksize) PetscCall(StackResize(stack, 2 * stack->stacksize));
665ac73474cSStefano Zampini /* update timenext for the previous step; necessary for step adaptivity */
666ac73474cSStefano Zampini if (stack->top > -1) {
6679566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
668ac73474cSStefano Zampini e->timenext = ts->ptime;
669ac73474cSStefano Zampini }
6705f80ce2aSJacob Faibussowitsch PetscCheck(stepnum >= stack->top, PetscObjectComm((PetscObject)ts), PETSC_ERR_MEMC, "Illegal modification of a non-top stack element");
671cc4f23bcSHong Zhang cptype = stack->solution_only ? SOLUTIONONLY : SOLUTION_STAGES; /* Always include solution in a checkpoint in non-adjoint mode */
6729566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
6739566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
6749566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
6753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
676ac73474cSStefano Zampini }
677ac73474cSStefano Zampini
TSTrajectoryMemoryGet_N(TS ts,TJScheduler * tjsch,PetscInt stepnum)678d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_N(TS ts, TJScheduler *tjsch, PetscInt stepnum)
679d71ae5a4SJacob Faibussowitsch {
6800c393656SHong Zhang Stack *stack = &tjsch->stack;
6818f4fbd80SHong Zhang StackElement e;
682ac73474cSStefano Zampini PetscInt ns;
6838f4fbd80SHong Zhang
6848f4fbd80SHong Zhang PetscFunctionBegin;
685abc3e776SHong Zhang /* If TSTrajectoryGet() is called after TSAdjointSolve() converges (e.g. outside the while loop in TSAdjointSolve()), skip getting the checkpoint. */
6863ba16761SJacob Faibussowitsch if (ts->reason) PetscFunctionReturn(PETSC_SUCCESS);
6870c393656SHong Zhang if (stepnum == tjsch->total_steps) {
6889566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
6893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
6908f4fbd80SHong Zhang }
6918f4fbd80SHong Zhang /* restore a checkpoint */
6929566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
6939566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
6949566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &ns, PETSC_IGNORE));
695ac73474cSStefano Zampini if (stack->solution_only && ns) { /* recompute one step */
6969566063dSJacob Faibussowitsch PetscCall(TurnForwardWithStepsize(ts, e->timenext - e->time));
6979566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stepnum));
6988f4fbd80SHong Zhang }
6999566063dSJacob Faibussowitsch PetscCall(StackPop(stack, &e));
7003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7018f4fbd80SHong Zhang }
7028f4fbd80SHong Zhang
TSTrajectoryMemoryGet_N_2(TS ts,TJScheduler * tjsch,PetscInt stepnum)703d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_N_2(TS ts, TJScheduler *tjsch, PetscInt stepnum)
704d71ae5a4SJacob Faibussowitsch {
705ac73474cSStefano Zampini Stack *stack = &tjsch->stack;
706ac73474cSStefano Zampini StackElement e = NULL;
707ac73474cSStefano Zampini
708ac73474cSStefano Zampini PetscFunctionBegin;
7099566063dSJacob Faibussowitsch PetscCall(StackFind(stack, &e, stepnum));
71063a3b9bcSJacob Faibussowitsch PetscCheck(stepnum == e->stepnum, PetscObjectComm((PetscObject)ts), PETSC_ERR_PLIB, "Inconsistent steps! %" PetscInt_FMT " != %" PetscInt_FMT, stepnum, e->stepnum);
7119566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_FALSE));
7123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
713ac73474cSStefano Zampini }
714ac73474cSStefano Zampini
TSTrajectoryMemorySet_TLNR(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)715d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_TLNR(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
716d71ae5a4SJacob Faibussowitsch {
7170c393656SHong Zhang Stack *stack = &tjsch->stack;
71869aec5caSHong Zhang PetscInt localstepnum, laststridesize;
7198f4fbd80SHong Zhang StackElement e;
7209ef973d6SHong Zhang PetscBool done;
721cc4f23bcSHong Zhang CheckpointType cptype;
7228f4fbd80SHong Zhang
7238f4fbd80SHong Zhang PetscFunctionBegin;
7243ba16761SJacob Faibussowitsch if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(PETSC_SUCCESS);
7253ba16761SJacob Faibussowitsch if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(PETSC_SUCCESS);
7263ba16761SJacob Faibussowitsch if (tjsch->save_stack && tjsch->recompute) PetscFunctionReturn(PETSC_SUCCESS);
7278f4fbd80SHong Zhang
72869aec5caSHong Zhang localstepnum = stepnum % tjsch->stride;
72969aec5caSHong Zhang /* (stridesize-1) checkpoints are saved in each stride; an extra point is added by StackDumpAll() */
7300c393656SHong Zhang laststridesize = tjsch->total_steps % tjsch->stride;
7310c393656SHong Zhang if (!laststridesize) laststridesize = tjsch->stride;
73269aec5caSHong Zhang
73369aec5caSHong Zhang if (!tjsch->recompute) {
7349566063dSJacob Faibussowitsch PetscCall(TopLevelStore(tj, ts, tjsch, stepnum, localstepnum, laststridesize, &done));
7353ba16761SJacob Faibussowitsch if (!tjsch->save_stack && stepnum < tjsch->total_steps - laststridesize) PetscFunctionReturn(PETSC_SUCCESS);
7368f4fbd80SHong Zhang }
7373ba16761SJacob Faibussowitsch if (!stack->solution_only && localstepnum == 0) PetscFunctionReturn(PETSC_SUCCESS); /* skip last point in each stride at recompute stage or last stride */
7383ba16761SJacob Faibussowitsch if (stack->solution_only && localstepnum == tjsch->stride - 1) PetscFunctionReturn(PETSC_SUCCESS); /* skip last step in each stride at recompute stage or last stride */
73969aec5caSHong Zhang
74084675038SHong Zhang cptype = stack->solution_only ? SOLUTIONONLY : STAGESONLY;
7419566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
7429566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
7439566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
7443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7458f4fbd80SHong Zhang }
7468f4fbd80SHong Zhang
TSTrajectoryMemoryGet_TLNR(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum)747d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_TLNR(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum)
748d71ae5a4SJacob Faibussowitsch {
7490c393656SHong Zhang Stack *stack = &tjsch->stack;
7508f4fbd80SHong Zhang PetscInt id, localstepnum, laststridesize;
7518f4fbd80SHong Zhang StackElement e;
7528f4fbd80SHong Zhang
7538f4fbd80SHong Zhang PetscFunctionBegin;
7540c393656SHong Zhang if (stepnum == tjsch->total_steps) {
7559566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
7563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7578f4fbd80SHong Zhang }
75869aec5caSHong Zhang
75969aec5caSHong Zhang localstepnum = stepnum % tjsch->stride;
7600c393656SHong Zhang laststridesize = tjsch->total_steps % tjsch->stride;
7610c393656SHong Zhang if (!laststridesize) laststridesize = tjsch->stride;
7620c393656SHong Zhang if (stack->solution_only) {
7638f4fbd80SHong Zhang /* fill stack with info */
7640c393656SHong Zhang if (localstepnum == 0 && tjsch->total_steps - stepnum >= laststridesize) {
7650c393656SHong Zhang id = stepnum / tjsch->stride;
7660c393656SHong Zhang if (tjsch->save_stack) {
7679566063dSJacob Faibussowitsch PetscCall(StackLoadAll(tj, ts, stack, id));
7680c393656SHong Zhang tjsch->skip_trajectory = PETSC_TRUE;
7699566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
7709566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, id * tjsch->stride - 1, id * tjsch->stride));
7710c393656SHong Zhang tjsch->skip_trajectory = PETSC_FALSE;
7728f4fbd80SHong Zhang } else {
7739566063dSJacob Faibussowitsch PetscCall(LoadSingle(tj, ts, stack, id));
7749566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
7759566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, (id - 1) * tjsch->stride, id * tjsch->stride));
7768f4fbd80SHong Zhang }
7773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
7788f4fbd80SHong Zhang }
7798f4fbd80SHong Zhang /* restore a checkpoint */
7809566063dSJacob Faibussowitsch PetscCall(StackPop(stack, &e));
7819566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
7820c393656SHong Zhang tjsch->skip_trajectory = PETSC_TRUE;
7839566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
7849566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stepnum));
7850c393656SHong Zhang tjsch->skip_trajectory = PETSC_FALSE;
7868f4fbd80SHong Zhang } else {
78784675038SHong Zhang CheckpointType cptype = STAGESONLY;
7888f4fbd80SHong Zhang /* fill stack with info */
7890c393656SHong Zhang if (localstepnum == 0 && tjsch->total_steps - stepnum >= laststridesize) {
7900c393656SHong Zhang id = stepnum / tjsch->stride;
7910c393656SHong Zhang if (tjsch->save_stack) {
7929566063dSJacob Faibussowitsch PetscCall(StackLoadAll(tj, ts, stack, id));
7938f4fbd80SHong Zhang } else {
7949566063dSJacob Faibussowitsch PetscCall(LoadSingle(tj, ts, stack, id));
7959566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
7969566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, (id - 1) * tjsch->stride + 1, ts->ptime, ts->vec_sol));
7979566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
7989566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
7999566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, id * tjsch->stride));
8008f4fbd80SHong Zhang }
8013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8028f4fbd80SHong Zhang }
8038f4fbd80SHong Zhang /* restore a checkpoint */
8049566063dSJacob Faibussowitsch PetscCall(StackPop(stack, &e));
8059566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
8068f4fbd80SHong Zhang }
8073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8088f4fbd80SHong Zhang }
8098f4fbd80SHong Zhang
8102f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
printwhattodo(PetscViewer viewer,PetscRevolveInt whattodo,RevolveCTX * rctx,PetscRevolveInt shift)811d71ae5a4SJacob Faibussowitsch static PetscErrorCode printwhattodo(PetscViewer viewer, PetscRevolveInt whattodo, RevolveCTX *rctx, PetscRevolveInt shift)
812d71ae5a4SJacob Faibussowitsch {
813aced365eSHong Zhang PetscFunctionBegin;
8143ba16761SJacob Faibussowitsch if (!viewer) PetscFunctionReturn(PETSC_SUCCESS);
815aced365eSHong Zhang
8168f4fbd80SHong Zhang switch (whattodo) {
817d71ae5a4SJacob Faibussowitsch case 1:
818d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Advance from %d to %d\n", rctx->oldcapo + shift, rctx->capo + shift));
819d71ae5a4SJacob Faibussowitsch break;
820d71ae5a4SJacob Faibussowitsch case 2:
821d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Store in checkpoint number %d (located in RAM)\n", rctx->check));
822d71ae5a4SJacob Faibussowitsch break;
823d71ae5a4SJacob Faibussowitsch case 3:
824d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "First turn: Initialize adjoints and reverse first step\n"));
825d71ae5a4SJacob Faibussowitsch break;
826d71ae5a4SJacob Faibussowitsch case 4:
827d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Forward and reverse one step\n"));
828d71ae5a4SJacob Faibussowitsch break;
829d71ae5a4SJacob Faibussowitsch case 5:
830d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Restore in checkpoint number %d (located in RAM)\n", rctx->check));
831d71ae5a4SJacob Faibussowitsch break;
832d71ae5a4SJacob Faibussowitsch case 7:
833d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Store in checkpoint number %d (located on disk)\n", rctx->check));
834d71ae5a4SJacob Faibussowitsch break;
835d71ae5a4SJacob Faibussowitsch case 8:
836d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Restore in checkpoint number %d (located on disk)\n", rctx->check));
837d71ae5a4SJacob Faibussowitsch break;
838d71ae5a4SJacob Faibussowitsch case -1:
839d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Error!"));
840d71ae5a4SJacob Faibussowitsch break;
8418f4fbd80SHong Zhang }
8423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8438f4fbd80SHong Zhang }
8448f4fbd80SHong Zhang
printwhattodo2(PetscViewer viewer,PetscRevolveInt whattodo,RevolveCTX * rctx,PetscRevolveInt shift)845d71ae5a4SJacob Faibussowitsch static PetscErrorCode printwhattodo2(PetscViewer viewer, PetscRevolveInt whattodo, RevolveCTX *rctx, PetscRevolveInt shift)
846d71ae5a4SJacob Faibussowitsch {
847aced365eSHong Zhang PetscFunctionBegin;
8483ba16761SJacob Faibussowitsch if (!viewer) PetscFunctionReturn(PETSC_SUCCESS);
849aced365eSHong Zhang
8509ef973d6SHong Zhang switch (whattodo) {
851d71ae5a4SJacob Faibussowitsch case 1:
852d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "[Top Level] Advance from stride %d to stride %d\n", rctx->oldcapo + shift, rctx->capo + shift));
853d71ae5a4SJacob Faibussowitsch break;
854d71ae5a4SJacob Faibussowitsch case 2:
855d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "[Top Level] Store in checkpoint number %d\n", rctx->check));
856d71ae5a4SJacob Faibussowitsch break;
857d71ae5a4SJacob Faibussowitsch case 3:
858d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "[Top Level] First turn: Initialize adjoints and reverse first stride\n"));
859d71ae5a4SJacob Faibussowitsch break;
860d71ae5a4SJacob Faibussowitsch case 4:
861d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "[Top Level] Forward and reverse one stride\n"));
862d71ae5a4SJacob Faibussowitsch break;
863d71ae5a4SJacob Faibussowitsch case 5:
864d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "[Top Level] Restore in checkpoint number %d\n", rctx->check));
865d71ae5a4SJacob Faibussowitsch break;
866d71ae5a4SJacob Faibussowitsch case 7:
867d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "[Top Level] Store in top-level checkpoint number %d\n", rctx->check));
868d71ae5a4SJacob Faibussowitsch break;
869d71ae5a4SJacob Faibussowitsch case 8:
870d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "[Top Level] Restore in top-level checkpoint number %d\n", rctx->check));
871d71ae5a4SJacob Faibussowitsch break;
872d71ae5a4SJacob Faibussowitsch case -1:
873d71ae5a4SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "[Top Level] Error!"));
874d71ae5a4SJacob Faibussowitsch break;
8759ef973d6SHong Zhang }
8763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
8779ef973d6SHong Zhang }
8789ef973d6SHong Zhang
InitRevolve(PetscInt fine,PetscInt snaps,RevolveCTX * rctx)879d71ae5a4SJacob Faibussowitsch static PetscErrorCode InitRevolve(PetscInt fine, PetscInt snaps, RevolveCTX *rctx)
880d71ae5a4SJacob Faibussowitsch {
881e43ad619SHong Zhang PetscRevolveInt rsnaps, rfine;
882e43ad619SHong Zhang
883d40cae4fSHong Zhang PetscFunctionBegin;
8849566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(snaps, &rsnaps));
8859566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(fine, &rfine));
886d40cae4fSHong Zhang revolve_reset();
887e43ad619SHong Zhang revolve_create_offline(rfine, rsnaps);
888e43ad619SHong Zhang rctx->snaps_in = rsnaps;
889e43ad619SHong Zhang rctx->fine = rfine;
890d40cae4fSHong Zhang rctx->check = 0;
891d40cae4fSHong Zhang rctx->capo = 0;
892d40cae4fSHong Zhang rctx->reverseonestep = PETSC_FALSE;
893d40cae4fSHong Zhang /* check stepsleft? */
8943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
895d40cae4fSHong Zhang }
896d40cae4fSHong Zhang
FastForwardRevolve(RevolveCTX * rctx)897d71ae5a4SJacob Faibussowitsch static PetscErrorCode FastForwardRevolve(RevolveCTX *rctx)
898d71ae5a4SJacob Faibussowitsch {
899e43ad619SHong Zhang PetscRevolveInt whattodo;
900d40cae4fSHong Zhang
901d40cae4fSHong Zhang PetscFunctionBegin;
902d40cae4fSHong Zhang whattodo = 0;
903d40cae4fSHong Zhang while (whattodo != 3) { /* we have to fast forward revolve to the beginning of the backward sweep due to unfriendly revolve interface */
904d40cae4fSHong Zhang whattodo = revolve_action(&rctx->check, &rctx->capo, &rctx->fine, rctx->snaps_in, &rctx->info, &rctx->where);
905d40cae4fSHong Zhang }
9063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
907d40cae4fSHong Zhang }
908d40cae4fSHong Zhang
ApplyRevolve(PetscViewer viewer,SchedulerType stype,RevolveCTX * rctx,PetscRevolveInt total_steps,PetscRevolveInt stepnum,PetscRevolveInt localstepnum,PetscBool toplevel,PetscInt * store)909d71ae5a4SJacob Faibussowitsch static PetscErrorCode ApplyRevolve(PetscViewer viewer, SchedulerType stype, RevolveCTX *rctx, PetscRevolveInt total_steps, PetscRevolveInt stepnum, PetscRevolveInt localstepnum, PetscBool toplevel, PetscInt *store)
910d71ae5a4SJacob Faibussowitsch {
911e43ad619SHong Zhang PetscRevolveInt shift, whattodo;
9128f4fbd80SHong Zhang
9138f4fbd80SHong Zhang PetscFunctionBegin;
9148f4fbd80SHong Zhang *store = 0;
9158f4fbd80SHong Zhang if (rctx->stepsleft > 0) { /* advance the solution without checkpointing anything as Revolve requires */
9168f4fbd80SHong Zhang rctx->stepsleft--;
9173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
9188f4fbd80SHong Zhang }
9198f4fbd80SHong Zhang /* let Revolve determine what to do next */
9208f4fbd80SHong Zhang shift = stepnum - localstepnum;
9218f4fbd80SHong Zhang rctx->oldcapo = rctx->capo;
9228f4fbd80SHong Zhang rctx->capo = localstepnum;
9239ef973d6SHong Zhang
9249ef973d6SHong Zhang if (!toplevel) whattodo = revolve_action(&rctx->check, &rctx->capo, &rctx->fine, rctx->snaps_in, &rctx->info, &rctx->where);
9259ef973d6SHong Zhang else whattodo = revolve2_action(&rctx->check, &rctx->capo, &rctx->fine, rctx->snaps_in, &rctx->info, &rctx->where);
92669aec5caSHong Zhang if (stype == REVOLVE_ONLINE && whattodo == 8) whattodo = 5;
92769aec5caSHong Zhang if (stype == REVOLVE_ONLINE && whattodo == 7) whattodo = 2;
9289566063dSJacob Faibussowitsch if (!toplevel) PetscCall(printwhattodo(viewer, whattodo, rctx, shift));
9299566063dSJacob Faibussowitsch else PetscCall(printwhattodo2(viewer, whattodo, rctx, shift));
9305f80ce2aSJacob Faibussowitsch PetscCheck(whattodo != -1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error in the Revolve library");
9318f4fbd80SHong Zhang if (whattodo == 1) { /* advance some time steps */
93269aec5caSHong Zhang if (stype == REVOLVE_ONLINE && rctx->capo >= total_steps - 1) {
93369aec5caSHong Zhang revolve_turn(total_steps, &rctx->capo, &rctx->fine);
9349566063dSJacob Faibussowitsch if (!toplevel) PetscCall(printwhattodo(viewer, whattodo, rctx, shift));
9359566063dSJacob Faibussowitsch else PetscCall(printwhattodo2(viewer, whattodo, rctx, shift));
9368f4fbd80SHong Zhang }
9378f4fbd80SHong Zhang rctx->stepsleft = rctx->capo - rctx->oldcapo - 1;
9388f4fbd80SHong Zhang }
9398f4fbd80SHong Zhang if (whattodo == 3 || whattodo == 4) { /* ready for a reverse step */
9408f4fbd80SHong Zhang rctx->reverseonestep = PETSC_TRUE;
9418f4fbd80SHong Zhang }
9428f4fbd80SHong Zhang if (whattodo == 5) { /* restore a checkpoint and ask Revolve what to do next */
9438f4fbd80SHong Zhang rctx->oldcapo = rctx->capo;
9449ef973d6SHong Zhang if (!toplevel) whattodo = revolve_action(&rctx->check, &rctx->capo, &rctx->fine, rctx->snaps_in, &rctx->info, &rctx->where); /* must return 1 or 3 or 4*/
9459ef973d6SHong Zhang else whattodo = revolve2_action(&rctx->check, &rctx->capo, &rctx->fine, rctx->snaps_in, &rctx->info, &rctx->where);
9469566063dSJacob Faibussowitsch if (!toplevel) PetscCall(printwhattodo(viewer, whattodo, rctx, shift));
9479566063dSJacob Faibussowitsch else PetscCall(printwhattodo2(viewer, whattodo, rctx, shift));
9488f4fbd80SHong Zhang if (whattodo == 3 || whattodo == 4) rctx->reverseonestep = PETSC_TRUE;
9498f4fbd80SHong Zhang if (whattodo == 1) rctx->stepsleft = rctx->capo - rctx->oldcapo;
9508f4fbd80SHong Zhang }
9518f4fbd80SHong Zhang if (whattodo == 7) { /* save the checkpoint to disk */
9528f4fbd80SHong Zhang *store = 2;
9538f4fbd80SHong Zhang rctx->oldcapo = rctx->capo;
9548f4fbd80SHong Zhang whattodo = revolve_action(&rctx->check, &rctx->capo, &rctx->fine, rctx->snaps_in, &rctx->info, &rctx->where); /* must return 1 */
9559566063dSJacob Faibussowitsch PetscCall(printwhattodo(viewer, whattodo, rctx, shift));
9568f4fbd80SHong Zhang rctx->stepsleft = rctx->capo - rctx->oldcapo - 1;
9578f4fbd80SHong Zhang }
9588f4fbd80SHong Zhang if (whattodo == 2) { /* store a checkpoint to RAM and ask Revolve how many time steps to advance next */
9598f4fbd80SHong Zhang *store = 1;
9608f4fbd80SHong Zhang rctx->oldcapo = rctx->capo;
9619ef973d6SHong Zhang if (!toplevel) whattodo = revolve_action(&rctx->check, &rctx->capo, &rctx->fine, rctx->snaps_in, &rctx->info, &rctx->where); /* must return 1 */
9629ef973d6SHong Zhang else whattodo = revolve2_action(&rctx->check, &rctx->capo, &rctx->fine, rctx->snaps_in, &rctx->info, &rctx->where);
9639566063dSJacob Faibussowitsch if (!toplevel) PetscCall(printwhattodo(viewer, whattodo, rctx, shift));
9649566063dSJacob Faibussowitsch else PetscCall(printwhattodo2(viewer, whattodo, rctx, shift));
96569aec5caSHong Zhang if (stype == REVOLVE_ONLINE && rctx->capo >= total_steps - 1) {
96669aec5caSHong Zhang revolve_turn(total_steps, &rctx->capo, &rctx->fine);
9679566063dSJacob Faibussowitsch PetscCall(printwhattodo(viewer, whattodo, rctx, shift));
9688f4fbd80SHong Zhang }
9698f4fbd80SHong Zhang rctx->stepsleft = rctx->capo - rctx->oldcapo - 1;
9708f4fbd80SHong Zhang }
9713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
9728f4fbd80SHong Zhang }
9738f4fbd80SHong Zhang
TSTrajectoryMemorySet_ROF(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)974d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_ROF(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
975d71ae5a4SJacob Faibussowitsch {
9760c393656SHong Zhang Stack *stack = &tjsch->stack;
9778f4fbd80SHong Zhang PetscInt store;
9788f4fbd80SHong Zhang StackElement e;
979e43ad619SHong Zhang PetscRevolveInt rtotal_steps, rstepnum;
980cc4f23bcSHong Zhang CheckpointType cptype;
9818f4fbd80SHong Zhang
9828f4fbd80SHong Zhang PetscFunctionBegin;
9833ba16761SJacob Faibussowitsch if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(PETSC_SUCCESS);
9843ba16761SJacob Faibussowitsch if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(PETSC_SUCCESS);
9859566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
9869566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
9879566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rstepnum, rstepnum, PETSC_FALSE, &store));
9888f4fbd80SHong Zhang if (store == 1) {
9895f80ce2aSJacob Faibussowitsch PetscCheck(stepnum >= stack->top, PetscObjectComm((PetscObject)ts), PETSC_ERR_MEMC, "Illegal modification of a non-top stack element");
990cc4f23bcSHong Zhang cptype = stack->solution_only ? SOLUTIONONLY : SOLUTION_STAGES;
9919566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
9929566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
9939566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
9948f4fbd80SHong Zhang }
9953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
9968f4fbd80SHong Zhang }
9978f4fbd80SHong Zhang
TSTrajectoryMemoryGet_ROF(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum)998d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_ROF(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum)
999d71ae5a4SJacob Faibussowitsch {
10000c393656SHong Zhang Stack *stack = &tjsch->stack;
1001e43ad619SHong Zhang PetscInt store;
1002e43ad619SHong Zhang PetscRevolveInt whattodo, shift, rtotal_steps, rstepnum;
10038f4fbd80SHong Zhang StackElement e;
10048f4fbd80SHong Zhang
10058f4fbd80SHong Zhang PetscFunctionBegin;
10060c393656SHong Zhang if (stepnum == 0 || stepnum == tjsch->total_steps) {
10079566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
10080f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
10093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
10108f4fbd80SHong Zhang }
10118f4fbd80SHong Zhang /* restore a checkpoint */
10129566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
10139566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
10149566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
10159566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
10160c393656SHong Zhang if (stack->solution_only) { /* start with restoring a checkpoint */
1017e43ad619SHong Zhang tjsch->rctx->capo = rstepnum;
10180c393656SHong Zhang tjsch->rctx->oldcapo = tjsch->rctx->capo;
10198f4fbd80SHong Zhang shift = 0;
10200c393656SHong Zhang whattodo = revolve_action(&tjsch->rctx->check, &tjsch->rctx->capo, &tjsch->rctx->fine, tjsch->rctx->snaps_in, &tjsch->rctx->info, &tjsch->rctx->where);
10219566063dSJacob Faibussowitsch PetscCall(printwhattodo(tj->monitor, whattodo, tjsch->rctx, shift));
10228f4fbd80SHong Zhang } else { /* 2 revolve actions: restore a checkpoint and then advance */
10239566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rstepnum, rstepnum, PETSC_FALSE, &store));
1024aced365eSHong Zhang if (tj->monitor) {
10259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
102663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Skip the step from %d to %d (stage values already checkpointed)\n", tjsch->rctx->oldcapo, tjsch->rctx->oldcapo + 1));
10279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
1028aced365eSHong Zhang }
1029d40cae4fSHong Zhang if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) tjsch->rctx->stepsleft--;
10308f4fbd80SHong Zhang }
10310c393656SHong Zhang if (stack->solution_only || (!stack->solution_only && e->stepnum < stepnum)) {
10329566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
10339566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stepnum));
10348f4fbd80SHong Zhang }
103548a46eb9SPierre Jolivet if ((stack->solution_only && e->stepnum + 1 == stepnum) || (!stack->solution_only && e->stepnum == stepnum)) PetscCall(StackPop(stack, &e));
10360f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
10373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
10388f4fbd80SHong Zhang }
10398f4fbd80SHong Zhang
TSTrajectoryMemorySet_RON(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)1040d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_RON(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
1041d71ae5a4SJacob Faibussowitsch {
10420c393656SHong Zhang Stack *stack = &tjsch->stack;
10438f4fbd80SHong Zhang Vec *Y;
10448f4fbd80SHong Zhang PetscInt i, store;
10458f4fbd80SHong Zhang PetscReal timeprev;
10468f4fbd80SHong Zhang StackElement e;
10470c393656SHong Zhang RevolveCTX *rctx = tjsch->rctx;
1048e43ad619SHong Zhang PetscRevolveInt rtotal_steps, rstepnum;
1049cc4f23bcSHong Zhang CheckpointType cptype;
10508f4fbd80SHong Zhang
10518f4fbd80SHong Zhang PetscFunctionBegin;
10523ba16761SJacob Faibussowitsch if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(PETSC_SUCCESS);
10533ba16761SJacob Faibussowitsch if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(PETSC_SUCCESS);
10549566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
10559566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
10569566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, rctx, rtotal_steps, rstepnum, rstepnum, PETSC_FALSE, &store));
10578f4fbd80SHong Zhang if (store == 1) {
10580c393656SHong Zhang if (rctx->check != stack->top + 1) { /* overwrite some non-top checkpoint in the stack */
10599566063dSJacob Faibussowitsch PetscCall(StackFind(stack, &e, rctx->check));
106048a46eb9SPierre Jolivet if (HaveSolution(e->cptype)) PetscCall(VecCopy(X, e->X));
1061cc4f23bcSHong Zhang if (HaveStages(e->cptype)) {
10629566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &stack->numY, &Y));
106348a46eb9SPierre Jolivet for (i = 0; i < stack->numY; i++) PetscCall(VecCopy(Y[i], e->Y[i]));
10648f4fbd80SHong Zhang }
10658f4fbd80SHong Zhang e->stepnum = stepnum;
10668f4fbd80SHong Zhang e->time = time;
10679566063dSJacob Faibussowitsch PetscCall(TSGetPrevTime(ts, &timeprev));
10688f4fbd80SHong Zhang e->timeprev = timeprev;
10698f4fbd80SHong Zhang } else {
10705f80ce2aSJacob Faibussowitsch PetscCheck(stepnum >= stack->top, PetscObjectComm((PetscObject)ts), PETSC_ERR_MEMC, "Illegal modification of a non-top stack element");
1071cc4f23bcSHong Zhang cptype = stack->solution_only ? SOLUTIONONLY : SOLUTION_STAGES;
10729566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
10739566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
10749566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
10758f4fbd80SHong Zhang }
10768f4fbd80SHong Zhang }
10773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
10788f4fbd80SHong Zhang }
10798f4fbd80SHong Zhang
TSTrajectoryMemoryGet_RON(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum)1080d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_RON(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum)
1081d71ae5a4SJacob Faibussowitsch {
10820c393656SHong Zhang Stack *stack = &tjsch->stack;
1083e43ad619SHong Zhang PetscRevolveInt whattodo, shift, rstepnum;
10848f4fbd80SHong Zhang StackElement e;
10858f4fbd80SHong Zhang
10868f4fbd80SHong Zhang PetscFunctionBegin;
10870c393656SHong Zhang if (stepnum == 0 || stepnum == tjsch->total_steps) {
10889566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
10890f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
10903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
10918f4fbd80SHong Zhang }
10929566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
1093e43ad619SHong Zhang tjsch->rctx->capo = rstepnum;
10940c393656SHong Zhang tjsch->rctx->oldcapo = tjsch->rctx->capo;
10958f4fbd80SHong Zhang shift = 0;
10960c393656SHong Zhang whattodo = revolve_action(&tjsch->rctx->check, &tjsch->rctx->capo, &tjsch->rctx->fine, tjsch->rctx->snaps_in, &tjsch->rctx->info, &tjsch->rctx->where); /* whattodo=restore */
10978f4fbd80SHong Zhang if (whattodo == 8) whattodo = 5;
10989566063dSJacob Faibussowitsch PetscCall(printwhattodo(tj->monitor, whattodo, tjsch->rctx, shift));
10998f4fbd80SHong Zhang /* restore a checkpoint */
11009566063dSJacob Faibussowitsch PetscCall(StackFind(stack, &e, tjsch->rctx->check));
11019566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
11020c393656SHong Zhang if (!stack->solution_only) { /* whattodo must be 5 */
11038f4fbd80SHong Zhang /* ask Revolve what to do next */
11040c393656SHong Zhang tjsch->rctx->oldcapo = tjsch->rctx->capo;
11050c393656SHong Zhang whattodo = revolve_action(&tjsch->rctx->check, &tjsch->rctx->capo, &tjsch->rctx->fine, tjsch->rctx->snaps_in, &tjsch->rctx->info, &tjsch->rctx->where); /* must return 1 or 3 or 4*/
11069566063dSJacob Faibussowitsch PetscCall(printwhattodo(tj->monitor, whattodo, tjsch->rctx, shift));
11070c393656SHong Zhang if (whattodo == 3 || whattodo == 4) tjsch->rctx->reverseonestep = PETSC_TRUE;
11080c393656SHong Zhang if (whattodo == 1) tjsch->rctx->stepsleft = tjsch->rctx->capo - tjsch->rctx->oldcapo;
1109aced365eSHong Zhang if (tj->monitor) {
11109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
111163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Skip the step from %d to %d (stage values already checkpointed)\n", tjsch->rctx->oldcapo, tjsch->rctx->oldcapo + 1));
11129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
1113aced365eSHong Zhang }
1114d40cae4fSHong Zhang if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) tjsch->rctx->stepsleft--;
11158f4fbd80SHong Zhang }
11160c393656SHong Zhang if (stack->solution_only || (!stack->solution_only && e->stepnum < stepnum)) {
11179566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
11189566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stepnum));
11198f4fbd80SHong Zhang }
11200f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
11213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
11228f4fbd80SHong Zhang }
11238f4fbd80SHong Zhang
TSTrajectoryMemorySet_TLR(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)1124d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_TLR(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
1125d71ae5a4SJacob Faibussowitsch {
11260c393656SHong Zhang Stack *stack = &tjsch->stack;
112769aec5caSHong Zhang PetscInt store, localstepnum, laststridesize;
11288f4fbd80SHong Zhang StackElement e;
11299ef973d6SHong Zhang PetscBool done = PETSC_FALSE;
1130e43ad619SHong Zhang PetscRevolveInt rtotal_steps, rstepnum, rlocalstepnum;
1131cc4f23bcSHong Zhang CheckpointType cptype;
11328f4fbd80SHong Zhang
11338f4fbd80SHong Zhang PetscFunctionBegin;
11343ba16761SJacob Faibussowitsch if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(PETSC_SUCCESS);
11353ba16761SJacob Faibussowitsch if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(PETSC_SUCCESS);
11368f4fbd80SHong Zhang
113769aec5caSHong Zhang localstepnum = stepnum % tjsch->stride;
11380c393656SHong Zhang laststridesize = tjsch->total_steps % tjsch->stride;
11390c393656SHong Zhang if (!laststridesize) laststridesize = tjsch->stride;
114069aec5caSHong Zhang
114194645148SHong Zhang if (!tjsch->recompute) {
11429566063dSJacob Faibussowitsch PetscCall(TopLevelStore(tj, ts, tjsch, stepnum, localstepnum, laststridesize, &done));
114394645148SHong Zhang /* revolve is needed for the last stride; different starting points for last stride between solutin_only and !solutin_only */
11443ba16761SJacob Faibussowitsch if (!stack->solution_only && !tjsch->save_stack && stepnum <= tjsch->total_steps - laststridesize) PetscFunctionReturn(PETSC_SUCCESS);
11453ba16761SJacob Faibussowitsch if (stack->solution_only && !tjsch->save_stack && stepnum < tjsch->total_steps - laststridesize) PetscFunctionReturn(PETSC_SUCCESS);
11468f4fbd80SHong Zhang }
11479ef973d6SHong Zhang if (tjsch->save_stack && done) {
11489566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
11493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
11508f4fbd80SHong Zhang }
115194645148SHong Zhang if (laststridesize < tjsch->stride) {
115294645148SHong Zhang if (stack->solution_only && stepnum == tjsch->total_steps - laststridesize && !tjsch->recompute) { /* step tjsch->total_steps-laststridesize-1 is skipped, but the next step is not */
11539566063dSJacob Faibussowitsch PetscCall(InitRevolve(laststridesize, tjsch->max_cps_ram, tjsch->rctx));
115494645148SHong Zhang }
115594645148SHong Zhang if (!stack->solution_only && stepnum == tjsch->total_steps - laststridesize + 1 && !tjsch->recompute) { /* step tjsch->total_steps-laststridesize is skipped, but the next step is not */
11569566063dSJacob Faibussowitsch PetscCall(InitRevolve(laststridesize, tjsch->max_cps_ram, tjsch->rctx));
115794645148SHong Zhang }
115894645148SHong Zhang }
11599566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
11609566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
11619566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(localstepnum, &rlocalstepnum));
11629566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rstepnum, rlocalstepnum, PETSC_FALSE, &store));
116369aec5caSHong Zhang if (store == 1) {
11645f80ce2aSJacob Faibussowitsch PetscCheck(localstepnum >= stack->top, PetscObjectComm((PetscObject)ts), PETSC_ERR_MEMC, "Illegal modification of a non-top stack element");
1165cc4f23bcSHong Zhang cptype = stack->solution_only ? SOLUTIONONLY : SOLUTION_STAGES;
11669566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
11679566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
11689566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
116969aec5caSHong Zhang }
11703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
11718f4fbd80SHong Zhang }
11728f4fbd80SHong Zhang
TSTrajectoryMemoryGet_TLR(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum)1173d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_TLR(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum)
1174d71ae5a4SJacob Faibussowitsch {
11750c393656SHong Zhang Stack *stack = &tjsch->stack;
1176e43ad619SHong Zhang PetscRevolveInt whattodo, shift, rstepnum, rlocalstepnum, rtotal_steps;
117769aec5caSHong Zhang PetscInt localstepnum, stridenum, laststridesize, store;
11788f4fbd80SHong Zhang StackElement e;
1179cc4f23bcSHong Zhang CheckpointType cptype;
11808f4fbd80SHong Zhang
11818f4fbd80SHong Zhang PetscFunctionBegin;
11820c393656SHong Zhang localstepnum = stepnum % tjsch->stride;
118369aec5caSHong Zhang stridenum = stepnum / tjsch->stride;
11840c393656SHong Zhang if (stepnum == tjsch->total_steps) {
11859566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
11860f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
11873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
11888f4fbd80SHong Zhang }
11890c393656SHong Zhang laststridesize = tjsch->total_steps % tjsch->stride;
11900c393656SHong Zhang if (!laststridesize) laststridesize = tjsch->stride;
11919566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
11929566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
11939566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(localstepnum, &rlocalstepnum));
11940c393656SHong Zhang if (stack->solution_only) {
11958f4fbd80SHong Zhang /* fill stack */
11960c393656SHong Zhang if (localstepnum == 0 && stepnum <= tjsch->total_steps - laststridesize) {
11970c393656SHong Zhang if (tjsch->save_stack) {
11989566063dSJacob Faibussowitsch PetscCall(StackLoadAll(tj, ts, stack, stridenum));
11999566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
12009566063dSJacob Faibussowitsch PetscCall(FastForwardRevolve(tjsch->rctx));
12010c393656SHong Zhang tjsch->skip_trajectory = PETSC_TRUE;
12029566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
12039566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, stridenum * tjsch->stride - 1, stridenum * tjsch->stride));
12040c393656SHong Zhang tjsch->skip_trajectory = PETSC_FALSE;
12058f4fbd80SHong Zhang } else {
12069566063dSJacob Faibussowitsch PetscCall(LoadSingle(tj, ts, stack, stridenum));
12079566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
12089566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
12099566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, (stridenum - 1) * tjsch->stride, stridenum * tjsch->stride));
12108f4fbd80SHong Zhang }
12113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
12128f4fbd80SHong Zhang }
12138f4fbd80SHong Zhang /* restore a checkpoint */
12149566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
12159566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
12168f4fbd80SHong Zhang /* start with restoring a checkpoint */
1217e43ad619SHong Zhang tjsch->rctx->capo = rstepnum;
12180c393656SHong Zhang tjsch->rctx->oldcapo = tjsch->rctx->capo;
1219e43ad619SHong Zhang shift = rstepnum - rlocalstepnum;
12200c393656SHong Zhang whattodo = revolve_action(&tjsch->rctx->check, &tjsch->rctx->capo, &tjsch->rctx->fine, tjsch->rctx->snaps_in, &tjsch->rctx->info, &tjsch->rctx->where);
12219566063dSJacob Faibussowitsch PetscCall(printwhattodo(tj->monitor, whattodo, tjsch->rctx, shift));
12229566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
12239566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stepnum));
122448a46eb9SPierre Jolivet if (e->stepnum + 1 == stepnum) PetscCall(StackPop(stack, &e));
12258f4fbd80SHong Zhang } else {
12268f4fbd80SHong Zhang /* fill stack with info */
12270c393656SHong Zhang if (localstepnum == 0 && tjsch->total_steps - stepnum >= laststridesize) {
12280c393656SHong Zhang if (tjsch->save_stack) {
12299566063dSJacob Faibussowitsch PetscCall(StackLoadAll(tj, ts, stack, stridenum));
12309566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
12319566063dSJacob Faibussowitsch PetscCall(FastForwardRevolve(tjsch->rctx));
12328f4fbd80SHong Zhang } else {
1233e43ad619SHong Zhang PetscRevolveInt rnum;
12349566063dSJacob Faibussowitsch PetscCall(LoadSingle(tj, ts, stack, stridenum));
12359566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
12369566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast((stridenum - 1) * tjsch->stride + 1, &rnum));
12379566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rnum, 1, PETSC_FALSE, &store));
1238aced365eSHong Zhang if (tj->monitor) {
12399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
12409371c9d4SSatish Balay PetscCall(
12419371c9d4SSatish Balay PetscViewerASCIIPrintf(tj->monitor, "Skip the step from %" PetscInt_FMT " to %" PetscInt_FMT " (stage values already checkpointed)\n", (stridenum - 1) * tjsch->stride + tjsch->rctx->oldcapo, (stridenum - 1) * tjsch->stride + tjsch->rctx->oldcapo + 1));
12429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
1243aced365eSHong Zhang }
1244cc4f23bcSHong Zhang cptype = SOLUTION_STAGES;
12459566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
12469566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, (stridenum - 1) * tjsch->stride + 1, ts->ptime, ts->vec_sol));
12479566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
12489566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
12499566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stridenum * tjsch->stride));
12508f4fbd80SHong Zhang }
12513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
12528f4fbd80SHong Zhang }
12538f4fbd80SHong Zhang /* restore a checkpoint */
12549566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
12559566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
12568f4fbd80SHong Zhang /* 2 revolve actions: restore a checkpoint and then advance */
12579566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rstepnum, rlocalstepnum, PETSC_FALSE, &store));
1258aced365eSHong Zhang if (tj->monitor) {
12599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
126063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Skip the step from %" PetscInt_FMT " to %" PetscInt_FMT " (stage values already checkpointed)\n", stepnum - localstepnum + tjsch->rctx->oldcapo, stepnum - localstepnum + tjsch->rctx->oldcapo + 1));
12619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
1262aced365eSHong Zhang }
1263d40cae4fSHong Zhang if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) tjsch->rctx->stepsleft--;
12648f4fbd80SHong Zhang if (e->stepnum < stepnum) {
12659566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
12669566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stepnum));
12678f4fbd80SHong Zhang }
126848a46eb9SPierre Jolivet if (e->stepnum == stepnum) PetscCall(StackPop(stack, &e));
12698f4fbd80SHong Zhang }
12700f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
12713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
12728f4fbd80SHong Zhang }
12738f4fbd80SHong Zhang
TSTrajectoryMemorySet_TLTR(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)1274d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_TLTR(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
1275d71ae5a4SJacob Faibussowitsch {
1276fc1d53bdSHong Zhang Stack *stack = &tjsch->stack;
12779ef973d6SHong Zhang PetscInt store, localstepnum, stridenum, laststridesize;
1278fc1d53bdSHong Zhang StackElement e;
12799ef973d6SHong Zhang PetscBool done = PETSC_FALSE;
1280e43ad619SHong Zhang PetscRevolveInt rlocalstepnum, rstepnum, rtotal_steps;
1281fc1d53bdSHong Zhang
1282fc1d53bdSHong Zhang PetscFunctionBegin;
12833ba16761SJacob Faibussowitsch if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(PETSC_SUCCESS);
12843ba16761SJacob Faibussowitsch if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(PETSC_SUCCESS);
1285fc1d53bdSHong Zhang
1286fc1d53bdSHong Zhang localstepnum = stepnum % tjsch->stride; /* index at the bottom level (inside a stride) */
1287fc1d53bdSHong Zhang stridenum = stepnum / tjsch->stride; /* index at the top level */
1288fc1d53bdSHong Zhang laststridesize = tjsch->total_steps % tjsch->stride;
1289fc1d53bdSHong Zhang if (!laststridesize) laststridesize = tjsch->stride;
12909ef973d6SHong Zhang if (stack->solution_only && localstepnum == 0 && !tjsch->rctx2->reverseonestep) {
12919566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast((tjsch->total_steps + tjsch->stride - 1) / tjsch->stride, &rtotal_steps));
12929566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stridenum, &rstepnum));
12939566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx2, rtotal_steps, rstepnum, rstepnum, PETSC_TRUE, &tjsch->store_stride));
129448a46eb9SPierre Jolivet if (laststridesize < tjsch->stride && stepnum == tjsch->total_steps - laststridesize) PetscCall(InitRevolve(laststridesize, tjsch->max_cps_ram, tjsch->rctx));
1295fc1d53bdSHong Zhang }
12969ef973d6SHong Zhang if (!stack->solution_only && localstepnum == 1 && !tjsch->rctx2->reverseonestep) {
12979566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast((tjsch->total_steps + tjsch->stride - 1) / tjsch->stride, &rtotal_steps));
12989566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stridenum, &rstepnum));
12999566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx2, rtotal_steps, rstepnum, rstepnum, PETSC_TRUE, &tjsch->store_stride));
130048a46eb9SPierre Jolivet if (laststridesize < tjsch->stride && stepnum == tjsch->total_steps - laststridesize + 1) PetscCall(InitRevolve(laststridesize, tjsch->max_cps_ram, tjsch->rctx));
13019ef973d6SHong Zhang }
13029ef973d6SHong Zhang if (tjsch->store_stride) {
13039566063dSJacob Faibussowitsch PetscCall(TopLevelStore(tj, ts, tjsch, stepnum, localstepnum, laststridesize, &done));
13042336627cSHong Zhang if (done) {
13059566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
13063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1307fc1d53bdSHong Zhang }
13089ef973d6SHong Zhang }
13099ef973d6SHong Zhang if (stepnum < tjsch->total_steps - laststridesize) {
13103ba16761SJacob Faibussowitsch if (tjsch->save_stack && !tjsch->store_stride && !tjsch->rctx2->reverseonestep) PetscFunctionReturn(PETSC_SUCCESS); /* store or forward-and-reverse at top level trigger revolve at bottom level */
13113ba16761SJacob Faibussowitsch if (!tjsch->save_stack && !tjsch->rctx2->reverseonestep) PetscFunctionReturn(PETSC_SUCCESS); /* store operation does not require revolve be called at bottom level */
13129ef973d6SHong Zhang }
1313d40cae4fSHong Zhang /* Skipping stepnum=0 for !stack->only is enough for TLR, but not for TLTR. Here we skip the first step for each stride so that the top-level revolve is applied (always at localstepnum=1) ahead of the bottom-level revolve */
13143ba16761SJacob Faibussowitsch if (!stack->solution_only && localstepnum == 0 && stepnum != tjsch->total_steps && !tjsch->recompute) PetscFunctionReturn(PETSC_SUCCESS);
13159566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
13169566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
13179566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(localstepnum, &rlocalstepnum));
13189566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rstepnum, rlocalstepnum, PETSC_FALSE, &store));
1319fc1d53bdSHong Zhang if (store == 1) {
1320cc4f23bcSHong Zhang CheckpointType cptype;
13215f80ce2aSJacob Faibussowitsch PetscCheck(localstepnum >= stack->top, PetscObjectComm((PetscObject)ts), PETSC_ERR_MEMC, "Illegal modification of a non-top stack element");
1322cc4f23bcSHong Zhang cptype = stack->solution_only ? SOLUTIONONLY : SOLUTION_STAGES;
13239566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
13249566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
13259566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
1326fc1d53bdSHong Zhang }
13273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
132869aec5caSHong Zhang }
132969aec5caSHong Zhang
TSTrajectoryMemoryGet_TLTR(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum)1330d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_TLTR(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum)
1331d71ae5a4SJacob Faibussowitsch {
1332fc1d53bdSHong Zhang Stack *stack = &tjsch->stack;
13339ef973d6SHong Zhang DiskStack *diskstack = &tjsch->diskstack;
13349ef973d6SHong Zhang PetscInt localstepnum, stridenum, restoredstridenum, laststridesize, store;
1335fc1d53bdSHong Zhang StackElement e;
1336e43ad619SHong Zhang PetscRevolveInt whattodo, shift;
1337e43ad619SHong Zhang PetscRevolveInt rtotal_steps, rstepnum, rlocalstepnum;
1338fc1d53bdSHong Zhang
1339fc1d53bdSHong Zhang PetscFunctionBegin;
1340fc1d53bdSHong Zhang localstepnum = stepnum % tjsch->stride;
1341fc1d53bdSHong Zhang stridenum = stepnum / tjsch->stride;
1342fc1d53bdSHong Zhang if (stepnum == tjsch->total_steps) {
13439566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
13440f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
13453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1346fc1d53bdSHong Zhang }
1347fc1d53bdSHong Zhang laststridesize = tjsch->total_steps % tjsch->stride;
1348fc1d53bdSHong Zhang if (!laststridesize) laststridesize = tjsch->stride;
13499ef973d6SHong Zhang /*
13509ef973d6SHong Zhang Last stride can be adjoined directly. All the other strides require that the stack in memory be ready before an adjoint step is taken (at the end of each stride). The following two cases need to be addressed differently:
13519ef973d6SHong Zhang Case 1 (save_stack)
13529ef973d6SHong Zhang Restore a disk checkpoint; update TS with the last element in the restored data; recompute to the current point.
13539ef973d6SHong Zhang Case 2 (!save_stack)
13549ef973d6SHong Zhang Restore a disk checkpoint; update TS with the restored point; recompute to the current point.
13559ef973d6SHong Zhang */
1356fc1d53bdSHong Zhang if (localstepnum == 0 && stepnum <= tjsch->total_steps - laststridesize) {
13579ef973d6SHong Zhang /* restore the top element in the stack for disk checkpoints */
13589ef973d6SHong Zhang restoredstridenum = diskstack->container[diskstack->top];
13590f3d5cd8SHong Zhang tjsch->rctx2->reverseonestep = PETSC_FALSE;
1360beb1f35cSHong Zhang /* top-level revolve must be applied before current step, just like the solution_only mode for single-level revolve */
1361beb1f35cSHong Zhang if (!tjsch->save_stack && stack->solution_only) { /* start with restoring a checkpoint */
13629566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stridenum, &rstepnum));
1363e43ad619SHong Zhang tjsch->rctx2->capo = rstepnum;
13649ef973d6SHong Zhang tjsch->rctx2->oldcapo = tjsch->rctx2->capo;
13659ef973d6SHong Zhang shift = 0;
13669ef973d6SHong Zhang whattodo = revolve2_action(&tjsch->rctx2->check, &tjsch->rctx2->capo, &tjsch->rctx2->fine, tjsch->rctx2->snaps_in, &tjsch->rctx2->info, &tjsch->rctx2->where);
13679566063dSJacob Faibussowitsch PetscCall(printwhattodo2(tj->monitor, whattodo, tjsch->rctx2, shift));
13689ef973d6SHong Zhang } else { /* 2 revolve actions: restore a checkpoint and then advance */
13699566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast((tjsch->total_steps + tjsch->stride - 1) / tjsch->stride, &rtotal_steps));
13709566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stridenum, &rstepnum));
13719566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx2, rtotal_steps, rstepnum, rstepnum, PETSC_TRUE, &tjsch->store_stride));
1372aced365eSHong Zhang if (tj->monitor) {
13739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
137463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "[Top Level] Skip the stride from %d to %d (stage values already checkpointed)\n", tjsch->rctx2->oldcapo, tjsch->rctx2->oldcapo + 1));
13759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
1376aced365eSHong Zhang }
1377d40cae4fSHong Zhang if (!tjsch->rctx2->reverseonestep && tjsch->rctx2->stepsleft > 0) tjsch->rctx2->stepsleft--;
13789ef973d6SHong Zhang }
13799ef973d6SHong Zhang /* fill stack */
13809ef973d6SHong Zhang if (stack->solution_only) {
1381fc1d53bdSHong Zhang if (tjsch->save_stack) {
1382d40cae4fSHong Zhang if (restoredstridenum < stridenum) {
13839566063dSJacob Faibussowitsch PetscCall(StackLoadLast(tj, ts, stack, restoredstridenum));
1384d40cae4fSHong Zhang } else {
13859566063dSJacob Faibussowitsch PetscCall(StackLoadAll(tj, ts, stack, restoredstridenum));
1386d40cae4fSHong Zhang }
13879ef973d6SHong Zhang /* recompute one step ahead */
13889ef973d6SHong Zhang tjsch->skip_trajectory = PETSC_TRUE;
13899566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
13909566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, stridenum * tjsch->stride - 1, stridenum * tjsch->stride));
13919ef973d6SHong Zhang tjsch->skip_trajectory = PETSC_FALSE;
13929ef973d6SHong Zhang if (restoredstridenum < stridenum) {
13939566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
13949566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
13959566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, restoredstridenum * tjsch->stride, stepnum));
13969ef973d6SHong Zhang } else { /* stack ready, fast forward revolve status */
13979566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
13989566063dSJacob Faibussowitsch PetscCall(FastForwardRevolve(tjsch->rctx));
13999ef973d6SHong Zhang }
1400fc1d53bdSHong Zhang } else {
14019566063dSJacob Faibussowitsch PetscCall(LoadSingle(tj, ts, stack, restoredstridenum));
14029566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
14039566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
14049566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, (restoredstridenum - 1) * tjsch->stride, stepnum));
14059ef973d6SHong Zhang }
14069ef973d6SHong Zhang } else {
14079ef973d6SHong Zhang if (tjsch->save_stack) {
14089ef973d6SHong Zhang if (restoredstridenum < stridenum) {
14099566063dSJacob Faibussowitsch PetscCall(StackLoadLast(tj, ts, stack, restoredstridenum));
14102336627cSHong Zhang /* reset revolve */
14119566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
14129566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
14139566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, restoredstridenum * tjsch->stride, stepnum));
14149ef973d6SHong Zhang } else { /* stack ready, fast forward revolve status */
14159566063dSJacob Faibussowitsch PetscCall(StackLoadAll(tj, ts, stack, restoredstridenum));
14169566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
14179566063dSJacob Faibussowitsch PetscCall(FastForwardRevolve(tjsch->rctx));
14189ef973d6SHong Zhang }
14199ef973d6SHong Zhang } else {
14209566063dSJacob Faibussowitsch PetscCall(LoadSingle(tj, ts, stack, restoredstridenum));
14219566063dSJacob Faibussowitsch PetscCall(InitRevolve(tjsch->stride, tjsch->max_cps_ram, tjsch->rctx));
14229ef973d6SHong Zhang /* push first element to stack */
14232336627cSHong Zhang if (tjsch->store_stride || tjsch->rctx2->reverseonestep) {
1424cc4f23bcSHong Zhang CheckpointType cptype = SOLUTION_STAGES;
1425cc4f23bcSHong Zhang shift = (restoredstridenum - 1) * tjsch->stride - localstepnum;
14269566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
14279566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast((restoredstridenum - 1) * tjsch->stride + 1, &rstepnum));
14289566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rstepnum, 1, PETSC_FALSE, &store));
1429aced365eSHong Zhang if (tj->monitor) {
14309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
143163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Skip the step from %" PetscInt_FMT " to %" PetscInt_FMT " (stage values already checkpointed)\n", (restoredstridenum - 1) * tjsch->stride, (restoredstridenum - 1) * tjsch->stride + 1));
14329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
1433aced365eSHong Zhang }
14349566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
14359566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, (restoredstridenum - 1) * tjsch->stride + 1, ts->ptime, ts->vec_sol));
14369566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
14379ef973d6SHong Zhang }
14389566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
14399566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, (restoredstridenum - 1) * tjsch->stride + 1, stepnum));
14409ef973d6SHong Zhang }
14419ef973d6SHong Zhang }
14429fbd8902SHong Zhang if (restoredstridenum == stridenum) diskstack->top--;
14430f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
14443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1445fc1d53bdSHong Zhang }
14469ef973d6SHong Zhang
14479ef973d6SHong Zhang if (stack->solution_only) {
1448fc1d53bdSHong Zhang /* restore a checkpoint */
14499566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
14509566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
1451fc1d53bdSHong Zhang /* start with restoring a checkpoint */
14529566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
14539566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(localstepnum, &rlocalstepnum));
1454e43ad619SHong Zhang tjsch->rctx->capo = rstepnum;
1455fc1d53bdSHong Zhang tjsch->rctx->oldcapo = tjsch->rctx->capo;
1456e43ad619SHong Zhang shift = rstepnum - rlocalstepnum;
1457fc1d53bdSHong Zhang whattodo = revolve_action(&tjsch->rctx->check, &tjsch->rctx->capo, &tjsch->rctx->fine, tjsch->rctx->snaps_in, &tjsch->rctx->info, &tjsch->rctx->where);
14589566063dSJacob Faibussowitsch PetscCall(printwhattodo(tj->monitor, whattodo, tjsch->rctx, shift));
14599566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
14609566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stepnum));
146148a46eb9SPierre Jolivet if (e->stepnum + 1 == stepnum) PetscCall(StackPop(stack, &e));
1462fc1d53bdSHong Zhang } else {
1463e43ad619SHong Zhang PetscRevolveInt rlocalstepnum;
1464fc1d53bdSHong Zhang /* restore a checkpoint */
14659566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
14669566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
1467fc1d53bdSHong Zhang /* 2 revolve actions: restore a checkpoint and then advance */
14689566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
14699566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stridenum, &rstepnum));
14709566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(localstepnum, &rlocalstepnum));
14719566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rstepnum, rlocalstepnum, PETSC_FALSE, &store));
1472aced365eSHong Zhang if (tj->monitor) {
14739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
147463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Skip the step from %" PetscInt_FMT " to %" PetscInt_FMT " (stage values already checkpointed)\n", stepnum - localstepnum + tjsch->rctx->oldcapo, stepnum - localstepnum + tjsch->rctx->oldcapo + 1));
14759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
1476aced365eSHong Zhang }
1477d40cae4fSHong Zhang if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) tjsch->rctx->stepsleft--;
1478fc1d53bdSHong Zhang if (e->stepnum < stepnum) {
14799566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
14809566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, e->stepnum, stepnum));
1481fc1d53bdSHong Zhang }
148248a46eb9SPierre Jolivet if (e->stepnum == stepnum) PetscCall(StackPop(stack, &e));
1483fc1d53bdSHong Zhang }
14840f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
14853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
148669aec5caSHong Zhang }
148769aec5caSHong Zhang
TSTrajectoryMemorySet_RMS(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)1488d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_RMS(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
1489d71ae5a4SJacob Faibussowitsch {
14900c393656SHong Zhang Stack *stack = &tjsch->stack;
14918f4fbd80SHong Zhang PetscInt store;
14928f4fbd80SHong Zhang StackElement e;
1493e43ad619SHong Zhang PetscRevolveInt rtotal_steps, rstepnum;
14948f4fbd80SHong Zhang
14958f4fbd80SHong Zhang PetscFunctionBegin;
14963ba16761SJacob Faibussowitsch if (!stack->solution_only && stepnum == 0) PetscFunctionReturn(PETSC_SUCCESS);
14973ba16761SJacob Faibussowitsch if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(PETSC_SUCCESS);
14989566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rtotal_steps));
14999566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
15009566063dSJacob Faibussowitsch PetscCall(ApplyRevolve(tj->monitor, tjsch->stype, tjsch->rctx, rtotal_steps, rstepnum, rstepnum, PETSC_FALSE, &store));
15018f4fbd80SHong Zhang if (store == 1) {
1502cc4f23bcSHong Zhang CheckpointType cptype;
15035f80ce2aSJacob Faibussowitsch PetscCheck(stepnum >= stack->top, PetscObjectComm((PetscObject)ts), PETSC_ERR_MEMC, "Illegal modification of a non-top stack element");
1504cc4f23bcSHong Zhang cptype = stack->solution_only ? SOLUTIONONLY : SOLUTION_STAGES;
15059566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, cptype, stack, &e));
15069566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
15079566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
15088f4fbd80SHong Zhang } else if (store == 2) {
15099566063dSJacob Faibussowitsch PetscCall(DumpSingle(tj, ts, stack, tjsch->rctx->check + 1));
15108f4fbd80SHong Zhang }
15113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
15128f4fbd80SHong Zhang }
15138f4fbd80SHong Zhang
TSTrajectoryMemoryGet_RMS(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum)1514d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_RMS(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum)
1515d71ae5a4SJacob Faibussowitsch {
15160c393656SHong Zhang Stack *stack = &tjsch->stack;
1517e43ad619SHong Zhang PetscRevolveInt whattodo, shift, rstepnum;
15188f4fbd80SHong Zhang PetscInt restart;
15198f4fbd80SHong Zhang PetscBool ondisk;
15208f4fbd80SHong Zhang StackElement e;
15218f4fbd80SHong Zhang
15228f4fbd80SHong Zhang PetscFunctionBegin;
15230c393656SHong Zhang if (stepnum == 0 || stepnum == tjsch->total_steps) {
15249566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
15250f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
15263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
15278f4fbd80SHong Zhang }
15289566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(stepnum, &rstepnum));
1529e43ad619SHong Zhang tjsch->rctx->capo = rstepnum;
15300c393656SHong Zhang tjsch->rctx->oldcapo = tjsch->rctx->capo;
15318f4fbd80SHong Zhang shift = 0;
15320c393656SHong Zhang whattodo = revolve_action(&tjsch->rctx->check, &tjsch->rctx->capo, &tjsch->rctx->fine, tjsch->rctx->snaps_in, &tjsch->rctx->info, &tjsch->rctx->where); /* whattodo=restore */
15339566063dSJacob Faibussowitsch PetscCall(printwhattodo(tj->monitor, whattodo, tjsch->rctx, shift));
15348f4fbd80SHong Zhang /* restore a checkpoint */
15350c393656SHong Zhang restart = tjsch->rctx->capo;
15360c393656SHong Zhang if (!tjsch->rctx->where) {
15378f4fbd80SHong Zhang ondisk = PETSC_TRUE;
15389566063dSJacob Faibussowitsch PetscCall(LoadSingle(tj, ts, stack, tjsch->rctx->check + 1));
15399566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
15408f4fbd80SHong Zhang } else {
15418f4fbd80SHong Zhang ondisk = PETSC_FALSE;
15429566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
15439566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
15448f4fbd80SHong Zhang }
15450c393656SHong Zhang if (!stack->solution_only) { /* whattodo must be 5 or 8 */
15468f4fbd80SHong Zhang /* ask Revolve what to do next */
15470c393656SHong Zhang tjsch->rctx->oldcapo = tjsch->rctx->capo;
15480c393656SHong Zhang whattodo = revolve_action(&tjsch->rctx->check, &tjsch->rctx->capo, &tjsch->rctx->fine, tjsch->rctx->snaps_in, &tjsch->rctx->info, &tjsch->rctx->where); /* must return 1 or 3 or 4*/
15499566063dSJacob Faibussowitsch PetscCall(printwhattodo(tj->monitor, whattodo, tjsch->rctx, shift));
15500c393656SHong Zhang if (whattodo == 3 || whattodo == 4) tjsch->rctx->reverseonestep = PETSC_TRUE;
15510c393656SHong Zhang if (whattodo == 1) tjsch->rctx->stepsleft = tjsch->rctx->capo - tjsch->rctx->oldcapo;
1552aced365eSHong Zhang if (tj->monitor) {
15539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(tj->monitor, ((PetscObject)tj)->tablevel));
155463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Skip the step from %d to %d (stage values already checkpointed)\n", tjsch->rctx->oldcapo, tjsch->rctx->oldcapo + 1));
15559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(tj->monitor, ((PetscObject)tj)->tablevel));
1556aced365eSHong Zhang }
1557d40cae4fSHong Zhang if (!tjsch->rctx->reverseonestep && tjsch->rctx->stepsleft > 0) tjsch->rctx->stepsleft--;
15588f4fbd80SHong Zhang restart++; /* skip one step */
15598f4fbd80SHong Zhang }
15600c393656SHong Zhang if (stack->solution_only || (!stack->solution_only && restart < stepnum)) {
15619566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
15629566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, restart, stepnum));
15638f4fbd80SHong Zhang }
156448a46eb9SPierre Jolivet if (!ondisk && ((stack->solution_only && e->stepnum + 1 == stepnum) || (!stack->solution_only && e->stepnum == stepnum))) PetscCall(StackPop(stack, &e));
15650f3d5cd8SHong Zhang tjsch->rctx->reverseonestep = PETSC_FALSE;
15663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
15678f4fbd80SHong Zhang }
15688f4fbd80SHong Zhang #endif
15698f4fbd80SHong Zhang
1570cc4f23bcSHong Zhang #if defined(PETSC_HAVE_CAMS)
1571cc4f23bcSHong Zhang /* Optimal offline adjoint checkpointing for multistage time integration methods */
TSTrajectoryMemorySet_AOF(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum,PetscReal time,Vec X)1572d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySet_AOF(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum, PetscReal time, Vec X)
1573d71ae5a4SJacob Faibussowitsch {
1574cc4f23bcSHong Zhang Stack *stack = &tjsch->stack;
1575cc4f23bcSHong Zhang StackElement e;
1576cc4f23bcSHong Zhang
1577cc4f23bcSHong Zhang PetscFunctionBegin;
15784dbe3957SHong Zhang /* skip if no checkpoint to use. This also avoids an error when num_units_avail=0 */
15793ba16761SJacob Faibussowitsch if (tjsch->actx->nextcheckpointstep == -1) PetscFunctionReturn(PETSC_SUCCESS);
15804dbe3957SHong Zhang if (stepnum == 0) { /* When placing the first checkpoint, no need to change the units available */
1581cc4f23bcSHong Zhang if (stack->solution_only) {
15823ba16761SJacob Faibussowitsch PetscCallExternal(offline_ca, tjsch->actx->lastcheckpointstep, tjsch->actx->num_units_avail, tjsch->actx->endstep, &tjsch->actx->nextcheckpointstep);
1583cc4f23bcSHong Zhang } else {
1584cc4f23bcSHong Zhang /* First two arguments must be -1 when first time calling cams */
15853ba16761SJacob Faibussowitsch PetscCallExternal(offline_cams, tjsch->actx->lastcheckpointstep, tjsch->actx->lastcheckpointtype, tjsch->actx->num_units_avail, tjsch->actx->endstep, tjsch->actx->num_stages, &tjsch->actx->nextcheckpointstep, &tjsch->actx->nextcheckpointtype);
1586cc4f23bcSHong Zhang }
1587cc4f23bcSHong Zhang }
1588cc4f23bcSHong Zhang
15893ba16761SJacob Faibussowitsch if (stack->solution_only && stepnum == tjsch->total_steps) PetscFunctionReturn(PETSC_SUCCESS);
1590cc4f23bcSHong Zhang
1591cc4f23bcSHong Zhang if (tjsch->actx->nextcheckpointstep == stepnum) {
15925f80ce2aSJacob Faibussowitsch PetscCheck(stepnum >= stack->top, PetscObjectComm((PetscObject)ts), PETSC_ERR_MEMC, "Illegal modification of a non-top stack element");
1593cc4f23bcSHong Zhang
1594cc4f23bcSHong Zhang if (tjsch->actx->nextcheckpointtype == 2) { /* solution + stage values */
159548a46eb9SPierre Jolivet if (tj->monitor) PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Store in checkpoint number %" PetscInt_FMT " with stage values and solution (located in RAM)\n", stepnum));
15969566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, SOLUTION_STAGES, stack, &e));
15979566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
1598cc4f23bcSHong Zhang }
1599cc4f23bcSHong Zhang if (tjsch->actx->nextcheckpointtype == 1) {
160048a46eb9SPierre Jolivet if (tj->monitor) PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Store in checkpoint number %" PetscInt_FMT " with stage values (located in RAM)\n", stepnum));
16019566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, STAGESONLY, stack, &e));
16029566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
1603cc4f23bcSHong Zhang }
1604cc4f23bcSHong Zhang if (tjsch->actx->nextcheckpointtype == 0) { /* solution only */
160548a46eb9SPierre Jolivet if (tj->monitor) PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Store in checkpoint number %" PetscInt_FMT " (located in RAM)\n", stepnum));
16069566063dSJacob Faibussowitsch PetscCall(ElementCreate(ts, SOLUTIONONLY, stack, &e));
16079566063dSJacob Faibussowitsch PetscCall(ElementSet(ts, stack, &e, stepnum, time, X));
1608cc4f23bcSHong Zhang }
16099566063dSJacob Faibussowitsch PetscCall(StackPush(stack, e));
1610cc4f23bcSHong Zhang
1611cc4f23bcSHong Zhang tjsch->actx->lastcheckpointstep = stepnum;
1612cc4f23bcSHong Zhang if (stack->solution_only) {
16133ba16761SJacob Faibussowitsch PetscCallExternal(offline_ca, tjsch->actx->lastcheckpointstep, tjsch->actx->num_units_avail, tjsch->actx->endstep, &tjsch->actx->nextcheckpointstep);
1614cc4f23bcSHong Zhang tjsch->actx->num_units_avail--;
1615cc4f23bcSHong Zhang } else {
1616cc4f23bcSHong Zhang tjsch->actx->lastcheckpointtype = tjsch->actx->nextcheckpointtype;
16173ba16761SJacob Faibussowitsch PetscCallExternal(offline_cams, tjsch->actx->lastcheckpointstep, tjsch->actx->lastcheckpointtype, tjsch->actx->num_units_avail, tjsch->actx->endstep, tjsch->actx->num_stages, &tjsch->actx->nextcheckpointstep, &tjsch->actx->nextcheckpointtype);
1618cc4f23bcSHong Zhang if (tjsch->actx->lastcheckpointtype == 2) tjsch->actx->num_units_avail -= tjsch->actx->num_stages + 1;
1619cc4f23bcSHong Zhang if (tjsch->actx->lastcheckpointtype == 1) tjsch->actx->num_units_avail -= tjsch->actx->num_stages;
1620cc4f23bcSHong Zhang if (tjsch->actx->lastcheckpointtype == 0) tjsch->actx->num_units_avail--;
1621cc4f23bcSHong Zhang }
1622cc4f23bcSHong Zhang }
16233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1624cc4f23bcSHong Zhang }
1625cc4f23bcSHong Zhang
TSTrajectoryMemoryGet_AOF(TSTrajectory tj,TS ts,TJScheduler * tjsch,PetscInt stepnum)1626d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemoryGet_AOF(TSTrajectory tj, TS ts, TJScheduler *tjsch, PetscInt stepnum)
1627d71ae5a4SJacob Faibussowitsch {
1628cc4f23bcSHong Zhang Stack *stack = &tjsch->stack;
1629cc4f23bcSHong Zhang StackElement e;
1630cc4f23bcSHong Zhang PetscInt estepnum;
1631cc4f23bcSHong Zhang
1632cc4f23bcSHong Zhang PetscFunctionBegin;
1633cc4f23bcSHong Zhang if (stepnum == 0 || stepnum == tjsch->total_steps) {
16349566063dSJacob Faibussowitsch PetscCall(TurnBackward(ts));
16353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1636cc4f23bcSHong Zhang }
1637cc4f23bcSHong Zhang /* Restore a checkpoint */
16389566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
1639cc4f23bcSHong Zhang estepnum = e->stepnum;
1640cc4f23bcSHong Zhang if (estepnum == stepnum && e->cptype == SOLUTIONONLY) { /* discard the checkpoint if not useful (corner case) */
16419566063dSJacob Faibussowitsch PetscCall(StackPop(stack, &e));
1642cc4f23bcSHong Zhang tjsch->actx->num_units_avail++;
16439566063dSJacob Faibussowitsch PetscCall(StackTop(stack, &e));
1644cc4f23bcSHong Zhang estepnum = e->stepnum;
1645cc4f23bcSHong Zhang }
1646cc4f23bcSHong Zhang /* Update TS with stage values if an adjoint step can be taken immediately */
1647cc4f23bcSHong Zhang if (HaveStages(e->cptype)) {
164848a46eb9SPierre Jolivet if (tj->monitor) PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Restore in checkpoint number %" PetscInt_FMT " with stage values (located in RAM)\n", e->stepnum));
1649cc4f23bcSHong Zhang if (e->cptype == STAGESONLY) tjsch->actx->num_units_avail += tjsch->actx->num_stages;
1650cc4f23bcSHong Zhang if (e->cptype == SOLUTION_STAGES) tjsch->actx->num_units_avail += tjsch->actx->num_stages + 1;
1651cc4f23bcSHong Zhang } else {
165248a46eb9SPierre Jolivet if (tj->monitor) PetscCall(PetscViewerASCIIPrintf(tj->monitor, "Restore in checkpoint number %" PetscInt_FMT " (located in RAM)\n", e->stepnum));
1653cc4f23bcSHong Zhang tjsch->actx->num_units_avail++;
1654cc4f23bcSHong Zhang }
16559566063dSJacob Faibussowitsch PetscCall(UpdateTS(ts, stack, e, stepnum, PETSC_TRUE));
1656cc4f23bcSHong Zhang /* Query the scheduler */
1657cc4f23bcSHong Zhang tjsch->actx->lastcheckpointstep = estepnum;
1658cc4f23bcSHong Zhang tjsch->actx->endstep = stepnum;
1659cc4f23bcSHong Zhang if (stack->solution_only) { /* start with restoring a checkpoint */
16603ba16761SJacob Faibussowitsch PetscCallExternal(offline_ca, tjsch->actx->lastcheckpointstep, tjsch->actx->num_units_avail, tjsch->actx->endstep, &tjsch->actx->nextcheckpointstep);
1661cc4f23bcSHong Zhang } else { /* 2 revolve actions: restore a checkpoint and then advance */
1662cc4f23bcSHong Zhang tjsch->actx->lastcheckpointtype = e->cptype;
16633ba16761SJacob Faibussowitsch PetscCallExternal(offline_cams, tjsch->actx->lastcheckpointstep, tjsch->actx->lastcheckpointtype, tjsch->actx->num_units_avail, tjsch->actx->endstep, tjsch->actx->num_stages, &tjsch->actx->nextcheckpointstep, &tjsch->actx->nextcheckpointtype);
1664cc4f23bcSHong Zhang }
1665cc4f23bcSHong Zhang /* Discard the checkpoint if not needed, decrease the number of available checkpoints if it still stays in stack */
1666cc4f23bcSHong Zhang if (HaveStages(e->cptype)) {
1667cc4f23bcSHong Zhang if (estepnum == stepnum) {
16689566063dSJacob Faibussowitsch PetscCall(StackPop(stack, &e));
1669cc4f23bcSHong Zhang } else {
1670cc4f23bcSHong Zhang if (e->cptype == STAGESONLY) tjsch->actx->num_units_avail -= tjsch->actx->num_stages;
1671cc4f23bcSHong Zhang if (e->cptype == SOLUTION_STAGES) tjsch->actx->num_units_avail -= tjsch->actx->num_stages + 1;
1672cc4f23bcSHong Zhang }
1673cc4f23bcSHong Zhang } else {
1674cc4f23bcSHong Zhang if (estepnum + 1 == stepnum) {
16759566063dSJacob Faibussowitsch PetscCall(StackPop(stack, &e));
1676cc4f23bcSHong Zhang } else {
1677cc4f23bcSHong Zhang tjsch->actx->num_units_avail--;
1678cc4f23bcSHong Zhang }
1679cc4f23bcSHong Zhang }
1680cc4f23bcSHong Zhang /* Recompute from the restored checkpoint */
1681cc4f23bcSHong Zhang if (stack->solution_only || (!stack->solution_only && estepnum < stepnum)) {
16829566063dSJacob Faibussowitsch PetscCall(TurnForward(ts));
16839566063dSJacob Faibussowitsch PetscCall(ReCompute(ts, tjsch, estepnum, stepnum));
1684cc4f23bcSHong Zhang }
16853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1686cc4f23bcSHong Zhang }
1687cc4f23bcSHong Zhang #endif
1688cc4f23bcSHong Zhang
TSTrajectorySet_Memory(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal time,Vec X)1689d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectorySet_Memory(TSTrajectory tj, TS ts, PetscInt stepnum, PetscReal time, Vec X)
1690d71ae5a4SJacob Faibussowitsch {
16910c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
16928f4fbd80SHong Zhang
16938f4fbd80SHong Zhang PetscFunctionBegin;
16940c393656SHong Zhang if (!tjsch->recompute) { /* use global stepnum in the forward sweep */
16959566063dSJacob Faibussowitsch PetscCall(TSGetStepNumber(ts, &stepnum));
16968f4fbd80SHong Zhang }
16978f4fbd80SHong Zhang /* for consistency */
16980c393656SHong Zhang if (!tjsch->recompute && stepnum == 0) ts->ptime_prev = ts->ptime - ts->time_step;
16990c393656SHong Zhang switch (tjsch->stype) {
17008f4fbd80SHong Zhang case NONE:
1701ac73474cSStefano Zampini if (tj->adjoint_solve_mode) {
17029566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_N(ts, tjsch, stepnum, time, X));
1703ac73474cSStefano Zampini } else {
17049566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_N_2(ts, tjsch, stepnum, time, X));
1705ac73474cSStefano Zampini }
17068f4fbd80SHong Zhang break;
17078f4fbd80SHong Zhang case TWO_LEVEL_NOREVOLVE:
17083c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17099566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_TLNR(tj, ts, tjsch, stepnum, time, X));
17108f4fbd80SHong Zhang break;
17112f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
17128f4fbd80SHong Zhang case TWO_LEVEL_REVOLVE:
17133c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17149566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_TLR(tj, ts, tjsch, stepnum, time, X));
17158f4fbd80SHong Zhang break;
171669aec5caSHong Zhang case TWO_LEVEL_TWO_REVOLVE:
17173c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17189566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_TLTR(tj, ts, tjsch, stepnum, time, X));
171969aec5caSHong Zhang break;
17208f4fbd80SHong Zhang case REVOLVE_OFFLINE:
17213c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17229566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_ROF(tj, ts, tjsch, stepnum, time, X));
17238f4fbd80SHong Zhang break;
17248f4fbd80SHong Zhang case REVOLVE_ONLINE:
17253c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17269566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_RON(tj, ts, tjsch, stepnum, time, X));
17278f4fbd80SHong Zhang break;
17288f4fbd80SHong Zhang case REVOLVE_MULTISTAGE:
17293c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17309566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_RMS(tj, ts, tjsch, stepnum, time, X));
17318f4fbd80SHong Zhang break;
17328f4fbd80SHong Zhang #endif
1733cc4f23bcSHong Zhang #if defined(PETSC_HAVE_CAMS)
1734cc4f23bcSHong Zhang case CAMS_OFFLINE:
17353c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17369566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemorySet_AOF(tj, ts, tjsch, stepnum, time, X));
1737cc4f23bcSHong Zhang break;
1738cc4f23bcSHong Zhang #endif
1739d71ae5a4SJacob Faibussowitsch default:
1740d71ae5a4SJacob Faibussowitsch break;
17418f4fbd80SHong Zhang }
17423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
17438f4fbd80SHong Zhang }
17448f4fbd80SHong Zhang
TSTrajectoryGet_Memory(TSTrajectory tj,TS ts,PetscInt stepnum,PetscReal * t)1745d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryGet_Memory(TSTrajectory tj, TS ts, PetscInt stepnum, PetscReal *t)
1746d71ae5a4SJacob Faibussowitsch {
17470c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
17488f4fbd80SHong Zhang
17498f4fbd80SHong Zhang PetscFunctionBegin;
17501c6b1c55SHong Zhang if (tj->adjoint_solve_mode && stepnum == 0) {
17519566063dSJacob Faibussowitsch PetscCall(TSTrajectoryReset(tj)); /* reset TSTrajectory so users do not need to reset TSTrajectory */
17523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
17531c6b1c55SHong Zhang }
17540c393656SHong Zhang switch (tjsch->stype) {
17558f4fbd80SHong Zhang case NONE:
1756ac73474cSStefano Zampini if (tj->adjoint_solve_mode) {
17579566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_N(ts, tjsch, stepnum));
1758ac73474cSStefano Zampini } else {
17599566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_N_2(ts, tjsch, stepnum));
1760ac73474cSStefano Zampini }
17618f4fbd80SHong Zhang break;
17628f4fbd80SHong Zhang case TWO_LEVEL_NOREVOLVE:
17633c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17649566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_TLNR(tj, ts, tjsch, stepnum));
17658f4fbd80SHong Zhang break;
17662f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
17678f4fbd80SHong Zhang case TWO_LEVEL_REVOLVE:
17683c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17699566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_TLR(tj, ts, tjsch, stepnum));
17708f4fbd80SHong Zhang break;
177169aec5caSHong Zhang case TWO_LEVEL_TWO_REVOLVE:
17723c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17739566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_TLTR(tj, ts, tjsch, stepnum));
177469aec5caSHong Zhang break;
17758f4fbd80SHong Zhang case REVOLVE_OFFLINE:
17763c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17779566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_ROF(tj, ts, tjsch, stepnum));
17788f4fbd80SHong Zhang break;
17798f4fbd80SHong Zhang case REVOLVE_ONLINE:
17803c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17819566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_RON(tj, ts, tjsch, stepnum));
17828f4fbd80SHong Zhang break;
17838f4fbd80SHong Zhang case REVOLVE_MULTISTAGE:
17843c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17859566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_RMS(tj, ts, tjsch, stepnum));
17868f4fbd80SHong Zhang break;
17878f4fbd80SHong Zhang #endif
1788cc4f23bcSHong Zhang #if defined(PETSC_HAVE_CAMS)
1789cc4f23bcSHong Zhang case CAMS_OFFLINE:
17903c633725SBarry Smith PetscCheck(tj->adjoint_solve_mode, PetscObjectComm((PetscObject)tj), PETSC_ERR_SUP, "Not implemented");
17919566063dSJacob Faibussowitsch PetscCall(TSTrajectoryMemoryGet_AOF(tj, ts, tjsch, stepnum));
1792cc4f23bcSHong Zhang break;
1793cc4f23bcSHong Zhang #endif
1794d71ae5a4SJacob Faibussowitsch default:
1795d71ae5a4SJacob Faibussowitsch break;
17968f4fbd80SHong Zhang }
17973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
17988f4fbd80SHong Zhang }
17998f4fbd80SHong Zhang
TSTrajectorySetStride_Memory(TSTrajectory tj,PetscInt stride)1800d71ae5a4SJacob Faibussowitsch PETSC_UNUSED static PetscErrorCode TSTrajectorySetStride_Memory(TSTrajectory tj, PetscInt stride)
1801d71ae5a4SJacob Faibussowitsch {
18020c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
180346c2e3beSHong Zhang
180446c2e3beSHong Zhang PetscFunctionBegin;
18050c393656SHong Zhang tjsch->stride = stride;
18063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
180746c2e3beSHong Zhang }
180846c2e3beSHong Zhang
TSTrajectorySetMaxCpsRAM_Memory(TSTrajectory tj,PetscInt max_cps_ram)1809d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectorySetMaxCpsRAM_Memory(TSTrajectory tj, PetscInt max_cps_ram)
1810d71ae5a4SJacob Faibussowitsch {
18110c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
181268bece0bSHong Zhang
181362b521acSHong Zhang PetscFunctionBegin;
18140c393656SHong Zhang tjsch->max_cps_ram = max_cps_ram;
18153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
181662b521acSHong Zhang }
181762b521acSHong Zhang
TSTrajectorySetMaxCpsDisk_Memory(TSTrajectory tj,PetscInt max_cps_disk)1818d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectorySetMaxCpsDisk_Memory(TSTrajectory tj, PetscInt max_cps_disk)
1819d71ae5a4SJacob Faibussowitsch {
18200c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
18215a3ef282SHong Zhang
18225a3ef282SHong Zhang PetscFunctionBegin;
18230c393656SHong Zhang tjsch->max_cps_disk = max_cps_disk;
18243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
18255a3ef282SHong Zhang }
18265a3ef282SHong Zhang
TSTrajectorySetMaxUnitsRAM_Memory(TSTrajectory tj,PetscInt max_units_ram)1827d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectorySetMaxUnitsRAM_Memory(TSTrajectory tj, PetscInt max_units_ram)
1828d71ae5a4SJacob Faibussowitsch {
1829cc4f23bcSHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
1830cc4f23bcSHong Zhang
1831cc4f23bcSHong Zhang PetscFunctionBegin;
18323c633725SBarry Smith PetscCheck(tjsch->max_cps_ram, PetscObjectComm((PetscObject)tj), PETSC_ERR_ARG_INCOMP, "Conflict with -ts_trjaectory_max_cps_ram or TSTrajectorySetMaxCpsRAM. You can set max_cps_ram or max_units_ram, but not both at the same time.");
1833cc4f23bcSHong Zhang tjsch->max_units_ram = max_units_ram;
18343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1835cc4f23bcSHong Zhang }
1836cc4f23bcSHong Zhang
TSTrajectorySetMaxUnitsDisk_Memory(TSTrajectory tj,PetscInt max_units_disk)1837d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectorySetMaxUnitsDisk_Memory(TSTrajectory tj, PetscInt max_units_disk)
1838d71ae5a4SJacob Faibussowitsch {
1839cc4f23bcSHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
1840cc4f23bcSHong Zhang
1841cc4f23bcSHong Zhang PetscFunctionBegin;
18423c633725SBarry Smith PetscCheck(tjsch->max_cps_disk, PetscObjectComm((PetscObject)tj), PETSC_ERR_ARG_INCOMP, "Conflict with -ts_trjaectory_max_cps_disk or TSTrajectorySetMaxCpsDisk. You can set max_cps_disk or max_units_disk, but not both at the same time.");
1843cc4f23bcSHong Zhang tjsch->max_units_ram = max_units_disk;
18443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1845cc4f23bcSHong Zhang }
1846cc4f23bcSHong Zhang
TSTrajectoryMemorySetType_Memory(TSTrajectory tj,TSTrajectoryMemoryType tj_memory_type)1847d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryMemorySetType_Memory(TSTrajectory tj, TSTrajectoryMemoryType tj_memory_type)
1848d71ae5a4SJacob Faibussowitsch {
1849533251d3SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
1850533251d3SHong Zhang
1851533251d3SHong Zhang PetscFunctionBegin;
18525f80ce2aSJacob Faibussowitsch PetscCheck(!tj->setupcalled, PetscObjectComm((PetscObject)tj), PETSC_ERR_ARG_WRONGSTATE, "Cannot change schedule software after TSTrajectory has been setup or used");
1853533251d3SHong Zhang tjsch->tj_memory_type = tj_memory_type;
18543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1855533251d3SHong Zhang }
1856533251d3SHong Zhang
18572f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
TSTrajectorySetRevolveOnline(TSTrajectory tj,PetscBool use_online)1858d71ae5a4SJacob Faibussowitsch PETSC_UNUSED static PetscErrorCode TSTrajectorySetRevolveOnline(TSTrajectory tj, PetscBool use_online)
1859d71ae5a4SJacob Faibussowitsch {
18600c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
18615a3ef282SHong Zhang
18625a3ef282SHong Zhang PetscFunctionBegin;
18630c393656SHong Zhang tjsch->use_online = use_online;
18643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
18655a3ef282SHong Zhang }
18663949484eSHong Zhang #endif
18675a3ef282SHong Zhang
TSTrajectorySetSaveStack(TSTrajectory tj,PetscBool save_stack)1868d71ae5a4SJacob Faibussowitsch PETSC_UNUSED static PetscErrorCode TSTrajectorySetSaveStack(TSTrajectory tj, PetscBool save_stack)
1869d71ae5a4SJacob Faibussowitsch {
18700c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
1871164d268aSHong Zhang
1872164d268aSHong Zhang PetscFunctionBegin;
18730c393656SHong Zhang tjsch->save_stack = save_stack;
18743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1875164d268aSHong Zhang }
1876164d268aSHong Zhang
TSTrajectorySetUseDRAM(TSTrajectory tj,PetscBool use_dram)1877d71ae5a4SJacob Faibussowitsch PETSC_UNUSED static PetscErrorCode TSTrajectorySetUseDRAM(TSTrajectory tj, PetscBool use_dram)
1878d71ae5a4SJacob Faibussowitsch {
1879c1706be6SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
1880c1706be6SHong Zhang
1881c1706be6SHong Zhang PetscFunctionBegin;
1882c1706be6SHong Zhang tjsch->stack.use_dram = use_dram;
18833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1884c1706be6SHong Zhang }
1885c1706be6SHong Zhang
1886cc4c1da9SBarry Smith /*@
1887533251d3SHong Zhang TSTrajectoryMemorySetType - sets the software that is used to generate the checkpointing schedule.
1888533251d3SHong Zhang
1889c3339decSBarry Smith Logically Collective
1890533251d3SHong Zhang
1891533251d3SHong Zhang Input Parameters:
1892bcf0153eSBarry Smith + tj - the `TSTrajectory` context
1893533251d3SHong Zhang - tj_memory_type - Revolve or CAMS
1894533251d3SHong Zhang
1895533251d3SHong Zhang Options Database Key:
1896533251d3SHong Zhang . -ts_trajectory_memory_type <tj_memory_type> - petsc, revolve, cams
1897533251d3SHong Zhang
1898533251d3SHong Zhang Level: intermediate
1899533251d3SHong Zhang
19001cc06b55SBarry Smith .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectorySetMaxUnitsRAM()`, `TSTrajectoryMemoryType`
1901533251d3SHong Zhang @*/
TSTrajectoryMemorySetType(TSTrajectory tj,TSTrajectoryMemoryType tj_memory_type)1902d71ae5a4SJacob Faibussowitsch PetscErrorCode TSTrajectoryMemorySetType(TSTrajectory tj, TSTrajectoryMemoryType tj_memory_type)
1903d71ae5a4SJacob Faibussowitsch {
1904533251d3SHong Zhang PetscFunctionBegin;
1905cac4c232SBarry Smith PetscTryMethod(tj, "TSTrajectoryMemorySetType_C", (TSTrajectory, TSTrajectoryMemoryType), (tj, tj_memory_type));
19063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1907533251d3SHong Zhang }
1908533251d3SHong Zhang
1909cc4c1da9SBarry Smith /*@
1910cc4f23bcSHong Zhang TSTrajectorySetMaxCpsRAM - Set maximum number of checkpoints in RAM
1911cc4f23bcSHong Zhang
191220f4b53cSBarry Smith Logically Collective
1913cc4f23bcSHong Zhang
1914cc4f23bcSHong Zhang Input Parameter:
1915cc4f23bcSHong Zhang . tj - tstrajectory context
1916cc4f23bcSHong Zhang
1917cc4f23bcSHong Zhang Output Parameter:
1918cc4f23bcSHong Zhang . max_cps_ram - maximum number of checkpoints in RAM
1919cc4f23bcSHong Zhang
1920cc4f23bcSHong Zhang Level: intermediate
1921cc4f23bcSHong Zhang
19221cc06b55SBarry Smith .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectorySetMaxUnitsRAM()`
1923cc4f23bcSHong Zhang @*/
TSTrajectorySetMaxCpsRAM(TSTrajectory tj,PetscInt max_cps_ram)1924d71ae5a4SJacob Faibussowitsch PetscErrorCode TSTrajectorySetMaxCpsRAM(TSTrajectory tj, PetscInt max_cps_ram)
1925d71ae5a4SJacob Faibussowitsch {
1926cc4f23bcSHong Zhang PetscFunctionBegin;
1927cac4c232SBarry Smith PetscUseMethod(tj, "TSTrajectorySetMaxCpsRAM_C", (TSTrajectory, PetscInt), (tj, max_cps_ram));
19283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1929cc4f23bcSHong Zhang }
1930cc4f23bcSHong Zhang
1931cc4c1da9SBarry Smith /*@
1932cc4f23bcSHong Zhang TSTrajectorySetMaxCpsDisk - Set maximum number of checkpoints on disk
1933cc4f23bcSHong Zhang
193420f4b53cSBarry Smith Logically Collective
1935cc4f23bcSHong Zhang
1936cc4f23bcSHong Zhang Input Parameter:
1937cc4f23bcSHong Zhang . tj - tstrajectory context
1938cc4f23bcSHong Zhang
1939cc4f23bcSHong Zhang Output Parameter:
1940cc4f23bcSHong Zhang . max_cps_disk - maximum number of checkpoints on disk
1941cc4f23bcSHong Zhang
1942cc4f23bcSHong Zhang Level: intermediate
1943cc4f23bcSHong Zhang
19441cc06b55SBarry Smith .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectorySetMaxUnitsDisk()`, `TSTrajectorySetMaxUnitsRAM()`
1945cc4f23bcSHong Zhang @*/
TSTrajectorySetMaxCpsDisk(TSTrajectory tj,PetscInt max_cps_disk)1946d71ae5a4SJacob Faibussowitsch PetscErrorCode TSTrajectorySetMaxCpsDisk(TSTrajectory tj, PetscInt max_cps_disk)
1947d71ae5a4SJacob Faibussowitsch {
1948cc4f23bcSHong Zhang PetscFunctionBegin;
1949cac4c232SBarry Smith PetscUseMethod(tj, "TSTrajectorySetMaxCpsDisk_C", (TSTrajectory, PetscInt), (tj, max_cps_disk));
19503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1951cc4f23bcSHong Zhang }
1952cc4f23bcSHong Zhang
1953cc4c1da9SBarry Smith /*@
1954cc4f23bcSHong Zhang TSTrajectorySetMaxUnitsRAM - Set maximum number of checkpointing units in RAM
1955cc4f23bcSHong Zhang
195620f4b53cSBarry Smith Logically Collective
1957cc4f23bcSHong Zhang
1958cc4f23bcSHong Zhang Input Parameter:
1959cc4f23bcSHong Zhang . tj - tstrajectory context
1960cc4f23bcSHong Zhang
1961cc4f23bcSHong Zhang Output Parameter:
1962cc4f23bcSHong Zhang . max_units_ram - maximum number of checkpointing units in RAM
1963cc4f23bcSHong Zhang
1964cc4f23bcSHong Zhang Level: intermediate
1965cc4f23bcSHong Zhang
19661cc06b55SBarry Smith .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectorySetMaxCpsRAM()`
1967cc4f23bcSHong Zhang @*/
TSTrajectorySetMaxUnitsRAM(TSTrajectory tj,PetscInt max_units_ram)1968d71ae5a4SJacob Faibussowitsch PetscErrorCode TSTrajectorySetMaxUnitsRAM(TSTrajectory tj, PetscInt max_units_ram)
1969d71ae5a4SJacob Faibussowitsch {
1970cc4f23bcSHong Zhang PetscFunctionBegin;
1971cac4c232SBarry Smith PetscUseMethod(tj, "TSTrajectorySetMaxUnitsRAM_C", (TSTrajectory, PetscInt), (tj, max_units_ram));
19723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1973cc4f23bcSHong Zhang }
1974cc4f23bcSHong Zhang
1975cc4c1da9SBarry Smith /*@
1976cc4f23bcSHong Zhang TSTrajectorySetMaxUnitsDisk - Set maximum number of checkpointing units on disk
1977cc4f23bcSHong Zhang
197820f4b53cSBarry Smith Logically Collective
1979cc4f23bcSHong Zhang
1980cc4f23bcSHong Zhang Input Parameter:
1981cc4f23bcSHong Zhang . tj - tstrajectory context
1982cc4f23bcSHong Zhang
1983cc4f23bcSHong Zhang Output Parameter:
1984cc4f23bcSHong Zhang . max_units_disk - maximum number of checkpointing units on disk
1985cc4f23bcSHong Zhang
1986cc4f23bcSHong Zhang Level: intermediate
1987cc4f23bcSHong Zhang
19881cc06b55SBarry Smith .seealso: [](ch_ts), `TSTrajectory`, `TSTrajectorySetMaxCpsDisk()`
1989cc4f23bcSHong Zhang @*/
TSTrajectorySetMaxUnitsDisk(TSTrajectory tj,PetscInt max_units_disk)1990d71ae5a4SJacob Faibussowitsch PetscErrorCode TSTrajectorySetMaxUnitsDisk(TSTrajectory tj, PetscInt max_units_disk)
1991d71ae5a4SJacob Faibussowitsch {
1992cc4f23bcSHong Zhang PetscFunctionBegin;
1993cac4c232SBarry Smith PetscUseMethod(tj, "TSTrajectorySetMaxUnitsDisk_C", (TSTrajectory, PetscInt), (tj, max_units_disk));
19943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1995cc4f23bcSHong Zhang }
1996cc4f23bcSHong Zhang
TSTrajectorySetFromOptions_Memory(TSTrajectory tj,PetscOptionItems PetscOptionsObject)1997ce78bad3SBarry Smith static PetscErrorCode TSTrajectorySetFromOptions_Memory(TSTrajectory tj, PetscOptionItems PetscOptionsObject)
1998d71ae5a4SJacob Faibussowitsch {
19990c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
2000533251d3SHong Zhang PetscEnum etmp;
2001cc4f23bcSHong Zhang PetscInt max_cps_ram, max_cps_disk, max_units_ram, max_units_disk;
2002cc4f23bcSHong Zhang PetscBool flg;
200362b521acSHong Zhang
200462b521acSHong Zhang PetscFunctionBegin;
2005d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "Memory based TS trajectory options");
200662b521acSHong Zhang {
20079566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_trajectory_max_cps_ram", "Maximum number of checkpoints in RAM", "TSTrajectorySetMaxCpsRAM", tjsch->max_cps_ram, &max_cps_ram, &flg));
20081baa6e33SBarry Smith if (flg) PetscCall(TSTrajectorySetMaxCpsRAM(tj, max_cps_ram));
20099566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_trajectory_max_cps_disk", "Maximum number of checkpoints on disk", "TSTrajectorySetMaxCpsDisk", tjsch->max_cps_disk, &max_cps_disk, &flg));
20101baa6e33SBarry Smith if (flg) PetscCall(TSTrajectorySetMaxCpsDisk(tj, max_cps_disk));
20119566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_trajectory_max_units_ram", "Maximum number of checkpointing units in RAM", "TSTrajectorySetMaxUnitsRAM", tjsch->max_units_ram, &max_units_ram, &flg));
20121baa6e33SBarry Smith if (flg) PetscCall(TSTrajectorySetMaxUnitsRAM(tj, max_units_ram));
20139566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_trajectory_max_units_disk", "Maximum number of checkpointing units on disk", "TSTrajectorySetMaxUnitsDisk", tjsch->max_units_disk, &max_units_disk, &flg));
20141baa6e33SBarry Smith if (flg) PetscCall(TSTrajectorySetMaxUnitsDisk(tj, max_units_disk));
20159566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-ts_trajectory_stride", "Stride to save checkpoints to file", "TSTrajectorySetStride", tjsch->stride, &tjsch->stride, NULL));
20162f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
20179566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_trajectory_revolve_online", "Trick TS trajectory into using online mode of revolve", "TSTrajectorySetRevolveOnline", tjsch->use_online, &tjsch->use_online, NULL));
20183949484eSHong Zhang #endif
20199566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_trajectory_save_stack", "Save all stack to disk", "TSTrajectorySetSaveStack", tjsch->save_stack, &tjsch->save_stack, NULL));
20209566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-ts_trajectory_use_dram", "Use DRAM for checkpointing", "TSTrajectorySetUseDRAM", tjsch->stack.use_dram, &tjsch->stack.use_dram, NULL));
2021f45b553cSPierre Jolivet PetscCall(PetscOptionsEnum("-ts_trajectory_memory_type", "Checkpointing schedule software to use", "TSTrajectoryMemorySetType", TSTrajectoryMemoryTypes, (PetscEnum)(int)tjsch->tj_memory_type, &etmp, &flg));
20221baa6e33SBarry Smith if (flg) PetscCall(TSTrajectoryMemorySetType(tj, (TSTrajectoryMemoryType)etmp));
202362b521acSHong Zhang }
2024d0609cedSBarry Smith PetscOptionsHeadEnd();
20253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
202662b521acSHong Zhang }
202762b521acSHong Zhang
TSTrajectorySetUp_Memory(TSTrajectory tj,TS ts)2028d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectorySetUp_Memory(TSTrajectory tj, TS ts)
2029d71ae5a4SJacob Faibussowitsch {
20300c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
20310c393656SHong Zhang Stack *stack = &tjsch->stack;
20322f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
20339ef973d6SHong Zhang RevolveCTX *rctx, *rctx2;
203450463271SHong Zhang DiskStack *diskstack = &tjsch->diskstack;
203550463271SHong Zhang PetscInt diskblocks;
203628816579SHong Zhang #endif
2037ac73474cSStefano Zampini PetscInt numY, total_steps;
2038ac73474cSStefano Zampini PetscBool fixedtimestep;
203968bece0bSHong Zhang
204068bece0bSHong Zhang PetscFunctionBegin;
2041ac73474cSStefano Zampini if (ts->adapt) {
20429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)ts->adapt, TSADAPTNONE, &fixedtimestep));
2043cc4f23bcSHong Zhang } else {
2044cc4f23bcSHong Zhang fixedtimestep = PETSC_TRUE;
2045cc4f23bcSHong Zhang }
2046ac73474cSStefano Zampini total_steps = (PetscInt)(PetscCeilReal((ts->max_time - ts->ptime) / ts->time_step));
20471690c2aeSBarry Smith total_steps = total_steps < 0 ? PETSC_INT_MAX : total_steps;
2048ac73474cSStefano Zampini if (fixedtimestep) tjsch->total_steps = PetscMin(ts->max_steps, total_steps);
2049b40c67f4SHong Zhang
2050f5ae182eSHong Zhang tjsch->stack.solution_only = tj->solution_only;
20519566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &numY, PETSC_IGNORE));
2052cc4f23bcSHong Zhang if (stack->solution_only) {
2053cc4f23bcSHong Zhang if (tjsch->max_units_ram) tjsch->max_cps_ram = tjsch->max_units_ram;
2054cc4f23bcSHong Zhang else tjsch->max_units_ram = tjsch->max_cps_ram;
2055cc4f23bcSHong Zhang if (tjsch->max_units_disk) tjsch->max_cps_disk = tjsch->max_units_disk;
2056cc4f23bcSHong Zhang } else {
2057cc4f23bcSHong Zhang if (tjsch->max_units_ram) tjsch->max_cps_ram = (ts->stifflyaccurate) ? tjsch->max_units_ram / numY : tjsch->max_units_ram / (numY + 1);
2058cc4f23bcSHong Zhang else tjsch->max_units_ram = (ts->stifflyaccurate) ? numY * tjsch->max_cps_ram : (numY + 1) * tjsch->max_cps_ram;
2059cc4f23bcSHong Zhang if (tjsch->max_units_disk) tjsch->max_cps_disk = (ts->stifflyaccurate) ? tjsch->max_units_disk / numY : tjsch->max_units_disk / (numY + 1);
2060cc4f23bcSHong Zhang else tjsch->max_units_disk = (ts->stifflyaccurate) ? numY * tjsch->max_cps_disk : (numY + 1) * tjsch->max_cps_disk;
2061cc4f23bcSHong Zhang }
2062cc4f23bcSHong Zhang if (tjsch->max_cps_ram > 0) stack->stacksize = tjsch->max_units_ram; /* maximum stack size. Could be overallocated. */
2063cc4f23bcSHong Zhang
2064cc4f23bcSHong Zhang /* Determine the scheduler type */
2065cf2e76e0SHong Zhang if (tjsch->stride > 1) { /* two level mode */
2066cad9d221SBarry Smith PetscCheck(!tjsch->save_stack || tjsch->max_cps_disk <= 1 || tjsch->max_cps_disk > tjsch->max_cps_ram, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_INCOMP, "The specified disk capacity is not enough to store a full stack of RAM checkpoints. You might want to change the disk capacity or use single level checkpointing instead.");
2067216862dbSHong Zhang if (tjsch->max_cps_disk <= 1 && tjsch->max_cps_ram > 1 && tjsch->max_cps_ram <= tjsch->stride - 1) tjsch->stype = TWO_LEVEL_REVOLVE; /* use revolve_offline for each stride */
2068216862dbSHong Zhang if (tjsch->max_cps_disk > 1 && tjsch->max_cps_ram > 1 && tjsch->max_cps_ram <= tjsch->stride - 1) tjsch->stype = TWO_LEVEL_TWO_REVOLVE; /* use revolve_offline for each stride */
2069216862dbSHong Zhang if (tjsch->max_cps_disk <= 1 && (tjsch->max_cps_ram >= tjsch->stride || tjsch->max_cps_ram == -1)) tjsch->stype = TWO_LEVEL_NOREVOLVE; /* can also be handled by TWO_LEVEL_REVOLVE */
2070cf2e76e0SHong Zhang } else { /* single level mode */
2071ac73474cSStefano Zampini if (fixedtimestep) {
20729371c9d4SSatish Balay if (tjsch->max_cps_ram >= tjsch->total_steps - 1 || tjsch->max_cps_ram == -1) tjsch->stype = NONE; /* checkpoint all */
20739371c9d4SSatish Balay else { /* choose the schedule software for offline checkpointing */ switch (tjsch->tj_memory_type) {
2074d71ae5a4SJacob Faibussowitsch case TJ_PETSC:
2075d71ae5a4SJacob Faibussowitsch tjsch->stype = NONE;
2076d71ae5a4SJacob Faibussowitsch break;
2077d71ae5a4SJacob Faibussowitsch case TJ_CAMS:
2078d71ae5a4SJacob Faibussowitsch tjsch->stype = CAMS_OFFLINE;
2079d71ae5a4SJacob Faibussowitsch break;
2080d71ae5a4SJacob Faibussowitsch case TJ_REVOLVE:
2081d71ae5a4SJacob Faibussowitsch tjsch->stype = (tjsch->max_cps_disk > 1) ? REVOLVE_MULTISTAGE : REVOLVE_OFFLINE;
2082d71ae5a4SJacob Faibussowitsch break;
2083d71ae5a4SJacob Faibussowitsch default:
2084d71ae5a4SJacob Faibussowitsch break;
2085533251d3SHong Zhang }
2086533251d3SHong Zhang }
2087216862dbSHong Zhang } else tjsch->stype = NONE; /* checkpoint all for adaptive time step */
20882f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
2089216862dbSHong Zhang if (tjsch->use_online) tjsch->stype = REVOLVE_ONLINE; /* trick into online (for testing purpose only) */
2090c9c01188SHong Zhang #endif
2091cad9d221SBarry Smith PetscCheck(tjsch->stype == NONE || tjsch->max_cps_ram >= 1 || tjsch->max_cps_disk >= 1, PetscObjectComm((PetscObject)ts), PETSC_ERR_ARG_INCOMP, "The specified storage capacity is insufficient for one checkpoint, which is the minimum");
20924dbe3957SHong Zhang }
2093cc4f23bcSHong Zhang if (tjsch->stype >= CAMS_OFFLINE) {
2094*beceaeb6SBarry Smith #if !defined(PETSC_HAVE_CAMS)
2095cc4f23bcSHong Zhang SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "CAMS is needed when there is not enough memory to checkpoint all time steps according to the user's settings, please reconfigure with the additional option --download-cams.");
2096cc4f23bcSHong Zhang #else
2097cc4f23bcSHong Zhang CAMSCTX *actx;
2098cc4f23bcSHong Zhang PetscInt ns = 0;
2099cc4f23bcSHong Zhang if (stack->solution_only) {
2100cc4f23bcSHong Zhang offline_ca_create(tjsch->total_steps, tjsch->max_cps_ram);
2101cc4f23bcSHong Zhang } else {
21029566063dSJacob Faibussowitsch PetscCall(TSGetStages(ts, &ns, PETSC_IGNORE));
2103cc4f23bcSHong Zhang offline_cams_create(tjsch->total_steps, tjsch->max_units_ram, ns, ts->stifflyaccurate);
2104cc4f23bcSHong Zhang }
21059566063dSJacob Faibussowitsch PetscCall(PetscNew(&actx));
21064dbe3957SHong Zhang actx->lastcheckpointstep = -1; /* -1 can trigger the initialization of CAMS */
21074dbe3957SHong Zhang actx->lastcheckpointtype = -1; /* -1 can trigger the initialization of CAMS */
2108cc4f23bcSHong Zhang actx->endstep = tjsch->total_steps;
2109cc4f23bcSHong Zhang actx->num_units_avail = tjsch->max_units_ram;
2110cc4f23bcSHong Zhang actx->num_stages = ns;
2111cc4f23bcSHong Zhang tjsch->actx = actx;
2112cc4f23bcSHong Zhang #endif
2113cc4f23bcSHong Zhang } else if (tjsch->stype > TWO_LEVEL_NOREVOLVE) {
2114*beceaeb6SBarry Smith #if !defined(PETSC_HAVE_REVOLVE)
2115285336bfSHong Zhang SETERRQ(PetscObjectComm((PetscObject)ts), PETSC_ERR_SUP, "revolve is needed when there is not enough memory to checkpoint all time steps according to the user's settings, please reconfigure with the additional option --download-revolve.");
21160cae4918SHong Zhang #else
2117e43ad619SHong Zhang PetscRevolveInt rfine, rsnaps, rsnaps2;
2118cc4f23bcSHong Zhang
2119216862dbSHong Zhang switch (tjsch->stype) {
2120216862dbSHong Zhang case TWO_LEVEL_REVOLVE:
21219566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->stride, &rfine));
21229566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->max_cps_ram, &rsnaps));
2123e43ad619SHong Zhang revolve_create_offline(rfine, rsnaps);
2124216862dbSHong Zhang break;
2125216862dbSHong Zhang case TWO_LEVEL_TWO_REVOLVE:
2126216862dbSHong Zhang diskblocks = tjsch->save_stack ? tjsch->max_cps_disk / (tjsch->max_cps_ram + 1) : tjsch->max_cps_disk; /* The block size depends on whether the stack is saved. */
2127216862dbSHong Zhang diskstack->stacksize = diskblocks;
21289566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->stride, &rfine));
21299566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->max_cps_ram, &rsnaps));
2130e43ad619SHong Zhang revolve_create_offline(rfine, rsnaps);
21319566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast((tjsch->total_steps + tjsch->stride - 1) / tjsch->stride, &rfine));
21329566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(diskblocks, &rsnaps));
2133e43ad619SHong Zhang revolve2_create_offline(rfine, rsnaps);
21349566063dSJacob Faibussowitsch PetscCall(PetscNew(&rctx2));
2135e43ad619SHong Zhang rctx2->snaps_in = rsnaps;
21369ef973d6SHong Zhang rctx2->reverseonestep = PETSC_FALSE;
21379ef973d6SHong Zhang rctx2->check = 0;
21389ef973d6SHong Zhang rctx2->oldcapo = 0;
21399ef973d6SHong Zhang rctx2->capo = 0;
21409ef973d6SHong Zhang rctx2->info = 2;
2141e43ad619SHong Zhang rctx2->fine = rfine;
21429ef973d6SHong Zhang tjsch->rctx2 = rctx2;
21439ef973d6SHong Zhang diskstack->top = -1;
21449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(diskstack->stacksize, &diskstack->container));
2145216862dbSHong Zhang break;
2146216862dbSHong Zhang case REVOLVE_OFFLINE:
21479566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rfine));
21489566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->max_cps_ram, &rsnaps));
2149e43ad619SHong Zhang revolve_create_offline(rfine, rsnaps);
2150216862dbSHong Zhang break;
2151216862dbSHong Zhang case REVOLVE_ONLINE:
2152216862dbSHong Zhang stack->stacksize = tjsch->max_cps_ram;
21539566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->max_cps_ram, &rsnaps));
2154e43ad619SHong Zhang revolve_create_online(rsnaps);
2155216862dbSHong Zhang break;
2156216862dbSHong Zhang case REVOLVE_MULTISTAGE:
21579566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rfine));
21589566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->max_cps_ram, &rsnaps));
21599566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->max_cps_ram + tjsch->max_cps_disk, &rsnaps2));
2160e43ad619SHong Zhang revolve_create_multistage(rfine, rsnaps2, rsnaps);
2161216862dbSHong Zhang break;
2162d71ae5a4SJacob Faibussowitsch default:
2163d71ae5a4SJacob Faibussowitsch break;
2164216862dbSHong Zhang }
21659566063dSJacob Faibussowitsch PetscCall(PetscNew(&rctx));
21669566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->max_cps_ram, &rsnaps));
2167e43ad619SHong Zhang rctx->snaps_in = rsnaps; /* for theta methods snaps_in=2*max_cps_ram */
216868bece0bSHong Zhang rctx->reverseonestep = PETSC_FALSE;
2169b2124117SHong Zhang rctx->check = 0;
217068bece0bSHong Zhang rctx->oldcapo = 0;
217168bece0bSHong Zhang rctx->capo = 0;
217268bece0bSHong Zhang rctx->info = 2;
2173e43ad619SHong Zhang if (tjsch->stride > 1) {
21749566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->stride, &rfine));
2175e43ad619SHong Zhang } else {
21769566063dSJacob Faibussowitsch PetscCall(PetscRevolveIntCast(tjsch->total_steps, &rfine));
2177e43ad619SHong Zhang }
2178e43ad619SHong Zhang rctx->fine = rfine;
21790c393656SHong Zhang tjsch->rctx = rctx;
21800c393656SHong Zhang if (tjsch->stype == REVOLVE_ONLINE) rctx->fine = -1;
21810cae4918SHong Zhang #endif
2182216862dbSHong Zhang } else {
2183216862dbSHong Zhang if (tjsch->stype == TWO_LEVEL_NOREVOLVE) stack->stacksize = tjsch->stride - 1; /* need tjsch->stride-1 at most */
2184216862dbSHong Zhang if (tjsch->stype == NONE) {
2185ac73474cSStefano Zampini if (fixedtimestep) stack->stacksize = stack->solution_only ? tjsch->total_steps : tjsch->total_steps - 1;
21869371c9d4SSatish Balay else { /* adaptive time step */ /* if max_cps_ram is not specified, use maximal allowed number of steps for stack size */
21871690c2aeSBarry Smith if (tjsch->max_cps_ram == -1) stack->stacksize = ts->max_steps < PETSC_INT_MAX ? ts->max_steps : 10000;
2188216862dbSHong Zhang tjsch->total_steps = stack->solution_only ? stack->stacksize : stack->stacksize + 1; /* will be updated as time integration advances */
2189216862dbSHong Zhang }
2190216862dbSHong Zhang }
219146c2e3beSHong Zhang }
21920cae4918SHong Zhang
21938a10d460SHong Zhang if ((tjsch->stype >= TWO_LEVEL_NOREVOLVE && tjsch->stype < REVOLVE_OFFLINE) || tjsch->stype == REVOLVE_MULTISTAGE) { /* these types need to use disk */
21949566063dSJacob Faibussowitsch PetscCall(TSTrajectorySetUp_Basic(tj, ts));
21958a10d460SHong Zhang }
21968a10d460SHong Zhang
21979378a5caSStefano Zampini stack->stacksize = PetscMax(stack->stacksize, 1);
21980c393656SHong Zhang tjsch->recompute = PETSC_FALSE;
21999566063dSJacob Faibussowitsch PetscCall(StackInit(stack, stack->stacksize, numY));
22003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
220168bece0bSHong Zhang }
220268bece0bSHong Zhang
TSTrajectoryReset_Memory(TSTrajectory tj)2203d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryReset_Memory(TSTrajectory tj)
2204d71ae5a4SJacob Faibussowitsch {
2205cc4f23bcSHong Zhang #if defined(PETSC_HAVE_REVOLVE) || defined(PETSC_HAVE_CAMS)
22061550c9b9SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
2207cc4f23bcSHong Zhang #endif
22081550c9b9SHong Zhang
22091550c9b9SHong Zhang PetscFunctionBegin;
2210cc4f23bcSHong Zhang #if defined(PETSC_HAVE_REVOLVE)
22111550c9b9SHong Zhang if (tjsch->stype > TWO_LEVEL_NOREVOLVE) {
22121550c9b9SHong Zhang revolve_reset();
22131550c9b9SHong Zhang if (tjsch->stype == TWO_LEVEL_TWO_REVOLVE) {
22141550c9b9SHong Zhang revolve2_reset();
22159566063dSJacob Faibussowitsch PetscCall(PetscFree(tjsch->diskstack.container));
22161550c9b9SHong Zhang }
22171550c9b9SHong Zhang }
22189a992471SHong Zhang if (tjsch->stype > TWO_LEVEL_NOREVOLVE) {
22199566063dSJacob Faibussowitsch PetscCall(PetscFree(tjsch->rctx));
22209566063dSJacob Faibussowitsch PetscCall(PetscFree(tjsch->rctx2));
22219a992471SHong Zhang }
2222cc4f23bcSHong Zhang #endif
2223cc4f23bcSHong Zhang #if defined(PETSC_HAVE_CAMS)
2224cc4f23bcSHong Zhang if (tjsch->stype == CAMS_OFFLINE) {
2225cc4f23bcSHong Zhang if (tjsch->stack.solution_only) offline_ca_destroy();
2226cc4f23bcSHong Zhang else offline_ca_destroy();
22279566063dSJacob Faibussowitsch PetscCall(PetscFree(tjsch->actx));
2228cc4f23bcSHong Zhang }
22299a992471SHong Zhang #endif
22303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
22311550c9b9SHong Zhang }
22321550c9b9SHong Zhang
TSTrajectoryDestroy_Memory(TSTrajectory tj)2233d71ae5a4SJacob Faibussowitsch static PetscErrorCode TSTrajectoryDestroy_Memory(TSTrajectory tj)
2234d71ae5a4SJacob Faibussowitsch {
22350c393656SHong Zhang TJScheduler *tjsch = (TJScheduler *)tj->data;
22369a53571cSHong Zhang
223745a28ef8SHong Zhang PetscFunctionBegin;
22389566063dSJacob Faibussowitsch PetscCall(StackDestroy(&tjsch->stack));
22399566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&tjsch->viewer));
22409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectorySetMaxCpsRAM_C", NULL));
22419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectorySetMaxCpsDisk_C", NULL));
22429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectorySetMaxUnitsRAM_C", NULL));
22439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectorySetMaxUnitsDisk_C", NULL));
22449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectoryMemorySetType_C", NULL));
22459566063dSJacob Faibussowitsch PetscCall(PetscFree(tjsch));
22463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
22479a53571cSHong Zhang }
22489a53571cSHong Zhang
22499a53571cSHong Zhang /*MC
22509a53571cSHong Zhang TSTRAJECTORYMEMORY - Stores each solution of the ODE/ADE in memory
22519a53571cSHong Zhang
22529a53571cSHong Zhang Level: intermediate
22539a53571cSHong Zhang
22541cc06b55SBarry Smith .seealso: [](ch_ts), `TSTrajectoryCreate()`, `TS`, `TSTrajectorySetType()`, `TSTrajectoryType`, `TSTrajectory`
22559a53571cSHong Zhang M*/
TSTrajectoryCreate_Memory(TSTrajectory tj,TS ts)2256d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TSTrajectoryCreate_Memory(TSTrajectory tj, TS ts)
2257d71ae5a4SJacob Faibussowitsch {
22580c393656SHong Zhang TJScheduler *tjsch;
22599a53571cSHong Zhang
22609a53571cSHong Zhang PetscFunctionBegin;
22619a53571cSHong Zhang tj->ops->set = TSTrajectorySet_Memory;
22629a53571cSHong Zhang tj->ops->get = TSTrajectoryGet_Memory;
226368bece0bSHong Zhang tj->ops->setup = TSTrajectorySetUp_Memory;
226462b521acSHong Zhang tj->ops->setfromoptions = TSTrajectorySetFromOptions_Memory;
22651550c9b9SHong Zhang tj->ops->reset = TSTrajectoryReset_Memory;
22669a992471SHong Zhang tj->ops->destroy = TSTrajectoryDestroy_Memory;
22679a53571cSHong Zhang
22689566063dSJacob Faibussowitsch PetscCall(PetscNew(&tjsch));
22690c393656SHong Zhang tjsch->stype = NONE;
22700c393656SHong Zhang tjsch->max_cps_ram = -1; /* -1 indicates that it is not set */
22710c393656SHong Zhang tjsch->max_cps_disk = -1; /* -1 indicates that it is not set */
22720c393656SHong Zhang tjsch->stride = 0; /* if not zero, two-level checkpointing will be used */
22732f21b5c6SHong Zhang #if defined(PETSC_HAVE_REVOLVE)
22740c393656SHong Zhang tjsch->use_online = PETSC_FALSE;
22758f4fbd80SHong Zhang #endif
22760c393656SHong Zhang tjsch->save_stack = PETSC_TRUE;
22770c393656SHong Zhang
2278ac73474cSStefano Zampini tjsch->stack.solution_only = tj->solution_only;
22799566063dSJacob Faibussowitsch PetscCall(PetscViewerCreate(PetscObjectComm((PetscObject)tj), &tjsch->viewer));
22809566063dSJacob Faibussowitsch PetscCall(PetscViewerSetType(tjsch->viewer, PETSCVIEWERBINARY));
22819566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(tjsch->viewer, PETSC_VIEWER_NATIVE));
22829566063dSJacob Faibussowitsch PetscCall(PetscViewerFileSetMode(tjsch->viewer, FILE_MODE_WRITE));
22830c393656SHong Zhang
22849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectorySetMaxCpsRAM_C", TSTrajectorySetMaxCpsRAM_Memory));
22859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectorySetMaxCpsDisk_C", TSTrajectorySetMaxCpsDisk_Memory));
22869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectorySetMaxUnitsRAM_C", TSTrajectorySetMaxUnitsRAM_Memory));
22879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectorySetMaxUnitsDisk_C", TSTrajectorySetMaxUnitsDisk_Memory));
22889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)tj, "TSTrajectoryMemorySetType_C", TSTrajectoryMemorySetType_Memory));
22890c393656SHong Zhang tj->data = tjsch;
22903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
22919a53571cSHong Zhang }
2292