Table of Contents
The main classes in the SAL are array_view and array, with the latter deriving from the former.
An array_view is a combination between two entities:
An array is just an array_view which is responsible
for allocating and destroying its own data internally.
Both array and array_view satisfy the requirements for being engines,
which means that they can be stored in the nodes of a workspace.
We call 'Cartesian' an array whose elements are indexed by sequences of integers
i0,i1,...,ir-1,
where the length r of these sequences if called the rank of the array,
and the integer ik is called the index in the (k+1)-th direction
(or simply the (k+1)-th index).
According to our convention, when traversing the elements according to the order
in which they are stored in memory, the index in the first direction varies the fastest,
then the second, etc, and the index along the last direction varies the slowest.
For matrices, this correspond to so-called row-major ordering,
and it is also the same convention used in Matlab and Fortran.
Restricting ourselves for the moment to the case where the whole array is stored in local memory,
the geometry of a Cartesian array is fully defined by a sequence of r unsigned integers
called the domain of the array.
The (k+1)-th integer Nk in the domain defines the range [[0,..,Nk-1]]
in which the (k+1)-th index is allowed to vary.
Identifiers which are specific to Cartesian arrays are defined in the namespace cartesian.
The class template cartesian::local_geometry
takes two template arguments:
rank_t rank | The rank of the array. |
class Domain | A Random Access Container type which will be used to store the domain of the array. |
The Domain has a default type which is boost::array<size_t,rank>,
and rarely needs to be specified explicitly.
To construct a 3D Cartesian geometry, one may proceed as follows:
typedef cartesian::local_geometry<3> geometry_type;
geometry_type::global_domain_type domain = {{32,64,64}};
geometry_type g(domain);
The geometry g defined above can in turn be used to construct a 3D array:
typedef array<geometry_type> a(g);
Indeed, the class template array takes the following template arguments:
class Geometry | The Geometry of the array. |
class TElem | The type of elements that will be stored in the array. |
The default value for TElem
is the macro SC_DEF_TELEM which is normally double but can be customized
at compile-time using the precision feature when calling bjam:
precision=32 corresponds to float,
precision=64 (the default) corresponds to double,
precision=128 corresponds to long double,
and precision=arbitrary makes use of the GNU multiprecision library
to provide arbirary precision floating point numbers.
The array construtor will take care of allocating the necessary memory,
which will eventually get freed at the time of destruction.
To prevent excessive memory allocation, array
is inherits from boost::noncopyable,
and therefore does not have an accessible copy constructor.
Deep copies of array objects must be constructed manually by declaring
another instance and using the member function copy.
Shallow copies are handled by the array_view class template,
and can be obtained by calling the member function view.
To use external memory management, array_view can also be instanciated
directly. Its template parameters are the same as array,
and its constructor takes as parameter a pair
made of a geometry and a pointer to some sufficiently large memory space:
double* data = new double[32*64*64];
{
array_view<geometry_type> a2(std::make_pair(g,data));
/* ... */
}
delete[] data;
Of course, the user is then responsible for freeing the allocated memory after the destruction
of the array_view object.
spectral::vec::vector class template, which is used to define vector-valued arrays:
namespace vec {
template<class TElem, unsigned int ncomponents>
class vector;
}
All the standard algebraic operations are defined for vectors in the namespace spectral::vec.
For more details, see there.