ADOL-C: Automatic Differentiation in C/C++ 2.7.3
Loading...
Searching...
No Matches
tapeevaluationcontext.h
Go to the documentation of this file.
1#ifndef ADOLC_TAPE_EVALUATION_CONTEXT_H
2#define ADOLC_TAPE_EVALUATION_CONTEXT_H
3
6#include <algorithm>
7#include <cstddef>
8#include <cstdio>
9#include <memory>
10#include <mutex>
11#include <shared_mutex>
12#include <type_traits>
13#include <utility>
14#include <variant>
15
16namespace ADOLC::detail {
17
18struct TapeEvaluationContext;
19
20template <typename T>
21concept EvalOrRecordContextType = std::is_same_v<T, TapeEvaluationContext> ||
22 std::is_same_v<T, TapeRecordingContext>;
23
37
41
45
48
50 if (originCtx_ != nullptr) {
52 releaseTo(*originCtx_);
53 }
54 delete[] signature;
55 delete[] paramstore;
56 }
57
59
61 const TapeRecordingContext &tapeCtx, TapeInfos::StatArray stats,
62 std::shared_lock<std::shared_mutex> &&lock,
63 std::shared_lock<std::shared_mutex> &&dataAccessLock)
64 : lock_(std::move(lock)), dataAccessLock_(std::move(dataAccessLock)) {
65 copyData(tapeCtx, stats);
66 }
67
69 TapeRecordingContext &&other, std::unique_lock<std::shared_mutex> &&lock,
70 std::shared_lock<std::shared_mutex> &&dataAccessLock) noexcept
71 : lock_(std::move(lock)), dataAccessLock_(std::move(dataAccessLock)),
72 originCtx_(&other) {
73 moveData(std::move(other));
74 }
75
78
80 : lock_(std::move(other.lock_)),
81 dataAccessLock_(std::move(other.dataAccessLock_)),
82 originCtx_(std::exchange(other.originCtx_, nullptr)) {
83 moveData(std::move(other));
84 }
85
87 operator=(TapeEvaluationContext &&other) noexcept = delete;
88
93
94 size_t numInds{0};
95 size_t numDeps{0};
97 size_t num_eq_prod{0};
98 int deg_save{0};
99 size_t tay_numInds{0};
100 size_t tay_numDeps{0};
101 size_t numSwitches{0};
102 bool nestedReverseEval{false};
105 double *signature{nullptr};
106 double *paramstore{nullptr};
107
108private:
109 using Lock = std::variant<std::unique_lock<std::shared_mutex>,
110 std::shared_lock<std::shared_mutex>>;
111
112 Lock lock_;
113 std::shared_lock<std::shared_mutex> dataAccessLock_;
114 // used to recover push data back to recordCtx if an exception happens.
115 TapeRecordingContext *originCtx_{nullptr};
116
117 void copyData(const TapeRecordingContext &other, TapeInfos::StatArray stats) {
118 opBuffer_ = OpBuffer{other.opBuffer_, bufferView};
119 valBuffer_ = ValBuffer{other.valBuffer_, bufferView};
120 locBuffer_ = LocBuffer{other.locBuffer_, bufferView};
121 tayBuffer_ = TayBuffer{other.tayBuffer_, bufferView};
122
123 numInds = other.numInds;
124 numDeps = other.numDeps;
125 keepTaylors = other.keepTaylors;
126 num_eq_prod = other.num_eq_prod;
127 deg_save = other.deg_save;
128 tay_numInds = other.tay_numInds;
129 tay_numDeps = other.tay_numDeps;
130 numSwitches = other.numSwitches;
131 nestedReverseEval = other.nestedReverseEval;
132 nextBufferNumber = other.nextBufferNumber;
133 lastTayBlockInCore = other.lastTayBlockInCore;
134
135 if (other.signature != nullptr) {
136 signature = new double[stats[TapeInfos::NUM_SWITCHES]];
137 std::copy_n(other.signature, stats[TapeInfos::NUM_SWITCHES], signature);
138 }
139 if (other.paramstore != nullptr) {
140 paramstore = new double[stats[TapeInfos::NUM_PARAM]];
141 std::copy_n(other.paramstore, stats[TapeInfos::NUM_PARAM], paramstore);
142 }
143 }
144
145 template <EvalOrRecordContextType Context>
146 void moveData(Context &&other) noexcept {
147 opBuffer_ = std::move(other.opBuffer_);
148 valBuffer_ = std::move(other.valBuffer_);
149 locBuffer_ = std::move(other.locBuffer_);
150 tayBuffer_ = std::move(other.tayBuffer_);
151
152 numInds = other.numInds;
153 numDeps = other.numDeps;
154 keepTaylors = other.keepTaylors;
155 num_eq_prod = other.num_eq_prod;
156 deg_save = other.deg_save;
157 tay_numInds = other.tay_numInds;
158 tay_numDeps = other.tay_numDeps;
159 numSwitches = other.numSwitches;
160 nestedReverseEval = other.nestedReverseEval;
161 nextBufferNumber = other.nextBufferNumber;
162 lastTayBlockInCore = other.lastTayBlockInCore;
163 signature = std::exchange(other.signature, nullptr);
164 paramstore = std::exchange(other.paramstore, nullptr);
165 }
166
167public:
173
175 recordCtx.opBuffer_ = std::move(opBuffer_);
176 recordCtx.valBuffer_ = std::move(valBuffer_);
177 recordCtx.locBuffer_ = std::move(locBuffer_);
178 recordCtx.tayBuffer_ = std::move(tayBuffer_);
179
180 recordCtx.numInds = numInds;
181 recordCtx.numDeps = numDeps;
182 recordCtx.keepTaylors = keepTaylors;
183 recordCtx.num_eq_prod = num_eq_prod;
184 recordCtx.deg_save = deg_save;
185 recordCtx.tay_numInds = tay_numInds;
186 recordCtx.tay_numDeps = tay_numDeps;
187 recordCtx.numSwitches = numSwitches;
191
192 assert(recordCtx.signature == nullptr);
193 recordCtx.signature = std::exchange(signature, nullptr);
194 assert(recordCtx.paramstore == nullptr);
195 recordCtx.paramstore = std::exchange(paramstore, nullptr);
196
197 originCtx_ = nullptr;
198 }
199
200 template <InfoType<TapeEvaluationContext, ErrorType> Info>
201 void openFile(const char *fileName) {
202 using ADOLCError::fail;
204 auto &buffer = Info::getBuffer(*this);
205 if (buffer.file() == nullptr) {
206 if (Info::removeExistingBeforeWrite) {
207 buffer.openFile(fileName, "rb");
208 if (buffer.file() != nullptr) {
209 buffer.closeFile();
210 if (remove(fileName)) {
211 fail(CANNOT_REMOVE_FILE, CURRENT_LOCATION);
212 }
213 }
214 }
215 buffer.openFile(fileName, Info::openWriteMode);
216 }
217 }
218
219 template <InfoType<TapeEvaluationContext, ErrorType> Info>
220 void put_block(const char *fileName, size_t lengthBlock) {
221 using ADOLC::detail::write;
222 using ADOLCError::fail;
224
225 openFile<Info>(fileName);
226 const size_t numChunks = lengthBlock / Info::chunkSize;
227
228 for (size_t chunk = 0; chunk < numChunks; chunk++) {
229 auto returnCode = write<TapeEvaluationContext, ErrorType, Info>(
230 *this, chunk, Info::chunkSize);
231 if (returnCode != 1)
232 fail(TAPING_FATAL_IO_ERROR, CURRENT_LOCATION);
233 }
234
235 const size_t remain = lengthBlock % Info::chunkSize;
236 if (remain != 0) {
237 auto returnCode = write<TapeEvaluationContext, ErrorType, Info>(
238 *this, numChunks, remain);
239 if (returnCode != 1)
240 fail(TAPING_FATAL_IO_ERROR, CURRENT_LOCATION);
241 }
242
243 auto &buffer = Info::getBuffer(*this);
244 buffer.numOnTape(buffer.numOnTape() + lengthBlock);
245 buffer.position(0);
246 }
247
248 template <InfoType<TapeEvaluationContext, ErrorType> Info>
249 void loadBlockIntoBuffer(size_t blockSize) {
250 using ADOLCError::fail;
251 auto &buffer = Info::getBuffer(*this);
252 if (!buffer.isOwner()) {
253 buffer.allocateAndOwn();
254 }
255 const size_t numChunks = blockSize / Info::chunkSize;
256 for (size_t chunk = 0; chunk < numChunks; chunk++) {
257 const auto ret =
258 fread(buffer.begin() + (chunk * Info::chunkSize),
259 Info::chunkSize * sizeof(typename Info::value_type), 1,
260 buffer.file());
261 if (ret != 1) {
262 fail(Info::error, CURRENT_LOCATION);
263 }
264 }
265 const size_t remain = blockSize % Info::chunkSize;
266 if (remain != 0) {
267 const auto ret =
268 fread(buffer.begin() + (numChunks * Info::chunkSize),
269 remain * sizeof(typename Info::value_type), 1, buffer.file());
270 if (ret != 1) {
271 fail(Info::error, CURRENT_LOCATION);
272 }
273 }
274 }
275
276 template <InfoType<TapeEvaluationContext, ErrorType> Info>
277 void loadBlockIntoBufferForward(size_t bufferSize) {
278 auto &buffer = Info::getBuffer(*this);
279 const size_t blockSize = std::min(bufferSize, buffer.numOnTape());
280 loadBlockIntoBuffer<Info>(blockSize);
281 Info::updateBufferStatsForward(*this, blockSize);
282 Info::updateBufferPositionForward(*this);
283 }
284
285 template <InfoType<TapeEvaluationContext, ErrorType> Info>
286 void loadBlockIntoBufferReverse(size_t blockSize) {
287 using ADOLCError::fail;
288
289 auto &buffer = Info::getBuffer(*this);
290 const long pos = Info::reverseSeekOffset(*this, blockSize);
291 const auto ret = fseek(buffer.file(), pos, SEEK_SET);
292 if (ret == -1) {
293 fail(Info::error, CURRENT_LOCATION);
294 }
295
296 loadBlockIntoBuffer<Info>(blockSize);
297 Info::updateBufferStatsReverse(*this, blockSize);
298 Info::updateBufferPositionReverse(*this, blockSize);
299 }
300
301 template <InfoType<TapeEvaluationContext, ErrorType> Info>
302 typename Info::value_type loadNextReverse(size_t blockSize) {
303 auto &buffer = Info::getBuffer(*this);
304 Info::ensureReverseReadable(*this, blockSize);
305 return buffer.retreatAndRead();
306 }
307
308 template <InfoType<TapeEvaluationContext, ErrorType> Info>
309 typename Info::value_type loadNextForward() {
310 auto &buffer = Info::getBuffer(*this);
311 return buffer.readAndAdvance();
312 }
313
314 double *get_val_v_f(size_t size) {
315 double *temp = valBuffer_.current();
317 return temp;
318 }
319
320 double *get_val_v_r(size_t size) {
322 return valBuffer_.current();
323 }
324
325 void reset_val_r(size_t valueBufferSize) {
327 if (valBuffer_.position() == 0) {
328 loadBlockIntoBufferReverse<ValInfoT>(valueBufferSize);
329 }
330 }
331
332 void discard_params_r(size_t valueBufferSize, size_t numParam);
333
334 void finish_tay_file(const char *tay_fileName) {
335 deg_save = -1;
336 if (tayBuffer_.file() != nullptr)
338 remove(tay_fileName);
339 }
340
341 void taylor_begin(int degreeSave, size_t taylorBufferSize,
342 const char *tay_fileName) {
343 if (tayBuffer_.begin()) {
344 finish_tay_file(tay_fileName);
345 } else {
346 tayBuffer_.allocIfNull(taylorBufferSize);
347 }
348
349 deg_save = degreeSave;
350 if (degreeSave >= 0)
351 keepTaylors = 1;
354 }
355
356 size_t taylor_close(const char *tay_fileName) {
358 if (tayBuffer_.file() != nullptr) {
359 if (keepTaylors != 0) {
360 put_block<TayInfoT>(tay_fileName, tayBuffer_.position());
361 if (std::fflush(tayBuffer_.file()) != 0)
362 ADOLCError::fail(ErrorType::TAPING_FATAL_IO_ERROR, CURRENT_LOCATION);
363 }
364 } else {
366 }
368 return tayBuffer_.numOnTape();
369 }
370
371 void taylor_back(size_t taylorBufferSize, short tapeId,
372 const char *tay_fileName);
373
374 void write_taylor(double *taylorCoefficientPos, std::ptrdiff_t keep,
375 const char *tay_fileName);
376
377 void write_scaylor(double val, const char *tay_fileName) {
380 put_block<TayInfoT>(tay_fileName, tayBuffer_.capacity());
382 }
383
384 void write_taylors(double *taylorCoefficientPos, int keep, int degree,
385 int numDir, const char *tay_fileName) {
387 for (int j = 0; j < numDir; ++j) {
388 for (int i = 0; i < keep; ++i) {
390 put_block<TayInfoT>(tay_fileName, tayBuffer_.capacity());
391
392 tayBuffer_.writeAndAdvance(*taylorCoefficientPos);
393 ++taylorCoefficientPos;
394 }
395 if (degree > keep)
396 taylorCoefficientPos += degree - keep;
397 }
398 }
399
400 void get_taylors(double *taylorCoefficients, std::ptrdiff_t degree,
401 size_t taylorBufferSize);
402
403 void get_taylors_p(double *taylorCoefficients, int degree, int numDir,
404 size_t taylorBufferSize);
405};
406
407} // namespace ADOLC::detail
408
409#endif // ADOLC_TAPE_EVALUATION_CONTEXT_H
#define CURRENT_LOCATION
Definition adolcerror.h:26
T * current()
Returns a pointer to the element at position().
Definition bufferstate.h:305
size_t position() const
Returns the current buffer index.
Definition bufferstate.h:260
void closeFile()
Closes the owned FILE handle, if present.
Definition bufferstate.h:206
T * begin()
Returns the beginning of the owned or viewed buffer.
Definition bufferstate.h:232
void allocIfNull(size_t capacity)
Allocates a new owned buffer if no buffer is currently present.
Definition bufferstate.h:251
void writeAndAdvance(T val)
Stores val at position(), then advances to the next element.
Definition bufferstate.h:299
FILE * file()
Returns the owned FILE handle without transferring ownership.
Definition bufferstate.h:202
size_t numOnTape() const
Returns the number of elements recorded on the tape.
Definition bufferstate.h:275
size_t capacity() const
Returns the capacity of the owned or viewed buffer.
Definition bufferstate.h:272
Definition tapeevaluationcontext.h:21
void ADOLC_API fail(ErrorType error, const source_location LocInfo, const FailInfo &failinfo=FailInfo())
Definition bufferstate.h:12
BufferState< double > ValBuffer
Definition bufferstate.h:329
BufferState< size_t > LocBuffer
Definition bufferstate.h:330
BufferState< unsigned char > OpBuffer
Operation tape buffer.
Definition bufferstate.h:328
constexpr BufferViewTag bufferView
Definition bufferstate.h:51
BufferState< double > TayBuffer
Definition bufferstate.h:331
Per-sweep state used while evaluating a recorded tape.
Definition tapeevaluationcontext.h:32
void loadBlockIntoBufferReverse(size_t blockSize)
Definition tapeevaluationcontext.h:286
TapeEvaluationContext(const TapeEvaluationContext &)=delete
TapeEvaluationContext & operator=(TapeEvaluationContext &&other) noexcept=delete
double * get_val_v_r(size_t size)
Definition tapeevaluationcontext.h:320
ADOLC::detail::LocBuffer locBuffer_
Definition tapeevaluationcontext.h:91
void loadBlockIntoBuffer(size_t blockSize)
Definition tapeevaluationcontext.h:249
void write_taylor(double *taylorCoefficientPos, std::ptrdiff_t keep, const char *tay_fileName)
int deg_save
Definition tapeevaluationcontext.h:98
TapeEvaluationContext & operator=(const TapeEvaluationContext &)=delete
size_t taylor_close(const char *tay_fileName)
Definition tapeevaluationcontext.h:356
size_t numSwitches
Definition tapeevaluationcontext.h:101
void discard_params_r(size_t valueBufferSize, size_t numParam)
size_t tay_numInds
Definition tapeevaluationcontext.h:99
static constexpr StatEntries VAL_FILE_ACCESS
Definition tapeevaluationcontext.h:44
ADOLC::detail::TayBuffer tayBuffer_
Definition tapeevaluationcontext.h:92
void releaseTo(TapeRecordingContext &recordCtx)
Definition tapeevaluationcontext.h:174
void taylor_back(size_t taylorBufferSize, short tapeId, const char *tay_fileName)
static constexpr StatEntries NUM_OPERATIONS
Definition tapeevaluationcontext.h:35
void closeSweepFiles()
Definition tapeevaluationcontext.h:168
TapeEvaluationContext(TapeRecordingContext &&other, std::unique_lock< std::shared_mutex > &&lock, std::shared_lock< std::shared_mutex > &&dataAccessLock) noexcept
Definition tapeevaluationcontext.h:68
TapeEvaluationContext(const TapeRecordingContext &tapeCtx, TapeInfos::StatArray stats, std::shared_lock< std::shared_mutex > &&lock, std::shared_lock< std::shared_mutex > &&dataAccessLock)
Definition tapeevaluationcontext.h:60
static constexpr StatEntries NUM_VALUES
Definition tapeevaluationcontext.h:43
static constexpr StatEntries LOC_BUFFER_SIZE
Definition tapeevaluationcontext.h:38
bool nestedReverseEval
Definition tapeevaluationcontext.h:102
void get_taylors(double *taylorCoefficients, std::ptrdiff_t degree, size_t taylorBufferSize)
static constexpr StatEntries LOC_FILE_ACCESS
Definition tapeevaluationcontext.h:40
void write_scaylor(double val, const char *tay_fileName)
Definition tapeevaluationcontext.h:377
void taylor_begin(int degreeSave, size_t taylorBufferSize, const char *tay_fileName)
Definition tapeevaluationcontext.h:341
void write_taylors(double *taylorCoefficientPos, int keep, int degree, int numDir, const char *tay_fileName)
Definition tapeevaluationcontext.h:384
double * get_val_v_f(size_t size)
Definition tapeevaluationcontext.h:314
void loadBlockIntoBufferForward(size_t bufferSize)
Definition tapeevaluationcontext.h:277
static constexpr StatEntries OP_BUFFER_SIZE
Definition tapeevaluationcontext.h:34
static constexpr StatEntries VAL_BUFFER_SIZE
Definition tapeevaluationcontext.h:42
static constexpr StatEntries NUM_TAYS
Definition tapeevaluationcontext.h:47
size_t numDeps
Definition tapeevaluationcontext.h:95
ADOLC::detail::ValBuffer valBuffer_
Definition tapeevaluationcontext.h:90
static constexpr StatEntries TAY_BUFFER_SIZE
Definition tapeevaluationcontext.h:46
ADOLC::detail::OpBuffer opBuffer_
Definition tapeevaluationcontext.h:89
static constexpr StatEntries OP_FILE_ACCESS
Definition tapeevaluationcontext.h:36
int keepTaylors
Definition tapeevaluationcontext.h:96
size_t tay_numDeps
Definition tapeevaluationcontext.h:100
size_t num_eq_prod
Definition tapeevaluationcontext.h:97
double * paramstore
Definition tapeevaluationcontext.h:106
static constexpr StatEntries NUM_LOCATIONS
Definition tapeevaluationcontext.h:39
~TapeEvaluationContext()
Definition tapeevaluationcontext.h:49
TapeEvaluationContext(TapeEvaluationContext &&other) noexcept
Definition tapeevaluationcontext.h:79
void finish_tay_file(const char *tay_fileName)
Definition tapeevaluationcontext.h:334
void reset_val_r(size_t valueBufferSize)
Definition tapeevaluationcontext.h:325
void openFile(const char *fileName)
Definition tapeevaluationcontext.h:201
Info::value_type loadNextReverse(size_t blockSize)
Definition tapeevaluationcontext.h:302
void put_block(const char *fileName, size_t lengthBlock)
Definition tapeevaluationcontext.h:220
void get_taylors_p(double *taylorCoefficients, int degree, int numDir, size_t taylorBufferSize)
double * signature
Definition tapeevaluationcontext.h:105
size_t numInds
Definition tapeevaluationcontext.h:94
char lastTayBlockInCore
Definition tapeevaluationcontext.h:104
Info::value_type loadNextForward()
Definition tapeevaluationcontext.h:309
size_t nextBufferNumber
Definition tapeevaluationcontext.h:103
Mutable buffers and bookkeeping used while recording a tape.
Definition taperecordingcontext.h:20
size_t nextBufferNumber
Definition taperecordingcontext.h:88
bool nestedReverseEval
Definition taperecordingcontext.h:85
int deg_save
Definition taperecordingcontext.h:71
size_t num_eq_prod
Definition taperecordingcontext.h:68
ADOLC::detail::TayBuffer tayBuffer_
Definition taperecordingcontext.h:61
ADOLC::detail::OpBuffer opBuffer_
Definition taperecordingcontext.h:58
double * signature
Definition taperecordingcontext.h:93
int keepTaylors
Definition taperecordingcontext.h:66
ADOLC::detail::LocBuffer locBuffer_
Definition taperecordingcontext.h:60
double * paramstore
Definition taperecordingcontext.h:94
size_t numSwitches
Definition taperecordingcontext.h:77
size_t tay_numDeps
Definition taperecordingcontext.h:75
ADOLC::detail::ValBuffer valBuffer_
Definition taperecordingcontext.h:59
size_t numInds
Definition taperecordingcontext.h:63
size_t tay_numInds
Definition taperecordingcontext.h:73
size_t numDeps
Definition taperecordingcontext.h:64
char lastTayBlockInCore
Definition taperecordingcontext.h:92
Adapter for the Taylor tape (tay tape).
Definition infotype.h:240
Adapter for the values tape (val tape).
Definition infotype.h:202
StatEntries
Definition tapeinfos.h:27
@ OP_FILE_ACCESS
Definition tapeinfos.h:34
@ NUM_TAYS
Definition tapeinfos.h:31
@ NUM_SWITCHES
Definition tapeinfos.h:44
@ NUM_PARAM
Definition tapeinfos.h:45
@ LOC_FILE_ACCESS
Definition tapeinfos.h:36
@ NUM_OPERATIONS
Definition tapeinfos.h:33
@ TAY_BUFFER_SIZE
Definition tapeinfos.h:41
@ VAL_BUFFER_SIZE
Definition tapeinfos.h:40
@ NUM_LOCATIONS
Definition tapeinfos.h:35
@ NUM_VALUES
Definition tapeinfos.h:37
@ LOC_BUFFER_SIZE
Definition tapeinfos.h:39
@ VAL_FILE_ACCESS
Definition tapeinfos.h:38
@ OP_BUFFER_SIZE
Definition tapeinfos.h:32
std::array< size_t, STAT_SIZE > StatArray
Definition tapeinfos.h:102
Numeric limits for taped active scalars.
Definition adtb_types.h:1417