range< Accessor > Class Template Reference#
|
Reference API
|
#include <ginkgo/core/base/range.hpp>
Public Types | |
| using | accessor = Accessor |
Public Member Functions | |
| ~range ()=default | |
| 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) |
| template<typename... DimensionTypes> | |
| constexpr auto | operator() (DimensionTypes &&... dimensions) const -> decltype(std::declval< accessor >()(std::forward< DimensionTypes >(dimensions)...)) |
| template<typename OtherAccessor > | |
| const range & | operator= (const range< OtherAccessor > &other) const |
| const range & | operator= (const range &other) const |
| range (const range &other)=default | |
| constexpr size_type | length (size_type dimension) const |
| constexpr const accessor * | operator-> () const noexcept |
| constexpr const accessor & | get_accessor () const noexcept |
Static Public Attributes | |
| static constexpr size_type | dimensionality = accessor::dimensionality |
Detailed Description
class gko::range< Accessor >
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:
- Code using ranges is easier to read and write, as there is no need for index linearizations.
- Code using ranges is safer, as it is impossible to accidentally miscalculate an index or step out of bounds, since range accessors perform bounds checking in debug builds. For performance, this can be disabled in release builds by defining the
NDEBUGflag. - Ranges enable generalized code, as algorithms can be written independent of the memory layout. This does not impede various optimizations based on memory layout, as it is always possible to specialize algorithms for ranges with specific memory layouts.
- Ranges have various pointwise operations predefined, which reduces the amount of loops that need to be written.
Range operations
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:
- standard unary operations:
+,-,!,~ - standard binary operations:
+,*(this is pointwise, not matrix multiplication),/,%,<,>,<=,>=,==,!=,||,&&,|,&,^,<<,>> - useful unary functions:
zero,one,abs,real,imag,conj,squared_norm - useful binary functions:
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.
Compound operations
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:
Caveats
__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.
Examples
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 spans 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.
- Template Parameters
-
Accessor underlying accessor of the range
Member Typedef Documentation
◆ accessor
| using gko::range< Accessor >::accessor = Accessor |
The type of the underlying accessor.
Constructor & Destructor Documentation
◆ ~range()
|
default |
Use the default destructor.
◆ range()
|
inlineexplicitconstexpr |
Creates a new range.
- Template Parameters
-
AccessorParam types of parameters forwarded to the accessor constructor
- Parameters
-
params parameters forwarded to Accessor constructor.
Member Function Documentation
◆ get_accessor()
|
inlineconstexprnoexcept |
`Returns a reference to the accessor.
- Returns
- reference to the accessor
Referenced by gko::range< Accessor >::operator=().
◆ length()
|
inlineconstexpr |
Returns the length of the specified dimension of the range.
- Parameters
-
dimension the dimensions whose length is returned
- Returns
- the length of the
dimension-th dimension of the range
◆ operator()()
|
inlineconstexpr |
Returns a value (or a sub-range) with the specified indexes.
- Template Parameters
-
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.
- Parameters
-
dimensions the indexes of the values.
- Returns
- a value on position
(dimensions...).
References gko::range< Accessor >::dimensionality.
◆ operator->()
|
inlineconstexprnoexcept |
Returns a pointer to the accessor.
Can be used to access data and functions of a specific accessor.
- Returns
- pointer to the accessor
◆ operator=() [1/2]
|
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.
- Note
- Temporary accessors are allowed to define the implementation of the assignment as deleted, so do not expect
r1 * r2 = r2to work.
- Parameters
-
other the range to copy the data from
References gko::range< Accessor >::get_accessor().
◆ operator=() [2/2]
|
inline |
This is a version of the function which allows to copy between ranges of different accessors.
- Template Parameters
-
OtherAccessor accessor of the other range
Member Data Documentation
◆ dimensionality
|
staticconstexpr |
The number of dimensions of the range.
Referenced by gko::range< Accessor >::operator()().
The documentation for this class was generated from the following file:
- ginkgo/core/base/range.hpp
Generated by