1 |
#include <iostream> |
2 |
|
3 |
class CP { |
4 |
public: |
5 |
static const int levels=4; // the number of levels |
6 |
int maxIter; // maximal iteration |
7 |
int aL[levels]; // allowed per level |
8 |
int uL[levels]; // used per level |
9 |
int iL[levels]; // current iteration per level |
10 |
int changedLevel; // level changed due to increment or decrement |
11 |
int topLevel; // the top Level |
12 |
int cpLevel; // current checkpoint level |
13 |
int tapeLevel; // current taping level |
14 |
int adjointLevel; // current adjoint level |
15 |
|
16 |
CP() { |
17 |
maxIter=0; |
18 |
for (int i=0;i<levels;i++) { |
19 |
iL[i]=aL[i]=uL[i]=ufL[i]=0; |
20 |
} |
21 |
topLevel=0; |
22 |
cpLevel=0; |
23 |
tapeLevel=0; |
24 |
adjointLevel=0; |
25 |
} |
26 |
|
27 |
void init(){ |
28 |
// determine top level |
29 |
topLevel=0; |
30 |
int steps=1; |
31 |
for(int i=0;i<levels;i++) { |
32 |
steps*=aL[i]; |
33 |
if (steps<maxIter) |
34 |
topLevel++; |
35 |
else |
36 |
break; |
37 |
} |
38 |
if (topLevel>=levels) { |
39 |
std::cerr << "insufficient checkpoints" << std::endl; |
40 |
} |
41 |
for(int i=0;i<topLevel;i++) { |
42 |
iL[i]=1; |
43 |
} |
44 |
// determine uses: |
45 |
steps/=aL[topLevel]; |
46 |
uL[topLevel]=1+maxIter/steps; |
47 |
for(int i=topLevel-1;i>=0;i--) { |
48 |
uL[i]=aL[i]; |
49 |
} |
50 |
// determine final uses: |
51 |
ufL[topLevel]=uL[topLevel]; |
52 |
steps=maxIter%steps; |
53 |
for(int i=topLevel-1;i>=0;i--) { |
54 |
// determine top level for the rest |
55 |
int rTopLevel=0; |
56 |
int rsteps=1; |
57 |
for(int j=0;j<=i;j++) { |
58 |
rsteps*=aL[j]; |
59 |
if (rsteps<steps) |
60 |
rTopLevel++; |
61 |
else |
62 |
break; |
63 |
} |
64 |
rsteps/=aL[rTopLevel]; |
65 |
ufL[rTopLevel]=steps/rsteps; |
66 |
steps%=rsteps; |
67 |
} |
68 |
for(int i=0;i<levels;i++) { |
69 |
std::cout << "level " << i << " aL: " << aL[i] << " uL: " << uL[i] << " ufL: " << ufL[i] << std::endl; |
70 |
} |
71 |
} |
72 |
|
73 |
void operator++() { |
74 |
for(changedLevel=0;changedLevel<topLevel;changedLevel++) { |
75 |
if (iL[changedLevel]==uL[changedLevel]) |
76 |
iL[changedLevel]=1; |
77 |
else { |
78 |
il[changedLevel]++; |
79 |
break; |
80 |
} |
81 |
} |
82 |
} |
83 |
|
84 |
void operator--() { |
85 |
for(changedLevel=0;changedLevel<levels;changedLevel++) { |
86 |
if (iL[changedLevel]==1) { |
87 |
iL[changedLevel]=uL[iLc]; |
88 |
for (int i=changedLevel;i<levels; i++) { |
89 |
|
90 |
} |
91 |
} |
92 |
else { |
93 |
il[changedLevel]--; |
94 |
break; |
95 |
} |
96 |
} |
97 |
} |
98 |
|
99 |
|
100 |
}; |
101 |
|
102 |
void cpscheme(int iter, |
103 |
bool adjoint, |
104 |
CP& cp) { |
105 |
int i; |
106 |
if (!adjoint) { |
107 |
// increment a level and remember which level changes: |
108 |
int iLc; // the level that changes: |
109 |
for(iLc=0;iLc<levels;iLc++) { |
110 |
if (iL[iLc]==uL[iLc]) |
111 |
iL[iLc]=1; |
112 |
else { |
113 |
il[iLc]++; |
114 |
break; |
115 |
} |
116 |
} |
117 |
if (iLc==cpLevel) { |
118 |
// do checkpoint |
119 |
} |
120 |
} |
121 |
else { // do the adjoint |
122 |
// decrement a level and remember which level changes: |
123 |
int iLc; // the level that changes: |
124 |
for(iLc=0;iLc<levels;iLc++) { |
125 |
if (iL[iLc]==1) |
126 |
iL[iLc]=ul; |
127 |
else { |
128 |
il[iLc]++; |
129 |
break; |
130 |
} |
131 |
} |
132 |
if (iLc==cpLevel) { |
133 |
// do checkpoint |
134 |
} |
135 |
} |
136 |
} |
137 |
|
138 |
int main(void) { |
139 |
CP cp; |
140 |
std::cout << "maxIter: "; |
141 |
std::cin >> cp.maxIter; |
142 |
cp.aL[0]=3; |
143 |
cp.aL[1]=4; |
144 |
cp.aL[2]=5; |
145 |
cp.aL[3]=6; |
146 |
cp.init(); |
147 |
|
148 |
for (int i=0;i<maxIter;i++) { |
149 |
cpscheme(i, cp); |
150 |
} |
151 |
} |
152 |
|