View
¶
Header File: <Kokkos_Core.hpp>
Class Interface¶
-
template<class DataType, class ...Properties>
class View¶ Kokkos View is a potentially reference counted multi dimensional array with compile time layouts and memory space. Its semantics are similar to that of
std::shared_ptr
.- Template Parameters:
DataType –
Defines the fundamental scalar type of the
View
and its dimensionality.The basic structure is
ScalarType STARS BRACKETS
where the number ofSTARS
denotes the number of runtime length dimensions and the number ofBRACKETS
defines the compile time dimensions. Due to C++ type restrictions runtime dimensions must come first. Examples:double**
: 2D View ofdouble
with 2 runtime dimensionsconst int***[5][3]
: 5D View ofint
with 3 runtime and 2 compile dimensions.The data is
const
.
Foo[6][2]
: 2D View of a classFoo
with 2 compile time dimensions.
Properties... –
Defines various properties of the
View
, including layout, memory space, and memory traits.View
’s template parameters afterDataType
are variadic and optional, but must be specified in order. That means for example thatLayoutType
can be omitted but if bothMemorySpace
andMemoryTraits
are specified,MemorySpace
must come beforeMemoryTraits
.The ordering of View template parameters.¶template <class DataType [, class LayoutType] [, class MemorySpace] [, class MemoryTraits]> class View;
LayoutType –
Determines the mapping of indices into the underlying 1D memory storage.
Kokkos comes with some built-in layouts:
LayoutRight
: strides increase from the right most to the left most dimension.The last dimension has a stride of one. This corresponds to how C multi dimensional arrays (e.g
foo[][][]
) are laid out in memory.
LayoutLeft
: strides increase from the left most to the right most dimension.The first dimension has a stride of one. This is the layout Fortran uses for its arrays.
LayoutStride
: strides can be arbitrary for each dimension.
MemorySpace –
Controls the storage location of the View.
If omitted the default memory space of the default execution space is used (i.e. DefaultExecutionSpace::memory_space)
MemoryTraits –
Sets access properties via enum parameters for the struct template
MemoryTraits
. Possible template parameters are bitwise OR of the following flags:Unmanaged
RandomAccess
Atomic
Restrict
Aligned
See the sub-section on memory access traits in the Programming Guide also for further information.
Public Constants¶
-
static constexpr bool reference_type_is_lvalue_reference¶
whether the reference type is a C++ lvalue reference.
Data Types¶
-
type data_type¶
The
DataType
of theView
, notedata_type
contains the array specifiers (e.g.int**[3]
)
-
type non_const_data_type¶
Non-
const
version ofDataType
, same asdata_type
if that is already non-const
.
-
type scalar_array_type¶
If
DataType
represents some properly specialised array data type such as Sacado FAD types,scalar_array_type
is the underlying fundamental scalar type.
-
type const_scalar_array_type¶
const
version ofscalar_array_type
, same asscalar_array_type
if that is alreadyconst
-
type non_const_scalar_array_type¶
Non-
const
version ofscalar_array_type
, same asscalar_array_type
if that is already non-const
.
Scalar Types¶
-
type value_type¶
The
data_type
stripped of its array specifiers, i.e. the scalar type of the data the view is referencing (e.g. ifdata_type
isconst int**[3]
,value_type
isconst int
).
-
type const_value_type¶
const
version ofvalue_type
.
-
type non_const_value_type¶
non-
const
version ofvalue_type
.
Spaces¶
-
type execution_space¶
The execution space associated with the view, will be used for performing view initialization, and certain deep_copy operations.
-
type memory_space¶
The memory space where the
View
data is stored.
-
type device_type¶
the compound type defined by Device<execution_space, memory_space>
-
type memory_traits¶
The memory traits of the view.
-
type host_mirror_space¶
Host accessible memory space used in
HostMirror
.
View Types¶
-
type non_const_type¶
this
View
type withnon_const_data_type
passed as theDataType
template parameter
-
type const_type¶
this
View
type withconst_data_type
passed as theDataType
template parameter
-
type HostMirror¶
compatible view type with the same
data_type
andarray_layout
stored in host accessible memory space.
Data Handles¶
-
type reference_type¶
return type of the view access operators.
-
type pointer_type¶
pointer to
value_type
.
Other Types¶
Constructors¶
-
View()¶
Default Constructor. No allocations are made, no reference counting happens. All extents are zero and its data pointer is
nullptr
.
-
template<class DT, class ...Prop>
View(const View<DT, Prop...> &rhs)¶ Copy constructor with a compatible view. Follows
View
assignment rules.See also
-
template<class IntType>
View(const std::string &name, const IntType&... extents)¶ Standard allocating constructor. The initialization is executed on the default instance of the execution space corresponding to
memory_space
and fences it.- Template Parameters:
IntType – an integral type
- Parameters:
name – a user provided label, which is used for profiling and debugging purposes. Names are not required to be unique.
extents – Extents of the
View
.
Requirements:
- sizeof(IntType...) == rank_dynamic() or sizeof(IntType...) == rank().
In the latter case, the extents corresponding to compile-time dimensions must match the
View
type’s compile-time extents.
array_layout::is_regular == true.
-
View(const std::string &name, const array_layout &layout)¶
Standard allocating constructor. The initialization is executed on the default instance of the execution space corresponding to
memory_space
and fences it.- Parameters:
name – a user provided label, which is used for profiling and debugging purposes. Names are not required to be unique.
layout – an instance of a layout class. The number of valid extents must either match the
rank_dynamic()
orrank()
. In the latter case, the extents corresponding to compile-time dimensions must match theView
type’s compile-time extents.
-
template<class IntType>
View(const ALLOC_PROP &prop, const IntType&... extents)¶ Allocating constructor with allocation properties (created by a call to
view_alloc()
). If an execution space is specified inprop
, the initialization uses it and does not fence. Otherwise, theView
is initialized using the default execution space instance corresponding tomemory_space
and fences it.- Template Parameters:
IntType – an integral type
- Parameters:
prop – An allocation properties object that is returned by
view_alloc()
.extents – Extents of the View.
Requirements:
- sizeof(IntType...) == rank_dynamic() or sizeof(IntType...) == rank().
In the latter case, the extents corresponding to compile-time dimensions must match the
View
type’s compile-time extents.
array_layout::is_regular == true.
-
View(const ALLOC_PROP &prop, const array_layout &layout)¶
Allocating constructor with allocation properties (created by a call to
view_alloc()
) and a layout object. If an execution space is specified inprop
, the initialization uses it and does not fence. Otherwise, theView
is initialized using the default execution space instance corresponding tomemory_space
and fences it.- Parameters:
prop – An allocation properties object that is returned by
view_alloc()
.layout – an instance of a layout class. The number of valid extents must either match the
rank_dynamic()
orrank()
. In the latter case, the extents corresponding to compile-time dimensions must match theView
type’s compile-time extents.
-
template<class IntType>
View(pointer_type ptr, const IntType&... extents)¶ Unmanaged data wrapping constructor.
- Template Parameters:
IntType – an integral type
- Parameters:
ptr – pointer to a user provided memory allocation. Must provide storage of size required_allocation_size(extents...)
extents – Extents of the
View
.
Requirements:
- sizeof(IntType...) == rank_dynamic() or sizeof(IntType...) == rank().
In the latter case, the extents corresponding to compile-time dimensions must match the
View
type’s compile-time extents.
array_layout::is_regular == true.
-
View(pointer_type ptr, const array_layout &layout)¶
Unmanaged data wrapper constructor.
- Parameters:
ptr – pointer to a user provided memory allocation. Must provide storage of size View::required_allocation_size(layout)
layout – an instance of a layout class. The number of valid extents must either match the dynamic rank or the total rank. In the latter case, the extents corresponding to compile-time dimensions must match the
View
type’s compile-time extents.
-
template<class IntType>
View(const ScratchSpace &space, const IntType&... extents)¶ Constructor which acquires memory from a Scratch Memory handle.
- Template Parameters:
IntType – an integral type
- Parameters:
space – scratch memory handle. Typically returned from
team_shmem()
,team_scratch()
, orthread_scratch()
inTeamPolicy
kernels.extents – Extents of the
View
.
Requirements:
- sizeof(IntType...) == rank_dynamic() or sizeof(IntType...) == rank().
In the latter case, the extents corresponding to compile-time dimensions must match the
View
type’s compile-time extents.
array_layout::is_regular == true.
-
View(const ScratchSpace &space, const array_layout &layout)¶
Constructor which acquires memory from a Scratch Memory handle.
- Parameters:
space – scratch memory handle. Typically returned from
team_shmem()
,team_scratch()
, orthread_scratch()
inTeamPolicy
kernels.layout – an instance of a layout class. The number of valid extents must either match the dynamic rank or the total rank. In the latter case, the extents corresponding to compile-time dimensions must match the
View
type’s compile-time extents.
-
template<class DT, class ...Prop>
View(const View<DT, Prop...> &rhs, Args... args)¶ - Parameters:
Subview constructor.
See also
-
explicit(traits::is_managed) View(const NATURAL_MDSPAN_TYPE &mds)¶
- Parameters:
mds – the mdspan to convert from.
Warning
explicit(bool)
is only available on C++20 and later. When building Kokkos with C++17, this constructor will be fully implicit. Be aware that later upgrading to C++20 will in some cases cause compilation issues in cases wheretraits::is_managed
isfalse
.NATURAL_MDSPAN_TYPE
is the natural mdspan of the View. The natural mdspan is only available ifarray_layout
is one ofLayoutLeft
,LayoutRight
, orLayoutStride
. This constructor is only available if natural mdspan is available.Constructs a
View
by converting frommds
. TheView
will be unmanaged and constructed as if byView(mds.data(), array_layout_from_mapping(mds.mapping()))
See also
Added in version 4.4.0.
-
template<class ElementType, class ExtentsType, class LayoutType, class AccessorType>
explicit(SEE_BELOW) View(const mdspan<ElementType, ExtentsType, LayoutType, AccessorType> &mds)¶ - Template Parameters:
ElementType – the mdspan element type
ExtentsType – the mdspan extents
LayoutType – the mdspan layout
AccessorType – the mdspan extents
- Parameters:
mds – the mdspan to convert from
Warning
explicit(bool)
is only available on C++20 and later. When building Kokkos with C++17, this constructor will be fully implicit. Be aware that later upgrading to C++20 will in some cases cause compilation issues in cases where the condition is false.Constructs a
View
by converting frommds
. TheView
’s natural mdspan must be constructible frommds
. TheView
will be constructed as if byView(NATURAL_MDSPAN_TYPE(mds))
- In C++20:
This constructor is implicit if
mds
is implicitly convertible to the natural mdspan of theView
.
Added in version 4.4.0.
Data Access Functions¶
-
template<class IntType>
reference_type operator()(const IntType&... indices) const¶ - Template Parameters:
IntType – an integral type
- Parameters:
indices – the indices of the element to get a reference to
- Returns:
a reference to the element at the given indices
Returns a value of
reference_type
which may or not be referenceable itself. The number of index arguments must match therank()
of the view.Requirements:
sizeof(IntType...) == rank_dynamic()
-
template<class IntType>
reference_type access(const IntType &i0 = 0, const IntType &i1 = 0, const IntType &i2 = 0, const IntType &i3 = 0, const IntType &i4 = 0, const IntType &i5 = 0, const IntType &i6 = 0, const IntType &i7 = 0) const¶ - Template Parameters:
IntType – an integral type
- Parameters:
i0, i1, i2, i3, i4, i5, i6, i7 – the indices of the element to get a reference to
- Returns:
a reference to the element at the given indices
Returns a value of
reference_type
which may or not be referenceable itself. The number of index arguments must be equal or larger than therank()
of the view. Index arguments beyondrank()
must be0
, which will be enforced ifKOKKOS_DEBUG
is defined.
Data Layout, Dimensions, Strides¶
-
static constexpr size_t rank()¶
- Returns:
the rank of the view.
Added in version 4.1.
-
static constexpr size_t rank_dynamic()¶
- Returns:
the number of runtime determined dimensions.
Added in version 4.1.
Note
In practice, rank()
and rank_dynamic()
are not actually implemented as static member functions but rank
and rank_dynamic
underlying types have a nullary member function (i.e. callable with no argument).
Changed in version 4.1: rank()
and rank_dynamic()
are static member constants that are convertible to size_t
.
Their underlying types are unspecified, but equivalent to std::integral_constant
with a nullary member function callable from host and device side.
Users are encouraged to use rank()
and rank_dynamic()
(akin to a static member function call) instead of relying on implicit conversion to an integral type.
The actual type of rank()
and rank_dynamic()
as they were defined until Kokkos 4.1 was left up to the implementation (that is, up to the compiler not to Kokkos) but in practice it was often int
which means this change may yield warnings about comparing signed and unsigned integral types.
It may also break code that was using the type of rank()
.
Furthermore, it appears that MSVC has issues with the implicit conversion to size_t
in certain constexpr contexts. Calling rank()
or rank_dynamic()
will work in those cases.
-
constexpr array_layout layout() const¶
- Returns:
the layout object that can be used to to construct other views with the same dimensions.
-
template<class iType>
constexpr size_t extent(const iType &dim) const¶ - Template Parameters:
iType – an integral type
- Parameters:
dim – the dimension to get the extent of
- Returns:
the extent of dimension
dim
Preconditions:
-
template<class iType>
constexpr int extent_int(const iType &dim) const¶ - Template Parameters:
iType – an integral type
- Parameters:
dim – the dimension to get the extent of
- Returns:
the extent of dimension
dim
as anint
Compared to
extent()
this function can be useful on architectures whereint
operations are more efficient thansize_t
. It also may eliminate the need for type casts in applications which otherwise perform all index operations withint
.Preconditions:
-
template<class iType>
constexpr size_t stride(const iType &dim) const¶ - Template Parameters:
iType – an integral type
- Parameters:
dim – the dimension to get the stride of
- Returns:
the stride of dimension
dim
Example: a.stride(3) == (&a(i0, i1, i2, i3 + 1, i4) - &a(i0, i1, i2, i3, i4))
Preconditions:
-
constexpr size_t stride_0() const¶
- Returns:
the stride of dimension 0.
-
constexpr size_t stride_1() const¶
- Returns:
the stride of dimension 1.
-
constexpr size_t stride_2() const¶
- Returns:
the stride of dimension 2.
-
constexpr size_t stride_3() const¶
- Returns:
the stride of dimension 3.
-
constexpr size_t stride_4() const¶
- Returns:
the stride of dimension 4.
-
constexpr size_t stride_5() const¶
- Returns:
the stride of dimension 5.
-
constexpr size_t stride_6() const¶
- Returns:
the stride of dimension 6.
-
constexpr size_t stride_7() const¶
- Returns:
the stride of dimension 7.
-
template<class iType>
void stride(iType *strides) const¶ - Template Parameters:
iType – an integral type
- Parameters:
strides – the output array of length rank() + 1
Sets strides[r] to stride(r) for all \(r\) with \(0 \le r \lt \texttt{rank()}\). Sets strides[rank()] to
span()
.Preconditions:
-
constexpr size_t span() const¶
- Returns:
the size of the span of memory between the element with the lowest and highest address
Obtains the memory span in elements between the element with the lowest and the highest address. This can be larger than the product of extents due to padding, and or non-contiguous data layout as for example
LayoutStride
allows.
-
constexpr size_t size() const¶
- Returns:
the product of extents, i.e. the logical number of elements in the
View
.
-
constexpr pointer_type data() const¶
- Returns:
the pointer to the underlying data allocation.
Warning
Calling any function that manipulates the behavior of the memory (e.g.
memAdvise
) on memory managed by Kokkos results in undefined behavior.
-
bool span_is_contiguous() const¶
- Returns:
whether the span is contiguous (i.e. whether every memory location between in span belongs to the index space covered by the
View
).
-
static constexpr size_t required_allocation_size(size_t N0 = 0, size_t N1 = 0, size_t N2 = 0, size_t N3 = 0, size_t N4 = 0, size_t N5 = 0, size_t N6 = 0, size_t N7 = 0);¶
- Parameters:
N0, N1, N2, N3, N4, N5, N6, N7 – the dimensions to query
- Returns:
the number of bytes necessary for an unmanaged
View
of the provided dimensions.
Requirements:
array_layout::is_regular == true.
-
static constexpr size_t required_allocation_size(const array_layout &layout);¶
- Parameters:
layout – the layout to query
- Returns:
the number of bytes necessary for an unmanaged
View
of the provided layout.
Other Utility Methods¶
-
int use_count() const;¶
- Returns:
the current reference count of the underlying allocation.
-
const std::string label() const;¶
- Returns:
the label of the View.
-
void assign_data(pointer_type arg_data);¶
- Parameters:
arg_data – the pointer to set the underlying
View
data pointer to
Decrement reference count of previously assigned data and set the underlying pointer to arg_data. Note that the effective result of this operation is that the view is now an unmanaged view; thus, the deallocation of memory associated with arg_data is not linked in anyway to the deallocation of the view.
-
constexpr bool is_allocated() const;¶
- Returns:
true if the view points to a valid memory location.
This function works for both managed and unmanaged views. With the unmanaged view, there is no guarantee that referenced address is valid, only that it is a non-null pointer.
Conversion to mdspan¶
-
template<class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherAccessor>
constexpr operator mdspan<OtherElementType, OtherExtents, OtherLayoutPolicy, OtherAccessor>()¶ - Template Parameters:
OtherElementType – the target mdspan element type
OtherExtents – the target mdspan extents
OtherLayoutPolicy – the target mdspan layout
OtherAccessor – the target mdspan accessor
- Constraints:
View
‘s natural mdspan must be assignable tomdspan<OtherElementType, OtherExtents, OtherLayoutPolicy, OtherAccessor>
- Returns:
an mdspan with extents and a layout converted from the
View
’s natural mdspan.
-
template<class OtherAccessorType = default_accessor<typename traits::value_type>>
constexpr auto to_mdspan(const OtherAccessorType &other_accessor = OtherAccessorType{})¶ - Template Parameters:
OtherAccessor – the target mdspan accessor
- Constraints:
typename OtherAccessorType::data_handle_type
must be assignable tovalue_type*
- Returns:
View
‘s natural mdspan, but with an accessor policy constructed fromother_accessor
Non-Member Functions¶
-
template<class ...ViewTDst, class ...ViewTSrc>
bool is_assignable(const View<ViewTDst...> &dst, const View<ViewTSrc...> &src)¶ - Returns:
true if src can be assigned to dst.
See also
-
template<class LT, class ...LP, class RT, class ...RP>
bool operator==(const View<LT, LP...> &lhs, const View<RT, RP...> &rhs)¶ - Returns:
true
ifvalue_type
,array_layout
,memory_space
,rank()
,data()
and extent(r), for \(0 \le r \lt \texttt{rank()}\), match.
Assignment Rules¶
Assignment rules cover the assignment operator as well as copy constructors.
We aim at making all logically legal assignments possible, while intercepting illegal assignments if possible at compile time, otherwise at runtime.
In the following we use DstType
and SrcType
as the type of the destination view and source view respectively.
dst_view
and src_view
refer to the runtime instances of the destination and source views, i.e.:
SrcType src_view(...);
DstType dst_view(src_view);
dst_view = src_view;
The following conditions must be met at and are evaluated at compile time:
DstType::rank() == SrcType::rank()
DstType::non_const_value_type
is the same asSrcType::non_const_value_type
If
std::is_const_v<SrcType::value_type> == true
thenstd::is_const_v<DstType::value_type>
must also betrue
.MemorySpaceAccess<DstType::memory_space,SrcType::memory_space>::assignable == true
If
DstType::rank_dynamic() != DstType::rank()
andSrcType::rank_dynamic() != SrcType::rank()
then for each dimensionk
that is compile time for both it must be true thatdst_view.extent(k) == src_view.extent(k)
Additionally the following conditions must be met at runtime:
If
DstType::rank_dynamic() != DstType::rank()
then for each compile time dimensionk
it must be true thatdst_view.extent(k) == src_view.extent(k)
.
Furthermore there are rules which must be met if DstType::array_layout
is not the same as SrcType::array_layout
.
These rules only cover cases where both layouts are one of LayoutLeft
, LayoutRight
or LayoutStride
If neither
DstType::array_layout
norSrcType::array_layout
isLayoutStride
:If
DstType::rank > 1
thenDstType::array_layout
must be the same asSrcType::array_layout
.
If either
DstType::array_layout
orSrcType::array_layout
isLayoutStride
For each dimension
k
it must hold thatdst_view.extent(k) == src_view.extent(k)
View<int*> a1 = View<int*>("A1",N); // OK
View<int**> a2 = View<int*[10]>("A2",N); // OK
View<int*[10]> a3 = View<int**>("A3",N,M); // OK if M == 10 otherwise runtime failure
View<const int*> a4 = a1; // OK
View<int*> a5 = a4; // Error: const to non-const assignment
View<int**> a6 = a1; // Error: Ranks do not match
View<int*[8]> a7 = a3; // Error: compile time dimensions do not match
View<int[4][10]> a8 = a3; // OK if N == 4 otherwise runtime failure
View<int*, LayoutLeft> a9 = a1; // OK since a1 is either LayoutLeft or LayoutRight
View<int**, LayoutStride> a10 = a8; // OK
View<int**> a11 = a10; // OK
View<int*, HostSpace> a12 = View<int*, CudaSpace>("A12",N); // Error: non-assignable memory spaces
View<int*, HostSpace> a13 = View<int*, CudaHostPinnedSpace>("A13",N); // OK
Natural mdspans¶
Added in version 4.4.0.
C++23 introduces mdspan, a non-owning multidimensional array view.
View
is compatible with std::mdspan
and can be implicitly converted from and to valid mdspans.
These conversion rules are dictated by the natural mdspan of a view.
For an mdspan m
of type M
that is the natural mdspan of a View
v
of type V
, the following properties hold:
M::value_type
isV::value_type
M::index_type
isstd::size_t
.M::extents_type
isstd::extents<M::index_type, Extents...>
wheresizeof(Extents...)
isV::rank()
and each element at index
r
ofExtents...
isV::static_extents(r)
ifV::static_extents(r) != 0
, otherwisestd::dynamic_extent
M::layout_type
isstd::layout_left_padded<std::dynamic_extent>
ifV::array_layout
isLayoutLeft
std::layout_right_padded<std::dynamic_extent>
ifV::array_layout
isLayoutRight
std::layout_stride
ifV::array_layout
isLayoutStride
M::accessor_type
isstd::default_accessor<V::value_type>
Additionally, the natural mdspan is constructed so that m.data() == v.data()
and for each extent r
, m.extents().extent(r) == v.extent(r)
.
Examples¶
#include<Kokkos_Core.hpp>
#include<cstdio>
int main(int argc, char* argv[]) {
Kokkos::initialize(argc,argv);
int N0 = atoi(argv[1]);
int N1 = atoi(argv[2]);
Kokkos::View<double*> a("A",N0);
Kokkos::View<double*> b("B",N1);
Kokkos::parallel_for("InitA", N0, KOKKOS_LAMBDA (const int& i) {
a(i) = i;
});
Kokkos::parallel_for("InitB", N1, KOKKOS_LAMBDA (const int& i) {
b(i) = i;
});
Kokkos::View<double**,Kokkos::LayoutLeft> c("C",N0,N1);
{
Kokkos::View<const double*> const_a(a);
Kokkos::View<const double*> const_b(b);
Kokkos::parallel_for("SetC", Kokkos::MDRangePolicy<Kokkos::Rank<2,Kokkos::Iterate::Left>>({0,0},{N0,N1}),
KOKKOS_LAMBDA (const int& i0, const int& i1) {
c(i0,i1) = a(i0) * b(i1);
});
}
Kokkos::finalize();
}