IBAMR  IBAMR version 0.19.
Public Types | Public Member Functions | List of all members
MDA_Access< MDA_TYPE, MDA_DIM, OrderType > Class Template Reference

Non-const multidimensional array access. More...

#include <MDA_Access.h>

Inheritance diagram for MDA_Access< MDA_TYPE, MDA_DIM, OrderType >:
Inheritance graph
[legend]

Public Types

typedef MDA_TYPE value_t
 Type of data. More...
 
typedef MDA_IndexRange< MDA_DIM > range_t
 
typedef range_t::dim_t dim_t
 
typedef range_t::index_t index_t
 
typedef OrderType order_t
 
typedef OrderType::reduced_order_t reduced_order_t
 

Public Member Functions

 MDA_Access (value_t *p=((value_t *) 0), const size_t *sz=((size_t *) 0), const index_t *st=((index_t *) 0))
 Constructor for setting all data, with default values. More...
 
 MDA_Access (value_t *p, const index_t *si, const index_t *sf)
 Constructor for setting all data, with default values. More...
 
 MDA_Access (value_t *p, const order_t &r)
 Constructor for specifying pointer and ordering object. More...
 
 MDA_Access (const MDA_Access &r)
 Copy constructor. More...
 
virtual ~MDA_Access ()
 Virtual destructor to support inheritance. More...
 
 operator bool () const
 Conversion into boolean. More...
 
 operator value_t * () const
 Conversion into pointer. More...
 
void setPointer (value_t *p)
 Set the data pointer. More...
 
void setSizeAndStart (const size_t *sz=((size_t *) 0), const index_t *st=((index_t *) 0))
 
void setInclusiveRange (const index_t first[MDA_DIM], const index_t final[MDA_DIM])
 
const range_tadjustDim (dim_t d, index_t first, index_t final)
 Adjust the dimensions. More...
 
Equivalence comparison
bool operator== (const MDA_Access &r) const
 

Inequivalence comparison

value_td_ptr
 Pointer to data. More...
 
value_td_ptr1
 Value of d_ptr-beg(0), used for optimizing 1D access. More...
 
order_t d_order
 Offset computing object. More...
 
bool operator!= (const MDA_Access &r) const
 
const range_trange () const
 
const index_tbeg (size_t i) const
 
const index_tend (size_t i) const
 
const size_t & size (size_t i) const
 
value_toperator() (const index_t i[MDA_DIM]) const
 Grant general access to item in an arbitrary dimensional array. More...
 
value_toperator() (index_t i0) const
 Grant general access to item in a 1D array. More...
 
value_toperator() (index_t i0, index_t i1) const
 Grant general access to item in a 2D array. More...
 
value_toperator() (index_t i0, index_t i1, index_t i2) const
 Grant general access to item in a 3D array. More...
 
value_toperator() (index_t i0, index_t i1, index_t i2, index_t i3) const
 Grant general access to item in a 4D array. More...
 
value_toperator[] (index_t i0) const
 Special case for 1D arrays, identical to operator(index_t), using pre-added fixed offsets. More...
 
MDA_Access< MDA_TYPE, OrderType::MDA_Reduced_DIM, typename OrderType::reduced_order_t > reduce (index_t i) const
 Fix the index of the slowest dimension and return the corresponding sub-array. More...
 
void setPtr1 ()
 

Detailed Description

template<class MDA_TYPE, unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
class MDA_Access< MDA_TYPE, MDA_DIM, OrderType >

This class never allocates or deallocates data. It takes pointers to preallocated data and provides an interface to that data. Member functions are used to give that interface.

This class provides functions for explicit index checking, but it does NO implicit error checking on either the dimensionality of the array or it size. Such may be done through subclassing.

The member functions should all be inlined for better performance.

This template class is set up to work with either row-major or column-major data, depending on the third template argument, which should be one of

  1. MDA_OrderRowMajor (default if omitted)
  2. MDA_OrderColMajor

The reduce() function return a new array of smaller dimensional that require less integer arithmetic to access individual array members. This should help in optimizing code. (My preliminary performance tests using gcc and gprof on i686 Linux showed that the MDA_Access functions run at half to slightly faster than the speed of Fortran, depending on use of reduced arrays. However, note that gcc is not great at optimizing Fortran.)

Member Typedef Documentation

◆ value_t

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
typedef MDA_TYPE MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::value_t

◆ range_t

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
typedef MDA_IndexRange<MDA_DIM> MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::range_t

◆ dim_t

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
typedef range_t::dim_t MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::dim_t

◆ index_t

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
typedef range_t::index_t MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::index_t

◆ order_t

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
typedef OrderType MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::order_t

◆ reduced_order_t

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
typedef OrderType::reduced_order_t MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::reduced_order_t

Constructor & Destructor Documentation

◆ MDA_Access() [1/4]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::MDA_Access ( value_t p = ((value_t*)0),
const size_t *  sz = ((size_t*)0),
const index_t st = ((index_t*)0) 
)
inline

Any pointers that are NULL are not used. The resulting default settings are:

  • Data pointer is NULL
  • Array sizes are 0
  • Array starting indices are 0

There is another constructor which accepts the first and final indices instead of the sizes and first indices. NOTE: the place of the initial indices is different than it is for the constructor taking final indices instead of sizes.

Parameters
pPointer to data
szArray sizes
stArray starting indices

◆ MDA_Access() [2/4]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::MDA_Access ( value_t p,
const index_t si,
const index_t sf 
)
inline

