CoDiPack  2.2.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
blockData.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2024 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://scicomp.rptu.de
6 * Contact: Prof. Nicolas R. Gauger (codi@scicomp.uni-kl.de)
7 *
8 * Lead developers: Max Sagebaum, Johannes Blühdorn (SciComp, University of Kaiserslautern-Landau)
9 *
10 * This file is part of CoDiPack (http://scicomp.rptu.de/software/codi).
11 *
12 * CoDiPack is free software: you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * CoDiPack is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU
23 * General Public License along with CoDiPack.
24 * If not, see <http://www.gnu.org/licenses/>.
25 *
26 * For other licensing options please contact us.
27 *
28 * Authors:
29 * - SciComp, University of Kaiserslautern-Landau:
30 * - Max Sagebaum
31 * - Johannes Blühdorn
32 * - Former members:
33 * - Tim Albring
34 */
35#pragma once
36
37#include <vector>
38
39#include "../../config.h"
40#include "../../misc/macros.hpp"
41#include "../../traits/misc/enableIfHelpers.hpp"
42#include "chunk.hpp"
43#include "dataInterface.hpp"
44#include "emptyData.hpp"
45#include "pointerStore.hpp"
46#include "position.hpp"
47
49namespace codi {
50
63 template<typename T_Chunk, typename T_NestedData = EmptyData, typename T_PointerInserter = PointerStore<T_Chunk>>
64 struct BlockData : public DataInterface<T_NestedData> {
65 public:
66
67 using Chunk = CODI_DD(T_Chunk, CODI_T(Chunk1<CODI_ANY>));
69 using PointerInserter = CODI_DD(T_PointerInserter, CODI_T(PointerStore<Chunk>));
70
71 using InternalPosHandle = size_t;
72 using NestedPosition = typename NestedData::Position;
73
75 template<int selectedDepth>
77 typename std::conditional<selectedDepth == 0, TerminatingPointerStore<PointerInserter>,
78 PointerInserter>::type;
79
81
82 private:
83 Chunk chunk;
84
85 NestedData* nested;
86
87 public:
88
90 BlockData(size_t const& chunkSize, NestedData* nested) : chunk(chunkSize), nested(nullptr) {
91 setNested(nested);
92 }
93
95 BlockData(size_t const& chunkSize) : chunk(chunkSize), nested(nullptr) {}
96
97 /*******************************************************************************/
99
101 template<typename... Data>
102 CODI_INLINE void pushData(Data const&... data) {
103 // This method should only be called if reserveItems has been called.
104 chunk.pushData(data...);
105 }
106
108 template<typename... Data>
109 CODI_INLINE void getDataPointers(Data*&... pointers) {
110 // This method should only be called if reserveItems has been called.
111 chunk.dataPointer(chunk.getUsedSize(), pointers...);
112 }
113
115 CODI_INLINE void addDataSize(size_t size) {
116 // This method should only be called if reserveItems has been called.
117 chunk.setUsedSize(chunk.getUsedSize() + size);
118 }
119
123 CODI_UNUSED(items);
124 codiAssert(chunk.getUsedSize() + items <= chunk.getSize());
125
126 return chunk.getUsedSize();
127 }
128
129 /*******************************************************************************/
131
133 void resize(size_t const& totalSize) {
134 chunk.resize(totalSize);
135 }
136
138 void reset() {
140 }
141
143 void resetHard() {
144 chunk.resize(0);
145
146 nested->resetHard();
147 }
148
150 void resetTo(Position const& pos) {
151 codiAssert(pos.data <= chunk.getSize());
152
153 chunk.setUsedSize(pos.data);
154
155 nested->resetTo(pos.inner);
156 }
157
160 void erase(Position const& start, Position const& end, bool recursive = true) {
161 chunk.erase(start.data, end.data);
162 if (recursive) {
163 nested->erase(start.inner, end.inner);
164 }
165 }
166
167 /*******************************************************************************/
169
171 CODI_INLINE size_t getDataSize() const {
172 return chunk.getUsedSize();
173 }
174
177 return Position(chunk.getUsedSize(), nested->getPosition());
178 }
179
182 return chunk.getUsedSize() - startPos;
183 }
184
187 return Position(0, nested->getZeroPosition());
188 }
189
190 /*******************************************************************************/
192
195 void addToTapeValues(TapeValues& values) const {
196 size_t allocedSize = chunk.getSize();
197 size_t dataEntries = getDataSize();
198 size_t entrySize = Chunk::EntrySize;
199
200 double memoryUsed = (double)dataEntries * (double)entrySize;
201 double memoryAlloc = (double)allocedSize * (double)entrySize;
202
203 values.addUnsignedLongEntry("Total number", dataEntries);
204 values.addDoubleEntry("Memory used", memoryUsed, true, false);
205 values.addDoubleEntry("Memory allocated", memoryAlloc, false, true);
206 }
207
209 template<typename TargetPosition, typename = typename enable_if_not_same<TargetPosition, Position>::type>
210 CODI_INLINE TargetPosition extractPosition(Position const& pos) const {
211 return nested->template extractPosition<TargetPosition>(pos.inner);
212 }
213
215 template<typename TargetPosition, typename = typename enable_if_same<TargetPosition, Position>::type>
217 return pos;
218 }
219
222 // Set nested is only called once during the initialization.
223 codiAssert(nullptr == this->nested);
224 codiAssert(v->getZeroPosition() == v->getPosition());
225
226 this->nested = v;
227 }
228
231 chunk.swap(other.chunk);
232
233 nested->swap(*other.nested);
234 }
235
236 /*******************************************************************************/
238
240 template<int selectedDepth = -1, typename FunctionObject, typename... Args>
241 CODI_INLINE void evaluateForward(Position const& start, Position const& end, FunctionObject function,
242 Args&&... args) {
244 pHandle.setPointers(0, &chunk);
245
246 size_t dataPos = start.data;
247 pHandle.template callNestedForward<selectedDepth - 1>(
248 /* arguments for callNestedForward */
249 nested, dataPos, end.data,
250 /* arguments for nested->evaluateForward */
251 start.inner, end.inner, function, std::forward<Args>(args)...);
252
253 codiAssert(dataPos == end.data);
254 }
255
257 template<int selectedDepth = -1, typename FunctionObject, typename... Args>
258 CODI_INLINE void evaluateReverse(Position const& start, Position const& end, FunctionObject function,
259 Args&&... args) {
261
262 size_t dataPos = start.data;
263 pHandle.setPointers(0, &chunk);
264
265 pHandle.template callNestedReverse<selectedDepth - 1>(
266 /* arguments for callNestedReverse */
267 nested, dataPos, end.data,
268 /* arguments for nested->evaluateReverse */
269 start.inner, end.inner, function, std::forward<Args>(args)...);
270
271 codiAssert(dataPos == end.data);
272 }
273
275 template<typename FunctionObject, typename... Args>
276 CODI_INLINE void forEachChunk(FunctionObject& function, bool recursive, Args&&... args) {
277 function(&chunk, std::forward<Args>(args)...);
278
279 if (recursive) {
280 nested->forEachChunk(function, recursive, std::forward<Args>(args)...);
281 }
282 }
283
285 template<typename FunctionObject, typename... Args>
286 CODI_INLINE void forEachForward(Position const& start, Position const& end, FunctionObject function,
287 Args&&... args) {
288 codiAssert(start.data <= end.data);
289
290 PointerInserter pHandle;
291
292 for (size_t dataPos = start.data; dataPos < end.data; dataPos += 1) {
293 pHandle.setPointers(dataPos, &chunk);
294 pHandle.call(function, std::forward<Args>(args)...);
295 }
296 }
297
299 template<typename FunctionObject, typename... Args>
300 CODI_INLINE void forEachReverse(Position const& start, Position const& end, FunctionObject function,
301 Args&&... args) {
302 codiAssert(start.data >= end.data);
303
304 PointerInserter pHandle;
305
306 // We do not initialize dataPos with start - 1 since the type can be unsigned.
307 for (size_t dataPos = start.data; dataPos > end.data; /* decrement is done inside the loop */) {
308 dataPos -= 1; // Decrement of loop variable.
309
310 pHandle.setPointers(dataPos, &chunk);
311 pHandle.call(function, std::forward<Args>(args)...);
312 }
313 }
314 };
315
317 template<typename Chunk, typename NestedData = EmptyData>
319}
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition config.h:457
#define codiAssert(x)
See codi::Config::EnableAssert.
Definition config.h:432
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:94
#define CODI_T(...)
Abbreviation for CODI_TEMPLATE.
Definition macros.hpp:111
CoDiPack - Code Differentiation Package.
Definition codi.hpp:90
void CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition macros.hpp:46
Position with one index for e.g. array access.
Definition position.hpp:102
size_t data
Array position index.
Definition position.hpp:107
NestedPosition inner
Position of nested data.
Definition position.hpp:109
Data is stored in one contiguous block in this DataInterface implementation.
Definition blockData.hpp:64
InternalPosHandle reserveItems(size_t const &items)
Reserve this many items on the data stream. See pushData for details.
Definition blockData.hpp:122
void addDataSize(size_t size)
Add this many items to the data stream, after the data has been manipulated via pointers obtained fro...
Definition blockData.hpp:115
void erase(Position const &start, Position const &end, bool recursive=true)
Definition blockData.hpp:160
void forEachChunk(FunctionObject &function, bool recursive, Args &&... args)
Calls the function object for each continuous segment of data.
Definition blockData.hpp:276
typename NestedData::Position NestedPosition
Position of NestedData.
Definition blockData.hpp:72
BlockData(size_t const &chunkSize)
Allocate chunkSize entries. Requires a call to setNested.
Definition blockData.hpp:95
void resize(size_t const &totalSize)
Definition blockData.hpp:133
void evaluateReverse(Position const &start, Position const &end, FunctionObject function, Args &&... args)
Evaluates the function object with segments of continuous and valid data for all nested DataInterface...
Definition blockData.hpp:258
size_t InternalPosHandle
Position in the chunk.
Definition blockData.hpp:71
Position extractPosition(Position const &pos) const
Extract the position of a nested DataInterface from the global position object provide by this interf...
Definition blockData.hpp:216
T_PointerInserter PointerInserter
See BlockData.
Definition blockData.hpp:69
Position getPosition() const
Definition blockData.hpp:176
typename std::conditional< selectedDepth==0, TerminatingPointerStore< PointerInserter >, PointerInserter >::type NestingDepthPointerInserter
For selectedDepth == 0 create a pointer inserter that calls the function object.
Definition blockData.hpp:76
void swap(BlockData< Chunk, NestedData > &other)
Definition blockData.hpp:230
void evaluateForward(Position const &start, Position const &end, FunctionObject function, Args &&... args)
Evaluates the function object with segments of continuous and valid data for all nested DataInterface...
Definition blockData.hpp:241
void reset()
Definition blockData.hpp:138
ArrayPosition< NestedPosition > Position
Contains position data for this DataInterface and all nested interfaces.
Definition blockData.hpp:80
T_Chunk Chunk
See BlockData.
Definition blockData.hpp:67
T_NestedData NestedData
See BlockData.
Definition blockData.hpp:68
void setNested(NestedData *v)
Definition blockData.hpp:221
void resetHard()
Definition blockData.hpp:143
void getDataPointers(Data *&... pointers)
Get pointers to the data from the storage implementation. The method can only be called after a call ...
Definition blockData.hpp:109
void forEachReverse(Position const &start, Position const &end, FunctionObject function, Args &&... args)
Calls the function object for each item in the data stream. This call is not recursive.
Definition blockData.hpp:300
TargetPosition extractPosition(Position const &pos) const
Extract the position of a nested DataInterface from the global position object provide by this interf...
Definition blockData.hpp:210
void resetTo(Position const &pos)
Definition blockData.hpp:150
Position getZeroPosition() const
Definition blockData.hpp:186
size_t getPushedDataCount(InternalPosHandle const &startPos)
Definition blockData.hpp:181
void pushData(Data const &... data)
Add data to the storage allocated by the implementation. The method can only be called after a call t...
Definition blockData.hpp:102
void forEachForward(Position const &start, Position const &end, FunctionObject function, Args &&... args)
Calls the function object for each item in the data stream. This call is not recursive.
Definition blockData.hpp:286
void addToTapeValues(TapeValues &values) const
Add amount of stored data to the TapeValues object. Not called on the nested vector.
Definition blockData.hpp:195
size_t getDataSize() const
Definition blockData.hpp:171
BlockData(size_t const &chunkSize, NestedData *nested)
Allocate chunkSize entries and set the nested DataInterface.
Definition blockData.hpp:90
Definition chunk.hpp:185
Data stream interface for tape data. Encapsulates data that is written e.g. for each statement or arg...
Definition dataInterface.hpp:149
Inserts data pointers at the back of all arguments in the nested call hierarchy.
Definition pointerStore.hpp:72
Tape information that can be printed in a pretty print format or a table format.
Definition tapeValues.hpp:73
void addDoubleEntry(std::string const &name, double const &value, bool usedMem=false, bool allocatedMem=false)
Add double entry. If it is a memory entry, it should be in bytes.
Definition tapeValues.hpp:126
void addUnsignedLongEntry(std::string const &name, unsigned long const &value)
Add unsigned long entry.
Definition tapeValues.hpp:150