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

Last change on this file since 605 was 605, checked in by kulshres, 4 years ago

merge branch 'master' of 'gitclone' into 'svn'

The following commits were merged:

commit 34ee2eb90cc10b6058c8ef531042d82e73fddbc7
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu May 7 11:02:52 2015 +0200

add extra void* argument in ext_diff_fct_v2

This is only for use by the user's own evaluation
routines and is completely opaque to ADOL-C.

The user is responsible for making sure it doesn't
kill his code.

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

commit da07c215cc32cf3c239e111c0a8764dec59580d3
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu May 7 10:04:21 2015 +0200

force users to use -std=c++11 in their code too

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

commit 40748fda778e351f97050d7f5214e028bc1b8a0d
Merge: 88d480c 5ff49e4
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Wed May 6 13:44:50 2015 +0200

Merge branch 'master' of sommerfeld.math.upb.de:Git/adolc

commit 88d480cf5e91b16279aa2dd3a26f0ffea4f26572
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Wed May 6 13:44:41 2015 +0200

add explicit downcasts from badouble to double

These are to be used only in very special cases.
Like when I/O is required, different from the default
I/O provided. Or to make certain variables passive.
The explicit specifier makes sure that the compiler
does not automatically do any type changes without
the user saying so in the code.

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

commit 4e660e12e8387f60f29b4cc62bed7fb61c61b1fb
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue May 5 16:53:33 2015 +0200

Revert "create a configure flag for user-IO in traceless mode"

We decided to introduce explicit casting to double from adouble
and adtl::adouble before output, if the user wants anything but default
behaviour here.

This reverts commit 26a981c2aa80ea6be5a474b93a2f30e9ccf2479b.

commit 5ff49e405c275d024f90b5a177b28df1de226997
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Fri Apr 24 11:45:23 2015 +0200

change order of includes and configure tests for mingw compatibility

This change allows me to compile ADOL-C using a mingw32-w64 cross compiler
when also using the mingw compiled boost library.

Native Visual studio support for using boost is still untested.

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

commit cf341fcb23a1abba4b83fbf89b3743035635afe2
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Thu Apr 23 11:22:52 2015 +0200

fix ext_diff_fct.cpp to compile again.

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

commit 26a981c2aa80ea6be5a474b93a2f30e9ccf2479b
Author: Kshitij Kulshreshtha <kshitij@…>
Date: Tue Apr 14 12:57:09 2015 +0200

create a configure flag for user-IO in traceless mode

some implementations don't like to read/write gradient information
so allow the user to define their own stream operators if they wish

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

  • Property svn:keywords set to Id
