Data stream interface for tape data. Encapsulates data that is written e.g. for each statement or argument. More...
#include <dataInterface.hpp>
Public Types | |
using | InternalPosHandle = T_InternalPosHandle |
See DataInterface. | |
using | NestedData = T_NestedData |
See DataInterface. | |
using | Position = EmptyPosition |
Contains position data for this DataInterface and all nested interfaces. | |
Public Member Functions | |
Adding items | |
void | addDataSize (size_t const &size) |
Add this many items to the data stream, after the data has been manipulated via pointers obtained from getDataPointers(). | |
template<typename... Data> | |
void | getDataPointers (Data *&... pointers) |
Get pointers to the data from the storage implementation. The method can only be called after a call to reserveItems() and data can only be accessed from 0 to the number given by reserveItems (excluding). Afterwards, addDataSize() needs to be called with the actual number of elements that have been written. | |
template<typename... Data> | |
void | pushData (Data const &... data) |
Add data to the storage allocated by the implementation. The method can only be called after a call to reserveItems and only as often as the number of reserved items. | |
InternalPosHandle | reserveItems (size_t const &items) |
Reserve this many items on the data stream. See pushData for details. | |
Size management | |
void | resize (size_t const &totalSize) |
void | reset () |
void | resetHard () |
void | resetTo (Position const &pos) |
void | erase (Position const &start, Position const &end, bool recursive=true) |
Position functions | |
size_t | getDataSize () const |
Position | getPosition () const |
size_t | getPushedDataCount (InternalPosHandle const &startPos) |
Position | getZeroPosition () const |
Misc functions | |
void | addToTapeValues (TapeValues &values) const |
Add amount of stored data to the TapeValues object. Not called on the nested vector. | |
template<typename TargetPosition > | |
TargetPosition | extractPosition (Position const &pos) const |
Extract the position of a nested DataInterface from the global position object provide by this interface. | |
void | setNested (NestedData *v) |
void | swap (DataInterface &other) |
Iterator functions | |
template<int selectedDepth = -1, typename FunctionObject , typename... Args> | |
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 DataInterfaces. | |
template<int selectedDepth = -1, typename FunctionObject , typename... Args> | |
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 DataInterfaces. | |
template<typename FunctionObject , typename... Args> | |
void | forEachChunk (FunctionObject &function, bool recursive, Args &&... args) |
Calls the function object for each continuous segment of data. | |
template<typename FunctionObject , typename... Args> | |
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. | |
template<typename FunctionObject , typename... Args> | |
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. | |
Data stream interface for tape data. Encapsulates data that is written e.g. for each statement or argument.
This interface defines the basic abstraction mechanism of how data is stored in an AD tape. During the recording of an AD tape, different types of data with a varying amount of items need to be stored and associated with each other. There is e.g. data for each statement and data for each argument. Each DataInterface covers one type of data. The management of multiple data streams can become quite cumbersome, therefore the DataInterface is designed in a recursive fashion. Each data stream can be nested with another data stream such that they can exchange position information and synchronize themselves.
Note that the recursive implementation is only that - an implementation. The data itself is not recursive. Think about is as multiple streams of associated data that grow alongside each other in varying speeds.
The * mark the current joint position of the streams (end of the last pushed batch of data). A new batch of associated data is now appended to the streams.
A data item on the data stream can consist of multiple entries, e.g., a data entry can be an int or it can be an int and a double. The underlying implementation defines how this data is stored, e.g. as an array of objects or as an object of arrays. For counting the number of items, each call to pushData() counts as one item regardless of how many entries each item has.
The getPosition() function produces a position for this DataInterface and all nested DataInterfaces. All methods that have the Position type as an argument or modify the position of the DataInterface work recursively on all nested DataInterfaces.
How the data is stored and allocated is determined by the actual implementation of this interface.
See Example tape implementation with CoDiPack for a usage of this interface.
Example usage:
For an example on how to use getDataPointers please see the method documentation.
The interface defines methods for adding data to the data stream, getting positional information, resetting the data and iterating over the data.
Adding data:
Positional information:
Reset:
Iterating:
T_NestedData | Nested data vector needs to implement this DataInterface. |
T_InternalPosHandle | Position handle of the the implementing class for internal size computations. |
|
inline |
Add this many items to the data stream, after the data has been manipulated via pointers obtained from getDataPointers().
See getDataPointers for details.
[in] | size | Number of data items that have been written. |
void codi::DataInterface< T_NestedData, T_InternalPosHandle >::addToTapeValues | ( | TapeValues & | values | ) | const |
Add amount of stored data to the TapeValues object. Not called on the nested vector.
[in,out] | values | Will only create new data entries and no new section. |
void codi::DataInterface< T_NestedData, T_InternalPosHandle >::erase | ( | Position const & | start, |
Position const & | end, | ||
bool | recursive = true ) |
Erase the given range of data. Implementations may choose to free allocated memory. The parameter recursive controls whether erase is also called on nested interfaces.
|
inline |
Evaluates the function object with segments of continuous and valid data for all nested DataInterfaces.
func is called for each region of continuous data that is valid for all nested DataInterfaces. func is then called as
What kind of data is appended by each DataInterface is implementation dependent. The default is the set (start, end, dataEntry1, dataEntry2, etc.) which is appended.
It has to hold start <= end.
Positions count up in this call.
[in] | start | Starting position. |
[in] | end | Ending position. |
[in] | function | Function object called. |
[in,out] | args | Additional arguments for the function object. |
selectedDepth | Selected depth for the recursion into nested data interfaces. 0 means that only the data from this interface is used. A value of 1 means that the data from the first nested interface is used, etc.. A value of -1 can be used to select the innermost interface, regardless of the number of nested interfaces. |
FunctionObject | Function object which is called. |
Args | Arguments for the function object. |
|
inline |
Evaluates the function object with segments of continuous and valid data for all nested DataInterfaces.
Same as evaluateForward. It has to hold start >= end. Positions count down in this call.
[in] | start | Starting position. |
[in] | end | Ending position. |
[in] | function | Function object called. |
[in,out] | args | Additional arguments for the function object. |
selectedDepth | Selected depth for the recursion into nested data interfaces. 0 means that only the data from this interface is used. A value of 1 means that the data from the first nested interface is used, etc.. A value of -1 can be used to select the innermost interface, regardless of the number of nested interfaces. |
FunctionObject | Function object which is called. |
Args | Arguments for the function object. |
|
inline |
Extract the position of a nested DataInterface from the global position object provide by this interface.
[in] | pos | Position of the DataInterface. |
TargetPosition | Position definition of a nested DataInterface. |
|
inline |
Calls the function object for each continuous segment of data.
The call is
Chunk is of the type ChunkBase.
[in] | function | Function object called. |
[in] | recursive | True if same call should be performed for all nested DataInterfaces. |
[in,out] | args | Additional arguments for the function object. |
FunctionObject | Function object which is called. |
Args | Arguments for the function object. |
|
inline |
Calls the function object for each item in the data stream. This call is not recursive.
The call to function is
It has to hold start <= end.
[in] | start | Starting position. |
[in] | end | Ending position |
[in] | function | Function object called. |
[in,out] | args | Additional arguments for the function object. |
FunctionObject | Function object which is called. |
Args | Arguments for the function object. |
|
inline |
Calls the function object for each item in the data stream. This call is not recursive.
See forEachForward.
It has to hold start >= end.
[in] | start | Starting position. |
[in] | end | Ending position |
[in] | function | Function object called. |
[in,out] | args | Additional arguments for the function object. |
FunctionObject | Function object which is called. |
Args | Arguments for the function object. |
|
inline |
Get pointers to the data from the storage implementation. The method can only be called after a call to reserveItems() and data can only be accessed from 0 to the number given by reserveItems (excluding). Afterwards, addDataSize() needs to be called with the actual number of elements that have been written.
The call to reserveItems only represents the maximum number of data items that can be accessed safely. It is fine if less data items are accessed.
After all elements have been written to the arrays, addDataSize needs to be called with the final written number of entries.
Example usage:
[in] | pointers | The pointers that are populated with the data from the internal representation. |
Data | Types of the pointers. |
|
inline |
|
inline |
|
inline |
Compute the number of data items stored after a call to reserveItems.
|
inline |
|
inline |
Add data to the storage allocated by the implementation. The method can only be called after a call to reserveItems and only as often as the number of reserved items.
pushData() can be called less often than indicated with reserveItems(). The call to reserveItems only represents the maximum number of data items that can be pushed safely.
After a new call to reserveItems(), only this many number of data items can be pushed, leftovers will not accumulate.
For an example of how to use pushData, please see the DataInterface documentation.
[in] | data | The number of arguments has to match the number of data stores of the implementation. |
Data | Types of the pushed data. |
|
inline |
Reserve this many items on the data stream. See pushData for details.
[in] | items | Number of data items to reserve. |
void codi::DataInterface< T_NestedData, T_InternalPosHandle >::reset | ( | ) |
Reset to the zero position. Data is not deallocated. Also called on nested interfaces.
void codi::DataInterface< T_NestedData, T_InternalPosHandle >::resetHard | ( | ) |
Reset to the zero position. Data is deallocated and the default size is allocated again. Also called on nested interfaces.
void codi::DataInterface< T_NestedData, T_InternalPosHandle >::resetTo | ( | Position const & | pos | ) |
Reset to the given position. Data is not deallocated. Also called on the nested interfaces.
void codi::DataInterface< T_NestedData, T_InternalPosHandle >::resize | ( | size_t const & | totalSize | ) |
Allocate the requested number of data items.
void codi::DataInterface< T_NestedData, T_InternalPosHandle >::setNested | ( | NestedData * | v | ) |
Set the pointer to the nested vector. Needs to be done before any other action and only once.
void codi::DataInterface< T_NestedData, T_InternalPosHandle >::swap | ( | DataInterface< T_NestedData, T_InternalPosHandle > & | other | ) |
Swap with other DataInterface of the same type.