ADOL-C: Automatic Differentiation in C/C++ 2.7.3
Loading...
Searching...
No Matches
valuetape.h
Go to the documentation of this file.
1
2#ifndef ADOLC_VALUETAPE_H
3#define ADOLC_VALUETAPE_H
4
5#include <adolc/adolcerror.h>
6#include <adolc/adolcexport.h>
7#include <adolc/buffer_temp.h>
9#include <adolc/dvlparms.h>
10#include <adolc/externfcts.h>
11#include <adolc/externfcts2.h>
12#include <adolc/storemanager.h>
20#include <atomic>
21#include <cstdarg>
22#include <cstddef>
23#include <cstdio>
24#include <limits>
25#include <memory>
26#include <mutex>
27#include <optional>
28#include <shared_mutex>
29#include <span>
30#include <stack>
31#include <stdexcept>
32#include <type_traits>
33
34// just ignore the missing DLL interface of the class members....
35#ifdef _MSC_VER
36#pragma warning(push)
37#pragma warning(disable : 4251)
38#endif
39
40#ifdef ADOLC_SPARSE
42#endif
43
44struct ext_diff_fct;
45struct ext_diff_fct_v2;
46
57
80 TapeRecordingContext recordCtx_;
81 GlobalTapeVarsCL globalTapeVars_;
82 TapeInfos tapeInfos_;
83 PersistantTapeInfos perTapeInfos_;
84 size_t ext_diff_fct_index_{0};
85 std::shared_mutex mutex_;
86 std::atomic<bool> statsNeedReload_{false};
87 std::mutex statsLoadMutex_;
88 std::optional<std::unique_lock<std::shared_mutex>> writeLock_;
89 enum class DataAccess { Exclusive, Shared };
90
97 struct DataAccessModeGuard {
98 std::shared_mutex mutex_;
99 DataAccess mode_{DataAccess::Exclusive};
100
101 explicit DataAccessModeGuard(DataAccess mode) : mode_(mode) {}
102 };
103
104 DataAccessModeGuard accessMode_{DataAccess::Exclusive};
105 bool containsExtDiff_{false};
106
107#define EDFCTS_BLOCK_SIZE 10
111
112#ifdef ADOLC_SPARSE
115
116 void initSparse() {
117 sJInfos_.~SparseJacInfos();
118 new (&sJInfos_) ADOLC::Sparse::SparseJacInfos();
119
120 sHInfos_.~SparseHessInfos();
121 new (&sHInfos_) ADOLC::Sparse::SparseHessInfos();
122 }
123#endif
124
125public:
127
128 // a tape always need a tapeId,
129 ValueTape() = delete;
130 explicit ValueTape(short tapeId) : tapeInfos_(tapeId, readConfigFile()) {}
131
132 // copying ValueTape is not allowed!
133 ValueTape(const ValueTape &other) = delete;
134 ValueTape &operator=(const ValueTape &other) = delete;
135
136 ValueTape(ValueTape &&other) noexcept
137 : recordCtx_(std::move(other.recordCtx_)),
138 globalTapeVars_(std::move(other.globalTapeVars_)),
139 tapeInfos_(std::move(other.tapeInfos_)),
140 perTapeInfos_(std::move(other.perTapeInfos_)),
141 ext_diff_fct_index_(other.ext_diff_fct_index_),
142 statsNeedReload_(
143 other.statsNeedReload_.exchange(false, std::memory_order_relaxed)),
144 accessMode_(other.accessMode_.mode_),
145 containsExtDiff_(other.containsExtDiff_),
146 ext_buffer_(std::move(other.ext_buffer_)),
147 ext2_buffer_(std::move(other.ext2_buffer_)),
148 cp_buffer_(std::move(other.cp_buffer_))
149#ifdef ADOLC_SPARSE
150 ,
151 sJInfos_(std::move(other.sJInfos_)), sHInfos_(std::move(other.sHInfos_))
152#endif
153 {
154 }
155
156 ValueTape &operator=(ValueTape &&other) noexcept {
157 if (this != &other) {
158 recordCtx_ = std::move(other.recordCtx_);
159 tapeInfos_ = std::move(other.tapeInfos_);
160 globalTapeVars_ = std::move(other.globalTapeVars_);
161 perTapeInfos_ = std::move(other.perTapeInfos_);
162 ext_diff_fct_index_ = other.ext_diff_fct_index_;
163 statsNeedReload_.store(
164 other.statsNeedReload_.exchange(false, std::memory_order_relaxed),
165 std::memory_order_release);
166 accessMode_.mode_ = other.accessMode_.mode_;
167 containsExtDiff_ = other.containsExtDiff_;
168 ext_buffer_ = std::move(other.ext_buffer_);
169 ext2_buffer_ = std::move(other.ext2_buffer_);
170 cp_buffer_ = std::move(other.cp_buffer_);
171#ifdef ADOLC_SPARSE
172 sJInfos_ = std::move(other.sJInfos_);
173 sHInfos_ = std::move(other.sHInfos_);
174#endif
175 }
176 return *this;
177 }
178
180 return accessMode_.mode_ == DataAccess::Exclusive;
181 }
183 std::shared_lock<std::shared_mutex> lock(accessMode_.mutex_);
184 return accessMode_.mode_ == DataAccess::Exclusive;
185 }
186 void registerExtDiff() { containsExtDiff_ = true; }
187 bool containsExtDiff() const { return containsExtDiff_; }
188
189private:
190 void setMode_(DataAccess mode) {
191 using ADOLCError::fail;
194 std::unique_lock<std::shared_mutex> dataAccessLock(accessMode_.mutex_);
195 if (accessMode_.mode_ == mode) {
196 return;
197 }
198 if (isRecording()) {
199 fail(TAPING_TAPE_STILL_IN_USE, CURRENT_LOCATION,
200 FailInfo{.info1 = tapeId()});
201 }
202 accessMode_.mode_ = mode;
203 }
204
205public:
212 void setSharedMode() { setMode_(DataAccess::Shared); }
213
215 void setExclusiveMode() { setMode_(DataAccess::Exclusive); }
216
218 statsNeedReload_.store(true, std::memory_order_release);
219 }
220
221 std::shared_mutex &accessMutex() noexcept { return mutex_; }
222
223 bool isRecording() const noexcept {
224 return currentTapeStack().back().current == this;
225 }
228
229#ifdef ADOLC_SPARSE
230 // updates the tape infos on sparse Jac or Hess for the given ID
231 void setTapeInfoJacSparse(ADOLC::Sparse::SparseJacInfos &&sJInfos) {
232 sJInfos_ = std::move(sJInfos);
233 }
234 void setTapeInfoHessSparse(ADOLC::Sparse::SparseHessInfos &&sHInfos) {
235 sHInfos_ = std::move(sHInfos);
236 }
237 ADOLC::Sparse::SparseJacInfos &sJInfos() { return sJInfos_; }
238 ADOLC::Sparse::SparseHessInfos &sHInfos() { return sHInfos_; }
239 const ADOLC::Sparse::SparseJacInfos &sJInfos() const { return sJInfos_; }
240 const ADOLC::Sparse::SparseHessInfos &sHInfos() const { return sHInfos_; }
241#endif
242
243 // Interface to PersistentTapeInfos
244 void tapeBaseNames(size_t loc, const std::string &baseName) {
245 tapeInfos_.tapeBaseNames_[loc] = baseName;
246 }
247 void skipFileCleanup(int skipFileCleanup) {
248 tapeInfos_.skipFileCleanup = skipFileCleanup;
249 }
250 int skipFileCleanup() const { return tapeInfos_.skipFileCleanup; }
251
252 char *tay_fileName() const {
253 return tapeInfos_.fileNames[TapeInfos::TAYLORS_FILE];
254 }
255 char *op_fileName() const {
256 return tapeInfos_.fileNames[TapeInfos::OPERATIONS_FILE];
257 }
258 char *loc_fileName() const {
259 return tapeInfos_.fileNames[TapeInfos::LOCATIONS_FILE];
260 }
261 char *val_fileName() const {
262 return tapeInfos_.fileNames[TapeInfos::VALUES_FILE];
263 }
264 void tay_fileName(char *name) {
265 tapeInfos_.fileNames[TapeInfos::TAYLORS_FILE] = name;
266 }
267 void op_fileName(char *name) {
268 tapeInfos_.fileNames[TapeInfos::OPERATIONS_FILE] = name;
269 }
270 void loc_fileName(char *name) {
271 tapeInfos_.fileNames[TapeInfos::LOCATIONS_FILE] = name;
272 }
273 void val_fileName(char *name) {
274 tapeInfos_.fileNames[TapeInfos::VALUES_FILE] = name;
275 }
276 int keepTape() const { return tapeInfos_.keepTape; }
277 void keepTape(int flag) { tapeInfos_.keepTape = flag; }
278 int jacSolv_nax() const { return perTapeInfos_.jacSolv_nax; }
279 int *jacSolv_ci() const { return perTapeInfos_.jacSolv_ci; }
280 int *jacSolv_ri() const { return perTapeInfos_.jacSolv_ri; }
281 double *jacSolv_xold() const { return perTapeInfos_.jacSolv_xold; }
282 double **jacSolv_I() const { return perTapeInfos_.jacSolv_I; }
283 double **jacSolv_J() const { return perTapeInfos_.jacSolv_J; }
284 int jacSolv_modeold() const { return perTapeInfos_.jacSolv_modeold; }
285 void jacSolv_nax(int nax) { perTapeInfos_.jacSolv_nax = nax; }
286 void jacSolv_I(double **I) { perTapeInfos_.jacSolv_I = I; }
287 void jacSolv_J(double **J) { perTapeInfos_.jacSolv_J = J; }
288 void jacSolv_xold(double *xold) { perTapeInfos_.jacSolv_xold = xold; }
289 void jacSolv_modeold(int mode) { perTapeInfos_.jacSolv_modeold = mode; }
290 void jacSolv_ci(int *ci) { perTapeInfos_.jacSolv_ci = ci; }
291 void jacSolv_ri(int *ri) { perTapeInfos_.jacSolv_ri = ri; }
292 int forodec_nax() const { return perTapeInfos_.forodec_nax; }
293 int forodec_dax() const { return perTapeInfos_.forodec_dax; }
294 double *forodec_y() const { return perTapeInfos_.forodec_y; }
295 double *forodec_z() const { return perTapeInfos_.forodec_z; }
296 double **forodec_Z() const { return perTapeInfos_.forodec_Z; }
297 void forodec_nax(int nax) { perTapeInfos_.forodec_nax = nax; }
298 void forodec_dax(int dax) { perTapeInfos_.forodec_dax = dax; }
299 void forodec_y(double *y) { perTapeInfos_.forodec_y = y; }
300 void forodec_z(double *z) { perTapeInfos_.forodec_z = z; }
301 void forodec_Z(double **Z) { perTapeInfos_.forodec_Z = Z; }
302
303 // Interface to TapeInfos
304 void readParams(double *&targetStore);
305 void compare_adolc_ids(const ADOLC_ID &id1, const ADOLC_ID &id2);
307 /****************************************************************************/
308 /* Tapestats: */
309 /* Returns statistics on the tape tag with following meaning: */
310 /* tape_stat[0] = # of independent variables. */
311 /* tape_stat[1] = # of dependent variables. */
312 /* tape_stat[2] = max # of live variables. */
313 /* tape_stat[3] = value stack size. */
314 /* tape_stat[4] = buffer size (# of chars, # of doubles, # of size_ts) */
315 /* tape_stat[5] = # of operations. */
316 /* tape_stat[6] = operation file access flag (1 = file in use, 0
317 * otherwise)
318 */
319 /* tape_stat[7] = # of saved locations. */
320 /* tape_stat[8] = location file access flag (1 = file in use, 0 otherwise)
321 */
322 /* tape_stat[9] = # of saved constant values. */
323 /* tape_stat[10]= value file access flag (1 = file in use, 0 otherwise) */
324 /****************************************************************************/
325 void tapestats(std::array<size_t, TapeInfos::STAT_SIZE> stats) {
326 std::copy(tapeInfos_.stats.cbegin(), tapeInfos_.stats.cend(),
327 stats.begin());
328 }
329 void tapestats(size_t *stats) {
330 std::copy(tapeInfos_.stats.cbegin(), tapeInfos_.stats.cend(), stats);
331 }
332 size_t tapestats(size_t stat) const { return tapeInfos_.stats[stat]; };
333 void tapestats(size_t stat, size_t val) { tapeInfos_.stats[stat] = val; };
334 std::array<size_t, TapeInfos::STAT_SIZE> tapestats() const {
335 return tapeInfos_.stats;
336 }
337
338 void deg_save(int val) { recordCtx_.deg_save = val; }
339 int deg_save() const { return recordCtx_.deg_save; }
340
341 int keepTaylors() const { return recordCtx_.keepTaylors; }
342 void keepTaylors(int val) { recordCtx_.keepTaylors = val; }
343
344 size_t numparam() const { return globalTapeVars_.numparam; }
345
347 recordCtx_.tayBuffer_.numOnTape(recordCtx_.tayBuffer_.numOnTape() + 1);
348 }
349 void add_numTays_Tape(size_t val) {
350 recordCtx_.tayBuffer_.numOnTape(recordCtx_.tayBuffer_.numOnTape() + val);
351 }
352
353 void lastTayBlockInCore(char val) { recordCtx_.lastTayBlockInCore = val; }
354 char lastTayBlockInCore() const { return recordCtx_.lastTayBlockInCore; }
355
357 recordCtx_.tayBuffer_.numOnTape(recordCtx_.tayBuffer_.numOnTape() - 1);
358 }
359
360 size_t num_eq_prod() const { return recordCtx_.num_eq_prod; }
361 void num_eq_prod(size_t num) { recordCtx_.num_eq_prod = num; }
362 void increment_num_eq_prod() { ++(recordCtx_.num_eq_prod); }
363 void add_num_eq_prod(size_t val) { recordCtx_.numDeps += val; }
364
365 void increment_numInds() { ++recordCtx_.numInds; }
366 size_t numInds() const { return recordCtx_.numInds; }
367
368 void increment_numDeps() { ++recordCtx_.numDeps; }
369 size_t numDeps() const { return recordCtx_.numDeps; }
370
371 void tay_numInds(size_t val) { recordCtx_.tay_numInds = val; }
372 size_t tay_numInds() const { return recordCtx_.tay_numInds; }
373
374 void tay_numDeps(size_t val) { recordCtx_.tay_numDeps = val; }
375 size_t tay_numDeps() const { return recordCtx_.tay_numDeps; }
376
377 void numSwitches(size_t num) { recordCtx_.numSwitches = num; }
378 size_t numSwitches() const { return recordCtx_.numSwitches; }
379 void increment_numSwitches() { ++recordCtx_.numSwitches; }
380
381 short tapeId() const { return tapeInfos_.tapeId_; }
382 size_t no_min_max() { return tapeInfos_.stats[TapeInfos::NO_MIN_MAX]; }
383 size_t ext_diff_fct_index() const { return ext_diff_fct_index_; }
384 void ext_diff_fct_index(size_t index) { ext_diff_fct_index_ = index; }
385
386 void nextBufferNumber(size_t num) { recordCtx_.nextBufferNumber = num; }
387 size_t nextBufferNumber() const { return recordCtx_.nextBufferNumber; }
388 void decrement_nextBufferNumber() { --recordCtx_.nextBufferNumber; }
389
390 constexpr static size_t maxLocsPerOp() { return TapeInfos::maxLocsPerOp; }
391
392 void put_op(OPCODES op, size_t reserveExtraLocations = 0) {
393 return recordCtx_.put_op(op, loc_fileName(), op_fileName(), val_fileName(),
394 reserveExtraLocations);
395 }
396
397 void put_loc(size_t loc) { return recordCtx_.put_loc(loc); };
398
399 void put_val(const double val) { recordCtx_.valBuffer_.writeAndAdvance(val); }
400 /* puts a single constant into the location buffer, no disk access */
401 void put_vals_writeBlock(double *reals, size_t numReals) {
402 return recordCtx_.put_vals_writeBlock(reals, numReals, op_fileName(),
403 val_fileName());
404 };
405 /* fill the constants buffer and write it to disk */
406 void put_vals_notWriteBlock(double *reals, size_t numReals) {
407 return recordCtx_.put_vals_notWriteBlock(reals, numReals);
408 }
409
410 /* reads the previous block of constants into the internal buffer */
411 size_t get_val_space() {
412 return recordCtx_.get_val_space(op_fileName(), val_fileName());
413 };
414 /* updates */
415 int upd_resloc(size_t temp, size_t lhs) {
416 return recordCtx_.upd_resloc(temp, lhs);
417 }
418 int upd_resloc_check(size_t temp) {
419 return recordCtx_.upd_resloc_check(temp);
420 }
421 int upd_resloc_inc_prod(size_t temp, size_t newlhs, unsigned char newop) {
422 return recordCtx_.upd_resloc_inc_prod(temp, newlhs, newop);
423 }
424 size_t get_num_param() { return tapeInfos_.stats[TapeInfos::NUM_PARAM]; }
425 // Marks reverse evaluation as nested so reverse outputs accumulate on the
426 // surrounding tape instead of overwriting its adjoints.
427 void nestedReverseEval(bool flag) { recordCtx_.nestedReverseEval = flag; }
428 // Returns whether reverse evaluation should accumulate into an outer tape.
429 bool nestedReverseEval() const { return recordCtx_.nestedReverseEval; }
430 double *signature() const { return recordCtx_.signature; }
431 void signature(double *buffer) { recordCtx_.signature = buffer; }
432
434 // free/allocate memory for buffers, initialize pointers
435 template <ADOLC::detail::EvalOrRecordContextType Context>
436 void initTapeBuffers(Context &ctx) {
437 ctx.opBuffer_.allocIfNull(tapestats(TapeInfos::OP_BUFFER_SIZE));
438 ctx.valBuffer_.allocIfNull(tapestats(TapeInfos::VAL_BUFFER_SIZE));
439 ctx.locBuffer_.allocIfNull(tapestats(TapeInfos::LOC_BUFFER_SIZE));
440 }
441 void initTapeBuffers() { initTapeBuffers(recordCtx_); }
442
443 //--------------------------------------------------------------
444
445 // Inteface global tape vars
446 size_t operationBufferSize() const {
447 return globalTapeVars_.operationBufferSize;
448 }
449 void operationBufferSize(size_t size) {
450 globalTapeVars_.operationBufferSize = size;
451 }
452
453 size_t locationBufferSize() const {
454 return globalTapeVars_.locationBufferSize;
455 }
456 void locationBufferSize(size_t size) {
457 globalTapeVars_.locationBufferSize = size;
458 }
459
460 size_t valueBufferSize() const { return globalTapeVars_.valueBufferSize; }
461 void valueBufferSize(size_t size) { globalTapeVars_.valueBufferSize = size; }
462
463 size_t taylorBufferSize() const { return globalTapeVars_.taylorBufferSize; }
464 void taylorBufferSize(size_t size) {
465 globalTapeVars_.taylorBufferSize = size;
466 }
467
468 size_t initalStoreSize() const { return globalTapeVars_.initialStoreSize; }
469 void initialStoreSize(size_t size) {
470 globalTapeVars_.initialStoreSize = size;
471 }
472 void checkInitialStoreSize() { globalTapeVars_.checkInitialStoreSize(); }
473
474 unsigned int nominmaxFlag() const { return globalTapeVars_.nominmaxFlag; }
475 void enableBranchSwitchWarnings() { globalTapeVars_.branchSwitchWarning = 1; }
477 globalTapeVars_.branchSwitchWarning = 0;
478 }
480 if (isRecording())
483 std::unique_lock lock(mutex_);
484 globalTapeVars_.nominmaxFlag = 1;
485 }
486
488 if (isRecording())
491 std::unique_lock lock(mutex_);
492 globalTapeVars_.nominmaxFlag = 0;
493 }
494
495 // helper for creating contiguous adouble locations
497 globalTapeVars_.storeManagerPtr->ensure_block(n);
498 }
499 size_t ensureContiguousLocations_(size_t n) {
500 globalTapeVars_.storeManagerPtr->ensure_block(n);
501 return n;
502 };
503 void setStoreManagerControl(double gcTriggerRatio, size_t gcTriggerMaxSize) {
504 globalTapeVars_.storeManagerPtr->setStoreManagerControl(gcTriggerRatio,
505 gcTriggerMaxSize);
506 }
507
508 void setStoreManagerType(unsigned char type) {
509 if (globalTapeVars_.storeManagerPtr->storeType() != type) {
510 if (!globalTapeVars_.numLives)
511 globalTapeVars_.reallocStore(type);
512 else
515 ADOLCError::FailInfo{.info5 = globalTapeVars_.numLives});
516 } else
518 }
519 // returns the next free location in "adouble" memory
520 size_t next_loc() { return globalTapeVars_.storeManagerPtr->next_loc(); }
521 // returns the next free location in "pdouble" memory
522 size_t p_next_loc() { return globalTapeVars_.paramStoreMgrPtr->next_loc(); }
523
524 // frees the specified location in "adouble" memory
525 void free_loc(size_t loc) const {
526 globalTapeVars_.storeManagerPtr->free_loc(loc);
527 }
528
529 // frees the specified location in "pdouble" memory
530 void p_free_loc(size_t loc) const {
531 globalTapeVars_.paramStoreMgrPtr->free_loc(loc);
532 }
533
534 double get_ad_value(size_t loc) const { return globalTapeVars_.store[loc]; }
535 void set_ad_value(size_t loc, double coval) {
536 if (globalTapeVars_.store)
537 globalTapeVars_.store[loc] = coval;
538 }
539 double get_pd_value(size_t loc) const { return globalTapeVars_.pStore[loc]; }
540 void set_pd_value(size_t loc, double coval) {
541 globalTapeVars_.pStore[loc] = coval;
542 }
543 size_t numLives() const { return globalTapeVars_.numLives; }
544#if defined(ADOLC_TRACK_ACTIVITY)
545 char get_active_value(size_t loc) const {
546 return globalTapeVars_.actStore[loc];
547 }
548 void set_active_value(size_t loc, char coval) {
549 globalTapeVars_.actStore[loc] = coval;
550 }
551#endif
552
553 size_t storeSize() const { return globalTapeVars_.storeSize; }
554 double *store() const { return globalTapeVars_.store; }
555 void store(double *buffer) { globalTapeVars_.store = buffer; }
556 double *pStore() const { return globalTapeVars_.pStore; }
557 void pStore(double *buffer) { globalTapeVars_.pStore = buffer; }
558 double store(size_t idx) { return globalTapeVars_.store[idx]; }
559 char branchSwitchWarning() const {
560 return globalTapeVars_.branchSwitchWarning;
561 }
562 void branchSwitchWarning(char val) {
563 globalTapeVars_.branchSwitchWarning = val;
564 }
565 char inParallelRegion() const { return globalTapeVars_.inParallelRegion; }
566
567 // ------------------------------- Buffer utils ---------------------------
568 ADOLC::CP::detail::Infos *cp_append() { return cp_buffer_.append(); }
570 return cp_buffer_.getElement(index);
571 }
572
573 ext_diff_fct *ext_diff_append() { return ext_buffer_.append(); }
575 return ext_buffer_.getElement(index);
576 }
577 ext_diff_fct_v2 *ext_diff_v2_append() { return ext2_buffer_.append(); }
579 return ext2_buffer_.getElement(index);
580 }
581
582 // ------------------------------------------- Combined
583 /* tries to read a local config file containing, e.g., buffer sizes */
584 std::array<std::string, 4> readConfigFile();
585
587 void taylor_begin(int degreeSave);
588
589 // close taylor file if necessary and refill buffer if possible
592
593 void write_scaylor(double val) {
594 recordCtx_.write_scaylor(val, tay_fileName());
595 }
596
597 // deletes the last (single) element (x) of the taylor buffer
598 void delete_scaylor(size_t loc) {
599 globalTapeVars_.store[loc] = recordCtx_.tayBuffer_.retreatAndRead();
600 }
601
608 template <typename Info> const char *fileName() const {
609 return tapeInfos_.fileNames[Info::fileIndex];
610 }
611
614 template <typename... Ts> struct AllTypes {};
616
638 template <InfoType<TapeEvaluationContext, ErrorType> Info>
640 size_t blockSize = 0;
641 auto &buffer = Info::getBuffer(evalCtx);
642 if (tapestats(Info::fileAccess) == 1) {
643 buffer.openFile(fileName<Info>(), "rb");
644
645 // preload at most one block, but never more than total elements on tape
646 blockSize = std::min(tapestats(Info::bufferSize), tapestats(Info::num));
647 evalCtx.loadBlockIntoBuffer<Info>(blockSize);
648 // remaining elements still residing on disk (not yet in buffer)
649 blockSize = tapestats(Info::num) - blockSize;
650 }
651 buffer.numOnTape(blockSize);
652 Info::prepareForwardPosition(evalCtx, tapeInfos_.stats[Info::bufferSize]);
653 }
654
667 template <InfoType<TapeEvaluationContext, ErrorType> Info>
669 auto number = (tapestats(Info::num) / tapestats(Info::bufferSize)) *
670 tapestats(Info::bufferSize);
671 auto offset = static_cast<long>(number * sizeof(typename Info::value_type));
672 auto &buffer = Info::getBuffer(evalCtx);
673 buffer.openFile(fileName<Info>(), "rb");
674 fseek(buffer.file(), offset, SEEK_SET);
675 }
676
693 template <InfoType<TapeEvaluationContext, ErrorType> Info>
695 size_t blockSize = tapestats(Info::num);
696 auto &buffer = Info::getBuffer(evalCtx);
697 if (tapestats(Info::fileAccess) == 1) {
698 setFilePosition<Info>(evalCtx);
699
700 // size of last (possibly partial) block
701 blockSize = tapestats(Info::num) % tapestats(Info::bufferSize);
702 evalCtx.loadBlockIntoBuffer<Info>(blockSize);
703 }
704 buffer.numOnTape(tapestats(Info::num) - blockSize);
705 buffer.position(blockSize);
706 }
707
713 template <InfoType<TapeEvaluationContext, ErrorType>... Infos>
715 AllTypes<Infos...> /*unused*/)
716 requires(requires { Infos::fileAccess; } && ...)
717 {
718 (prepare_for<Infos>(evalCtx), ...);
719 }
720
726 template <InfoType<TapeEvaluationContext, ErrorType>... Infos>
728 AllTypes<Infos...> /*unused*/)
729 requires(requires { Infos::fileAccess; } && ...)
730 {
731 (prepare_rev<Infos>(evalCtx), ...);
732 }
733
735 struct Mode {};
737 struct Forward : Mode {};
739 struct Reverse : Mode {};
740
741private:
742 template <typename Mode> void prepareSweep(TapeEvaluationContext &evalCtx) {
743 using namespace ADOLC::detail;
744
745 initTapeBuffers(evalCtx);
746 if (tapestats(TapeInfos::NUM_PARAM) > 0 && evalCtx.paramstore == nullptr)
747 readParams(evalCtx.paramstore);
748 if constexpr (std::is_same_v<Mode, Forward>) {
749 prepare_for_all(evalCtx, AllInfoTypes{});
750#ifdef ADOLC_AMPI_SUPPORT
751 TAPE_AMPI_resetBottom();
752#endif
753 } else if constexpr (std::is_same_v<Mode, Reverse>) {
754 prepare_rev_all(evalCtx, AllInfoTypes{});
755#ifdef ADOLC_AMPI_SUPPORT
756 TAPE_AMPI_resetTop();
757#endif
758 } else {
759 static_assert(!std::is_same_v<Mode, Mode>, "Mode not implemented!");
760 }
761 }
762
763 template <typename Mode>
765 initSweepKeep(std::shared_lock<std::shared_mutex> &&dataAccessLock) {
766 std::unique_lock<std::shared_mutex> lock(mutex_);
767 openTape();
768 TapeEvaluationContext evalCtx(std::move(recordCtx_), std::move(lock),
769 std::move(dataAccessLock));
770 prepareSweep<Mode>(evalCtx);
771 return evalCtx;
772 }
773
774 template <typename Mode>
776 initSweepNoKeep(std::shared_lock<std::shared_mutex> &&dataAccessLock) {
777 std::shared_lock<std::shared_mutex> lock(mutex_);
778 if (containsExtDiff_) {
779 ADOLCError::fail(ErrorType::EXT_DIFF_SHARED_MODE, CURRENT_LOCATION,
780 ADOLCError::FailInfo{.info1 = tapeId()});
781 }
782 openTape();
783 TapeEvaluationContext evalCtx(recordCtx_, tapeInfos_.stats, std::move(lock),
784 std::move(dataAccessLock));
785 prepareSweep<Mode>(evalCtx);
786 return evalCtx;
787 }
788
789public:
807 template <typename Mode> TapeEvaluationContext init_sweep(int keep = 0) {
808 std::shared_lock<std::shared_mutex> lock(accessMode_.mutex_);
809 if (keep || accessMode_.mode_ == DataAccess::Exclusive) {
810 return initSweepKeep<Mode>(std::move(lock));
811 } else {
812 return initSweepNoKeep<Mode>(std::move(lock));
813 }
814 }
815 // finish a forward or reverse sweep
818 // initialization for the taping process -> buffer allocation, sets files
819 // names, and calls appropriate setup routines
821
822 // record all existing adoubles on the tape - intended to be used in
823 // start_trace only
825
826 /* record all remaining live variables on the value stack tape
827 * - turns off trace_flag
828 * - intended to be used in stop_trace only */
829 size_t keep_stock();
830
831 // stop Tracing, clean up, and turn off trace_flag
832 void stop_trace(int flag);
833
834 /* initializes a new tape
835 * - returns 0 on success
836 * - returns 1 in case tapeId is already/still in use */
838
839 // ------------------- Combined methods ------------------------
840 // opens an existing tape or creates a new one
841 void openTape();
842
843 // updates the tape infos for the given ID - a tapeInfos struct is created
844 // and registered if non is found but its state will remain "not in use"
845 std::shared_ptr<ValueTape> getTapeInfos(short tapeId);
846
847 // close open tapes, update stats and clean up
848 void close_tape(int flag);
849
866 void setParamVec(std::span<const double> paramvec);
868 /****************************************************************************/
869 /* Frees parameter indices after taping is complete */
870 /****************************************************************************/
871 /* Only called during stop_trace() via save_params() */
873 size_t np = tapeInfos_.stats[TapeInfos::NUM_PARAM];
874 while (np > 0)
875 globalTapeVars_.paramStoreMgrPtr->free_loc(--np);
876 }
877
878 /* special IEEE values */
879 static double make_nan() {
880 return std::numeric_limits<double>::quiet_NaN();
881 ;
882 }
883
884 static double make_inf() { return std::numeric_limits<double>::infinity(); }
885
887 return cp_buffer_.getElement(index);
888 }
889};
890
891#endif // ADOLC_VALUETAPE_H
#define CURRENT_LOCATION
Definition adolcerror.h:26
#define ADOLC_API
Definition adolcexport.h:16
Block-based storage for registered external-function descriptors.
Definition buffer_temp.h:36
T * append()
Definition buffer_temp.h:110
T * getElement(size_t index) const
Definition buffer_temp.h:140
Owns one recorded function and the state required to evaluate it.
Definition valuetape.h:79
void ensureContiguousLocations(size_t n)
Definition valuetape.h:496
void forodec_nax(int nax)
Definition valuetape.h:297
char branchSwitchWarning() const
Definition valuetape.h:559
void forodec_z(double *z)
Definition valuetape.h:300
ADOLC::CP::detail::Infos * cp_getElement(size_t index)
Definition valuetape.h:569
void taylorBufferSize(size_t size)
Definition valuetape.h:464
void jacSolv_xold(double *xold)
Definition valuetape.h:288
void prepare_rev(TapeEvaluationContext &evalCtx)
Prepare for reverse sweep.
Definition valuetape.h:694
void add_numTays_Tape(size_t val)
Definition valuetape.h:349
void end_sweep(TapeEvaluationContext &evalCtx)
TapeEvaluationContext init_sweep(int keep=0)
Initialize a tape sweep.
Definition valuetape.h:807
void nestedReverseEval(bool flag)
Definition valuetape.h:427
size_t get_val_space()
Definition valuetape.h:411
void forodec_y(double *y)
Definition valuetape.h:299
void locationBufferSize(size_t size)
Definition valuetape.h:456
void put_vals_notWriteBlock(double *reals, size_t numReals)
Definition valuetape.h:406
void free_all_taping_params()
Definition valuetape.h:872
static constexpr size_t maxLocsPerOp()
Definition valuetape.h:390
void ext_diff_fct_index(size_t index)
Definition valuetape.h:384
void disableMinMaxUsingAbs()
Definition valuetape.h:487
ValueTape()=delete
static double make_nan()
Definition valuetape.h:879
void jacSolv_nax(int nax)
Definition valuetape.h:285
void checkInitialStoreSize()
Definition valuetape.h:472
char * val_fileName() const
Definition valuetape.h:261
void tapestats(std::array< size_t, TapeInfos::STAT_SIZE > stats)
Definition valuetape.h:325
void setStoreManagerControl(double gcTriggerRatio, size_t gcTriggerMaxSize)
Definition valuetape.h:503
void delete_scaylor(size_t loc)
Definition valuetape.h:598
void setFilePosition(TapeEvaluationContext &evalCtx)
Position the tape file at the beginning of the last on-disk block.
Definition valuetape.h:668
ADOLC::CP::detail::Infos * get_cp_fct(size_t index) const
Definition valuetape.h:886
void save_params()
ext_diff_fct * ext_diff_append()
Definition valuetape.h:573
size_t get_num_param()
Definition valuetape.h:424
void loc_fileName(char *name)
Definition valuetape.h:270
void pStore(double *buffer)
Definition valuetape.h:557
void tay_numInds(size_t val)
Definition valuetape.h:371
size_t numInds() const
Definition valuetape.h:366
size_t valueBufferSize() const
Definition valuetape.h:460
int keepTaylors() const
Definition valuetape.h:341
size_t no_min_max()
Definition valuetape.h:382
void endRecording()
ext_diff_fct_v2 * ext_diff_v2_getElement(size_t index)
Definition valuetape.h:578
size_t tapestats(size_t stat) const
Definition valuetape.h:332
size_t numLives() const
Definition valuetape.h:543
size_t p_next_loc()
Definition valuetape.h:522
void add_num_eq_prod(size_t val)
Definition valuetape.h:363
void statsNeedReload()
Definition valuetape.h:217
size_t numparam() const
Definition valuetape.h:344
void write_scaylor(double val)
Definition valuetape.h:593
void tapestats(size_t stat, size_t val)
Definition valuetape.h:333
void p_free_loc(size_t loc) const
Definition valuetape.h:530
void deg_save(int val)
Definition valuetape.h:338
double ** jacSolv_J() const
Definition valuetape.h:283
bool isExclusiveLocking()
Definition valuetape.h:182
void keepTaylors(int val)
Definition valuetape.h:342
std::shared_ptr< ValueTape > getTapeInfos(short tapeId)
void finish_tay_file()
void readParams(double *&targetStore)
void close_tape(int flag)
void tapestats(size_t *stats)
Definition valuetape.h:329
void jacSolv_ci(int *ci)
Definition valuetape.h:290
int jacSolv_nax() const
Definition valuetape.h:278
void val_fileName(char *name)
Definition valuetape.h:273
void start_trace()
void lastTayBlockInCore(char val)
Definition valuetape.h:353
void initTapeBuffers(Context &ctx)
Definition valuetape.h:436
int initNewTape()
double ** jacSolv_I() const
Definition valuetape.h:282
double get_ad_value(size_t loc) const
Definition valuetape.h:534
void put_op(OPCODES op, size_t reserveExtraLocations=0)
Definition valuetape.h:392
void prepare_rev_all(TapeEvaluationContext &evalCtx, AllTypes< Infos... >)
Run prepare_for() for all tape types listed in AllTypes.
Definition valuetape.h:727
void nextBufferNumber(size_t num)
Definition valuetape.h:386
void decrement_numTays_Tape()
Definition valuetape.h:356
int deg_save() const
Definition valuetape.h:339
void set_ad_value(size_t loc, double coval)
Definition valuetape.h:535
size_t storeSize() const
Definition valuetape.h:553
void prepare_for(TapeEvaluationContext &evalCtx)
Prepare for a forward sweep.
Definition valuetape.h:639
void taylor_close()
void set_pd_value(size_t loc, double coval)
Definition valuetape.h:540
unsigned int nominmaxFlag() const
Definition valuetape.h:474
void increment_num_eq_prod()
Definition valuetape.h:362
void increment_numSwitches()
Definition valuetape.h:379
void forodec_Z(double **Z)
Definition valuetape.h:301
ADOLC::CP::detail::Infos * cp_append()
Definition valuetape.h:568
int keepTape() const
Definition valuetape.h:276
bool containsExtDiff() const
Definition valuetape.h:187
char * tay_fileName() const
Definition valuetape.h:252
void registerExtDiff()
Definition valuetape.h:186
void jacSolv_ri(int *ri)
Definition valuetape.h:291
double * pStore() const
Definition valuetape.h:556
void jacSolv_I(double **I)
Definition valuetape.h:286
void setExclusiveMode()
Restores the default single-evaluation mode with reusable owned buffers.
Definition valuetape.h:215
static double make_inf()
Definition valuetape.h:884
bool nestedReverseEval() const
Definition valuetape.h:429
size_t tay_numDeps() const
Definition valuetape.h:375
bool isExclusiveNonLocking()
Definition valuetape.h:179
void valueBufferSize(size_t size)
Definition valuetape.h:461
size_t initalStoreSize() const
Definition valuetape.h:468
void taylor_begin(int degreeSave)
Initialize Taylor-stack recording for the current tape.
void put_vals_writeBlock(double *reals, size_t numReals)
Definition valuetape.h:401
ValueTape(const ValueTape &other)=delete
int forodec_nax() const
Definition valuetape.h:292
void put_loc(size_t loc)
Definition valuetape.h:397
int skipFileCleanup() const
Definition valuetape.h:250
size_t numDeps() const
Definition valuetape.h:369
void stop_trace(int flag)
void read_tape_stats()
size_t tay_numInds() const
Definition valuetape.h:372
char inParallelRegion() const
Definition valuetape.h:565
void operationBufferSize(size_t size)
Definition valuetape.h:449
int * jacSolv_ri() const
Definition valuetape.h:280
void numSwitches(size_t num)
Definition valuetape.h:377
std::shared_mutex & accessMutex() noexcept
Definition valuetape.h:221
void initialStoreSize(size_t size)
Definition valuetape.h:469
void increment_numTays_Tape()
Definition valuetape.h:346
void op_fileName(char *name)
Definition valuetape.h:267
std::array< std::string, 4 > readConfigFile()
size_t next_loc()
Definition valuetape.h:520
void decrement_nextBufferNumber()
Definition valuetape.h:388
void openTape()
void put_val(const double val)
Definition valuetape.h:399
int upd_resloc_check(size_t temp)
Definition valuetape.h:418
double * forodec_z() const
Definition valuetape.h:295
double * signature() const
Definition valuetape.h:430
void setStoreManagerType(unsigned char type)
Definition valuetape.h:508
int forodec_dax() const
Definition valuetape.h:293
ValueTape(short tapeId)
Definition valuetape.h:130
void keepTape(int flag)
Definition valuetape.h:277
void setParamVec(std::span< const double > paramvec)
Update parameter values used by subsequent evaluations.
void initTapeInfos_keep()
char * loc_fileName() const
Definition valuetape.h:258
void free_loc(size_t loc) const
Definition valuetape.h:525
size_t ensureContiguousLocations_(size_t n)
Definition valuetape.h:499
void skipFileCleanup(int skipFileCleanup)
Definition valuetape.h:247
void compare_adolc_ids(const ADOLC_ID &id1, const ADOLC_ID &id2)
void prepare_for_all(TapeEvaluationContext &evalCtx, AllTypes< Infos... >)
Run prepare_for() for all tape types listed in AllTypes.
Definition valuetape.h:714
char * op_fileName() const
Definition valuetape.h:255
void beginRecording()
size_t num_eq_prod() const
Definition valuetape.h:360
size_t operationBufferSize() const
Definition valuetape.h:446
int upd_resloc_inc_prod(size_t temp, size_t newlhs, unsigned char newop)
Definition valuetape.h:421
double ** forodec_Z() const
Definition valuetape.h:296
int * jacSolv_ci() const
Definition valuetape.h:279
void num_eq_prod(size_t num)
Definition valuetape.h:361
void jacSolv_modeold(int mode)
Definition valuetape.h:289
void end_sweep(TapeEvaluationContext &&evalCtx)
double * forodec_y() const
Definition valuetape.h:294
void increment_numDeps()
Definition valuetape.h:368
double get_pd_value(size_t loc) const
Definition valuetape.h:539
size_t keep_stock()
size_t locationBufferSize() const
Definition valuetape.h:453
size_t taylorBufferSize() const
Definition valuetape.h:463
ext_diff_fct_v2 * ext_diff_v2_append()
Definition valuetape.h:577
void jacSolv_J(double **J)
Definition valuetape.h:287
void enableMinMaxUsingAbs()
Definition valuetape.h:479
void enableBranchSwitchWarnings()
Definition valuetape.h:475
ValueTape & operator=(ValueTape &&other) noexcept
Definition valuetape.h:156
const char * fileName() const
Return the tape file name associated with the given Info adapter.
Definition valuetape.h:608
size_t ext_diff_fct_index() const
Definition valuetape.h:383
void tay_fileName(char *name)
Definition valuetape.h:264
ext_diff_fct * ext_diff_getElement(size_t index)
Definition valuetape.h:574
void tapeBaseNames(size_t loc, const std::string &baseName)
Definition valuetape.h:244
short tapeId() const
Definition valuetape.h:381
size_t nextBufferNumber() const
Definition valuetape.h:387
int upd_resloc(size_t temp, size_t lhs)
Definition valuetape.h:415
void setSharedMode()
Enables concurrent no-keep evaluations of this tape.
Definition valuetape.h:212
void forodec_dax(int dax)
Definition valuetape.h:298
char lastTayBlockInCore() const
Definition valuetape.h:354
int jacSolv_modeold() const
Definition valuetape.h:284
void increment_numInds()
Definition valuetape.h:365
double * store() const
Definition valuetape.h:554
bool isRecording() const noexcept
Definition valuetape.h:223
void branchSwitchWarning(char val)
Definition valuetape.h:562
double store(size_t idx)
Definition valuetape.h:558
ValueTape(ValueTape &&other) noexcept
Definition valuetape.h:136
ValueTape & operator=(const ValueTape &other)=delete
double * jacSolv_xold() const
Definition valuetape.h:281
void tay_numDeps(size_t val)
Definition valuetape.h:374
void signature(double *buffer)
Definition valuetape.h:431
void initTapeBuffers()
Definition valuetape.h:441
void store(double *buffer)
Definition valuetape.h:555
std::array< size_t, TapeInfos::STAT_SIZE > tapestats() const
Definition valuetape.h:334
size_t numSwitches() const
Definition valuetape.h:378
void take_stock()
void disableBranchSwitchWarnings()
Definition valuetape.h:476
Concept describing the required interface of a tape Info adapter.
Definition infotype.h:43
ErrorType
Definition adolcerror.h:89
void ADOLC_API fail(ErrorType error, const source_location LocInfo, const FailInfo &failinfo=FailInfo())
Definition bufferstate.h:12
OPCODES
Definition oplate.h:23
Additional typed fields used when formatting an ADOL-C failure.
Definition adolcerror.h:225
short info1
Definition adolcerror.h:226
size_t info5
Definition adolcerror.h:230
Internal checkpointing state shared between the public context and the recorded external function.
Definition checkpointing.h:69
Cached sparse Hessian recovery data stored on a tape.
Definition sparseinfos.h:131
Cached sparse Jacobian recovery data stored on a tape.
Definition sparseinfos.h:21
Adapter for the locations tape (loc tape).
Definition infotype.h:159
Adapter for the operations tape (op tape).
Definition infotype.h:132
Per-sweep state used while evaluating a recorded tape.
Definition tapeevaluationcontext.h:32
void loadBlockIntoBuffer(size_t blockSize)
Definition tapeevaluationcontext.h:249
double * paramstore
Definition tapeevaluationcontext.h:106
Mutable buffers and bookkeeping used while recording a tape.
Definition taperecordingcontext.h:20
Adapter for the values tape (val tape).
Definition infotype.h:202
Per-tape active-value stores and location allocators.
Definition globaltapevarscl.h:15
void checkInitialStoreSize()
Definition globaltapevarscl.h:37
char inParallelRegion
Definition globaltapevarscl.h:61
std::unique_ptr< StoreManager > paramStoreMgrPtr
Definition globaltapevarscl.h:70
uint nominmaxFlag
Definition globaltapevarscl.h:65
size_t valueBufferSize
Definition globaltapevarscl.h:57
size_t numparam
Definition globaltapevarscl.h:66
size_t initialStoreSize
Definition globaltapevarscl.h:69
void reallocStore(unsigned char type)
size_t taylorBufferSize
Definition globaltapevarscl.h:58
size_t operationBufferSize
Definition globaltapevarscl.h:55
size_t storeSize
Definition globaltapevarscl.h:48
double * pStore
Definition globaltapevarscl.h:68
std::unique_ptr< StoreManager > storeManagerPtr
Definition globaltapevarscl.h:71
double * store
Definition globaltapevarscl.h:43
size_t numLives
Definition globaltapevarscl.h:49
char branchSwitchWarning
Definition globaltapevarscl.h:64
size_t locationBufferSize
Definition globaltapevarscl.h:56
Reusable scratch storage retained by higher-level tape drivers.
Definition persistanttapeinfos.h:12
double ** jacSolv_J
Definition persistanttapeinfos.h:28
double ** jacSolv_I
Definition persistanttapeinfos.h:29
int jacSolv_nax
Definition persistanttapeinfos.h:33
int jacSolv_modeold
Definition persistanttapeinfos.h:34
double * jacSolv_xold
Definition persistanttapeinfos.h:30
double * forodec_y
Definition persistanttapeinfos.h:25
double ** forodec_Z
Definition persistanttapeinfos.h:27
int forodec_dax
Definition persistanttapeinfos.h:24
int * jacSolv_ri
Definition persistanttapeinfos.h:31
int forodec_nax
Definition persistanttapeinfos.h:23
int * jacSolv_ci
Definition persistanttapeinfos.h:32
double * forodec_z
Definition persistanttapeinfos.h:26
Identity, statistics, file names, and recording metadata of one tape.
Definition tapeinfos.h:24
std::array< std::string, 4 > tapeBaseNames_
Definition tapeinfos.h:106
std::array< char *, 4 > fileNames
Definition tapeinfos.h:104
int skipFileCleanup
Definition tapeinfos.h:117
@ NUM_PARAM
Definition tapeinfos.h:45
@ VAL_BUFFER_SIZE
Definition tapeinfos.h:40
@ NO_MIN_MAX
Definition tapeinfos.h:43
@ LOC_BUFFER_SIZE
Definition tapeinfos.h:39
@ OP_BUFFER_SIZE
Definition tapeinfos.h:32
@ OPERATIONS_FILE
Definition tapeinfos.h:49
@ LOCATIONS_FILE
Definition tapeinfos.h:49
@ TAYLORS_FILE
Definition tapeinfos.h:49
@ VALUES_FILE
Definition tapeinfos.h:49
StatArray stats
Definition tapeinfos.h:103
int keepTape
Definition tapeinfos.h:114
static constexpr size_t maxLocsPerOp
Definition tapeinfos.h:109
short tapeId_
Definition tapeinfos.h:107
Compile-time list used to prepare tape buffers for forward and reverse sweeps.
Definition valuetape.h:614
Selects forward-order tape traversal.
Definition valuetape.h:737
Base tag for the direction selected by init_sweep().
Definition valuetape.h:735
Selects reverse-order tape traversal.
Definition valuetape.h:739
Callback descriptor for a block-structured external function.
Definition externfcts2.h:68
Callback descriptor for an externally differentiated function.
Definition externfcts.h:106
ADOLC_API std::array< size_t, TapeInfos::STAT_SIZE > tapestats(short tapeId)
Writes the tapestats of the tape into an array.
Definition tape_interface.h:115
std::vector< RecordingFrame > & currentTapeStack()
Returns a thread-local stack holding pointers to ValueTape instances.
Definition taperegistry.h:46