ADOL-C: Automatic Differentiation in C/C++ 2.7.3
Loading...
Searching...
No Matches
storemanager.h
Go to the documentation of this file.
1/*----------------------------------------------------------------------------
2 ADOL-C-- Automatic Differentiation by Overloading in C++ - simplified
3 File: storemanager.h
4 Revision: $Id$
5 Contents: storemanager.h contains definitions of abstract interface
6 class StoreManager and some derived classes implementing the
7 desired functionality.
8
9 Copyright (c) 2006 Johannes Willkomm <johannes.willkomm@rwth-aachen.de>
10 2011-2013 Kshitij Kulshreshtha <kshitij@math.upb.de>
11 2012 Benjamin Letschert <letschi@mail.upb.de>
12 2013 Jean Utke <utke@mcs.anl.gov>
13
14 This file is part of ADOL-C.
15
16 The classes StoreManagerXYZ basically takes the global double *store pointer
17 into their obhut and implement next_loc and free_loc.
18
19 They basic idea is taken from "The C++ Programming Language" by Bjarne
20 Stroustrup, from the chapter 19 on iterators and allocators.
21
22 To understand how and why they work do the following:
23 1) Have a look at StoreManagerInSitu and convince yourself that it is
24 exactly the same as the solution presented in the Stroustrup book,
25 except that we always have just one big array instead of a linked
26 list of chunks.
27
28 This means in particular that we have to copy the values from the
29 old array into the lower half of the new one (we always double the size).
30
31 2) Have a look at StoreManagerLocint and convince yourself that these do
32 the same as StoreManagerInSitu except that the linked list of free
33 slots is maintained in a completely different portion of memory. This
34 means the values in freed slots remain untouched until they are
35 allocated again.
36
37
38 3) Have a look a class StoreManagerLocintBlock. This class uses a list of
39 of free blocks of different sizes instead of free locations.
40
41 class StoreManagerInSitu
42 An unsafe implementation is provided as well, but commented out.
43 It does not use the indexFeld array which saves between
44 25% and 50% memory relative to the above safe implementation.
45
46 It is most closely modelled after the example found in the
47 Stroustrup book.
48
49 It appears that it works very well, if one does not use the
50 trace_on(tag, 1); ... trace_off(); reverse(); way of using ADOL-C.
51 If the first sweep is forward it works fine.
52 Therefore I left it in here as a comment so an interested user
53 with acute main memory scarcity may give it a try.
54
55
56 History:
57 20120427 bl: add blocking store management
58 20110208 kk: incorporated in ADOL-C; moved some code arround
59 20060507 jw: begin
60
61----------------------------------------------------------------------------*/
62
63#ifndef ADOL_C__STOREMANAGER_H
64#define ADOL_C__STOREMANAGER_H
65
66#if defined(ADOLC_INTERNAL)
67#if HAVE_CONFIG_H
68#include "config.h"
69#endif
70#endif
71#include <adolc/internal/adolc_settings.h>
73#include <cassert>
74#include <forward_list>
75
76#if USE_BOOST_POOL
77#include <boost/pool/pool_alloc.hpp>
78#endif
79
87
88protected:
89 static size_t const initialSize{4};
92
93public:
94 // options for the StorageManagerType
96 ADOLC_LOCATION_BLOCKS, /* can allocate contiguous location blocks */
97 ADOLC_LOCATION_SINGLETONS /* only singleton locations, no blocks */
98 };
99
101 virtual ~StoreManager() {}
102 virtual locint next_loc() = 0;
103 virtual void free_loc(locint) = 0;
104 virtual void ensure_block(size_t n) = 0;
109 double gcTriggerRatio() const { return myGcTriggerRatio; }
110 size_t gcTriggerMaxSize() const { return myGcTriggerMaxSize; }
111 // // effectively the current size of the store array
112 virtual size_t maxSize() const = 0;
113
114 // // the number of slots currently in use
115 virtual size_t size() const = 0;
116 virtual unsigned char storeType() const = 0;
117 static size_t get_initialSize() { return initialSize; }
118 virtual void grow(size_t mingrow = 0) = 0;
119};
120
129protected:
130 double *&storePtr;
131#if defined(ADOLC_TRACK_ACTIVITY)
132 char activityTracking;
133 static char const *const nowhere;
134 char *&actStorePtr;
135#endif
136 locint *indexFree;
137 locint head;
138 size_t &maxsize;
139 size_t &currentfill;
140
141public:
142#if defined(ADOLC_TRACK_ACTIVITY)
143 StoreManagerLocint(double *&storePtr, char *&actStorePtr, size_t &size,
144 size_t &numlives);
145 StoreManagerLocint(const StoreManagerLocint *const stm, double *&storePtr,
146 char *&actStorePtr, size_t &size, size_t &numLives);
147#endif
148 StoreManagerLocint(double *&storePtr, size_t &size, size_t &numlives);
150 size_t &size, size_t &numLives);
151
153 virtual inline size_t size() const { return currentfill; }
154
155 virtual inline size_t maxSize() const { return maxsize; }
156 virtual inline unsigned char storeType() const {
158 }
159
160 virtual inline bool realloc_on_next_loc() const { return (head == 0); }
161
162 virtual locint next_loc();
163 virtual void free_loc(locint loc);
164 virtual void ensure_block(size_t n);
165 virtual void grow(size_t mingrow = 0);
166};
167
175protected:
176 double *&storePtr;
177#if defined(ADOLC_TRACK_ACTIVITY)
178 char activityTracking{0};
179 static char const *const nowhere{0};
180 char *&actStorePtr;
181#endif
183 struct FreeBlock {
184 size_t next{0}; // next location
185 size_t size{0}; // number of following free locations
187 FreeBlock(const struct FreeBlock &block)
188 : next(block.next), size(block.size) {}
189 FreeBlock(const locint &n, const size_t &s) : next(n), size(s) {}
190 bool operator<(const struct FreeBlock &b) const { return (next < b.next); }
191 };
192
193#if USE_BOOST_POOL
194 std::forward_list<FreeBlock, boost::fast_pool_allocator<FreeBlock>> indexFree{
195 0};
196#else
197 std::forward_list<FreeBlock> indexFree{0};
198#endif
199
200 size_t &maxsize;
201 size_t &currentfill;
202
204#ifdef ADOLC_LOCDEBUG
205 unsigned int ensure_blockCallsSinceLastConsolidateBlocks;
206#endif
207
208public:
209#if defined(ADOLC_TRACK_ACTIVITY)
210 StoreManagerLocintBlock(double *&storePtr, char *&actStorePtr, size_t &size,
211 size_t &numlives);
213 double *&storePtr, char *&actStorePtr, size_t &size,
214 size_t &numLives);
215#endif
216 StoreManagerLocintBlock(double *&storePtr, size_t &size, size_t &numlives);
218 double *&storePtr, size_t &size, size_t &numLives);
221
224
226 virtual inline size_t size() const { return currentfill; }
227
228 virtual inline size_t maxSize() const { return maxsize; }
229 virtual inline unsigned char storeType() const {
231 }
232
233 virtual size_t next_loc();
234 virtual void free_loc(size_t loc);
235 virtual void ensure_block(size_t n);
236
241 virtual void grow(size_t minGrow = 0);
242};
243
244#if 0
245/* This implementation is unsafe in that using tace_on with keep=1 and
246 reverse mode directly afterwards will yield incorrect results.
247 For all other purposes it seem to work just fine, so it's left here
248 for reference as a comment.
249*/
250
251/* unsafe - use with care */
252
253class StoreManagerInSitu : public StoreManager {
254 // static size_t const initialeGroesse = 512;
255protected:
256 double * &storePtr;
257 struct Link {
258 struct Link *next;
259 };
260 Link *head;
261 size_t groesse;
262 size_t anzahl;
263public:
264 size_t maxIndexUsed;
265
266 StoreManager(double * &storePtr) :
267 storePtr(storePtr),
268 head(0),
269 groesse(initialeGroesse),
270 anzahl(0),
271 maxIndexUsed(0)
272 {
273 // while a place in store is unused we want to place
274 // a Link stucture (i.e. a pointer) there
275 assert(sizeof(double) >= sizeof(void*));
276 assert(sizeof(double) >= sizeof(Link));
277 std::cerr << "StoreManager::StoreManager()\n";
278 }
279
280 virtual ~StoreManager() {
281 if (storePtr) {
282 delete [] storePtr;
283 storePtr = 0;
284 }
285 std::cerr << "StoreManager::~StoreManager()\n";
286 }
287
288 virtual inline size_t size() const { return anzahl; }
289
290 virtual inline size_t maxSize() const { return groesse; }
291
292 virtual locint next_loc(size_t n = 1) {
293 assert(n == 1);
294 if (head == 0) {
295 grow();
296 }
297 assert(head);
298 double * const dPtr = reinterpret_cast<double*>(head);
299 head = head->next;
300 ++anzahl;
301 locint const result = dPtr - storePtr;
302 maxIndexUsed = std::max((locint)maxIndexUsed, result);
303 return result;
304 }
305
306 virtual void free_loc(locint loc) {
307 assert(loc < groesse);
308 Link *returned = reinterpret_cast<Link*>(storePtr + loc);
309 returned->next = head;
310 head = returned;
311 --anzahl;
312 }
313private:
314 void grow() {
315 size_t const alteGroesse = groesse;
316 groesse *= 2;
317 assert(alteGroesse == initialeGroesse or size() == alteGroesse);
318 std::cerr << "StoreManager::grow(): increase size to " << groesse << "\n";
319 double *const oldStore = storePtr;
320 std::cerr << "StoreManager::grow(): allocate " << groesse * sizeof(double) << " B\n";
321 storePtr = new double[groesse];
322 size_t i = 0;
323 if (alteGroesse != initialeGroesse) { // nicht beim ersten Mal
324 std::cerr << "StoreManager::grow(): copy values\n";
325 for ( ; i < alteGroesse; ++i) {
326 storePtr[i] = oldStore[i];
327 }
328 std::cerr << "StoreManager::grow(): free " << alteGroesse * sizeof(double) << " B\n";
329 delete [] oldStore;
330 }
331 head = reinterpret_cast<Link*>(storePtr + i);
332 for ( ; i < groesse-1; ++i) {
333 reinterpret_cast<Link*>(storePtr + i)->next
334 = reinterpret_cast<Link*>(storePtr + i + 1);
335 }
336 reinterpret_cast<Link*>(storePtr + i)->next = 0;
337 }
338
339};
340#endif /* 0 */
341#endif /* ADOL_C__STOREMANAGER_H */
Location allocator that tracks contiguous free blocks.
Definition storemanager.h:174
virtual ~StoreManagerLocintBlock()
StoreManagerLocintBlock(StoreManagerLocintBlock &&)=delete
double *& storePtr
Definition storemanager.h:176
virtual size_t maxSize() const
Definition storemanager.h:228
virtual void free_loc(size_t loc)
StoreManagerLocintBlock & operator=(const StoreManagerLocintBlock &)=delete
size_t & currentfill
Definition storemanager.h:201
StoreManagerLocintBlock & operator=(StoreManagerLocintBlock &&)=delete
StoreManagerLocintBlock(double *&storePtr, size_t &size, size_t &numlives)
virtual size_t size() const
Definition storemanager.h:226
virtual void grow(size_t minGrow=0)
virtual void ensure_block(size_t n)
std::forward_list< FreeBlock > indexFree
Definition storemanager.h:197
virtual size_t next_loc()
StoreManagerLocintBlock(const StoreManagerLocintBlock &)=delete
StoreManagerLocintBlock(const StoreManagerLocintBlock *const stm, double *&storePtr, size_t &size, size_t &numLives)
size_t & maxsize
Definition storemanager.h:200
virtual unsigned char storeType() const
Definition storemanager.h:229
Location allocator backed by a free-location index array.
Definition storemanager.h:128
virtual void ensure_block(size_t n)
size_t & currentfill
Definition storemanager.h:139
virtual bool realloc_on_next_loc() const
Definition storemanager.h:160
locint * indexFree
Definition storemanager.h:136
StoreManagerLocint(double *&storePtr, size_t &size, size_t &numlives)
virtual size_t maxSize() const
Definition storemanager.h:155
StoreManagerLocint(const StoreManagerLocint *const stm, double *&storePtr, size_t &size, size_t &numLives)
virtual ~StoreManagerLocint()
locint head
Definition storemanager.h:137
virtual void grow(size_t mingrow=0)
double *& storePtr
Definition storemanager.h:130
virtual locint next_loc()
virtual void free_loc(locint loc)
virtual size_t size() const
Definition storemanager.h:153
virtual unsigned char storeType() const
Definition storemanager.h:156
size_t & maxsize
Definition storemanager.h:138
Abstract allocator for locations in ADOL-C's active-value store.
Definition storemanager.h:86
virtual void grow(size_t mingrow=0)=0
void setStoreManagerControl(double gcTriggerRatio, size_t gcTriggerMaxSize)
Definition storemanager.h:105
StoreManager()
Definition storemanager.h:100
LocationMgrType
Definition storemanager.h:95
@ ADOLC_LOCATION_BLOCKS
Definition storemanager.h:96
@ ADOLC_LOCATION_SINGLETONS
Definition storemanager.h:97
size_t myGcTriggerMaxSize
Definition storemanager.h:91
virtual size_t size() const =0
size_t gcTriggerMaxSize() const
Definition storemanager.h:110
virtual void ensure_block(size_t n)=0
virtual size_t maxSize() const =0
double myGcTriggerRatio
Definition storemanager.h:90
static size_t get_initialSize()
Definition storemanager.h:117
virtual locint next_loc()=0
virtual unsigned char storeType() const =0
virtual void free_loc(locint)=0
virtual ~StoreManager()
Definition storemanager.h:101
static size_t const initialSize
Definition storemanager.h:89
double gcTriggerRatio() const
Definition storemanager.h:109
Descriptor for one contiguous range of free locations.
Definition storemanager.h:183
bool operator<(const struct FreeBlock &b) const
Definition storemanager.h:190
FreeBlock(const struct FreeBlock &block)
Definition storemanager.h:187
size_t next
Definition storemanager.h:184
FreeBlock()
Definition storemanager.h:186
size_t size
Definition storemanager.h:185
FreeBlock(const locint &n, const size_t &s)
Definition storemanager.h:189
static constexpr double max() noexcept
Definition adtb_types.h:1424