File size: 8.7 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 605 2015-05-11 09:55:32Z 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#include <forward_list>
68#if defined(HAVE_BOOST_POOL_POOL_ALLOC_HPP) && defined(HAVE_BOOST_SYSTEM)
69#include <boost/pool/pool_alloc.hpp>
70#define USE_BOOST_POOL 1
71#else
72#define USE_BOOST_POOL 0
73#endif
74#include <adolc/internal/common.h>
75
76class Keeper;
77
78class StoreManager {
79  friend class Keeper;
80protected:
81  static size_t const initialSize = 4;
82  double myGcTriggerRatio;
83  size_t myGcTriggerMaxSize;
84  virtual void grow(size_t mingrow = 0) = 0;
85public:
86  StoreManager() : myGcTriggerRatio(1.5), myGcTriggerMaxSize(initialSize) {}
87  virtual ~StoreManager() {}
88  virtual locint next_loc() = 0;
89  virtual void free_loc(locint) = 0;
90  virtual void ensure_block(size_t n) = 0;
91  void setStoreManagerControl(double gcTriggerRatio, size_t gcTriggerMaxSize) { myGcTriggerRatio=gcTriggerRatio; myGcTriggerMaxSize=gcTriggerMaxSize;}
92  double gcTriggerRatio() const {return myGcTriggerRatio;}
93  size_t gcTriggerMaxSize() const {return myGcTriggerMaxSize;}
94
95//   // effectively the current size of the store array
96  virtual size_t maxSize() const = 0;
97
98//   // the number of slots currently in use
99  virtual size_t size() const = 0;
100};
101
102class StoreManagerLocint : public StoreManager {
103protected:
104  double * &storePtr;
105  locint * indexFree;
106  locint head;
107  size_t &maxsize;
108  size_t &currentfill;
109  virtual void grow(size_t mingrow = 0);
110public:
111
112  StoreManagerLocint(double * &storePtr, size_t &size, size_t &numlives);
113  StoreManagerLocint(const StoreManagerLocint *const stm, double * &storePtr, size_t &size, size_t &numLives);
114
115  virtual ~StoreManagerLocint();
116  virtual inline size_t size() const { return currentfill; }
117
118  virtual inline size_t maxSize() const { return maxsize; }
119
120  virtual inline bool realloc_on_next_loc() const { 
121      return (head == 0);
122  }
123
124  virtual locint next_loc();
125  virtual void free_loc(locint loc); 
126  virtual void ensure_block(size_t n) {}
127};
128
129class StoreManagerLocintBlock : public StoreManager {
130protected:
131    double * &storePtr;
132    struct FreeBlock {
133        locint next; // next location
134        size_t size; // number of following free locations
135        FreeBlock(): next(0), size(0) {}
136        FreeBlock(const struct FreeBlock &block) :
137            next(block.next),size(block.size) {}
138        FreeBlock(const locint& n, const size_t& s) :
139            next(n), size(s) {}
140        bool operator<(const struct FreeBlock& b) const {
141            return (next < b.next);
142        }
143    };
144
145    std::forward_list<struct FreeBlock
146#if USE_BOOST_POOL
147                      , boost::fast_pool_allocator<struct FreeBlock> 
148#endif
149                      >  indexFree;
150    size_t &maxsize;
151    size_t &currentfill;
152
153    void consolidateBlocks();
154#ifdef ADOLC_LOCDEBUG
155    unsigned int ensure_blockCallsSinceLastConsolidateBlocks;
156#endif
157    /**
158     * when minGrow is specified we asssume that we have already
159     * search the blocks and found no block with minGrow locations in it
160     */
161    virtual void grow(size_t minGrow=0 );
162public:
163    StoreManagerLocintBlock(double * &storePtr, size_t &size, size_t &numlives);
164    StoreManagerLocintBlock(const StoreManagerLocintBlock *const stm, double * &storePtr, size_t &size, size_t &numLives);
165
166    virtual ~StoreManagerLocintBlock();
167    virtual inline size_t size() const { return currentfill; }
168
169    virtual inline size_t maxSize() const { return maxsize; }
170
171    virtual locint next_loc();
172    virtual void free_loc(locint loc);
173    virtual void ensure_block(size_t n);
174};
175
176#if 0
177/* This implementation is unsafe in that using tace_on with keep=1 and
178   reverse mode directly afterwards will yield incorrect results.
179   For all other purposes it seem to work just fine, so it's left here
180   for reference as a comment.
181*/
182
183/* unsafe - use with care */
184
185class StoreManagerInSitu : public StoreManager {
186  //  static size_t const initialeGroesse = 512;
187protected:
188  double * &storePtr;
189  struct Link {
190    struct Link *next;
191  };
192  Link *head;
193  size_t groesse;
194  size_t anzahl;
195public:
196  size_t maxIndexUsed;
197
198  StoreManager(double * &storePtr) :
199    storePtr(storePtr),
200    head(0),
201    groesse(initialeGroesse),
202    anzahl(0),
203    maxIndexUsed(0)
204  {
205    // while a place in store is unused we want to place
206    // a Link stucture (i.e. a pointer) there
207    assert(sizeof(double) >= sizeof(void*));
208    assert(sizeof(double) >= sizeof(Link));
209    std::cerr << "StoreManager::StoreManager()\n";
210  }
211
212  virtual ~StoreManager() {
213    if (storePtr) {
214      delete [] storePtr;
215      storePtr = 0;
216    }
217    std::cerr << "StoreManager::~StoreManager()\n";
218  }
219
220  virtual inline size_t size() const { return anzahl; }
221
222  virtual inline size_t maxSize() const { return groesse; }
223
224  virtual locint next_loc(size_t n = 1) {
225    assert(n == 1);
226    if (head == 0) {
227      grow();
228    }
229    assert(head);
230    double * const dPtr = reinterpret_cast<double*>(head);
231    head = head->next;
232    ++anzahl;
233    locint const result = dPtr - storePtr;
234    maxIndexUsed = std::max((locint)maxIndexUsed, result);
235    return result;
236  }
237
238  virtual void free_loc(locint loc) {
239    assert(loc < groesse);
240    Link *returned = reinterpret_cast<Link*>(storePtr + loc);
241    returned->next = head;
242    head = returned;
243    --anzahl;
244  }
245private:
246  void grow() {
247    size_t const alteGroesse = groesse;
248    groesse *= 2;
249    assert(alteGroesse == initialeGroesse or size() == alteGroesse);
250    std::cerr << "StoreManager::grow(): increase size to " << groesse << "\n";
251    double *const oldStore = storePtr;
252    std::cerr << "StoreManager::grow(): allocate " << groesse * sizeof(double) << " B\n";
253    storePtr = new double[groesse];
254    size_t i = 0;
255    if (alteGroesse != initialeGroesse) { // nicht beim ersten Mal
256      std::cerr << "StoreManager::grow(): copy values\n";
257      for ( ; i < alteGroesse; ++i) {
258        storePtr[i] = oldStore[i];
259      }
260      std::cerr << "StoreManager::grow(): free " << alteGroesse * sizeof(double) << " B\n";
261      delete [] oldStore;
262    }
263    head = reinterpret_cast<Link*>(storePtr + i);
264    for ( ; i < groesse-1; ++i) {
265      reinterpret_cast<Link*>(storePtr + i)->next
266        = reinterpret_cast<Link*>(storePtr + i + 1);
267    }
268    reinterpret_cast<Link*>(storePtr + i)->next = 0;
269  }
270
271};
272#endif /* 0 */
273
274#endif /* ADOL_C__STOREMANAGER_H */
275
Note: See TracBrowser for help on using the repository browser.