source: trunk/ADOL-C/src/storemanager.h @ 708

Last change on this file since 708 was 708, checked in by kulshres, 3 years ago

Merge branch 'master' of 'gitclone' into 'svn'

The following changes have been merged:

commit e2291bde44a282a133894b0db350aeb0b92a87db
Author: Mladen Banovic <mladenbanovic2705@…>
Date: Fri Jul 8 10:15:51 2016 +0200

Add methods getNumLiveVar and getNumDir in adtl.h, change counter type in FOR_I_EQ_0_LT_NUMDIR macro to size_t (instead of int). Update chunk size of BOOST pool in adouble_tl.cpp according to adouble::numDir.

commit 2ffb294465b973bfd4bf1f73d84478f8233c0d2f
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu Jun 23 12:32:14 2016 +0200

implement missing ref_eq_mult_p und ref_eq_min_p in ho_rev.c

somehow these were left out when parameters were being implemented.

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 8cf0e5c1bd36f1dcf3be72cd67de631b2e1d0ee6
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu Jun 23 12:31:04 2016 +0200

make sure the result is the last locint written in trace for each operation

since we're trying to generate ascii traces in the future, we'll need this
convention that the last location is the result, and previous locations
are arguments. This has been the case for almost all operations anyway
except for a few new one's that I wrote without keeping this in mind.

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 9ae0ff220f37463f2ed85cafc8a626c24e472f2f
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue Jun 21 14:16:27 2016 +0200

on some compilers newer boost interferes with AC_FUNC_MALLOC test

so do AC_FUNC_MALLOC and AC_FUNC_REALLOC as usual and check for boost
library later.

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit b746f620772cc8cce53e8f350adc6281279caf72
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Mon Jun 20 15:32:22 2016 +0200

make Klaus Röbenack's name UTF-8 instead of ISO-8859-1

These are the only places where we're not simple ASCII or UTF-8 already

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 1171aa3961b5eb46a5d2ee64751c02a393a8a6f5
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Fri Jun 17 10:42:39 2016 +0200

correct short_ref document about include file

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 2c6b2aac2ef04431ece2c6ff80e574aa2e58814b
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Fri Jun 17 10:40:34 2016 +0200

correct error message to new semantics

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 506cde73451740bf0a15eff7d4abb158ee719ab0
Author: mflehmig <martin.flehmig@…>
Date: Fri Jun 17 10:14:26 2016 +0200

Fixed include of ADOL-C header.

ADOL-C header was included in old fashion (without adolc directory) for this example.

commit 2a023d3281d3d6d9824bad724a5768e3ee2fff94
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu Jun 16 13:50:39 2016 +0200

Try to use boost::pool for allocating advals in traceless vector mode

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

commit 80f1e2019ac1faab96fe06f3e9da47efcc1bcd23
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Mon May 23 15:13:22 2016 +0200

correct a reference in doc and rebuild

commit d7ab5283afe58bacb2e8739d72ede4e17f4c8081
Author: Mladen Banovic <mladenbanovic2705@…>
Date: Fri May 20 16:42:13 2016 +0200

Update section 7 of adolc-manual related to the Traceless forward differentiation.

commit bedb8e36f959c5272e4610fe504acc83208e5e9d
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue May 17 16:09:36 2016 +0200

macro name correction

commit 92ff596a0331776901df7f172ca347572e3daafd
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue May 17 15:56:17 2016 +0200

Add a warning about using static build of ADOL-C

static build of ADOL-C does not call constructors
for internal global objects, thereby causing
segmentation faults.

Signed-off-by: Kshitij Kulshreshtha <kshitij@…>

  • Property svn:keywords set to Id
