Low-Level Abstraction of Memory Access
Projection.hpp
Go to the documentation of this file.
1 // Copyright 2022 Bernhard Manfred Gruber
2 // SPDX-License-Identifier: MPL-2.0
3 
4 #pragma once
5 
6 #include "../ProxyRefOpMixin.hpp"
7 #include "../View.hpp"
8 #include "Common.hpp"
9 
10 namespace llama::mapping
11 {
12  namespace internal
13  {
14  template<typename F>
16  {
17  static_assert(sizeof(F) == 0, "F is not an unary function");
18  };
19 
20  template<typename Arg, typename Ret>
21  struct UnaryFunctionTraits<Ret (*)(Arg)>
22  {
23  using ArgumentType = Arg;
24  using ReturnType = Ret;
25  };
26 
27  template<typename ProjectionMap, typename Coord, typename RecordDimType>
29  {
30  if constexpr(mp_map_contains<ProjectionMap, Coord>::value)
31  return mp_identity<mp_second<mp_map_find<ProjectionMap, Coord>>>{};
32  else if constexpr(mp_map_contains<ProjectionMap, RecordDimType>::value)
33  return mp_identity<mp_second<mp_map_find<ProjectionMap, RecordDimType>>>{};
34  else
35  return mp_identity<void>{};
36  }
37 
38  template<typename ProjectionMap, typename Coord, typename RecordDimType>
39  using ProjectionOrVoid = typename decltype(projectionOrVoidImpl<ProjectionMap, Coord, RecordDimType>())::type;
40 
41  template<typename ProjectionMap>
43  {
44  template<typename Coord, typename RecordDimType>
45  static auto replacedTypeProj()
46  {
48  if constexpr(std::is_void_v<Projection>)
49  return mp_identity<RecordDimType>{};
50  else
51  {
52  using LoadFunc = UnaryFunctionTraits<decltype(&Projection::load)>;
53  using StoreFunc = UnaryFunctionTraits<decltype(&Projection::store)>;
54 
55  static_assert(std::is_same_v<typename LoadFunc::ReturnType, RecordDimType>);
56  static_assert(std::is_same_v<typename StoreFunc::ArgumentType, RecordDimType>);
57  static_assert(std::is_same_v<typename LoadFunc::ArgumentType, typename StoreFunc::ReturnType>);
58 
59  return mp_identity<typename StoreFunc::ReturnType>{};
60  }
61  }
62 
63  template<typename Coord, typename RecordDimType>
64  using fn = typename decltype(replacedTypeProj<Coord, RecordDimType>())::type;
65  };
66 
67  template<typename RecordDim, typename ProjectionMap>
70 
71  template<typename Reference, typename Projection>
72  // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
75  ProjectionReference<Reference, Projection>,
76  decltype(Projection::load(std::declval<Reference>()))>
77  {
78  private:
79  Reference storageRef;
80 
81  public:
82  using value_type = decltype(Projection::load(std::declval<Reference>()));
83 
84  LLAMA_FN_HOST_ACC_INLINE constexpr explicit ProjectionReference(Reference storageRef)
85  : storageRef{storageRef}
86  {
87  }
88 
90 
91  // NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
93  {
94  *this = static_cast<value_type>(other);
95  return *this;
96  }
97 
98  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
99  LLAMA_FN_HOST_ACC_INLINE constexpr operator value_type() const
100  {
102  return Projection::load(storageRef);
104  }
105 
107  {
109  storageRef = Projection::store(v);
111  return *this;
112  }
113  };
114  } // namespace internal
115 
125  template<
126  typename TArrayExtents,
127  typename TRecordDim,
128  template<typename, typename>
129  typename InnerMapping,
130  typename TProjectionMap>
131  struct Projection
132  : private InnerMapping<TArrayExtents, internal::ReplaceTypesByProjectionResults<TRecordDim, TProjectionMap>>
133  {
134  using Inner
135  = InnerMapping<TArrayExtents, internal::ReplaceTypesByProjectionResults<TRecordDim, TProjectionMap>>;
136  using ProjectionMap = TProjectionMap;
138  using RecordDim = TRecordDim; // hide Inner::RecordDim
139  using Inner::blobCount;
140  using Inner::blobSize;
141  using Inner::extents;
142  using Inner::Inner;
143 
144  protected:
145  using ArrayIndex = typename ArrayExtents::Index;
146 
147  public:
148  template<typename RecordCoord>
149  LLAMA_FN_HOST_ACC_INLINE static constexpr auto isComputed(RecordCoord) -> bool
150  {
151  return !std::is_void_v<
153  }
154 
155  template<std::size_t... RecordCoords, typename BlobArray>
157  ArrayIndex ai,
159  BlobArray& blobs) const
160  {
161  static_assert(isComputed(rc));
162  using RecordDimType = GetType<RecordDim, RecordCoord<RecordCoords...>>;
163  using Reference = decltype(mapToMemory(static_cast<const Inner&>(*this), ai, rc, blobs));
164  using Projection = internal::ProjectionOrVoid<ProjectionMap, RecordCoord<RecordCoords...>, RecordDimType>;
165  static_assert(!std::is_void_v<Projection>);
166  Reference r = mapToMemory(static_cast<const Inner&>(*this), ai, rc, blobs);
167 
171  }
172 
173  template<std::size_t... RecordCoords>
176  {
177  static_assert(!isComputed(rc));
178  return Inner::blobNrAndOffset(ai, rc);
179  }
180  };
181 
185  template<template<typename, typename> typename InnerMapping, typename ProjectionMap>
187  {
188  template<typename ArrayExtents, typename RecordDim>
190  };
191 
193  template<typename Mapping>
194  inline constexpr bool isProjection = false;
195 
197  template<
198  typename TArrayExtents,
199  typename TRecordDim,
200  template<typename, typename>
201  typename InnerMapping,
202  typename ReplacementMap>
203  inline constexpr bool isProjection<Projection<TArrayExtents, TRecordDim, InnerMapping, ReplacementMap>> = true;
204 } // namespace llama::mapping
#define LLAMA_EXPORT
Definition: macros.hpp:192
#define LLAMA_BEGIN_SUPPRESS_HOST_DEVICE_WARNING
Definition: macros.hpp:141
#define LLAMA_FN_HOST_ACC_INLINE
Definition: macros.hpp:96
#define LLAMA_END_SUPPRESS_HOST_DEVICE_WARNING
Definition: macros.hpp:153
typename decltype(projectionOrVoidImpl< ProjectionMap, Coord, RecordDimType >())::type ProjectionOrVoid
Definition: Projection.hpp:39
TransformLeavesWithCoord< RecordDim, MakeReplacerProj< ProjectionMap >::template fn > ReplaceTypesByProjectionResults
Definition: Projection.hpp:69
constexpr bool isProjection
Definition: Projection.hpp:194
ArrayExtents(Args...) -> ArrayExtents< typename internal::IndexTypeFromArgs< std::size_t, Args... >::type,(Args{}, dyn)... >
typename internal::TransformLeavesWithCoordImpl< RecordCoord<>, RecordDim, FieldTypeFunctor >::type TransformLeavesWithCoord
Definition: Core.hpp:751
typename internal::GetTypeImpl< RecordDim, RecordCoordOrTags... >::type GetType
Definition: Core.hpp:388
auto mapToMemory(Mapping &mapping, typename Mapping::ArrayExtents::Index ai, RecordCoord rc, Blobs &blobs) -> decltype(auto)
Definition: View.hpp:359
ArrayIndex< T, rank > Index
CRTP mixin for proxy reference types to support all compound assignment and increment/decrement opera...
constexpr auto compute(ArrayIndex ai, RecordCoord< RecordCoords... > rc, BlobArray &blobs) const
Definition: Projection.hpp:156
TProjectionMap ProjectionMap
Definition: Projection.hpp:136
InnerMapping< TArrayExtents, internal::ReplaceTypesByProjectionResults< TRecordDim, TProjectionMap > > Inner
Definition: Projection.hpp:135
typename Inner::ArrayExtents ArrayExtents
Definition: Projection.hpp:137
constexpr auto blobNrAndOffset(ArrayIndex ai, RecordCoord< RecordCoords... > rc={}) const -> NrAndOffset< typename ArrayExtents::value_type >
Definition: Projection.hpp:174
typename ArrayExtents::Index ArrayIndex
Definition: Projection.hpp:145
static constexpr auto isComputed(RecordCoord) -> bool
Definition: Projection.hpp:149
typename decltype(replacedTypeProj< Coord, RecordDimType >())::type fn
Definition: Projection.hpp:64
constexpr ProjectionReference(Reference storageRef)
Definition: Projection.hpp:84
constexpr auto operator=(value_type v) -> ProjectionReference &
Definition: Projection.hpp:106
ProjectionReference(const ProjectionReference &)=default
decltype(Projection::load(std::declval< Reference >())) value_type
Definition: Projection.hpp:82
constexpr auto operator=(const ProjectionReference &other) -> ProjectionReference &
Definition: Projection.hpp:92