Any pointers that are NULL are not used. The resulting default settings are:

  • Data pointer is NULL
  • Array sizes are 0
  • Array starting indices are 0

This version takes two int* arguments, for the initial and final indices. It does not support default arguments until after the indices argument. NOTE: the place of the initial indices is different than it is for the constructor taking sizes instead of final indices.

If si is NULL, starting indices are set to 0. If sf is NULL, sizes are set to zero.

Parameters
pPointer to data
siArray of initial indices
sfArray of final indices

◆ MDA_Access() [3/4]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::MDA_Access ( value_t p,
const order_t r 
)
inline
Parameters
pPointer to data
rArray index object

◆ MDA_Access() [4/4]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::MDA_Access ( const MDA_Access< MDA_TYPE, MDA_DIM, OrderType > &  r)
inline
Parameters
rCopyee object

◆ ~MDA_Access()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
virtual MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::~MDA_Access ( )
inlinevirtual

Member Function Documentation

◆ operator bool()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator bool ( ) const
inline
Returns
true iff data pointer is not NULL.

◆ operator value_t *()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator value_t * ( ) const
inline
Returns
the data pointer.

◆ setPointer()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
void MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::setPointer ( value_t p)
inline
Parameters
pPointer value

◆ setSizeAndStart()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
void MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::setSizeAndStart ( const size_t *  sz = ((size_t*)0),
const index_t st = ((index_t*)0) 
)
inline

Set size and starting indices.

See also
MDA_IndexRange
Parameters
szArray sizes (NULL for no change)
stStarting indices (NULL for no change)

◆ setInclusiveRange()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
void MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::setInclusiveRange ( const index_t  first[MDA_DIM],
const index_t  final[MDA_DIM] 
)
inline

Set first and final indices (inclusive).

See also
MDA_IndexRange
Parameters
firstFirst valid indices (NULL for no change)
finalFinal valid indices (NULL for no change)

◆ adjustDim()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
const range_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::adjustDim ( dim_t  d,
index_t  first,
index_t  final 
)
inline
See also
MDA_IndexRange::adjustDim.
Parameters
dDimension to adjust
firstIncrement to first index
finalIncrement to final index

◆ operator==()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
bool MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator== ( const MDA_Access< MDA_TYPE, MDA_DIM, OrderType > &  r) const
inline

◆ operator!=()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
bool MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator!= ( const MDA_Access< MDA_TYPE, MDA_DIM, OrderType > &  r) const
inline

◆ range()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
const range_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::range ( ) const
inline

◆ beg()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
const index_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::beg ( size_t  i) const
inline

◆ end()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
const index_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::end ( size_t  i) const
inline

◆ size()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
const size_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::size ( size_t  i) const
inline

◆ operator()() [1/5]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
value_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator() ( const index_t  i[MDA_DIM]) const
inline

This is flexible but not efficient! You should use dimension-specific accesses whenever possible.

◆ operator()() [2/5]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
value_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator() ( index_t  i0) const
inline

◆ operator()() [3/5]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
value_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator() ( index_t  i0,
index_t  i1 
) const
inline

◆ operator()() [4/5]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
value_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator() ( index_t  i0,
index_t  i1,
index_t  i2 
) const
inline

◆ operator()() [5/5]

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
value_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator() ( index_t  i0,
index_t  i1,
index_t  i2,
index_t  i3 
) const
inline

◆ operator[]()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
value_t& MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::operator[] ( index_t  i0) const
inline

This may be more efficient than (i) but it only works in 1D. It is not guaranteed to work if the fixed offset is negative and has greater value than the pointer address, since the addition of the two gives a negative address, which the C standard leaves as undefined behavior.

◆ reduce()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
MDA_Access<MDA_TYPE,OrderType::MDA_Reduced_DIM,typename OrderType::reduced_order_t> MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::reduce ( index_t  i) const
inline

This function is meant to facilitate optimization when using this class. In nested loops, the inner loops executes many times with the indices corresponding to outer loops remaining constants. This leads to many many repeated integer arithmetics operations that could be removed from the inner loop (but may not be removed automatically by the compiler optimization). To do this, reduce the array dimensionality one dimension at a time, by fixing index corresponding to the slowest varying dimension. (If you code is written to maximize cache data, this will NOT be the index of the innermost loop.)

To reduce multiple dimensions, string these calls together, i.e. array.reduce(i).reduce(j). However, since reduction contains loops that cost O(MDA_DIM) and may be difficult for compilers to optimize, you may want to save array.reduce(i) and reuse it.

Parameters
iIndex in slowest dimension, which is the first dimension in a row-major array and the last dimension in a column-major array.
Returns
The sub-array of dimension MDA_DIM-1, corresponding to the index given.

◆ setPtr1()

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
void MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::setPtr1 ( )
inlineprivate

Member Data Documentation

◆ d_ptr

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
value_t* MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::d_ptr
private

◆ d_ptr1

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
value_t* MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::d_ptr1
private

The use of precomputed d_ptr1=d_ptr-beg(0) speeds up 1D offset computations by allowing us to compute d_ptr1+i0 instead of d_ptr+(i0-beg(0)), saving one integer subtraction for each 1D access. However, this could be a real problem if d_ptr<beg(0). So far, that has not happened, and we are keeping our fingers crossed.

See also
setPtr1()

◆ d_order

template<class MDA_TYPE , unsigned short MDA_DIM, class OrderType = MDA_OrderRowMajor<MDA_DIM>>
order_t MDA_Access< MDA_TYPE, MDA_DIM, OrderType >::d_order
private

The documentation for this class was generated from the following file: