alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
Api.hpp
Go to the documentation of this file.
1/* Copyright 2024 René Widera, Simeon Ehrig
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
10#include "alpaka/concepts.hpp"
11#include "alpaka/mem/trait.hpp"
13#include "alpaka/utility.hpp"
14
15#include <string>
16
17namespace alpaka
18{
19 namespace api
20 {
21 struct OneApi : public GenericSycl<OneApi>
22 {
23 static std::string getName()
24 {
25 return "OneApi";
26 }
27 };
28
29 constexpr auto oneApi = OneApi{};
30 } // namespace api
31
32#if ALPAKA_LANG_ONEAPI
33
34 namespace onHost::trait
35 {
36 template<>
37 struct IsPlatformAvailable::Op<api::OneApi> : std::true_type
38 {
39 };
40
41 template<>
42 struct IsDeviceSupportedBy::Op<deviceKind::IntelGpu, api::OneApi> : std::true_type
43 {
44 };
45
46 template<>
47 struct IsDeviceSupportedBy::Op<deviceKind::NvidiaGpu, api::OneApi> : std::true_type
48 {
49 };
50
51 template<>
52 struct IsDeviceSupportedBy::Op<deviceKind::AmdGpu, api::OneApi> : std::true_type
53 {
54 };
55
56 template<>
57 struct IsDeviceSupportedBy::Op<deviceKind::Cpu, api::OneApi> : std::true_type
58 {
59 };
60
61 /** This limit is not exact but for typical CPUs, and GPUs from Intel, NVIDIA and AMD we can at least use 1024
62 * threads per block.
63 * @todo Check if this produces issues on FPGAs, in this case the deviceKind should be used and the
64 * limit should be different for each deviceKind.
65 */
66 template<alpaka::concepts::DeviceKind T_DeviceKind>
67 struct GetMaxThreadsPerBlock::Op<api::OneApi, T_DeviceKind, exec::OneApi>
68 {
69 consteval uint32_t operator()(api::OneApi const, T_DeviceKind const, exec::OneApi const) const
70 {
71 return 1024u;
72 }
73 };
74 } // namespace onHost::trait
75
76#endif
77 namespace trait
78 {
79
80 template<typename T_Type>
81 struct GetArchSimdWidth::Op<T_Type, api::OneApi, deviceKind::Cpu>
82 {
83 constexpr uint32_t operator()(api::OneApi const, deviceKind::Cpu const) const
84 {
86 }
87 };
88
89 template<>
91 {
92 constexpr uint32_t operator()(api::OneApi const, deviceKind::Cpu const) const
93 {
95 }
96 };
97
98 template<>
100 {
101 constexpr uint32_t operator()(api::OneApi const, deviceKind::Cpu const) const
102 {
104 }
105 };
106
107 // for GPU
108 template<typename T_Type, concepts::GpuType T_DeviceKind>
109 struct GetArchSimdWidth::Op<T_Type, api::OneApi, T_DeviceKind>
110 {
111 constexpr uint32_t operator()(api::OneApi const, T_DeviceKind const) const
112 {
113 /** vector load and store width in bytes */
114 // copied from CUDA/HIP -> not verified if this is the optional value
115 constexpr std::size_t simdWidthInByte = 16u;
116 return alpaka::divExZero(simdWidthInByte, sizeof(T_Type));
117 }
118 };
119
120 template<concepts::GpuType T_DeviceKind>
121 struct GetNumPipelines::Op<api::OneApi, T_DeviceKind>
122 {
123 constexpr uint32_t operator()(api::OneApi const, T_DeviceKind const) const
124 {
125 /* AMD GPUs SIMD units will be interpreted as pipelines, CUDA GPUs using 2 pipelines (2 warp schedular)
126 * @TODO check INTEL GPUs
127 */
128 constexpr uint32_t numPipes = 4u;
129 return numPipes;
130 }
131 };
132
133 template<concepts::GpuType T_DeviceKind>
134 struct GetCachelineSize::Op<api::OneApi, T_DeviceKind>
135 {
136 constexpr uint32_t operator()(api::OneApi const, T_DeviceKind const) const
137 {
138 // loading 16 byte per thread will result in optimal memory bandwidth
139 // copied from CUDA/HIP -> not verified if this is the optional value
140 return 16u;
141 }
142 };
143
144 template<typename T_Type>
146 {
147 consteval uint32_t operator()(api::OneApi const, deviceKind::IntelGpu const, uint32_t const alignmentBytes)
148 const
149 {
150 /* Level Zero imposes a 64 KiB alignment limit.
151 @see https://www.intel.com/content/www/us/en/developer/articles/release-notes/oneapi-dpcpp/2024.html
152 Quote: "Limit alignment of allocation requests at 64KB which is the only alignment supported by Level
153 Zero."
154 */
155 constexpr uint32_t onePageSize = 64u * 1024u;
156 uint32_t tmp = alignmentBytes;
157 while(tmp > onePageSize && tmp >= alignof(T_Type) * 2)
158 {
159 tmp /= 2;
160 }
161 return tmp;
162 }
163 };
164 } // namespace trait
165
166 namespace onAcc::internal::trait
167 {
168 template<typename T_Acc>
170 {
171 constexpr auto operator()(T_Acc const&, api::OneApi, deviceKind::Cpu) const
172 {
173 return layout::Contiguous{};
174 }
175 };
176 } // namespace onAcc::internal::trait
177} // namespace alpaka
constexpr auto oneApi
Definition Api.hpp:29
constexpr DeviceKind deviceKind
Definition tag.hpp:30
constexpr Api api
Definition tag.hpp:24
constexpr uint32_t getCPUSimdWidth()
constexpr uint32_t getCPUNumPipelines()
constexpr uint32_t getCPUCachelineSize()
main alpaka namespace.
Definition alpaka.hpp:76
ALPAKA_FN_HOST_ACC constexpr auto divExZero(Integral a, Integral b) -> Integral
Returns the max(a / b, 1) as integer.
Definition utility.hpp:41
static std::string getName()
Definition Api.hpp:23
constexpr auto operator()(T_Acc const &, api::OneApi, deviceKind::Cpu) const
Definition Api.hpp:171
Indices will be contiguous within each dimension for each worker thread.
Definition layout.hpp:20
consteval uint32_t operator()(T_Api const, T_DeviceKind const, T_Exec const) const
Definition trait.hpp:132
consteval uint32_t operator()(api::OneApi const, deviceKind::IntelGpu const, uint32_t const alignmentBytes) const
Definition Api.hpp:147
constexpr uint32_t operator()(api::OneApi const, T_DeviceKind const) const
Definition Api.hpp:111
constexpr uint32_t operator()(api::OneApi const, deviceKind::Cpu const) const
Definition Api.hpp:83
constexpr uint32_t operator()(api::OneApi const, T_DeviceKind const) const
Definition Api.hpp:136
constexpr uint32_t operator()(api::OneApi const, deviceKind::Cpu const) const
Definition Api.hpp:101
constexpr uint32_t operator()(api::OneApi const, T_DeviceKind const) const
Definition Api.hpp:123
constexpr uint32_t operator()(api::OneApi const, deviceKind::Cpu const) const
Definition Api.hpp:92