Low-Level Abstraction of Memory Access
Bytesplit.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 "Common.hpp"
8 
9 namespace llama::mapping
10 {
11  namespace internal
12  {
13  template<typename T>
14  using ReplaceByByteArray = std::byte[sizeof(T)];
15 
16  template<typename RecordDim>
18  } // namespace internal
19 
23  template<typename TArrayExtents, typename TRecordDim, template<typename, typename> typename InnerMapping>
24  struct Bytesplit : private InnerMapping<TArrayExtents, internal::SplitBytes<TRecordDim>>
25  {
26  using Inner = InnerMapping<TArrayExtents, internal::SplitBytes<TRecordDim>>;
27 
29  using RecordDim = TRecordDim; // hide Inner::RecordDim
30  using Inner::blobCount;
31 
32  using Inner::blobSize;
33  using Inner::extents;
34 
35  private:
36  using ArrayIndex = typename TArrayExtents::Index;
37 
38  public:
40  constexpr explicit Bytesplit(TArrayExtents extents, TRecordDim = {}) : Inner(extents)
41  {
42  }
43 
44  template<typename... Args>
45  LLAMA_FN_HOST_ACC_INLINE constexpr explicit Bytesplit(std::tuple<Args...> innerMappingArgs, TRecordDim = {})
46  : Inner(std::make_from_tuple<Inner>(innerMappingArgs))
47  {
48  }
49 
50  template<std::size_t... RecordCoords>
52  {
53  return true;
54  }
55 
56  template<typename RC, typename BlobArray>
57  // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
58  struct Reference : ProxyRefOpMixin<Reference<RC, BlobArray>, GetType<TRecordDim, RC>>
59  {
60  private:
61  const Inner& inner;
62  ArrayIndex ai;
63  BlobArray& blobs;
64 
65  public:
67 
68  LLAMA_FN_HOST_ACC_INLINE constexpr Reference(const Inner& innerMapping, ArrayIndex ai, BlobArray& blobs)
69  : inner(innerMapping)
70  , ai(ai)
71  , blobs(blobs)
72  {
73  }
74 
75  Reference(const Reference&) = default;
76 
77  // NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
78  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator=(const Reference& other) -> Reference&
79  {
80  *this = static_cast<value_type>(other);
81  return *this;
82  }
83 
84  // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)
85  LLAMA_FN_HOST_ACC_INLINE constexpr operator value_type() const
86  {
87 #ifdef _MSC_VER
88  // MSVC workaround. Without this, MSVC deduces the last template parameter of mapToMemory wrongly
89  BlobArray& blobs = this->blobs;
90 #endif
91 
92  value_type v;
93  auto* p = reinterpret_cast<std::byte*>(&v);
94  mp_for_each_inline<mp_iota_c<sizeof(value_type)>>(
95  [&](auto ic) LLAMA_LAMBDA_INLINE
96  {
97  constexpr auto i = decltype(ic)::value;
98  auto&& ref = mapToMemory(inner, ai, Cat<RC, RecordCoord<i>>{}, blobs);
99 
100  p[i] = ref;
101  });
102  return v;
103  }
104 
106  {
107 #ifdef _MSC_VER
108  // MSVC workaround. Without this, MSVC deduces the last template parameter of mapToMemory wrongly
109  BlobArray& blobs = this->blobs;
110 #endif
111 
112  auto* p = reinterpret_cast<std::byte*>(&v);
113  mp_for_each_inline<mp_iota_c<sizeof(value_type)>>(
114  [&](auto ic) LLAMA_LAMBDA_INLINE
115  {
116  constexpr auto i = decltype(ic)::value;
117 
118  auto&& ref = mapToMemory(inner, ai, Cat<RC, RecordCoord<i>>{}, blobs);
119  ref = p[i];
120  });
121  return *this;
122  }
123  };
124 
125  template<std::size_t... RecordCoords, typename BlobArray>
126  LLAMA_FN_HOST_ACC_INLINE constexpr auto compute(ArrayIndex ai, RecordCoord<RecordCoords...>, BlobArray& blobs)
127  const
128  {
129  return Reference<RecordCoord<RecordCoords...>, BlobArray>{*this, ai, blobs};
130  }
131  };
132 
136  template<template<typename, typename> typename InnerMapping>
138  {
139  template<typename ArrayExtents, typename RecordDim>
141  };
142 
144  template<typename Mapping>
145  inline constexpr bool isBytesplit = false;
146 
148  template<typename TArrayExtents, typename TRecordDim, template<typename, typename> typename InnerMapping>
149  inline constexpr bool isBytesplit<Bytesplit<TArrayExtents, TRecordDim, InnerMapping>> = true;
150 } // namespace llama::mapping
#define LLAMA_EXPORT
Definition: macros.hpp:192
#define LLAMA_LAMBDA_INLINE
Gives strong indication to the compiler to inline the attributed lambda.
Definition: macros.hpp:113
#define LLAMA_FN_HOST_ACC_INLINE
Definition: macros.hpp:96
TransformLeaves< RecordDim, ReplaceByByteArray > SplitBytes
Definition: Bytesplit.hpp:17
std::byte[sizeof(T)] ReplaceByByteArray
Definition: Bytesplit.hpp:14
constexpr bool isBytesplit
Definition: Bytesplit.hpp:145
ArrayExtents(Args...) -> ArrayExtents< typename internal::IndexTypeFromArgs< std::size_t, Args... >::type,(Args{}, dyn)... >
constexpr void mp_for_each_inline(F &&f)
Like boost::mp11::mp_for_each, but marked with LLAMA_FN_HOST_ACC_INLINE.
Definition: Meta.hpp:59
TransformLeavesWithCoord< RecordDim, internal::MakePassSecond< FieldTypeFunctor >::template fn > TransformLeaves
Definition: Core.hpp:758
RecordCoordFromList< mp_append< typename RecordCoords::List... > > Cat
Concatenate a set of RecordCoords.
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
CRTP mixin for proxy reference types to support all compound assignment and increment/decrement opera...
Reference(const Reference &)=default
constexpr auto operator=(const Reference &other) -> Reference &
Definition: Bytesplit.hpp:78
constexpr Reference(const Inner &innerMapping, ArrayIndex ai, BlobArray &blobs)
Definition: Bytesplit.hpp:68
constexpr auto operator=(value_type v) -> Reference &
Definition: Bytesplit.hpp:105
GetType< TRecordDim, RC > value_type
Definition: Bytesplit.hpp:66
static constexpr auto isComputed(RecordCoord< RecordCoords... >)
Definition: Bytesplit.hpp:51
constexpr Bytesplit(std::tuple< Args... > innerMappingArgs, TRecordDim={})
Definition: Bytesplit.hpp:45
typename Inner::ArrayExtents ArrayExtents
Definition: Bytesplit.hpp:28
constexpr Bytesplit(TArrayExtents extents, TRecordDim={})
Definition: Bytesplit.hpp:40
constexpr auto compute(ArrayIndex ai, RecordCoord< RecordCoords... >, BlobArray &blobs) const
Definition: Bytesplit.hpp:126
InnerMapping< TArrayExtents, internal::SplitBytes< TRecordDim > > Inner
Definition: Bytesplit.hpp:26