alpaka
Abstraction Library for Parallel Kernel Acceleration
ViewTest.hpp
Go to the documentation of this file.
1 /* Copyright 2023 Benjamin Worpitz, Sergei Bastrakov, RenĂ© Widera, Bernhard Manfred Gruber, Jan Stephan
2  * SPDX-License-Identifier: MPL-2.0
3  */
4 
5 #pragma once
6 
7 #include "alpaka/alpaka.hpp"
10 
11 #include <catch2/catch_test_macros.hpp>
12 
13 #include <numeric>
14 #include <type_traits>
15 
16 //! The test specifics.
17 namespace alpaka::test
18 {
19  template<typename TElem, typename TDim, typename TIdx, typename TDev, typename TView>
21  TView const& view,
22  TDev const& dev,
23  Vec<TDim, TIdx> const& extent,
24  Vec<TDim, TIdx> const& offset) -> void
25  {
26  // trait::DevType
27  {
28  static_assert(
29  std::is_same_v<Dev<TView>, TDev>,
30  "The device type of the view has to be equal to the specified one.");
31  }
32 
33  // trait::GetDev
34  {
35  REQUIRE(dev == getDev(view));
36  }
37 
38  // trait::DimType
39  {
40  static_assert(
41  Dim<TView>::value == TDim::value,
42  "The dimensionality of the view has to be equal to the specified one.");
43  }
44 
45  // trait::ElemType
46  {
47  static_assert(
48  std::is_same_v<Elem<TView>, TElem>,
49  "The element type of the view has to be equal to the specified one.");
50  }
51 
52  // trait::GetExtents
53  {
54  REQUIRE(extent == getExtents(view));
55  }
56 
57  // trait::GetPitchBytes
58  {
59  auto const pitchMinimum = alpaka::detail::calculatePitchesFromExtents<TElem>(extent);
60  auto const pitchView = getPitchesInBytes(view);
61 
62  for(TIdx i = TDim::value; i > static_cast<TIdx>(0u); --i)
63  {
64  REQUIRE(pitchView[i - 1] >= pitchMinimum[i - 1]);
65  }
66  }
67 
68  // trait::GetPtrNative
69  {
70  // The view is a const& so the pointer has to point to a const value.
71  using NativePtr = decltype(getPtrNative(view));
72  static_assert(std::is_pointer_v<NativePtr>, "The value returned by getPtrNative has to be a pointer.");
73  static_assert(
74  std::is_const_v<std::remove_pointer_t<NativePtr>>,
75  "The value returned by getPtrNative has to be const when the view is const.");
76 
77  if(getExtentProduct(view) != static_cast<TIdx>(0u))
78  {
79  // The pointer is only required to be non-null when the extent is > 0.
80  TElem const* const invalidPtr(nullptr);
81  REQUIRE(invalidPtr != getPtrNative(view));
82  }
83  else
84  {
85  // When the extent is 0, the pointer is undefined but it should still be possible get it.
86  getPtrNative(view);
87  }
88  }
89 
90  // trait::GetOffsets
91  {
92  REQUIRE(offset == getOffsets(view));
93  }
94 
95  // trait::IdxType
96  {
97  static_assert(
98  std::is_same_v<Idx<TView>, TIdx>,
99  "The idx type of the view has to be equal to the specified one.");
100  }
101  }
102 
103  //! Compares element-wise that all bytes are set to the same value.
105  {
107  template<typename TAcc, typename TIter>
109  TAcc const& acc [[maybe_unused]], // used by SYCL back-end
110  bool* success,
111  TIter const& begin,
112  TIter const& end,
113  std::uint8_t const& byte) const
114  {
115  constexpr auto elemSizeInByte = static_cast<unsigned>(sizeof(decltype(*begin)));
116  for(auto it = begin; it != end; ++it)
117  {
118  auto const& elem = *it;
119  auto const pBytes = reinterpret_cast<std::uint8_t const*>(&elem);
120  for(unsigned i = 0; i < elemSizeInByte; ++i)
121  {
122  if(pBytes[i] != byte)
123  {
124  printf("Byte at offset %u is different: %u != %u\n", i, unsigned{pBytes[i]}, unsigned{byte});
125  *success = false;
126  }
127  }
128  }
129  }
130  };
131 
132  template<typename TAcc, typename TView>
133  ALPAKA_FN_HOST auto verifyBytesSet(TView const& view, std::uint8_t const& byte) -> void
134  {
135  using Dim = Dim<TView>;
136  using Idx = Idx<TView>;
137 
139 
141 
142  REQUIRE(fixture(verifyBytesSet, test::begin(view), test::end(view), byte));
143  }
144 
145  //! Compares iterators element-wise
146 #if BOOST_COMP_GNUC
147 # pragma GCC diagnostic push
148 # pragma GCC diagnostic ignored "-Wfloat-equal" // "comparing floating point with == or != is unsafe"
149 #endif
151  {
153  template<typename TAcc, typename TIterA, typename TIterB>
155  TAcc const& acc [[maybe_unused]], // used by SYCL back-end
156  bool* success,
157  TIterA beginA,
158  TIterA const& endA,
159  TIterB beginB) const
160  {
161  for(; beginA != endA; ++beginA, ++beginB)
162  {
163 #if BOOST_COMP_CLANG
164 # pragma clang diagnostic push
165 # pragma clang diagnostic ignored "-Wfloat-equal" // "comparing floating point with == or != is unsafe"
166 #endif
167  ALPAKA_CHECK(*success, *beginA == *beginB);
168 #if BOOST_COMP_CLANG
169 # pragma clang diagnostic pop
170 #endif
171  }
172  }
173  };
174 #if BOOST_COMP_GNUC
175 # pragma GCC diagnostic pop
176 #endif
177 
178  template<typename TAcc, typename TViewB, typename TViewA>
179  ALPAKA_FN_HOST auto verifyViewsEqual(TViewA const& viewA, TViewB const& viewB) -> void
180  {
181  using DimA = Dim<TViewA>;
182  using DimB = Dim<TViewB>;
183  static_assert(DimA::value == DimB::value, "viewA and viewB are required to have identical Dim");
184  using IdxA = Idx<TViewA>;
185  using IdxB = Idx<TViewB>;
186  static_assert(std::is_same_v<IdxA, IdxB>, "viewA and viewB are required to have identical Idx");
187 
189 
190  VerifyViewsEqualKernel verifyViewsEqualKernel;
191 
192  REQUIRE(fixture(verifyViewsEqualKernel, test::begin(viewA), test::end(viewA), test::begin(viewB)));
193  }
194 
195  //! Fills the given view with increasing values starting at 0.
196  template<typename TView, typename TQueue>
197  ALPAKA_FN_HOST auto iotaFillView(TQueue& queue, TView& view) -> void
198  {
199  using Elem = Elem<TView>;
200 
201  auto const platformHost = alpaka::PlatformCpu{};
202  auto const devHost = alpaka::getDevByIdx(platformHost, 0);
203 
204  auto const extent = getExtents(view);
205 
206  // Init buf with increasing values
207  std::vector<Elem> v(static_cast<std::size_t>(extent.prod()), static_cast<Elem>(0));
208  std::iota(std::begin(v), std::end(v), static_cast<Elem>(0));
209  auto plainBuf = createView(devHost, v, extent);
210 
211  // Copy the generated content into the given view.
212  memcpy(queue, view, plainBuf);
213 
214  wait(queue);
215  }
216 
217  template<typename TAcc, typename TView, typename TQueue>
218  ALPAKA_FN_HOST auto testViewMutable(TQueue& queue, TView& view) -> void
219  {
220  // trait::GetPtrNative
221  {
222  // The view is a non-const so the pointer has to point to a non-const value.
223  using NativePtr = decltype(getPtrNative(view));
224  static_assert(std::is_pointer_v<NativePtr>, "The value returned by getPtrNative has to be a pointer.");
225  static_assert(
226  !std::is_const_v<std::remove_pointer_t<NativePtr>>,
227  "The value returned by getPtrNative has to be non-const when the view is non-const.");
228  }
229 
230  // set
231  {
232  auto const byte(static_cast<uint8_t>(42u));
233  memset(queue, view, byte);
234  wait(queue);
235  verifyBytesSet<TAcc>(view, byte);
236  }
237 
238  // copy
239  {
240  using Elem = Elem<TView>;
241  using Idx = Idx<TView>;
242 
243  auto const devAcc = getDev(view);
244  auto const extent = getExtents(view);
245 
246  // copy into given view
247  {
248  auto srcBufAcc = allocBuf<Elem, Idx>(devAcc, extent);
249  iotaFillView(queue, srcBufAcc);
250  memcpy(queue, view, srcBufAcc);
251  wait(queue);
252  verifyViewsEqual<TAcc>(view, srcBufAcc);
253  }
254 
255  // copy from given view
256  {
257  auto dstBufAcc = allocBuf<Elem, Idx>(devAcc, extent);
258  memcpy(queue, dstBufAcc, view);
259  wait(queue);
260  verifyViewsEqual<TAcc>(dstBufAcc, view);
261  }
262  }
263  }
264 } // namespace alpaka::test
#define ALPAKA_CHECK(success, expression)
Definition: Check.hpp:11
The fixture for executing a kernel on a given accelerator.
#define ALPAKA_FN_ACC
All functions that can be used on an accelerator have to be attributed with ALPAKA_FN_ACC or ALPAKA_F...
Definition: Common.hpp:38
#define ALPAKA_FN_HOST
Definition: Common.hpp:40
#define ALPAKA_NO_HOST_ACC_WARNING
Disable nvcc warning: 'calling a host function from host device function.' Usage: ALPAKA_NO_HOST_ACC_...
Definition: Common.hpp:82
The test specifics.
Definition: TestAccs.hpp:27
ALPAKA_FN_HOST auto verifyBytesSet(TView const &view, std::uint8_t const &byte) -> void
Definition: ViewTest.hpp:133
ALPAKA_FN_HOST auto iotaFillView(TQueue &queue, TView &view) -> void
Fills the given view with increasing values starting at 0.
Definition: ViewTest.hpp:197
ALPAKA_FN_HOST auto end(TView &view) -> Iterator< TView >
Definition: Iterator.hpp:139
ALPAKA_FN_HOST auto testViewMutable(TQueue &queue, TView &view) -> void
Definition: ViewTest.hpp:218
ALPAKA_FN_HOST auto verifyViewsEqual(TViewA const &viewA, TViewB const &viewB) -> void
Definition: ViewTest.hpp:179
ALPAKA_FN_HOST auto testViewImmutable(TView const &view, TDev const &dev, Vec< TDim, TIdx > const &extent, Vec< TDim, TIdx > const &offset) -> void
Definition: ViewTest.hpp:20
constexpr auto offset
Definition: Extent.hpp:34
ALPAKA_FN_HOST auto begin(TView &view) -> Iterator< TView >
Definition: Iterator.hpp:133
typename trait::IdxType< T >::type Idx
Definition: Traits.hpp:29
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getExtentProduct(T const &object) -> Idx< T >
Definition: Traits.hpp:134
ALPAKA_FN_HOST auto memcpy(TQueue &queue, alpaka::detail::DevGlobalImplGeneric< TTag, TTypeDst > &viewDst, TViewSrc const &viewSrc) -> void
typename trait::DevType< T >::type Dev
The device type trait alias template to remove the ::type.
Definition: Traits.hpp:56
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getExtents(T const &object) -> Vec< Dim< T >, Idx< T >>
Definition: Traits.hpp:59
ALPAKA_FN_HOST auto getPitchesInBytes(TView const &view) -> Vec< Dim< TView >, Idx< TView >>
Definition: Traits.hpp:196
ALPAKA_FN_HOST auto getPtrNative(TView const &view) -> Elem< TView > const *
Gets the native pointer of the memory view.
Definition: Traits.hpp:136
std::remove_volatile_t< typename trait::ElemType< TView >::type > Elem
The element type trait alias template to remove the ::type.
Definition: Traits.hpp:21
ALPAKA_FN_HOST auto memset(TQueue &queue, TViewFwd &&view, std::uint8_t const &byte, TExtent const &extent) -> void
Sets the bytes of the memory of view, described by extent, to the given value.
Definition: Traits.hpp:231
ALPAKA_FN_HOST auto getDevByIdx(TPlatform const &platform, std::size_t const &devIdx) -> Dev< TPlatform >
Definition: Traits.hpp:62
ALPAKA_FN_HOST auto getDev(T const &t)
Definition: Traits.hpp:68
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getOffsets(T const &object) -> Vec< Dim< T >, Idx< T >>
Definition: Traits.hpp:55
ALPAKA_FN_HOST auto wait(TAwaited const &awaited) -> void
Waits the thread for the completion of the given awaited action to complete.
Definition: Traits.hpp:34
auto createView(TDev const &dev, TElem *pMem, TExtent const &extent)
Creates a view to a device pointer.
Definition: Traits.hpp:434
typename trait::DimType< T >::type Dim
The dimension type trait alias template to remove the ::type.
Definition: Traits.hpp:19
The CPU device platform.
Definition: PlatformCpu.hpp:18
Compares element-wise that all bytes are set to the same value.
Definition: ViewTest.hpp:105
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC void operator()(TAcc const &acc[[maybe_unused]], bool *success, TIter const &begin, TIter const &end, std::uint8_t const &byte) const
Definition: ViewTest.hpp:108
Compares iterators element-wise.
Definition: ViewTest.hpp:151
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC void operator()(TAcc const &acc[[maybe_unused]], bool *success, TIterA beginA, TIterA const &endA, TIterB beginB) const
Definition: ViewTest.hpp:154