alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
ApiHipRt.hpp
Go to the documentation of this file.
1/* Copyright 2026 Andrea Bocci, Maria Michailidi
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
9
10#ifdef ALPAKA_ACC_GPU_HIP_ENABLED
11
12# include <hip/hip_runtime_api.h>
13# include <hip/hip_version.h>
14
15namespace alpaka
16{
17 struct ApiHipRt
18 {
19 // Names
20 static constexpr char name[] = "Hip";
21 static constexpr auto version = ALPAKA_VERSION_NUMBER(HIP_VERSION_MAJOR, HIP_VERSION_MINOR, 0);
22
23 // Types
24 using DeviceAttr_t = ::hipDeviceAttribute_t;
25 using DeviceProp_t = ::hipDeviceProp_t;
26 using Error_t = ::hipError_t;
27 using Event_t = ::hipEvent_t;
28 using Extent_t = ::hipExtent;
29 using Flag_t = unsigned int;
30 using FuncAttributes_t = ::hipFuncAttributes;
31 using HostFn_t = void (*)(void* data); // same as hipHostFn_t
32 using Limit_t = ::hipLimit_t;
33 using Memcpy3DParms_t = ::hipMemcpy3DParms;
34 using MemcpyKind_t = ::hipMemcpyKind;
35 using PitchedPtr_t = ::hipPitchedPtr;
36 using Pos_t = ::hipPos;
37 using Stream_t = ::hipStream_t;
38
39 // Constants
40 static constexpr Error_t success = ::hipSuccess;
41 static constexpr Error_t errorNotReady = ::hipErrorNotReady;
42 static constexpr Error_t errorHostMemoryAlreadyRegistered = ::hipErrorHostMemoryAlreadyRegistered;
43 static constexpr Error_t errorHostMemoryNotRegistered = ::hipErrorHostMemoryNotRegistered;
44 static constexpr Error_t errorUnsupportedLimit = ::hipErrorUnsupportedLimit;
45 static constexpr Error_t errorUnknown = ::hipErrorUnknown;
46
47 static constexpr Flag_t eventDefault = hipEventDefault;
48 static constexpr Flag_t eventBlockingSync = hipEventBlockingSync;
49 static constexpr Flag_t eventDisableTiming = hipEventDisableTiming;
50 static constexpr Flag_t eventInterprocess = hipEventInterprocess;
51
52 static constexpr Flag_t hostMallocDefault = hipHostMallocDefault;
53 static constexpr Flag_t hostMallocMapped = hipHostMallocMapped;
54 static constexpr Flag_t hostMallocPortable = hipHostMallocPortable;
55 static constexpr Flag_t hostMallocWriteCombined = hipHostMallocWriteCombined;
56 static constexpr Flag_t hostMallocCoherent = hipHostMallocCoherent;
57 static constexpr Flag_t hostMallocNonCoherent = hipHostMallocNonCoherent;
58
59 static constexpr Flag_t memAttachGlobal = hipMemAttachGlobal;
60 static constexpr Flag_t memAttachHost = hipMemAttachHost;
61
62 static constexpr Flag_t hostRegisterDefault = hipHostRegisterDefault;
63 static constexpr Flag_t hostRegisterPortable = hipHostRegisterPortable;
64 static constexpr Flag_t hostRegisterMapped = hipHostRegisterMapped;
65 static constexpr Flag_t hostRegisterIoMemory = hipHostRegisterIoMemory;
66
67 static constexpr MemcpyKind_t memcpyDefault = ::hipMemcpyDefault;
68 static constexpr MemcpyKind_t memcpyDeviceToDevice = ::hipMemcpyDeviceToDevice;
69 static constexpr MemcpyKind_t memcpyDeviceToHost = ::hipMemcpyDeviceToHost;
70 static constexpr MemcpyKind_t memcpyHostToDevice = ::hipMemcpyHostToDevice;
71
72 static constexpr Flag_t streamDefault = hipStreamDefault;
73 static constexpr Flag_t streamNonBlocking = hipStreamNonBlocking;
74
75 static constexpr DeviceAttr_t deviceAttributeMaxBlockDimX = ::hipDeviceAttributeMaxBlockDimX;
76 static constexpr DeviceAttr_t deviceAttributeMaxBlockDimY = ::hipDeviceAttributeMaxBlockDimY;
77 static constexpr DeviceAttr_t deviceAttributeMaxBlockDimZ = ::hipDeviceAttributeMaxBlockDimZ;
78 static constexpr DeviceAttr_t deviceAttributeMaxGridDimX = ::hipDeviceAttributeMaxGridDimX;
79 static constexpr DeviceAttr_t deviceAttributeMaxGridDimY = ::hipDeviceAttributeMaxGridDimY;
80 static constexpr DeviceAttr_t deviceAttributeMaxGridDimZ = ::hipDeviceAttributeMaxGridDimZ;
81 static constexpr DeviceAttr_t deviceAttributeMaxSharedMemoryPerBlock
82 = ::hipDeviceAttributeMaxSharedMemoryPerBlock;
83 static constexpr DeviceAttr_t deviceAttributeMaxThreadsPerBlock = ::hipDeviceAttributeMaxThreadsPerBlock;
84 static constexpr DeviceAttr_t deviceAttributeMultiprocessorCount = ::hipDeviceAttributeMultiprocessorCount;
85 static constexpr DeviceAttr_t deviceAttributeWarpSize = ::hipDeviceAttributeWarpSize;
86 static constexpr DeviceAttr_t deviceAttributeCooperativeLaunch = ::hipDeviceAttributeCooperativeLaunch;
87
88# if HIP_VERSION >= 40'500'000
89 static constexpr Limit_t limitPrintfFifoSize = ::hipLimitPrintfFifoSize;
90# else
91 static constexpr Limit_t limitPrintfFifoSize
92 = static_cast<Limit_t>(0x01); // Implemented only in ROCm 4.5.0 and later.
93# endif
94 static constexpr Limit_t limitMallocHeapSize = ::hipLimitMallocHeapSize;
95
96 // Host function helper
97 // Encapsulates the different function signatures used by hipStreamAddCallback and hipLaunchHostFn, and the
98 // different calling conventions used by CUDA (__stdcall on Win32) and HIP (standard).
99 struct HostFnAdaptor
100 {
101 HostFn_t func_;
102 void* data_;
103
104 static void hostFunction(void* data)
105 {
106 auto ptr = reinterpret_cast<HostFnAdaptor*>(data);
107 ptr->func_(ptr->data_);
108 delete ptr;
109 }
110
111 static void streamCallback(Stream_t, Error_t, void* data)
112 {
113 auto ptr = reinterpret_cast<HostFnAdaptor*>(data);
114 ptr->func_(ptr->data_);
115 delete ptr;
116 }
117 };
118
119 // Runtime API
120 static inline Error_t deviceGetAttribute(int* value, DeviceAttr_t attr, int device)
121 {
122 return ::hipDeviceGetAttribute(value, attr, device);
123 }
124
125 static inline Error_t deviceGetLimit(size_t* pValue, Limit_t limit)
126 {
127# if HIP_VERSION < 40'500'000
128 if(limit == limitPrintfFifoSize)
129 {
130 // Implemented only in ROCm 4.5.0 and later.
131 return errorUnsupportedLimit;
132 }
133# endif
134 return ::hipDeviceGetLimit(pValue, limit);
135 }
136
137 static inline Error_t deviceReset()
138 {
139 return ::hipDeviceReset();
140 }
141
142 static inline Error_t deviceSetLimit(Limit_t /* limit */, size_t /* value */)
143 {
144 // Not implemented.
145 return errorUnsupportedLimit;
146 }
147
148 static inline Error_t deviceSynchronize()
149 {
150 return ::hipDeviceSynchronize();
151 }
152
153 static inline Error_t eventCreate(Event_t* event)
154 {
155 return ::hipEventCreate(event);
156 }
157
158 static inline Error_t eventCreateWithFlags(Event_t* event, Flag_t flags)
159 {
160 return ::hipEventCreateWithFlags(event, flags);
161 }
162
163 static inline Error_t eventDestroy(Event_t event)
164 {
165 return ::hipEventDestroy(event);
166 }
167
168 static inline Error_t eventQuery(Event_t event)
169 {
170 return ::hipEventQuery(event);
171 }
172
173 static inline Error_t eventRecord(Event_t event, Stream_t stream)
174 {
175 return ::hipEventRecord(event, stream);
176 }
177
178 static inline Error_t eventSynchronize(Event_t event)
179 {
180 return ::hipEventSynchronize(event);
181 }
182
183 static inline Error_t free(void* devPtr)
184 {
185 return ::hipFree(devPtr);
186 }
187
188 static inline Error_t freeAsync([[maybe_unused]] void* devPtr, [[maybe_unused]] Stream_t stream)
189 {
190 // stream-ordered memory operations are fully implemented only in ROCm 5.3.0 and later.
191# if HIP_VERSION >= 50'300'000
192 // hipFreeAsync fails on a null pointer deallocation
193 if(devPtr)
194 {
195 return ::hipFreeAsync(devPtr, stream);
196 }
197 else
198 {
199 return ::hipSuccess;
200 }
201# else
202 // Not implemented.
203 return errorUnknown;
204# endif
205 }
206
207 static inline Error_t funcGetAttributes(FuncAttributes_t* attr, void const* func)
208 {
209 return ::hipFuncGetAttributes(attr, func);
210 }
211
212 template<typename T>
213 static inline Error_t funcGetAttributes(FuncAttributes_t* attr, T* func)
214 {
215# if ALPAKA_COMP_GNUC
216# pragma GCC diagnostic push
217# pragma GCC diagnostic ignored "-Wconditionally-supported"
218# endif
219 return ::hipFuncGetAttributes(attr, reinterpret_cast<void const*>(func));
220# if ALPAKA_COMP_GNUC
221# pragma GCC diagnostic pop
222# endif
223 }
224
225 static inline int getCurrentDevice()
226 {
227 int device;
228 using TApi = alpaka::ApiHipRt;
229 ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK(::hipGetDevice(&device));
230
231 return device;
232 }
233
234 static inline Error_t getDeviceCount(int* count)
235 {
236 return ::hipGetDeviceCount(count);
237 }
238
239 static inline Error_t getDeviceProperties(DeviceProp_t* prop, int device)
240 {
241 return ::hipGetDeviceProperties(prop, device);
242 }
243
244 static inline char const* getErrorName(Error_t error)
245 {
246 return ::hipGetErrorName(error);
247 }
248
249 static inline char const* getErrorString(Error_t error)
250 {
251 return ::hipGetErrorString(error);
252 }
253
254 static inline Error_t getLastError()
255 {
256 return ::hipGetLastError();
257 }
258
259 static inline Error_t getSymbolAddress(void** devPtr, void const* symbol)
260 {
261 return ::hipGetSymbolAddress(devPtr, symbol);
262 }
263
264 template<class T>
265 static inline Error_t getSymbolAddress(void** devPtr, T const& symbol)
266 {
267 return ::hipGetSymbolAddress(devPtr, symbol);
268 }
269
270 static inline Error_t hostGetDevicePointer(void** pDevice, void* pHost, Flag_t flags)
271 {
272 return ::hipHostGetDevicePointer(pDevice, pHost, flags);
273 }
274
275 static inline Error_t hostFree(void* ptr)
276 {
277 return ::hipHostFree(ptr);
278 }
279
280 static inline Error_t hostMalloc(void** ptr, size_t size, Flag_t flags)
281 {
282 return ::hipHostMalloc(ptr, size, flags);
283 }
284
285 static inline Error_t hostRegister(void* ptr, size_t size, Flag_t flags)
286 {
287 return ::hipHostRegister(ptr, size, flags);
288 }
289
290 static inline Error_t hostUnregister(void* ptr)
291 {
292 return ::hipHostUnregister(ptr);
293 }
294
295 template<class T>
296 static inline Error_t launchCooperativeKernel(
297 T* func,
298 dim3 gridDim,
299 dim3 blockDim,
300 void** args,
301 size_t sharedMem,
302 Stream_t stream)
303 {
304 return ::hipLaunchCooperativeKernel(func, gridDim, blockDim, args, static_cast<uint>(sharedMem), stream);
305 }
306
307 static inline Error_t launchHostFunc(Stream_t stream, HostFn_t fn, void* userData)
308 {
309 // hipLaunchHostFunc is implemented only in ROCm 5.4.0 and later.
310# if HIP_VERSION >= 50'400'000
311 // Wrap the host function using the proper calling convention.
312 return ::hipLaunchHostFunc(stream, HostFnAdaptor::hostFunction, new HostFnAdaptor{fn, userData});
313# else
314 // Emulate hipLaunchHostFunc using hipStreamAddCallback with a callback adaptor.
315 return ::hipStreamAddCallback(stream, HostFnAdaptor::streamCallback, new HostFnAdaptor{fn, userData}, 0);
316# endif
317 }
318
319 static inline Error_t malloc(void** devPtr, size_t size)
320 {
321 return ::hipMalloc(devPtr, size);
322 }
323
324 static inline Error_t malloc3D(PitchedPtr_t* pitchedDevPtr, Extent_t extent)
325 {
326 return ::hipMalloc3D(pitchedDevPtr, extent);
327 }
328
329 static inline Error_t mallocAsync(
330 [[maybe_unused]] void** devPtr,
331 [[maybe_unused]] size_t size,
332 [[maybe_unused]] Stream_t stream)
333 {
334 // stream-ordered memory operations are fully implemented only in ROCm 5.3.0 and later.
335# if HIP_VERSION >= 50'600'000
336 return ::hipMallocAsync(devPtr, size, stream);
337# elif HIP_VERSION >= 50'300'000
338 // before ROCm 5.6.0, hipMallocAsync fails for an allocation of 0 bytes
339 if(size > 0)
340 {
341 return ::hipMallocAsync(devPtr, size, stream);
342 }
343 else
344 {
345 // make sure the pointer can safely be passed to hipFreeAsync
346 *devPtr = nullptr;
347 return ::hipSuccess;
348 }
349# else
350 // Not implemented.
351 return errorUnknown;
352# endif
353 }
354
355 static inline Error_t mallocManaged(void** ptr, size_t size, Flag_t flags)
356 {
357 return ::hipMallocManaged(ptr, size, flags);
358 }
359
360 static inline Error_t mallocPitch(void** devPtr, size_t* pitch, size_t width, size_t height)
361 {
362 return ::hipMallocPitch(devPtr, pitch, width, height);
363 }
364
365 static inline Error_t memGetInfo(size_t* free, size_t* total)
366 {
367 return ::hipMemGetInfo(free, total);
368 }
369
370 static inline Error_t memcpy(void* dst, void const* src, size_t count, MemcpyKind_t kind)
371 {
372 return ::hipMemcpy(dst, src, count, kind);
373 }
374
375 static inline Error_t memcpy2DAsync(
376 void* dst,
377 size_t dpitch,
378 void const* src,
379 size_t spitch,
380 size_t width,
381 size_t height,
382 MemcpyKind_t kind,
383 Stream_t stream)
384 {
385 return ::hipMemcpy2DAsync(dst, dpitch, src, spitch, width, height, kind, stream);
386 }
387
388 static inline Error_t memcpy3DAsync(Memcpy3DParms_t const* p, Stream_t stream)
389 {
390 return ::hipMemcpy3DAsync(p, stream);
391 }
392
393 static inline Error_t memcpyAsync(void* dst, void const* src, size_t count, MemcpyKind_t kind, Stream_t stream)
394 {
395 return ::hipMemcpyAsync(dst, src, count, kind, stream);
396 }
397
398 static inline Error_t memset2DAsync(
399 void* devPtr,
400 size_t pitch,
401 int value,
402 size_t width,
403 size_t height,
404 Stream_t stream)
405 {
406 return ::hipMemset2DAsync(devPtr, pitch, value, width, height, stream);
407 }
408
409 static inline Error_t memset3DAsync(PitchedPtr_t pitchedDevPtr, int value, Extent_t extent, Stream_t stream)
410 {
411 return ::hipMemset3DAsync(pitchedDevPtr, value, extent, stream);
412 }
413
414 static inline Error_t memsetAsync(void* devPtr, int value, size_t count, Stream_t stream)
415 {
416 return ::hipMemsetAsync(devPtr, value, count, stream);
417 }
418
419 static inline Error_t setDevice(int device)
420 {
421 return ::hipSetDevice(device);
422 }
423
424 static inline Error_t streamCreate(Stream_t* pStream)
425 {
426 return ::hipStreamCreate(pStream);
427 }
428
429 static inline Error_t streamCreateWithFlags(Stream_t* pStream, Flag_t flags)
430 {
431 return ::hipStreamCreateWithFlags(pStream, flags);
432 }
433
434 static inline Error_t streamDestroy(Stream_t stream)
435 {
436 return ::hipStreamDestroy(stream);
437 }
438
439 static inline Error_t streamQuery(Stream_t stream)
440 {
441 return ::hipStreamQuery(stream);
442 }
443
444 static inline Error_t streamSynchronize(Stream_t stream)
445 {
446 return ::hipStreamSynchronize(stream);
447 }
448
449 static inline Error_t streamWaitEvent(Stream_t stream, Event_t event, Flag_t flags)
450 {
451 return ::hipStreamWaitEvent(stream, event, flags);
452 }
453
454 static inline PitchedPtr_t makePitchedPtr(void* d, size_t p, size_t xsz, size_t ysz)
455 {
456 return ::make_hipPitchedPtr(d, p, xsz, ysz);
457 }
458
459 static inline Pos_t makePos(size_t x, size_t y, size_t z)
460 {
461 return ::make_hipPos(x, y, z);
462 }
463
464 static inline Extent_t makeExtent(size_t w, size_t h, size_t d)
465 {
466 return ::make_hipExtent(w, h, d);
467 }
468
469 template<class T>
470 static inline Error_t occupancyMaxActiveBlocksPerMultiprocessor(
471 int* numBlocks,
472 T func,
473 int blockSize,
474 size_t dynamicSMemSize)
475 {
476 return ::hipOccupancyMaxActiveBlocksPerMultiprocessor(numBlocks, func, blockSize, dynamicSMemSize);
477 }
478 };
479
480} // namespace alpaka
481
482#endif // ALPAKA_ACC_GPU_HIP_ENABLED
#define ALPAKA_VERSION_NUMBER(major, minor, patch)
Definition PP.hpp:15
#define ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK(cmd)
CUDA/HIP runtime error checking with log and exception.
The alpaka accelerator library.
ALPAKA_FN_HOST auto free(TAlloc const &alloc, T const *const ptr) -> void
Frees the memory identified by the given pointer.
Definition Traits.hpp:41
ALPAKA_FN_HOST auto memcpy(TQueue &queue, alpaka::detail::DevGlobalImplGeneric< TTag, TTypeDst > &viewDst, TViewSrc const &viewSrc) -> void
ALPAKA_FN_HOST auto malloc(TAlloc const &alloc, std::size_t const &sizeElems) -> T *
Definition Traits.hpp:33