File size: 8.9 KB
Line 
1// -*- c++ -*- hello emacs...
2/*----------------------------------------------------------------------------
3 ADOL-C--  Automatic Differentiation by Overloading in C++ - simplified
4 File:     storemanager.h
5 Revision: $Id: storemanager.h 708 2016-07-12 08:18:44Z kulshres $
6 Contents: storemanager.h contains definitions of abstract interface
7           class StoreManager and some derived classes implementing the
8           desired functionality.
9
10 Copyright (c) 2006 Johannes Willkomm <johannes.willkomm@rwth-aachen.de>
11               2011-2013 Kshitij Kulshreshtha <kshitij@math.upb.de>
12               2012 Benjamin Letschert <letschi@mail.upb.de>
13               2013 Jean Utke <utke@mcs.anl.gov>
14
15 This file is part of ADOL-C.
16
17 The classes StoreManagerXYZ basically takes the global double *store pointer
18 into their obhut and implement next_loc and free_loc.
19
20 They basic idea is taken from "The C++ Programming Language" by Bjarne
21 Stroustrup, from the chapter 19 on iterators and allocators.
22
23 To understand how and why they work do the following:
24 1) Have a look at StoreManagerInSitu and convince yourself that it is
25    exactly the same as the solution presented in the Stroustrup book,
26    except that we always have just one big array instead of a linked
27    list of chunks.
28
29    This means in particular that we have to copy the values from the
30    old array into the lower half of the new one (we always double the size).
31
32 2) Have a look at StoreManagerLocint and convince yourself that these do
33    the same as StoreManagerInSitu except that the linked list of free
34    slots is maintained in a completely different portion of memory. This
35    means the values in freed slots remain untouched until they are
36    allocated again.
37
38
39 3) Have a look a class StoreManagerLocintBlock. This class uses a list of
40    of free blocks of different sizes instead of free locations.
41
42 class StoreManagerInSitu
43 An unsafe implementation is provided as well, but commented out.
44 It does not use the indexFeld array which saves between
45 25% and 50% memory relative to the above safe implementation.
46
47 It is most closely modelled after the example found in the
48 Stroustrup book.
49
50 It appears that it works very well, if one does not use the
51 trace_on(tag, 1); ... trace_off(); reverse(); way of using ADOL-C.
52 If the first sweep is forward it works fine.
53 Therefore I left it in here as a comment so an interested user
54 with acute main memory scarcity may give it a try.
55           
56
57 History:
58          20120427 bl:     add blocking store management
59          20110208 kk:     incorporated in ADOL-C; moved some code arround
60          20060507 jw:     begin
61
62----------------------------------------------------------------------------*/
63
64#ifndef ADOL_C__STOREMANAGER_H
65#define ADOL_C__STOREMANAGER_H
66
67#if defined(ADOLC_INTERNAL)
68#    if HAVE_CONFIG_H
69#        include "config.h"
70#    endif
71#endif
72#include <adolc/internal/adolc_settings.h>
73#include <forward_list>
74
75#if USE_BOOST_POOL
76#include <boost/pool/pool_alloc.hpp>
77#endif
78
79#include <adolc/internal/common.h>
80
81class GlobalTapeVarsCL;
82extern "C" void checkInitialStoreSize(GlobalTapeVarsCL* gtv);
83
84class StoreManager {
85  friend void checkInitialStoreSize(GlobalTapeVarsCL* gtv);
86protected:
87  static size_t const initialSize = 4;
88  double myGcTriggerRatio;
89  size_t myGcTriggerMaxSize;
90  virtual void grow(size_t mingrow = 0) = 0;
91public:
92  StoreManager() : myGcTriggerRatio(1.5), myGcTriggerMaxSize(initialSize) {}
93  virtual ~StoreManager() {}
94  virtual locint next_loc() = 0;
95  virtual void free_loc(locint) = 0;
96  virtual void ensure_block(size_t n) = 0;
97  void setStoreManagerControl(double gcTriggerRatio, size_t gcTriggerMaxSize) { myGcTriggerRatio=gcTriggerRatio; myGcTriggerMaxSize=gcTriggerMaxSize;}
98  double gcTriggerRatio() const {return myGcTriggerRatio;}
99  size_t gcTriggerMaxSize() const {return myGcTriggerMaxSize;}
100
101//   // effectively the current size of the store array
102  virtual size_t maxSize() const = 0;
103
104//   // the number of slots currently in use
105  virtual size_t size() const = 0;
106};
107
108class StoreManagerLocint : public StoreManager {
109protected:
110  double * &storePtr;
111  locint * indexFree;
112  locint head;
113  size_t &maxsize;
114  size_t &currentfill;
115  virtual void grow(size_t mingrow = 0);
116public:
117
118  StoreManagerLocint(double * &storePtr, size_t &size, size_t &numlives);
119  StoreManagerLocint(const StoreManagerLocint *const stm, double * &storePtr, size_t &size, size_t &numLives);
120
121  virtual ~StoreManagerLocint();
122  virtual inline size_t size() const { return currentfill; }
123
124  virtual inline size_t maxSize() const { return maxsize; }
125
126  virtual inline bool realloc_on_next_loc() const { 
127      return (head == 0);
128  }
129
130  virtual locint next_loc();
131  virtual void free_loc(locint loc); 
132  virtual void ensure_block(size_t n) {}
133};
134
135class StoreManagerLocintBlock : public StoreManager {
136protected:
137    double * &storePtr;
138    struct FreeBlock {
139        locint next; // next location
140        size_t size; // number of following free locations
141        FreeBlock(): next(0), size(0) {}
142        FreeBlock(const struct FreeBlock &block) :
143            next(block.next),size(block.size) {}
144        FreeBlock(const locint& n, const size_t& s) :
145            next(n), size(s) {}
146        bool operator<(const struct FreeBlock& b) const {
147            return (next < b.next);
148        }
149    };
150
151    std::forward_list<struct FreeBlock
152#if USE_BOOST_POOL
153                      , boost::fast_pool_allocator<struct FreeBlock> 
154#endif
155                      >  indexFree;
156    size_t &maxsize;
157    size_t &currentfill;
158
159    void consolidateBlocks();
160#ifdef ADOLC_LOCDEBUG
161    unsigned int ensure_blockCallsSinceLastConsolidateBlocks;
162#endif
163    /**
164     * when minGrow is specified we asssume that we have already
165     * search the blocks and found no block with minGrow locations in it
166     */
167    virtual void grow(size_t minGrow=0 );
168public:
169    StoreManagerLocintBlock(double * &storePtr, size_t &size, size_t &numlives);
170    StoreManagerLocintBlock(const StoreManagerLocintBlock *const stm, double * &storePtr, size_t &size, size_t &numLives);
171
172    virtual ~StoreManagerLocintBlock();
173    virtual inline size_t size() const { return currentfill; }
174
175    virtual inline size_t maxSize() const { return maxsize; }
176
177    virtual locint next_loc();
178    virtual void free_loc(locint loc);
179    virtual void ensure_block(size_t n);
180};
181
182#if 0
183/* This implementation is unsafe in that using tace_on with keep=1 and
184   reverse mode directly afterwards will yield incorrect results.
185   For all other purposes it seem to work just fine, so it's left here
186   for reference as a comment.
187*/
188
189/* unsafe - use with care */
190
191class StoreManagerInSitu : public StoreManager {
192  //  static size_t const initialeGroesse = 512;
193protected:
194  double * &storePtr;
195  struct Link {
196    struct Link *next;
197  };
198  Link *head;
199  size_t groesse;
200  size_t anzahl;
201public:
202  size_t maxIndexUsed;
203
204  StoreManager(double * &storePtr) :
205    storePtr(storePtr),
206    head(0),
207    groesse(initialeGroesse),
208    anzahl(0),
209    maxIndexUsed(0)
210  {
211    // while a place in store is unused we want to place
212    // a Link stucture (i.e. a pointer) there
213    assert(sizeof(double) >= sizeof(void*));
214    assert(sizeof(double) >= sizeof(Link));
215    std::cerr << "StoreManager::StoreManager()\n";
216  }
217
218  virtual ~StoreManager() {
219    if (storePtr) {
220      delete [] storePtr;
221      storePtr = 0;
222    }
223    std::cerr << "StoreManager::~StoreManager()\n";
224  }
225
226  virtual inline size_t size() const { return anzahl; }
227
228  virtual inline size_t maxSize() const { return groesse; }
229
230  virtual locint next_loc(size_t n = 1) {
231    assert(n == 1);
232    if (head == 0) {
233      grow();
234    }
235    assert(head);
236    double * const dPtr = reinterpret_cast<double*>(head);
237    head = head->next;
238    ++anzahl;
239    locint const result = dPtr - storePtr;
240    maxIndexUsed = std::max((locint)maxIndexUsed, result);
241    return result;
242  }
243
244  virtual void free_loc(locint loc) {
245    assert(loc < groesse);
246    Link *returned = reinterpret_cast<Link*>(storePtr + loc);
247    returned->next = head;
248    head = returned;
249    --anzahl;
250  }
251private:
252  void grow() {
253    size_t const alteGroesse = groesse;
254    groesse *= 2;
255    assert(alteGroesse == initialeGroesse or size() == alteGroesse);
256    std::cerr << "StoreManager::grow(): increase size to " << groesse << "\n";
257    double *const oldStore = storePtr;
258    std::cerr << "StoreManager::grow(): allocate " << groesse * sizeof(double) << " B\n";
259    storePtr = new double[groesse];
260    size_t i = 0;
261    if (alteGroesse != initialeGroesse) { // nicht beim ersten Mal
262      std::cerr << "StoreManager::grow(): copy values\n";
263      for ( ; i < alteGroesse; ++i) {
264        storePtr[i] = oldStore[i];
265      }
266      std::cerr << "StoreManager::grow(): free " << alteGroesse * sizeof(double) << " B\n";
267      delete [] oldStore;
268    }
269    head = reinterpret_cast<Link*>(storePtr + i);
270    for ( ; i < groesse-1; ++i) {
271      reinterpret_cast<Link*>(storePtr + i)->next
272        = reinterpret_cast<Link*>(storePtr + i + 1);
273    }
274    reinterpret_cast<Link*>(storePtr + i)->next = 0;
275  }
276
277};
278#endif /* 0 */
279
280#endif /* ADOL_C__STOREMANAGER_H */
281
Note: See TracBrowser for help on using the repository browser.