Commit 120506ab authored by thomas.forbriger's avatar thomas.forbriger Committed by thomas.forbriger
Browse files

design concept with three classes per container;

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.
provide converters in converters.h


SVN Path:     http://gpitrsvn.gpi.uni-karlsruhe.de/repos/TFSoftware/branches/libfourier
SVN Revision: 3950
SVN UUID:     67feda4a-a26e-11df-9d6e-31afc202ad0c
parent b483b8b7
......@@ -168,6 +168,7 @@ its index is inherently set to the first index.
- \ref sec_design_interface_tcontainer
- \ref sec_design_interface_internals
- \ref sec_design_interface_nobaseclass
- \ref sec_design_threeclasses
- \ref sec_design_hierarchy
- \ref sec_design_replicated
- \ref sec_design_replicated_fact
......@@ -395,6 +396,32 @@ its index is inherently set to the first index.
code for each feature. Since we prefer \ref sec_design_interface_sparse this
method was rejected.
<HR>
\section sec_design_threeclasses Three classes for one container
One container class like aff::Array or aff::Series is made up from its class
definition together with two other classes like the representation in
aff::SharedHeap and a shape like aff::Strided or aff::LinearShape.
Why not put all this functionality within one class like aff::Array?
-# aff::Array and aff::Series are class templates because they shall be
provided for any element type the user desires.
Consequently for each element type in use a separate instantiation of
this template class must be compiled.
The code describing the shape of the memory layout and the way index
values to raw memory have to be calculated is completely independent from
the element type of the container.
The shapes code can be compiled once for all template instantiations
needed.
For this reason it is efficient to provide this code in a separate class.
-# The containers in this library use reference counted pointers to raw
memory.
This way they share data in memory.
The default way to copy containers is a shallow copy, where only a
reference is copied (see \ref page_representation).
Using a seperate class aff::SharedHeap to handle these reference counted
pointers allows us to share memory between containers of different types,
i.e. an aff::Series<T> and an aff::Array<T>.
<HR>
\section sec_design_hierarchy Class hierarchy: member data vs. inheritance
......
/*! \file seriesconnectors.h
* \brief some helpers to connect to a series container from other representations (prototypes)
/*! \file converters.h
* \brief converters for AFF containers
*
* ----------------------------------------------------------------------------
*
......@@ -7,7 +7,7 @@
* \author Thomas Forbriger
* \date 15/05/2011
*
* some helpers to connect to a series container from other representations (prototypes)
* converters for AFF containers
*
* Copyright (c) 2011 by Thomas Forbriger (BFO Schiltach)
*
......@@ -35,11 +35,11 @@
*/
// include guard
#ifndef AFF_SERIESCONNECTORS_H_VERSION
#ifndef AFF_CONVERTERS_H_VERSION
#define AFF_SERIESCONNECTORS_H_VERSION \
"AFF_SERIESCONNECTORS_H V1.0 "
#define AFF_SERIESCONNECTORS_H_CVSID \
#define AFF_CONVERTERS_H_VERSION \
"AFF_CONVERTERS_H V1.0 "
#define AFF_CONVERTERS_H_CVSID \
"$Id$"
#include<aff/array.h>
......@@ -48,8 +48,6 @@
namespace aff {
/*----------------------------------------------------------------------*/
/*! \brief create a series container from an array container.
*
* \ingroup group_series_extensions group_array_extensions
......@@ -57,8 +55,17 @@ namespace aff {
template<class T>
aff::Series<T> series_from_array(const aff::Array<T>& array)
{
AFF_assert(is_dense_1D_array(array),
typedef aff::Series<T> Tseries;
typedef aff::Array<T> Tarray;
typename Tarray::Tshape shape(array.shape());
AFF_assert(aff::util::is_dense_1D_array(shape),
"ERROR: array is not suitable to be converted to series");
typename Tseries::Trepresentation representation=array.representation();
typename Tseries::Tshape seriesshape(shape.first(0),
shape.last(0),
shape.first_offset());
Tseries retval(seriesshape, representation);
return retval;
} // aff::Series<T> series_from_array(const aff::Array<T>& array)
/*----------------------------------------------------------------------*/
......@@ -70,15 +77,26 @@ namespace aff {
template<class T>
aff::ConstSeries<T> series_from_array(const aff::ConstArray<T>& array)
{
AFF_assert(is_dense_1D_array(array),
typedef aff::ConstSeries<T> Tseries;
typedef aff::ConstArray<T> Tarray;
typename Tarray::Tshape shape(array.shape());
AFF_assert(aff::util::is_dense_1D_array(shape),
"ERROR: array is not suitable to be converted to series");
} // aff::Series<T> series_from_array(const aff::Array<T>& array)
typename Tseries::Trepresentation representation=array.representation();
typename Tseries::Tshape seriesshape(shape.first(0),
shape.last(0),
shape.first_offset());
Tseries retval(seriesshape, representation);
return retval;
} // aff::ConstSeries<T> series_from_array(const aff::ConstArray<T>& array)
/*----------------------------------------------------------------------*/
/*! \brief create an array container from a series container.
*
* \ingroup group_series_extensions group_array_extensions
* \todo
* implement aff::Array<T> array_from_series(const aff::Series<T>& array)
*/
template<class T>
aff::Array<T> array_from_series(const aff::Series<T>& array)
......@@ -91,6 +109,8 @@ namespace aff {
/*! \brief create an array container from a series container.
*
* \ingroup group_series_extensions group_array_extensions
* \todo
* implement aff::ConstArray<T> array_from_series(const aff::ConstSeries<T>& array)
*/
template<class T>
aff::ConstArray<T> array_from_series(const aff::ConstSeries<T>& array)
......@@ -119,8 +139,109 @@ namespace aff {
return(retval);
} // aff::Series<T> series_from_raw_memory
/*----------------------------------------------------------------------*/
/*! \brief access Series contents through raw memory
*
* \ingroup group_series_extensions
*/
template<class T>
class CSeries {
public:
/*! \name Various types
*
* In particular due to our concept of const-correctness we need
* several typedefs to declare types derived from the element type of
* the array.
*
* \sa \ref sec_design_interface_typedef
* \sa \ref sec_design_const
*/
//@{
//! Type of array to be interfaced
typedef aff::Series<T> Tseries;
//! Type of representation
typedef typename Tseries::Trepresentation Trepresentation;
//! Type of shape
typedef typename Tseries::Tshape Tshape;
//! Element type
typedef typename Tseries::Tvalue Tvalue;
//! Type of pointer to element
typedef typename Tseries::Tpointer Tpointer;
//! Type of reference to element
typedef typename Tseries::Treference Treference;
//! const element type
typedef typename Tseries::Tconst_value Tconst_value;
//! Type of pointer to const element
typedef typename Tseries::Tconst_pointer Tconst_pointer;
//! Type of reference to const element
typedef typename Tseries::Tconst_reference Tconst_reference;
//! Type of this array
typedef CSeries<T> Tcontainer;
//@}
/*-----------------------------------------------------------------*/
/*! \name Constructors
*
* No copy constructors or copy operators are provided since this is
* provided as an interface class only.
*/
//@{
//! construct from shape and representation
CSeries(const Tseries& series)
: Mrepresentation(series.representation())
{
Tshape shape=series.shape();
Moffset=shape.offset(shape.first());
Msize=shape.size();
}
//@}
/*------------------------------------------------------------------*/
/*! \name Shape access
*/
//@{
//! size of dimension \par i
const Tsize& size() const
{ return (Msize); }
//@}
/*-----------------------------------------------------------------*/
/*! \name Memory access
*
*/
//@{
//! return pointer to first element in Fortran layout
Tpointer pointer() const
{ return(&Mrepresentation[Moffset]); }
/*! \brief return type-casted pointer to first element in Fortran
* layout
*
* The cast checks for const-correctness and type-size. But you have
* to ensure that there is a meaningful relation between both types
* involved.
*
* \sa aff::util::SizeCheckedCast
*/
template<class TT>
TT* castedpointer() const
{ return(SizeCheckedCast<Tvalue,TT>::cast(this->pointer())); }
//@}
private:
//! representation member
Trepresentation Mrepresentation;
//! sizes of series
aff::Tsize Msize;
//! offset of memory location of first element
aff::Tsize Moffset;
}; // class CSeries
} // namespace aff
#endif // AFF_SERIESCONNECTORS_H_VERSION (includeguard)
#endif // AFF_CONVERTERS_H_VERSION (includeguard)
/* ----- END OF seriesconnectors.h ----- */
/* ----- END OF converters.h ----- */
......@@ -51,12 +51,14 @@
* - essential correction in collapse
* - 29/12/2002 V1.7 (thof)
* - now provides basic Fortran style constructor
* - 15/05/2011 V1.8 (thof)
* - added dense 1D array check
*
* ============================================================================
*/
#define AFF_STRIDED_CC_VERSION \
"AFF_STRIDED_DEF_H V1.7"
"AFF_STRIDED_DEF_H V1.8"
#define AFF_STRIDED_CC_CVSID \
"$Id$"
......@@ -298,6 +300,18 @@ namespace aff {
return(this->shift(ishift));
}
/*======================================================================*/
bool aff::util::is_dense_1D_array(const aff::Strided& shape)
{
bool retval
=((shape.size(1)==1)
&& (shape.size(2)==1)
&& (shape.size(3)==1)
&& (shape.stride(0)==1));
return retval;
} // bool is_dense_1D_array(const aff::Strided& shape)
} // namespace aff
/* ----- END OF strided.cc ----- */
......@@ -59,6 +59,8 @@
* - typedef Tstepper
* - 29/12/2002 V1.7 (thof)
* - now provides basic Fortran style constructor
* - 15/05/2011 V1.8 (thof)
* - added dense 1D array check
*
* ============================================================================
*/
......@@ -67,7 +69,7 @@
#ifndef AFF_STRIDED_H_VERSION
#define AFF_STRIDED_H_VERSION \
"AFF_STRIDED_H V1.7"
"AFF_STRIDED_H V1.8"
#define AFF_STRIDED_H_CVSID \
"$Id$"
......@@ -290,6 +292,22 @@ namespace aff {
TIndexVec Mbase; //<! base for each dimension (see index operators)
};
/*======================================================================*/
// helper functions
namespace util {
/*! \brief check whether array shape describes a 1D array with dense
* layout in the memory.
*
* \ingroup group_array_extensions
* \param shape array shape
* \return true if shape is dense and 1D
*/
bool is_dense_1D_array(const aff::Strided& shape);
} // namespace util
} // namespace aff
#endif // AFF_STRIDED_H_VERSION (includeguard)
......
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