Neko 1.99.6
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
unified.hip
Go to the documentation of this file.
1/*
2 Copyright (c) 2026, The Neko Authors
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 * Redistributions in binary form must reproduce the above
13 copyright notice, this list of conditions and the following
14 disclaimer in the documentation and/or other materials provided
15 with the distribution.
16
17 * Neither the name of the authors nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33*/
34
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <stdint.h>
50#ifdef __linux__
51#include <unistd.h>
52#include <sys/mman.h>
53#endif
54#include <hip/hip_runtime.h>
55#include <device/hip/unified.h>
56
61 unsigned char v, size_t n)
62{
63 const size_t idx = blockIdx.x * (size_t) blockDim.x + threadIdx.x;
64 const size_t str = (size_t) blockDim.x * gridDim.x;
65 for (size_t i = idx; i < n; i += str)
66 a[i] = v;
67}
68
74 const unsigned long long
75 * __restrict__ b, size_t n)
76{
77 const size_t idx = blockIdx.x * (size_t) blockDim.x + threadIdx.x;
78 const size_t str = (size_t) blockDim.x * gridDim.x;
79 for (size_t i = idx; i < n; i += str)
80 a[i] = b[i];
81}
82
84 const unsigned char * __restrict__ b,
85 size_t n)
86{
87 const size_t idx = blockIdx.x * (size_t) blockDim.x + threadIdx.x;
88 const size_t str = (size_t) blockDim.x * gridDim.x;
89 for (size_t i = idx; i < n; i += str)
90 a[i] = b[i];
91}
92
93extern "C" {
94
123{
124 static int zerocopy = -1;
125 if (zerocopy < 0) {
126 const char *env = getenv("NEKO_HIP_ZEROCOPY");
127
128 if (env != NULL && atoi(env) != 0) {
129 int dev = 0, integrated = 0, pageable = 0;
130 if (hipGetDevice(&dev) == hipSuccess &&
133 dev) == hipSuccess &&
136 dev) == hipSuccess)
138 else
139 zerocopy = 0;
141
142 if (!zerocopy)
144 "Neko: warning: NEKO_HIP_ZEROCOPY=1 requested but this "
145 "device does not support zero-copy mapping (needs a "
146 "unified-memory APU with XNACK); using replicated "
147 "buffers\n");
148 } else {
149 zerocopy = 0;
150 }
151 }
152 return zerocopy;
153}
154
165hipError_t hip_map(void **ptr_d, void *ptr_h, size_t s)
166{
167 if (hip_zerocopy() && ptr_h != NULL) {
168 static int warned = 0;
169 int dev = 0;
170 *ptr_d = ptr_h;
171 /* Advice only, but warn on the first failure: without coarse
172 grain, kernels on fine-grained system memory can be slower */
173 if (hipGetDevice(&dev) == hipSuccess) {
175 != hipSuccess && !warned) {
177 "Neko: warning: coarse-grain advise of zero-copy mapping "
178 "failed; mapped arrays stay fine-grained (slower kernels)\n");
179 warned = 1;
180 }
181 }
183#ifdef __linux__
184 /* Best effort: back the mapping with transparent huge pages,
185 reducing GPU TLB pressure (system pages are much smaller than
186 the large pages backing hipMalloc allocations) */
187 {
189 const uintptr_t beg = ((uintptr_t) ptr_h + pgsz - 1) & ~(pgsz - 1);
190 const uintptr_t end = ((uintptr_t) ptr_h + s) & ~(pgsz - 1);
191 if (end > beg)
192 (void) madvise((void *) beg, end - beg, MADV_HUGEPAGE);
193 }
194#endif
195 return hipSuccess;
196 }
197
198 return hipMalloc(ptr_d, s);
199}
200
205static int hip_is_device_alloc(void *ptr_d)
206{
210 return 0;
211 }
212#if HIP_VERSION_MAJOR >= 6
213 return (attr.type == hipMemoryTypeDevice);
214#else
215 return (attr.memoryType == hipMemoryTypeDevice);
216#endif
217}
218
229{
231 return hipDeviceSynchronize();
232
233 return hipFree(ptr_d);
234}
235
243hipError_t hip_map_memset(void *ptr_d, int value, size_t s, void *stream)
244{
246 const size_t nb = (s + 1024 - 1) / 1024;
247 const dim3 nthrds(1024, 1, 1);
248 const dim3 nblcks((unsigned int) (nb > 65535 ? 65535 :
249 (nb == 0 ? 1 : nb)), 1, 1);
251 (hipStream_t) stream,
252 (unsigned char *) ptr_d, (unsigned char) value, s);
253 return hipGetLastError();
254 }
255
256 return hipMemsetAsync(ptr_d, value, s, (hipStream_t) stream);
257}
258
269hipError_t hip_map_memcpy(void *dst, void *src, size_t s,
270 int kind, void *stream)
271{
272 if (hip_zerocopy()) {
273 if (s == 0)
274 return hipSuccess;
275 if ((((uintptr_t) dst | (uintptr_t) src | s) & 7) == 0) {
276 const size_t n = s / 8;
277 const size_t nb = (n + 1024 - 1) / 1024;
278 const dim3 nthrds(1024, 1, 1);
279 const dim3 nblcks((unsigned int) (nb > 65535 ? 65535 : nb), 1, 1);
281 (hipStream_t) stream,
282 (unsigned long long *) dst,
283 (const unsigned long long *) src, n);
284 }
285 else {
286 const size_t nb = (s + 1024 - 1) / 1024;
287 const dim3 nthrds(1024, 1, 1);
288 const dim3 nblcks((unsigned int) (nb > 65535 ? 65535 : nb), 1, 1);
290 (hipStream_t) stream,
291 (unsigned char *) dst,
292 (const unsigned char *) src, s);
293 }
294 return hipGetLastError();
295 }
296
298 (hipStream_t) stream);
299}
300
301} /* extern "C" */
__global__ void ale_add_kinematics_kernel(const int n, T *__restrict__ wx, T *__restrict__ wy, T *__restrict__ wz, const T *__restrict__ x_ref, const T *__restrict__ y_ref, const T *__restrict__ z_ref, const T *__restrict__ phi, const T *__restrict__ x, const T *__restrict__ y, const T *__restrict__ z, const kinematics_params_t kin_params)
const int i
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ v
__global__ void hip_unified_copy8_kernel(unsigned long long *__restrict__ a, const unsigned long long *__restrict__ b, size_t n)
Definition unified.hip:73
__global__ void hip_unified_copy1_kernel(unsigned char *__restrict__ a, const unsigned char *__restrict__ b, size_t n)
Definition unified.hip:83
hipError_t hip_map(void **ptr_d, void *ptr_h, size_t s)
Definition unified.hip:165
static int hip_is_device_alloc(void *ptr_d)
Definition unified.hip:205
hipError_t hip_map_memset(void *ptr_d, int value, size_t s, void *stream)
Definition unified.hip:243
int hip_zerocopy(void)
Definition unified.hip:122
hipError_t hip_map_free(void *ptr_d)
Definition unified.hip:228
__global__ void hip_unified_memset_kernel(unsigned char *a, unsigned char v, size_t n)
Definition unified.hip:60
hipError_t hip_map_memcpy(void *dst, void *src, size_t s, int kind, void *stream)
Definition unified.hip:269