Commit 0689b37c authored by thomas.forbriger's avatar thomas.forbriger Committed by thomas.forbriger
Browse files

commited code from branch branches/libfourier

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.
contains:
new access module for array in libaff
new array fftw engine in libfourierxx


SVN Path:     http://gpitrsvn.gpi.uni-karlsruhe.de/repos/TFSoftware/trunk
SVN Revision: 3957
SVN UUID:     67feda4a-a26e-11df-9d6e-31afc202ad0c
parents a41c7fa5 568052e6
/*! \file Carray.h
* \brief classes to interface raw C arrays (prototypes)
*
* ----------------------------------------------------------------------------
*
* $Id$
* \author Thomas Forbriger
* \date 14/05/2011
*
* classes to interface raw C arrays (prototypes)
*
* Copyright (c) 2011 by Thomas Forbriger (BFO Schiltach)
*
* ----
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* ----
*
*
* REVISIONS and CHANGES
* - 14/05/2011 V1.0 Thomas Forbriger
*
* ============================================================================
*/
// include guard
#ifndef AFF_CARRAY_H_VERSION
#define AFF_CARRAY_H_VERSION \
"AFF_CARRAY_H V1.0 "
#define AFF_CARRAY_H_CVSID \
"$Id$"
#include<aff/array.h>
#include<aff/lib/checkedcast.h>
namespace aff {
/*! \brief Interface class to raw memory (C style array)
*
* This class together with aff::CArray is provided as an interface for
* users which have to provide the contents of an array through raw memory
* pointers in C style.
* Both classes take an aff::ConstArray or aff::Array instance respectively
* as an argument for their constructor.
* They provide a pointer to raw memory through their member functions
* pointer() and castedpointer().
* If a pointer \c p to the raw memeory behind \c array is defined by
* \code
* aff::Array<T> array;
* aff::CArray<T> carray(array);
* T* p=carray.pointer();
* \endcode
* then the array element \c array(i0,i1,i2,i3) is addressed by
* \code
* p[i0*s0+i1*s1+i2*s2+i3*s3]
* \endcode
* where the index value ranges are
* - \c i0=0,1,... \c n0-1
* - \c i1=0,1,... \c n1-1
* - \c i2=0,1,... \c n2-1
* - \c i3=0,1,... \c n3-1
*
* and
* - \c n0=carray.size(0)
* - \c n1=carray.size(1)
* - \c n2=carray.size(2)
* - \c n3=carray.size(3)
*
* and
* - \c s0=carray.stride(0)
* - \c s1=carray.stride(1)
* - \c s2=carray.stride(2)
* - \c s3=carray.stride(3)
*
* \note
* The pointers passed by the access functions of this class are (certainly)
* not reference counted.
* Make sure to keep an instance of one of the arrays maintining the
* underlying memory allocation as long as these pointers are in use.
*
* \sa helpertest.cc
*/
template<class T>
class ConstCArray
{
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 ConstArray<T> Tarray;
//! Type of representation
typedef typename Tarray::Trepresentation Trepresentation;
//! Type of shape
typedef typename Tarray::Tshape Tshape;
//! we use this for one of the access operators
typedef typename Tshape::TSizeVec TSizeVec;
//! Element type
typedef typename Tarray::Tvalue Tvalue;
//! Type of pointer to element
typedef typename Tarray::Tpointer Tpointer;
//! Type of reference to element
typedef typename Tarray::Treference Treference;
//! const element type
typedef typename Tarray::Tconst_value Tconst_value;
//! Type of pointer to const element
typedef typename Tarray::Tconst_pointer Tconst_pointer;
//! Type of reference to const element
typedef typename Tarray::Tconst_reference Tconst_reference;
//! Type of this array
typedef ConstCArray<T> Tcontainer;
//! Type of the array of const values
typedef Tcontainer Tcontainer_of_const;
//! Short for Tcontainer_of_const
typedef Tcontainer Tcoc;
//@}
/*-----------------------------------------------------------------*/
/*! \name Constructors
*
* No copy constructors or copy operators are provided since this is
* provided as an interface class only.
*/
//@{
//! construct from shape and representation
ConstCArray(const Tarray& array)
: Mrepresentation(array.representation())
{
Tshape shape=array.shape();
// index range is zero based
shape.setfirst(typename Tshape::TIndexVec(0));
// offset to first element in represented memory
Moffset=shape.first_offset();
// strides
Mstride=shape.stride();
// sizes
Msize=shape.last();
for (unsigned i=0; i<Msize.size(); ++i)
{
++Msize[i];
}
}
//@}
/*------------------------------------------------------------------*/
/*! \name Shape access
*/
//@{
//! 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]; }
//! size of dimensions
const TSizeVec& size() const
{ return (Msize); }
//! strides of dimensions
const TSizeVec& stride() const
{ return Mstride; }
//@}
/*-----------------------------------------------------------------*/
/*! \name Memory access
*
*/
//@{
//! return pointer to first element in Fortran layout
Tconst_pointer pointer() const
{ return(&Mrepresentation[this->offset()]); }
/*! \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<Tconst_value,TT>::cast(this->pointer())); }
//@}
protected:
//! pass offset to derived class
const typename TSizeVec::Tvalue& offset() const { return Moffset; }
private:
//! representation member
Trepresentation Mrepresentation;
//! sizes of dimensions
TSizeVec Msize;
//! strides of dimensions
TSizeVec Mstride;
//! offset to first index
typename TSizeVec::Tvalue Moffset;
}; // class ConstCArray
/*======================================================================*/
/*! \brief Interface class to raw memory (C style array)
*
* See aff::ConstCArray for the basic concepts used here.
*
* \sa aff::ConstCArray
*/
template<class T>
class CArray:
public ConstCArray<T>
{
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::Array<T> Tarray;
//! Base class
typedef aff::ConstCArray<T> Tbase;
//! Type of representation
typedef typename Tarray::Trepresentation Trepresentation;
//! Type of shape
typedef typename Tarray::Tshape Tshape;
//! we use this for one of the access operators
typedef typename Tshape::TSizeVec TSizeVec;
//! Element type
typedef typename Tarray::Tvalue Tvalue;
//! Type of pointer to element
typedef typename Tarray::Tpointer Tpointer;
//! Type of reference to element
typedef typename Tarray::Treference Treference;
//! const element type
typedef typename Tarray::Tconst_value Tconst_value;
//! Type of pointer to const element
typedef typename Tarray::Tconst_pointer Tconst_pointer;
//! Type of reference to const element
typedef typename Tarray::Tconst_reference Tconst_reference;
//! Type of this array
typedef CArray<T> Tcontainer;
//! Type of the array of const values
typedef Tbase Tcontainer_of_const;
//! Short for Tcontainer_of_const
typedef Tcontainer Tcoc;
//@}
/*-----------------------------------------------------------------*/
/*! \name Constructors
*
* No copy constructors or copy operators are provided since this is
* provided as an interface class only.
*/
//@{
//! construct from shape and representation
CArray(const Tarray& array)
: Tbase(array), Mrepresentation(array.representation())
{ }
//@}
/*-----------------------------------------------------------------*/
/*! \name Memory access
*
*/
//@{
//! return pointer to first element in Fortran layout
Tpointer pointer() const
{ return(&Mrepresentation[this->offset()]); }
/*! \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:
//! my (mutable) data representation
Trepresentation Mrepresentation;
}; // class CArray
} // namespace aff
#endif // AFF_CARRAY_H_VERSION (includeguard)
/* ----- END OF Carray.h ----- */
......@@ -101,11 +101,11 @@ HEADERS=$(shell find . -name \*.h)
# (see below for the configuration of a preinstantiated version of template
# code)
SRC=lib/error.cc dump.cc lib/strided.cc lib/stridedstepper.cc \
lib/seriesstepper.cc fortranshape.cc
lib/seriesstepper.cc fortranshape.cc
# test programs are placed in a subdirectory
TESTS=$(wildcard tests/*.cc)
# whereever we find a README, we will use it
README=$(shell find . -name README) README.changelog
README=$(shell find . -name README) README.changelog README.groups
# place where we will copy header files
INCINSTALLPATH=$(LOCINCLUDEDIR)/aff
......
......@@ -50,6 +50,11 @@
* - 10/11/2010 V1.6 (thof)
* - code fragments for precompiled templates are
* removed from the library (\ref sec_design_binary)
* - 14/05/2011 V1.7 (thof)
* - add info on raw-major and column-major order
* - 15/05/2011 V1.8 (thof)
* - reordered documentation, movde modules to
* README.groups
*
* ============================================================================
*/
......@@ -77,20 +82,19 @@ $Id$
Contents of this page:
- \ref sec_main_aims
- \ref sec_main_modules
- \ref sec_main_modules_basic
- \ref sec_main_modules_extended
- \ref sec_main_need
- \ref sec_main_peculiar
- \ref sec_main_modules
Additional information:
- \ref page_design
- \ref page_changelog
- \ref page_project_status
- \ref page_using
- \ref page_notes
- \ref page_array_layout
- \ref page_design
- \ref page_naming
- \ref page_representation
- \ref page_fortran
- \ref page_changelog
- \ref page_project_status
\section sec_main_aims Aims of the library
......@@ -103,93 +107,54 @@ $Id$
module to the other. If you want to exploit the power of expression
templates, pass the array contents to something like Blitz++.
\sa \ref sec_notes_need
\section sec_main_modules Modules of the library
The main module is the array class aff::Array. It provides basic
functionality through its interface. See the explanation there.
It is presented in aff/array.h
The object code is placed in libaff.a.
Contents of this page:
\subsection sec_main_modules_basic Basic array modules
By including aff/array.h you will get access to the following modules:
-# aff::Array is the main array interface (see example tests/arraytest.cc).
-# aff::Strided is the shape of a strided Fortran array and defines the
memory layout of aff::Array objects (see example
tests/shapetest.cc).
-# aff::SharedHeap is the representation used by aff::Array. It holds the
data in memory and provides an interface to it. This interface
may be passed separately from the array object (see also
\ref page_representation and example tests/reprtest.cc).
-# aff::SimpleRigidArray is a linear array with size fixed at compile-time.
There are several inline functions defined for operations with
this array class (see example tests/simplearraytest.cc).
-# aff::Exception is the exception base class used in the library.
-# aff::AllocException is the exception that indicated a failed memory
allocation(see also \ref group_error).
It additionally offers the following type definitions:
-# aff::Tsubscript is the type of subscripts to arrays (positive and
negative).
-# aff::Tsize is the type of size values (non-negative).
-# aff::Tdim is the type of the dimension index (small, non-negative).
\subsection sec_main_modules_extended Extensions
The library provides some additional modules. You need only include the
header file of those modules that you really want to use in addition to the
basic aff::Array functionality.
These additional modules are:
-# aff::Shaper presented in aff/shaper.h and used to pass Fortran layouts
to array constructors (see example tests/shapetest.cc).
-# aff::Series presented in aff/series.h which is used to interface linear
sequences of data (like time series or Fourier coefficients).
-# aff::Iterator presented in aff/iterator.h which is an iterator interface
to containers like aff::Array or aff::Series (see example
tests/helpertest.cc).
-# aff::subarray presented in aff/subarray.h to conveniently create
subarrays from aff::Array objects (see example
tests/helpertest.cc).
-# aff::slice presented in aff/slice.h to conveniently create
slices from aff::Array objects (see example
tests/helpertest.cc).
-# aff::FortranArray and its associate aff::util::FortranShape are presented
in aff/fortranshape.h. They calculate a Fortran 77 array
layout (leading dimensions) from a given AFF array (see
example tests/f77test.cc).
-# aff::dump and its associates, presented in aff/dump.h. They are used to
dump shape or contents of containers and are thus useful when
debugging your code. See also \ref group_helpers.
\sa \ref sec_design_namespaces
\sa \ref sec_naming_files
\section sec_main_peculiar Peculiarities
\section sec_main_peculiar Peculiarities of AFF
\par Containers use counted references
All containers (e.g. aff::Array, aff::Series) use counted references to access
global memory. Assigning one container object to another just assigns the
reference. Both will use the same data in memory afterwards.
See also \ref page_representation.
\sa \ref page_representation.
\par Const-correctness for array elements
In this library we follow provide functionality to write const-correct code
with regard to the array container and with regard to its element values.
See also \ref sec_design_const.
\sa \ref sec_design_const.
\par Multidimensional arrays
Every aff::Array of this class has aff::Strided::Mmax_dimen dimensions.
Construction and access for lower dimensionality is provided. In the case of
using less dimensions, the size of the unused dimensions is 1 by default and
its index is inherently set to the first index.
See also \ref sec_design_multidimensional.
\sa \ref sec_design_multidimensional.
\section sec_main_need Why do we need this array library
One major reason for replacing Fortran77 by C++ in numerical code is the
convenience in expressing logistics. Data of different type and size may be
packed into classes and encapsulated from the outside world. Most numerical
results are to be stored in arrays, multi-dimensional arrays in particular.
This library provides the basic functionality for storing many data of the
same type in memory, passing them around between subroutines in an efficient
way and accessing them through convenient interfaces. The main purpose of
this library is not calculation but managing (passing between program
modules, selection of subsets of the data) large amounts of numbers. In the
future it might provide interfaces to libraries like blitz++ for finite
difference calculations, MTL for linear algebra calculations, and POOMA for
parallel computations.
\sa http://www.sophya.org/, http://www.boost.org
\section sec_main_modules Modules of the library
The main module is the array class aff::Array. It provides basic
functionality through its interface. See the explanation there.
It is presented in aff/array.h
The object code is placed in libaff.a.
\sa \ref group_array, \ref group_array_extensions
*/
/*======================================================================*/
......@@ -203,6 +168,7 @@ See also \ref sec_design_multidimensional.
- \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
......@@ -430,6 +396,32 @@ See also \ref sec_design_multidimensional.
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
......@@ -859,30 +851,6 @@ We need more text and examples.
*/
/*======================================================================*/
/*! \page page_notes General notes
Contents of this page:
- \ref sec_notes_need
\section sec_notes_need The need of an array library
One major reason for replacing Fortran77 by C++ in numerical code is the
convenience in expressing logistics. Data of different type and size may be
packed into classes and encapsulated from the outside world. Most numerical
results are to be stored in arrays, multi-dimensional arrays in particular.
This library provides the basic functionality for storing many data of the
same type in memory, passing them around between subroutines in an efficient
way and accessing them through convenient interfaces. The main purpose of
this library is not calculation but managing (passing between program
modules, selection of subsets of the data) large amounts of numbers. In the
future it might provide interfaces to libraries like blitz++ for finite
difference calculations, MTL for linear algebra calculations, and POOMA for
parallel computations.
*/
/*======================================================================*/
/*! \page page_naming Naming conventions
......@@ -930,4 +898,60 @@ We need more text and examples.
*/
/*======================================================================*/
/*! \page page_array_layout Array layout
The array class template aff::Array uses the shape class aff::Strided.
Usually and in particular when constructed by using aff::Shaper,
aff::Strided uses a Fortran like column-major layout in memory.
aff::FortranArray and aff::util::FortranShape are provided to interface
Fortran code with such kind of arrays.
Nevertheless aff::Array together with aff::Strided is able to address a
row-major C like memory layout too.
Classes to interface raw memory arrays are presented in Carray.h.
By definition the first index \f$ i \f$ on a two-dimenional matrix
\f$ A_{ij} \f$ as represented by the array
\c A(i,j) is the row index while the second index \f$ j \f$ is the
column index.
If elements of the two-dimensional matrix or array are arranged in linear
computer memory, there are two options:
\section sec_array_layout_column_major Column major layout
When traversing the linear representation in memory byte by byte in
increasing address order the elements of the first column in order of
increasing row index are passed first.
Next the elements of the second column are passed in increasing row order
and so forth.
When labelling the array elements in linear memory, the first index
varies quicker than the second index of the array if the elements are
traversed in increasing address order.
This is called the "column major order" and is the usualy layout of
Fortran arrays.
Column major layout is described in detail at
http://en.wikipedia.org/wiki/Row-major_order#Column-major_order
\section sec_array_layout_row_major Row major layout
When traversing the linear representation in memory byte by byte in
increasing address order the elements of the first row in order of
increasing column index are passed first.
Next the elements of the second row are passed in increasing column order
and so forth.
When labelling the array elements in linear memory, the second index
varies quicker than the first index of the array if the elements are
traversed in increasing address order.
This is called the "row major order" and is the usualy layout of
C arrays.
Row major layout is described in detail at
http://en.wikipedia.org/wiki/Row-major_order#Row-major_order
\todo
Provide details on indexing raw memory in both layouts here.
*/
// ----- END OF README -----
......@@ -27,6 +27,14 @@
Major changes in the interface of the library are marked by \b !!.