Ginkgo
Generated from pipelines/1556235455 branch based on develop. Ginkgo version 1.9.0
A numerical linear algebra library targeting many-core architectures
|
A range is a multidimensional view of the memory. More...
#include <ginkgo/core/base/range.hpp>
Public Types | |
using | accessor = Accessor |
The type of the underlying accessor. | |
Public Member Functions | |
~range ()=default | |
Use the default destructor. | |
template<typename... AccessorParams, typename = std::enable_if_t< sizeof...(AccessorParams) != 1 || !std::is_same< range, std::decay<detail::head_t<AccessorParams...>>>::value>> | |
constexpr | range (AccessorParams &&... params) |
Creates a new range. More... | |
template<typename... DimensionTypes> | |
constexpr auto | operator() (DimensionTypes &&... dimensions) const -> decltype(std::declval< accessor >()(std::forward< DimensionTypes >(dimensions)...)) |
Returns a value (or a sub-range) with the specified indexes. More... | |
template<typename OtherAccessor > | |
const range & | operator= (const range< OtherAccessor > &other) const |
const range & | operator= (const range &other) const |
Assigns another range to this range. More... | |
range (const range &other)=default | |
constexpr size_type | length (size_type dimension) const |
Returns the length of the specified dimension of the range. More... | |
constexpr const accessor * | operator-> () const noexcept |
Returns a pointer to the accessor. More... | |
constexpr const accessor & | get_accessor () const noexcept |
`Returns a reference to the accessor. More... | |
Static Public Attributes | |
static constexpr size_type | dimensionality = accessor::dimensionality |
The number of dimensions of the range. | |
A range is a multidimensional view of the memory.
The range does not store any of its values by itself. Instead, it obtains the values through an accessor (e.g. accessor::row_major) which describes how the indexes of the range map to physical locations in memory.
There are several advantages of using ranges instead of plain memory pointers:
NDEBUG
flag.Ranges define a complete set of pointwise unary and binary operators which extend the basic arithmetic operators in C++, as well as a few pointwise operations and mathematical functions useful in ginkgo, and a couple of non-pointwise operations. Compound assignment (+=
, *=
, etc.) is not yet supported at this moment. Here is a complete list of operations:
+
, -
, !
, ~
+
, *
(this is pointwise, not matrix multiplication), /
, %
, <
, >
, <=
, >=
, ==
, !=
, ||
, &&
, |
, &
, ^
, <<
, >>
zero
, one
, abs
, real
, imag
, conj
, squared_norm
min
, max
All binary pointwise operations also work as expected if one of the operands is a scalar and the other is a range. The scalar operand will have the effect as if it was a range of the same size as the other operand, filled with the specified scalar.
Two "global" functions transpose
and mmul
are also supported. transpose
transposes the first two dimensions of the range (i.e. transpose(r)(i, j, ...) == r(j, i, ...)
). mmul
performs a (batched) matrix multiply of the ranges - the first two dimensions represent the matrices, while the rest represent the batch. For example, given the ranges r1
and r2
of dimensions (3, 2, 3)
and (2, 4, 3)
, respectively, mmul(r1, r2)
will return a range of dimensions (3, 4, 3)
, obtained by multiplying the 3 frontal slices of the range, and stacking the result back vertically.
Multiple range operations can be combined into a single expression. For example, an "axpy" operation can be obtained using y = alpha * x + y
, where x
an y
are ranges, and alpha
is a scalar. Range operations are optimized for memory access, and the above code does not allocate additional storage for intermediate ranges alpha * x
or alpha * x + y
. In fact, the entire computation is done during the assignment, and the results of operations +
and *
only register the data, and the types of operations that will be computed once the results are needed.
It is possible to store and reuse these intermediate expressions. The following example will overwrite the range x
with it's 4th power:
__mmul
is not a highly-optimized BLAS-3 version of the matrix multiplication.__ The current design of ranges and accessors prevents that, so if you need a high-performance matrix multiplication, you should use one of the libraries that provide that, or implement your own (you can use pointwise range operations to help simplify that). However, range design might get improved in the future to allow efficient implementations of BLAS-3 kernels.
Aliasing the result range in mmul
and transpose
is not allowed. Constructs like A = transpose(A)
, A = mmul(A, A)
, or A = mmul(A, A) + C
lead to undefined behavior. However, aliasing input arguments is allowed: C = mmul(A, A)
, and even C = mmul(A, A) + C
is valid code (in the last example, only pointwise operations are aliased). C = mmul(A, A + C)
is not valid though.
The range unit tests in core/test/base/range.cpp contain lots of simple 1-line examples of range operations. The accessor unit tests in core/test/base/range.cpp show how to use ranges with concrete accessors, and how to use range slices using span
s as arguments to range function call operator. Finally, examples/range contains a complete example where ranges are used to implement a simple version of the right-looking LU factorization.
Accessor | underlying accessor of the range |
|
inlineexplicitconstexpr |
Creates a new range.
AccessorParam | types of parameters forwarded to the accessor constructor |
params | parameters forwarded to Accessor constructor. |
|
inlineconstexprnoexcept |
`Returns a reference to the accessor.
Referenced by gko::range< Accessor >::operator=().
|
inlineconstexpr |
Returns the length of the specified dimension of the range.
dimension | the dimensions whose length is returned |
dimension
-th dimension of the range Referenced by gko::matrix_data< ValueType, IndexType >::matrix_data().
|
inlineconstexpr |
Returns a value (or a sub-range) with the specified indexes.
DimensionTypes | The types of indexes. Supported types depend on the underlying accessor, but are usually either integer types or spans. If at least one index is a span, the returned value will be a sub-range. |
dimensions | the indexes of the values. |
(dimensions...)
. References gko::range< Accessor >::dimensionality.
|
inlineconstexprnoexcept |
Returns a pointer to the accessor.
Can be used to access data and functions of a specific accessor.
|
inline |
Assigns another range to this range.
The order of assignment is defined by the accessor of this range, thus the memory access will be optimized for the resulting range, and not for the other range. If the sizes of two ranges do not match, the result is undefined. Sizes of the ranges are checked at runtime in debug builds.
r1 * r2 = r2
to work.other | the range to copy the data from |
References gko::range< Accessor >::get_accessor().
|
inline |
This is a version of the function which allows to copy between ranges of different accessors.
OtherAccessor | accessor of the other range |