alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
AccCpuThreads.hpp
Go to the documentation of this file.
1/* Copyright 2026 Axel Huebl, Benjamin Worpitz, René Widera, Jan Stephan, Bernhard Manfred Gruber, Andrea Bocci
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
7// Base classes.
24
25// Specialized traits.
26#include "alpaka/acc/Traits.hpp"
27#include "alpaka/dev/Traits.hpp"
28#include "alpaka/idx/Traits.hpp"
31
32// Implementation details.
33#include "alpaka/acc/Tag.hpp"
37#include "alpaka/dev/DevCpu.hpp"
38
39#ifdef __cpp_lib_format
40# include <format>
41#endif
42#include <memory>
43#include <string>
44#include <thread>
45
46#ifdef ALPAKA_ACC_CPU_B_SEQ_T_THREADS_ENABLED
47
48namespace alpaka
49{
50 template<typename TDim, typename TIdx, typename TKernelFnObj, typename... TArgs>
51 class TaskKernelCpuThreads;
52
53 //! The CPU threads accelerator.
54 //!
55 //! This accelerator allows parallel kernel execution on a CPU device.
56 //! It uses std::thread to implement the parallelism.
57 template<typename TDim, typename TIdx>
58 class AccCpuThreads final
59 : public WorkDivMembers<TDim, TIdx>
60 , public gb::IdxGbRef<TDim, TIdx>
61 , public bt::IdxBtRefThreadIdMap<TDim, TIdx>
62 , public AtomicHierarchy<
63 AtomicCpu, // grid atomics
64 AtomicCpu, // block atomics
65 AtomicCpu> // thread atomics
66 , public math::MathStdLib
69 , public BlockSyncBarrierThread<TIdx>
70 , public GridSyncBarrierThread<TIdx>
71 , public IntrinsicCpu
72 , public MemFenceCpu
73# ifdef ALPAKA_DISABLE_VENDOR_RNG
74 , public rand::RandDefault
75# else
76 , public rand::RandStdLib
77# endif
79 , public interface::Implements<InterfaceAcc, AccCpuThreads<TDim, TIdx>>
80 {
81 static_assert(
82 sizeof(TIdx) >= sizeof(int),
83 "Index type is not supported, consider using int or a larger type.");
84
85 public:
86 // Partial specialization with the correct TDim and TIdx is not allowed.
87 template<typename TDim2, typename TIdx2, typename TKernelFnObj, typename... TArgs>
88 friend class ::alpaka::TaskKernelCpuThreads;
89
90 AccCpuThreads(AccCpuThreads const&) = delete;
92 auto operator=(AccCpuThreads const&) -> AccCpuThreads& = delete;
94
95 private:
96 template<typename TWorkDiv>
97 ALPAKA_FN_HOST AccCpuThreads(TWorkDiv const& workDiv, std::size_t const& blockSharedMemDynSizeBytes)
98 : WorkDivMembers<TDim, TIdx>(workDiv)
99 , gb::IdxGbRef<TDim, TIdx>(m_gridBlockIdx)
100 , bt::IdxBtRefThreadIdMap<TDim, TIdx>(m_threadToIndexMap)
101 , BlockSharedMemDynMember<>(blockSharedMemDynSizeBytes)
105 [this]() { syncBlockThreads(*this); },
106 [this]() noexcept { return (m_idMasterThread == std::this_thread::get_id()); })
109 , m_gridBlockIdx(Vec<TDim, TIdx>::zeros())
110 {
111 }
112
113 private:
114 // getIdx
115 std::mutex mutable m_mtxMapInsert; //!< The mutex used to secure insertion into the ThreadIdToIdxMap.
116 typename bt::IdxBtRefThreadIdMap<TDim, TIdx>::
117 ThreadIdToIdxMap mutable m_threadToIndexMap; //!< The mapping of thread id's to indices.
118 Vec<TDim, TIdx> mutable m_gridBlockIdx; //!< The index of the currently executed block.
119
120 // allocBlockSharedArr
121 std::thread::id mutable m_idMasterThread; //!< The id of the master thread.
122 };
123
124 namespace trait
125 {
126 //! The CPU threads accelerator accelerator type trait specialization.
127 template<typename TDim, typename TIdx>
128 struct AccType<AccCpuThreads<TDim, TIdx>>
129 {
131 };
132
133 //! The CPU threads single thread accelerator type trait specialization.
134 template<typename TDim, typename TIdx>
135 struct IsSingleThreadAcc<AccCpuThreads<TDim, TIdx>> : std::false_type
136 {
137 };
138
139 //! The CPU threads multi thread accelerator type trait specialization.
140 template<typename TDim, typename TIdx>
141 struct IsMultiThreadAcc<AccCpuThreads<TDim, TIdx>> : std::true_type
142 {
143 };
144
145 //! The CPU threads accelerator device properties get trait specialization.
146 template<typename TDim, typename TIdx>
147 struct GetAccDevProps<AccCpuThreads<TDim, TIdx>>
148 {
150 {
151# ifdef ALPAKA_CI
152 auto const blockThreadCountMax = static_cast<TIdx>(8);
153# else
154 // \TODO: Magic number. What is the maximum? Just set a reasonable value? There is a implementation
155 // defined maximum where the creation of a new thread crashes. std::thread::hardware_concurrency can
156 // return 0, so 1 is the default case?
157 auto const blockThreadCountMax = std::max(
158 static_cast<TIdx>(1),
159 alpaka::core::clipCast<TIdx>(std::thread::hardware_concurrency() * 8));
160# endif
161 auto const memBytes = getMemBytes(dev);
162 return {// m_multiProcessorCount
163 static_cast<TIdx>(1),
164 // m_gridBlockExtentMax
165 Vec<TDim, TIdx>::all(std::numeric_limits<TIdx>::max()),
166 // m_gridBlockCountMax
167 std::numeric_limits<TIdx>::max(),
168 // m_blockThreadExtentMax
169 Vec<TDim, TIdx>::all(blockThreadCountMax),
170 // m_blockThreadCountMax
171 blockThreadCountMax,
172 // m_threadElemExtentMax
173 Vec<TDim, TIdx>::all(std::numeric_limits<TIdx>::max()),
174 // m_threadElemCountMax
175 std::numeric_limits<TIdx>::max(),
176 // m_sharedMemSizeBytes
177 memBytes,
178 // m_globalMemSizeBytes
179 memBytes,
180 // m_cooperativeLaunch
181 true};
182 }
183 };
184
185 //! The CPU threads accelerator name trait specialization.
186 template<typename TDim, typename TIdx>
187 struct GetAccName<AccCpuThreads<TDim, TIdx>>
188 {
189 ALPAKA_FN_HOST static auto getAccName() -> std::string
190 {
191# if ALPAKA_COMP_CLANG
192# pragma clang diagnostic push
193# pragma clang diagnostic ignored "-Wexit-time-destructors"
194# endif
195 using namespace std::literals;
196 static std::string const accName =
197# ifdef __cpp_lib_format
198 std::format("AccCpuThreads<{},{}>", TDim::value, core::demangled<TIdx>);
199# else
200 "AccCpuThreads<"s + std::to_string(TDim::value) + ","s + std::string(core::demangled<TIdx>) + ">"s;
201# endif
202 return accName;
203# if ALPAKA_COMP_CLANG
204# pragma clang diagnostic pop
205# endif
206 }
207 };
208
209 //! The CPU threads accelerator device type trait specialization.
210 template<typename TDim, typename TIdx>
211 struct DevType<AccCpuThreads<TDim, TIdx>>
212 {
213 using type = DevCpu;
214 };
215
216 //! The CPU threads accelerator dimension getter trait specialization.
217 template<typename TDim, typename TIdx>
218 struct DimType<AccCpuThreads<TDim, TIdx>>
219 {
220 using type = TDim;
221 };
222
223 //! The CPU threads accelerator execution task type trait specialization.
224 template<typename TDim, typename TIdx, typename TWorkDiv, typename TKernelFnObj, typename... TArgs>
225 struct CreateTaskKernel<AccCpuThreads<TDim, TIdx>, TWorkDiv, TKernelFnObj, TArgs...>
226 {
228 TWorkDiv const& workDiv,
229 TKernelFnObj const& kernelFnObj,
230 TArgs&&... args)
231 {
232 return TaskKernelCpuThreads<TDim, TIdx, TKernelFnObj, TArgs...>(
233 workDiv,
234 kernelFnObj,
235 std::forward<TArgs>(args)...);
236 }
237 };
238
239 //! The CPU threads thread accelerator execution cooperative task type trait specialization.
240 template<typename TDim, typename TIdx, typename TWorkDiv, typename TKernelFnObj, typename... TArgs>
241 struct CreateTaskCooperativeKernel<AccCpuThreads<TDim, TIdx>, TWorkDiv, TKernelFnObj, TArgs...>
242 {
244 TWorkDiv const& workDiv,
245 TKernelFnObj const& kernelFnObj,
246 TArgs&&... args)
247 {
248 auto const gridBlockExtent = getWorkDiv<Grid, Blocks>(workDiv);
249 if(gridBlockExtent.prod() != static_cast<TIdx>(1u))
250 {
251 throw std::runtime_error(
252 "The std::thread accelerator supports only a single block operation with cooperative kernel!\n"
253 "Consider useing a different CPU accelerator.");
254 }
255
256 return TaskKernelCpuThreads<TDim, TIdx, TKernelFnObj, TArgs...>(
257 workDiv,
258 kernelFnObj,
259 std::forward<TArgs>(args)...);
260 }
261 };
262
263 //! The CPU threads execution task platform type trait specialization.
264 template<typename TDim, typename TIdx>
265 struct PlatformType<AccCpuThreads<TDim, TIdx>>
266 {
268 };
269
270 //! The CPU threads accelerator idx type trait specialization.
271 template<typename TDim, typename TIdx>
272 struct IdxType<AccCpuThreads<TDim, TIdx>>
273 {
274 using type = TIdx;
275 };
276
277 template<typename TDim, typename TIdx>
278 struct AccToTag<alpaka::AccCpuThreads<TDim, TIdx>>
279 {
281 };
282
283 template<typename TDim, typename TIdx>
284 struct TagToAcc<alpaka::TagCpuThreads, TDim, TIdx>
285 {
287 };
288 } // namespace trait
289} // namespace alpaka
290
291#endif
The CPU threads accelerator.
auto operator=(AccCpuThreads const &) -> AccCpuThreads &=delete
AccCpuThreads(AccCpuThreads &&)=delete
AccCpuThreads(AccCpuThreads const &)=delete
auto operator=(AccCpuThreads &&) -> AccCpuThreads &=delete
Dynamic block shared memory provider using fixed-size member array to allocate memory on the stack or...
auto staticMemCapacity() const -> std::uint32_t
The thread id map barrier block synchronization.
ALPAKA_FN_HOST BlockSyncBarrierThread(TIdx const &blockThreadCount)
The CPU device handle.
Definition DevCpu.hpp:56
The thread id map barrier grid synchronization.
ALPAKA_FN_HOST GridSyncBarrierThread(TIdx const &blockThreadCount)
The CPU intrinsic.
The default CPU memory fence.
The CPU threads execution task.
A n-dimensional vector.
Definition Vec.hpp:38
ALPAKA_NO_HOST_ACC_WARNING static ALPAKA_FN_HOST_ACC constexpr auto zeros() -> Vec< TDim, TVal >
Zero value constructor.
Definition Vec.hpp:99
ALPAKA_NO_HOST_ACC_WARNING static ALPAKA_FN_HOST_ACC constexpr auto all(TVal const &val) -> Vec< TDim, TVal >
Single value constructor.
Definition Vec.hpp:89
A basic class holding the work division as grid block extent, block thread and thread element extent.
The threads accelerator index provider.
ALPAKA_FN_HOST IdxBtRefThreadIdMap(ThreadIdToIdxMap const &mThreadToIndices)
A IdxGbRef grid block index.
Definition IdxGbRef.hpp:20
IdxGbRef(Vec< TDim, TIdx > const &gridBlockIdx)
Definition IdxGbRef.hpp:22
The standard library math trait specializations.
"Tiny" state mersenne twister implementation
#define ALPAKA_FN_HOST
Definition Common.hpp:43
constexpr std::string_view demangled
auto clipCast(V const &val) -> T
Definition ClipCast.hpp:16
The alpaka accelerator library.
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_HOST_ACC auto getWorkDiv(TWorkDiv const &workDiv) -> Vec< Dim< TWorkDiv >, Idx< TWorkDiv > >
Get the extent requested.
Definition Traits.hpp:33
ALPAKA_FN_HOST auto getMemBytes(TDev const &dev) -> std::size_t
Definition Traits.hpp:102
ALPAKA_NO_HOST_ACC_WARNING ALPAKA_FN_ACC auto syncBlockThreads(TBlockSync const &blockSync) -> void
Synchronizes all threads within the current block (independently for all blocks).
Definition Traits.hpp:36
The acceleration properties on a device.
The CPU device platform.
Tag used in class inheritance hierarchies that describes that a specific interface (TInterface) is im...
Definition Interface.hpp:15
The accelerator type trait.
Definition Traits.hpp:42
static ALPAKA_FN_HOST auto createTaskCooperativeKernel(TWorkDiv const &workDiv, TKernelFnObj const &kernelFnObj, TArgs &&... args)
The cooperative kernel execution task creation trait.
Definition Traits.hpp:46
static ALPAKA_FN_HOST auto createTaskKernel(TWorkDiv const &workDiv, TKernelFnObj const &kernelFnObj, TArgs &&... args)
The kernel execution task creation trait.
Definition Traits.hpp:37
The device type trait.
Definition Traits.hpp:23
The dimension getter type trait.
Definition Traits.hpp:14
static ALPAKA_FN_HOST auto getAccDevProps(DevCpu const &dev) -> AccDevProps< TDim, TIdx >
The device properties get trait.
Definition Traits.hpp:66
static ALPAKA_FN_HOST auto getAccName() -> std::string
The accelerator name trait.
Definition Traits.hpp:73
The idx type trait.
Definition Traits.hpp:25
The multi thread accelerator trait.
Definition Traits.hpp:61
The single thread accelerator trait.
Definition Traits.hpp:51
The platform type trait.
Definition Traits.hpp:38
The single-threaded warp to emulate it on CPUs.