Commit 7235169b authored by thomas.forbriger's avatar thomas.forbriger Committed by thomas.forbriger
Browse files

strided should work - hopefully

This is a legacy commit from before 2015-03-01.
It may be incomplete as well as inconsistent.
See COPYING.legacy and README.history for details.


SVN Path:     http://gpitrsvn.gpi.uni-karlsruhe.de/repos/TFSoftware/trunk
SVN Revision: 1188
SVN UUID:     67feda4a-a26e-11df-9d6e-31afc202ad0c
parent 04a23de1
......@@ -3,7 +3,7 @@
*
* ----------------------------------------------------------------------------
*
* $Id: rawarfun.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $
* $Id: rawarfun.h,v 1.3 2002-12-11 20:58:10 forbrig Exp $
* \author Thomas Forbriger
* \since 08/12/2002
*
......@@ -19,6 +19,7 @@
*
* REVISIONS and CHANGES
* - 08/12/2002 V1.0 copied from libcontxx
* - 11/12/2002 V1.1 introduced mixed type operatrions
*
* ============================================================================
*/
......@@ -27,9 +28,9 @@
#ifndef AFF_RAWARFUN_H_VERSION
#define AFF_RAWARFUN_H_VERSION \
"AFF_RAWARFUN_H V1.0 "
"AFF_RAWARFUN_H V1.1 "
#define AFF_RAWARFUN_H_CVSID \
"$Id: rawarfun.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $"
"$Id: rawarfun.h,v 1.3 2002-12-11 20:58:10 forbrig Exp $"
#include<aff/lib/types.h>
......@@ -139,6 +140,84 @@ namespace util {
{ return(A[0]); }
};
/*----------------------------------------------------------------------*/
//! Recursive functions to inline raw array operations.
template<typename T1, typename T2, int I>
class Inline2 {
public:
//! copy all values from source to target
static inline void copy(const T1* source, T2* target)
{
target[I-1]=source[I-1];
Inline<T1, T2,I-1>::copy(source, target);
}
//! set all elements to value
static inline void set(T1* array, const T2& value)
{
array[I-1]=value; Inline<T1, T2 ,I-1>::set(array, value);
}
//! true if ony of A is smaller than corresponding B
static inline bool anysmaller(const T1* A, const T2* B)
{
return (((*A) < (*B))
|| Inline<T1, T2, I-1>::anysmaller(&(A[1]), &(B[1])));
}
//! true if ony of A is larger than corresponding B
static inline bool anylarger(const T1* A, const T2* B)
{
return (((*A) > (*B))
|| Inline<T1, T2,I-1>::anylarger(&(A[1]), &(B[1])));
}
/*! \brief calculate inner product
*
* \param A \f$ A_l \f$
* \param B \f$ B_l \f$
* \return \f$ \sum\limits_{l=0}^{I-1}A_l\,B_l \f$
*/
static inline T1 innerproduct(const T1* A, const T2* B)
{
return(A[I-1]*B[I-1]+Inline<T1, T2, I-1>::innerproduct(A,B));
}
/*! \brief calculate stride product
*
* \param A \f$ A_l \f$
* \param B \f$ B_l \f$
* \return
* \f$
* A_{0}+\sum\limits_{l=1}^{I-1}
* \left(A_l\,\prod\limits_{k=0}^{l-1}B_k\right)
* =A_{0}+B_{0}\;(A_{1}+B_{1}\;(A_{2}+\ldots))
* \f$
*
* This is used to calculate offset values for the dense strided
* shape.
* \sa contxx::shape::DenseStrided
*/
static inline T1 strideproduct(const T1* A, const T2* B)
{
return((*A)+(*B)*Inline<T1, T2, I-1>::strideproduct(&(A[1]),&(B[1])));
}
};
//! Partial specialization to stop recursion.
template<typename T1, typename T2>
class Inline2<T1, T2, 1> {
public:
static inline void copy(const T1* source, T2* target)
{ target[0]=source[0]; }
static inline void set(T1* array, const T2& value)
{ array[0]=value; }
static inline bool anysmaller(const T1* A, const T2* B)
{ return (((*A) < (*B))); }
static inline bool anylarger(const T1* A, const T2* B)
{ return (((*A) > (*B))); }
static inline T1 innerproduct(const T1* A, const T2* B)
{ return(A[0]*B[0]); }
static inline T1 strideroduct(const T1* A, const T2* B)
{ return(A[0]); }
};
} // namespace util
#ifdef AFF_PREBUILT
......
......@@ -3,7 +3,7 @@
*
* ----------------------------------------------------------------------------
*
* $Id: simplearray.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $
* $Id: simplearray.h,v 1.3 2002-12-11 20:58:10 forbrig Exp $
* \author Thomas Forbriger
* \since 08/12/2002
*
......@@ -20,6 +20,7 @@
*
* REVISIONS and CHANGES
* - 08/12/2002 V1.0 copied from libcontxx
* - 11/12/2002 V1.1 introduced extra inner product for mixed types
*
* ============================================================================
*/
......@@ -28,9 +29,9 @@
#ifndef AFF_SIMPLEARRAY_H_VERSION
#define AFF_SIMPLEARRAY_H_VERSION \
"AFF_SIMPLEARRAY_H V1.0 "
"AFF_SIMPLEARRAY_H V1.1 "
#define AFF_SIMPLEARRAY_H_CVSID \
"$Id: simplearray.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $"
"$Id: simplearray.h,v 1.3 2002-12-11 20:58:10 forbrig Exp $"
#include<aff/lib/types.h>
#include<aff/lib/rawarfun.h>
......@@ -41,6 +42,12 @@ namespace aff {
namespace prebuilt {
#endif
#ifdef AFF_PREBUILT
using namespace aff::prebuilt::util;
#else
using namespace aff::util;
#endif
/*! \brief A very basic rigid array class (with deep inline copy).
*
* This class is intensively used by the array classes, in particular by the
......@@ -139,6 +146,12 @@ namespace prebuilt {
const SimpleRigidArray<T, N>& B)
{ return Inline<T, N>::innerproduct(A.pointer(), B.pointer()); }
//! Returns inner product
template<typename T1, typename T2, Tsize N>
inline T1 inline_innerproduct(const SimpleRigidArray<T1, N>& A,
const SimpleRigidArray<T2, N>& B)
{ return Inline2<T1, T2, N>::innerproduct(A.pointer(), B.pointer()); }
//! Returns strided product
template<typename T, Tsize N>
inline T inline_strideproduct(const SimpleRigidArray<T, N>& A,
......
......@@ -3,7 +3,7 @@
*
* ----------------------------------------------------------------------------
*
* $Id: strided.h,v 1.3 2002-12-10 19:56:02 forbrig Exp $
* $Id: strided.h,v 1.4 2002-12-11 20:58:11 forbrig Exp $
* \author Thomas Forbriger
* \since 08/12/2002
*
......@@ -21,6 +21,12 @@
*
* REVISIONS and CHANGES
* - 08/12/2002 V1.0 copied from libcontxx
* - 11/12/2002 V1.1 revision of this part of code (thof)
* - remove template parameter
* - replace by maximum dimensionality constant
* - does not need to know anything about stepper
* - introduced Mbase (is necessary for new concept of
* multidemensional arrays proposed by wolle)
*
* ============================================================================
*/
......@@ -29,14 +35,12 @@
#ifndef AFF_STRIDED_H_VERSION
#define AFF_STRIDED_H_VERSION \
"AFF_STRIDED_H V1.0 "
"AFF_STRIDED_H V1.1 "
#define AFF_STRIDED_H_CVSID \
"$Id: strided.h,v 1.3 2002-12-10 19:56:02 forbrig Exp $"
"$Id: strided.h,v 1.4 2002-12-11 20:58:11 forbrig Exp $"
#include<aff/lib/types.h>
#include<aff/lib/rawarfun.h>
#include<aff/lib/simplearray.h>
#include<aff/lib/stridedstepper.h>
namespace aff {
......@@ -44,11 +48,12 @@ namespace aff {
namespace prebuilt {
#endif
#ifdef AFF_PREBUILT
using namespace aff::prebuilt::util;
#else
using namespace aff::util;
#endif
// do we need this?
// #ifdef AFF_PREBUILT
// using namespace aff::prebuilt::util;
// #else
// using namespace aff::util;
// #endif
/*! \brief Shape for a rectangular array layout.
*
......@@ -61,57 +66,116 @@ namespace prebuilt {
*
* See contxx::shape::Shape for a description of the common interface for
* all shapes.
*
* \note
* dimension index is 0,1,2,... (zero-based) when calling size(i) member
* function e.g.
*
* \todo
* rework documentation of Strided
*
* \todo
* do we need using namespace util?
*/
template<Tdim N>
class Strided {
public:
//! type of stride array
typedef SimpleRigidArray<Tsize, N> Tstrides;
//! type of limit arrays
typedef SimpleRigidArray<Tsubscript, N> Tlimits;
//! type of Stepper class
typedef contxx::stepper::StridedStepper<Strided, N> Tstepper;
//! construct and initialize to zero
Strided(): Mstride(0), Mfirst(0), Msize(0), Moffset(0) { }
//! construct do given size and first index
Strided(const Tstrides& sizes, const Tsubscript& shift=0);
//! construct do given first and last index
Strided(const Tlimits& first, const Tlimits& last,
const Tsubscript& shift=0);
//! construct do given strides, first index, and size
Strided(const Tstrides& strides, const Tlimits& first,
const Tstrides& size, const Tsubscript& offset):
Mstride(strides), Mfirst(first), Msize(size), Moffset(offset) { }
//! first index of dimension
const Tsubscript& first(const Tsubscript& i) const
{ return Mfirst[i]; }
//! last index of dimension
Tsubscript last(const Tsubscript& i) const
{ return (Mfirst[i]+Msize[i]-1); }
//! size of dimension
const Tsize& size(const Tsubscript& i) const
{ return Msize[i]; }
//! total number of elements
Tsize size() const
{ return inline_product<Tsize, N>(Msize.pointer()); }
//! dimensionality
Tdim dimensionality() const { return N; }
//! index offset
const Tsubscript& offset() const { return Moffset; }
//! stride of dimension \par i
const Tsize& stride(const Tsubscript& i) const
{ return Mstride[i]; }
//! return a stepper
Tstepper stepper() const
{ return(Tstepper(Mfirst, Msize, Mstride, Moffset)); }
private:
Tstrides Mstride; //<! strides for each dimension
Tlimits Mfirst; //<! first index of each dimension
Tstrides Msize; //<! size of each dimension
Tsubscript Moffset; //<! total offset for indexing
};
class Strided {
public:
//! maximum dimensionality
static const Tdim Mmax_dimen=4;
//! type of size and stride array (always positive)
typedef SimpleRigidArray<Tsize, Mmax_dimen> TSizeVec;
//! type of limit arrays (any sign)
typedef SimpleRigidArray<Tsubscript, Mmax_dimen> TIndexVec;
//! construct and initialize to zero
Strided(): Mstride(0), Mfirst(0), Msize(0), Mbase(0), Moffset(0) { }
/*! \brief construct do given size and first index
*
* \param sizes vector defining index range size for each dimension
* \param first defines first index for each dimension
* \param shift defines offset shift (i.e. first element accessed in
* memory representation)
*/
Strided(const TSizeVec& sizes, const Tsubscript& first=1,
const Tsubscript& shift=0);
/*! \brief construct do given first and last index
*
* \param first vector of first index value in each dimension
* \param last vector of last index value in each dimension
* \param shift defines offset shift (i.e. first element accessed in
* memory representation)
*/
Strided(const TIndexVec& first, const TIndexVec& last,
const Tsubscript& shift=0);
/*! \brief construct do given strides, first index, and size
*
* The parameters set the shape vectors directly. This constructor is
* used mainly together with shapers, slicers and projectors...
*
* \param strides vector of strides for each dimension
* \param first vector of first index value in each dimension
* \param size vector of index range size for each dimension
* \param offset defines memory offset value
*/
Strided(const TSizeVec& strides, const TIndexVec& first,
const TSizeVec& size, const Tsubscript& offset);
//! total size of mapped memory range
Tsize memory_size() const
{ return (offset(Mlast)-offset(Mfirst)+1); }
//! total number of mapped elements
Tsize size() const
{ return inline_product(Msize); }
//! first index of dimension \par i
const Tsubscript& first(const Tsubscript& i) const
{ return Mfirst[i]; }
//! last index of dimension \par i
Tsubscript last(const Tsubscript& i) const
{ return (Mfirst[i]+Msize[i]-1); }
//! size of dimension \par i
const Tsize& size(const Tsubscript& i) const
{ return Msize[i]; }
//! stride of dimension \par i
const Tsize& stride(const Tsubscript& i) const
{ return Mstride[i]; }
//! full dimensionality access
inline
Tsubscript offset()(const TIndexVec& index) const
{ return(inner_product(index,Mstride)+Moffset); }
//! offset from 1 index value
inline
Tsubscript offset()(const Tsubscript& i0) const
{ return(i0*Mstride[0]+Mbase[0]); }
//! offset from 2 index values
inline
Tsubscript offset()(const Tsubscript& i0,
const Tsubscript& i1) const
{ return(i0*Mstride[0]+i1*Mstride[1]+Mbase[1]); }
//! offset from 3 index values
inline
Tsubscript offset()(const Tsubscript& i0,
const Tsubscript& i1,
const Tsubscript& i2) const
{ return(i0*Mstride[0]+i1*Mstride[1]+i2*Mstride[2]+Mbase[2]); }
//! offset from 4 index values
inline
Tsubscript offset()(const Tsubscript& i0,
const Tsubscript& i1,
const Tsubscript& i2,
const Tsubscript& i3) const
{ return(i0*Mstride[0]+i1*Mstride[1]+i2*Mstride[2]+
i3*Mstride[3]+Mbase[3]); }
private:
void calculate_base() const;
TSizeVec Mstride; //<! strides for each dimension
TIndexVec Mfirst; //<! first index of each dimension
TSizeVec Msize; //<! size of each dimension
TIndexVec Mbase; //<! base for each dimension (see index operators)
Tsubscript Moffset; //<! total offset for indexing
};
#ifdef AFF_PREBUILT
} // namespace prebuilt
......
......@@ -3,7 +3,7 @@
*
* ----------------------------------------------------------------------------
*
* $Id: strided_def.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $
* $Id: strided_def.h,v 1.3 2002-12-11 20:58:11 forbrig Exp $
* \author Thomas Forbriger
* \since 08/12/2002
*
......@@ -18,6 +18,10 @@
*
* REVISIONS and CHANGES
* - 08/12/2002 V1.0 copied from libcontxx
* - 11/12/2002 V1.1 major revision (thof)
* - removed template parameter
* - calculates base for index operator of
* each dimensionality
*
* ============================================================================
*/
......@@ -30,9 +34,9 @@
#ifndef AFF_STRIDED_DEF_H_VERSION
#define AFF_STRIDED_DEF_H_VERSION \
"AFF_STRIDED_DEF_H V1.0 "
"AFF_STRIDED_DEF_H V1.1 "
#define AFF_STRIDED_DEF_H_CVSID \
"$Id: strided_def.h,v 1.2 2002-12-08 22:33:54 forbrig Exp $"
"$Id: strided_def.h,v 1.3 2002-12-11 20:58:11 forbrig Exp $"
namespace aff {
......@@ -46,64 +50,53 @@ namespace prebuilt {
#endif
#endif
#ifdef AFF_PREBUILT
using namespace aff::prebuilt::util;
#else
using namespace aff::util;
#endif
//! instantiate static member (otherwise the linker won't find it)
const Tdim Strided::Mmax_dimen;
//! construct do given size and first index
template<Tdim N>
inline
Strided<N>::Strided(const Tstrides& sizes, const Tsubscript& shift)
{
Mfirst=0;
Msize=sizes;
Mstride[0]=1;
for(Tdim i=1; i<N; i++) { Mstride[i]=Mstride[i-1]*Msize[i-1]; }
Moffset=shift;
}
//! construct do given size and first index
template<>
inline
Strided<1>::Strided(const Tstrides& sizes, const Tsubscript& shift)
Strided::Strided(const TSizeVec& sizes, const Tsubscript& shift)
{
Mfirst=0;
Msize=sizes;
Mstride[0]=1;
for(Tdim i=1; i<Mmax_dimen; i++) { Mstride[i]=Mstride[i-1]*Msize[i-1]; }
Moffset=shift;
calculate_base();
}
//! construct do given first and last index
template<Tdim N>
inline
Strided<N>::Strided(const Tlimits& first, const Tlimits& last,
const Tsubscript& shift)
Strided::Strided(const TIndexVec& first, const TIndexVec& last,
const Tsubscript& shift)
{
Mfirst=first;
for(Tdim i=0; i<N; i++) { Msize[i]=last[i]-first[i]+1; }
for(Tdim i=0; i<Mmax_dimen; i++) { Msize[i]=last[i]-first[i]+1; }
Mstride[0]=1;
Moffset=-Mfirst[0];
for(Tdim i=1; i<N; i++)
for(Tdim i=1; i<Mmax_dimen; i++)
{
Mstride[i]=Mstride[i-1]*Msize[i-1];
Moffset-=Mfirst[i]*Mstride[i];
}
Moffset+=shift;
calculate_base();
}
//! construct from full layout information
Strided::Strided(const TSizeVec& strides, const TIndexVec& first,
const TSizeVec& size, const Tsubscript& offset):
Mstrides(strides), Mfirst(first), Msize(size), Mbase(0), Moffset(offset)
{
calculate_base();
}
//! construct do given first and last index
template<>
inline
Strided<1>::Strided(const Tlimits& first, const Tlimits& last,
const Tsubscript& shift)
void Strided::calculate_base() const
{
Mfirst=first;
Msize[0]=last[0]-first[0]+1;
Mstride[0]=1;
Moffset=-Mfirst[0];
Moffset+=shift;
Mbase[Mmax_dimen-1]=Moffset;
for (Tdim i=Mmax_dimen-1; i>0; i--)
{
Mbase[i-1]=Mbase[i]+Mfirst[i]*Mstride[i];
}
}
#ifdef AFF_PREBUILT
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment