6#include <experimental/source_location>
9#include "../utils/error_handling.h"
13 #include <hip/hip_runtime.h>
15 #include <hip/hip_cooperative_groups.h>
17 #if defined(PARIS) || defined(PARIS_GALACTIC)
23 #if !defined(HIP_VERSION) || (HIP_VERSION < 40200000)
35 #error "The current version of HIP is too old"
39static constexpr int maxWarpsPerBlock = 1024 / WARPSIZE;
41 #define CUFFT_D2Z HIPFFT_D2Z
42 #define CUFFT_FORWARD HIPFFT_FORWARD
43 #define CUFFT_INVERSE HIPFFT_BACKWARD
44 #define CUFFT_Z2D HIPFFT_Z2D
45 #define CUFFT_Z2Z HIPFFT_Z2Z
46 #define CUFFT_SUCCESS HIPFFT_SUCCESS
47 #define cufftResult_t hipfftResult_t
49 #define cudaDeviceSynchronize hipDeviceSynchronize
50 #define cudaError hipError_t
51 #define cudaError_t hipError_t
52 #define cudaErrorInsufficientDriver hipErrorInsufficientDriver
53 #define cudaErrorNoDevice hipErrorNoDevice
54 #define cudaEvent_t hipEvent_t
55 #define cudaEventCreate hipEventCreate
56 #define cudaEventElapsedTime hipEventElapsedTime
57 #define cudaEventRecord hipEventRecord
58 #define cudaEventSynchronize hipEventSynchronize
59 #define cudaFree hipFree
60 #define cudaFreeHost hipHostFree
61 #define cudaGetDevice hipGetDevice
62 #define cudaGetDeviceCount hipGetDeviceCount
63 #define cudaGetErrorString hipGetErrorString
64 #define cudaGetLastError hipGetLastError
65 #define cudaHostAlloc hipHostMalloc
66 #define cudaHostAllocDefault hipHostMallocDefault
67 #define cudaMalloc hipMalloc
68 #define cudaMemcpy hipMemcpy
69 #define cudaMemcpyAsync hipMemcpyAsync
70 #define cudaMemcpyPeer hipMemcpyPeer
71 #define cudaMemcpyDeviceToHost hipMemcpyDeviceToHost
72 #define cudaMemcpyDeviceToDevice hipMemcpyDeviceToDevice
73 #define cudaMemcpyHostToDevice hipMemcpyHostToDevice
74 #define cudaMemGetInfo hipMemGetInfo
75 #define cudaMemset hipMemset
76 #define cudaReadModeElementType hipReadModeElementType
77 #define cudaSetDevice hipSetDevice
78 #define cudaSuccess hipSuccess
79 #define cudaDeviceProp hipDeviceProp_t
80 #define cudaGetDeviceProperties hipGetDeviceProperties
81 #define cudaPointerAttributes hipPointerAttribute_t
82 #define cudaPointerGetAttributes hipPointerGetAttributes
83 #define cudaOccupancyMaxPotentialBlockSize hipOccupancyMaxPotentialBlockSize
84 #define cudaDeviceGetAttribute hipDeviceGetAttribute
85 #define cudaDevAttrCooperativeLaunch hipDeviceAttributeCooperativeLaunch
86 #define cudaOccupancyMaxActiveBlocksPerMultiprocessor hipOccupancyMaxActiveBlocksPerMultiprocessor
87 #define cudaLaunchCooperativeKernel hipLaunchCooperativeKernel
88 #define cudaMemGetInfo hipMemGetInfo
89 #define cudaDeviceGetPCIBusId hipDeviceGetPCIBusId
90 #define cudaPeekAtLastError hipPeekAtLastError
91 #define cudaFuncAttributes hipFuncAttributes
92 #define cudaFuncGetAttributes hipFuncGetAttributes
95 #define cudaArray hipArray
96 #define cudaMallocArray hipMallocArray
97 #define cudaFreeArray hipFreeArray
98 #define cudaMemcpyToArray hipMemcpyToArray
99 #define cudaMemcpy2DToArray hipMemcpy2DToArray
101 #define cudaTextureObject_t hipTextureObject_t
102 #define cudaCreateTextureObject hipCreateTextureObject
103 #define cudaDestroyTextureObject hipDestroyTextureObject
104 #define cudaGetTextureObjectResourceDesc hipGetTextureObjectResourceDesc
106 #define cudaChannelFormatDesc hipChannelFormatDesc
107 #define cudaCreateChannelDesc hipCreateChannelDesc
108 #define cudaChannelFormatKindFloat hipChannelFormatKindFloat
110 #define cudaResourceDesc hipResourceDesc
111 #define cudaResourceTypeArray hipResourceTypeArray
112 #define cudaTextureDesc hipTextureDesc
113 #define cudaAddressModeClamp hipAddressModeClamp
114 #define cudaFilterModeLinear hipFilterModeLinear
115 #define cudaFilterModePoint hipFilterModePoint
117 #define cudaPointerAttributes hipPointerAttribute_t
118 #define cudaPointerGetAttributes hipPointerGetAttributes
121 #define cufftDestroy hipfftDestroy
122 #define cufftDoubleComplex hipfftDoubleComplex
123 #define cufftDoubleReal hipfftDoubleReal
124 #define cufftExecD2Z hipfftExecD2Z
125 #define cufftExecZ2D hipfftExecZ2D
126 #define cufftExecZ2Z hipfftExecZ2Z
127 #define cufftHandle hipfftHandle
128 #define cufftPlan3d hipfftPlan3d
129 #define cufftPlanMany hipfftPlanMany
131 #define curandStateMRG32k3a_t hiprandStateMRG32k3a_t
132 #define curand_init hiprand_init
133 #define curand hiprand
134 #define curand_poisson hiprand_poisson
138 #include <cooperative_groups.h>
139 #include <cuda_runtime.h>
141 #if defined(PARIS) || defined(PARIS_GALACTIC)
148static constexpr int maxWarpsPerBlock = 1024 / WARPSIZE;
149 #define hipLaunchKernelGGL(F, G, B, M, S, ...) F<<<G, B, M, S>>>(__VA_ARGS__)
150 #define __shfl_down(...) __shfl_down_sync(0xFFFFFFFF, __VA_ARGS__)
154 #define HIP_KERNEL_NAME(...) __VA_ARGS__
157#define GPU_MAX_THREADS 256
166inline void Format_GPU_Error_Check_Err_(cudaError_t code,
bool abort, std::experimental::source_location location)
172 if (code != cudaSuccess) {
173 std::cout <<
"GPU_Error_Check: Failed at "
174 <<
"Line: " << location.line() <<
", File: " << location.file_name()
175 <<
", Function: " << location.function_name() <<
", with code: " << cudaGetErrorString(code) << std::endl;
210inline void GPU_Error_Check(cudaError_t code = cudaPeekAtLastError(),
bool abort =
true,
211 std::experimental::source_location location = std::experimental::source_location::current())
218 if (code != cudaSuccess) Format_GPU_Error_Check_Err_(code, abort, location);
220#ifndef DISABLE_GPU_ERROR_CHECKING
222 code = cudaDeviceSynchronize();
223 if (code != cudaSuccess) Format_GPU_Error_Check_Err_(code, abort, location);
227#if defined(PARIS) || defined(PARIS_GALACTIC)
235inline void GPU_Error_Check(cufftResult_t code,
bool abort =
true,
236 std::experimental::source_location location = std::experimental::source_location::current())
238 #ifndef DISABLE_GPU_ERROR_CHECKING
240 if (code != CUFFT_SUCCESS) {
241 std::cout <<
"GPU_Error_Check: Failed at "
242 <<
"Line: " << location.line() <<
", File: " << location.file_name()
243 <<
", Function: " << location.function_name() <<
", with FFT code: " << code << std::endl;
252#if defined(__CUDACC__) || defined(__HIPCC__)
255__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun0(
const int n0,
const F f)
257 const int i0 = blockIdx.x * blockDim.x + threadIdx.x;
264void gpuFor(
const int n0,
const F f)
269 const int b0 = (n0 + GPU_MAX_THREADS - 1) / GPU_MAX_THREADS;
270 const int t0 = (n0 + b0 - 1) / b0;
271 gpuRun0<<<b0, t0>>>(n0, f);
276__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun0x2(
const F f)
278 const int i0 = threadIdx.y;
279 const int i1 = threadIdx.x;
284__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun1x1(
const F f)
286 const int i0 = blockIdx.x;
287 const int i1 = threadIdx.x;
292__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun2x0(
const int n1,
const F f)
294 const int i0 = blockIdx.y;
295 const int i1 = blockIdx.x * blockDim.x + threadIdx.x;
302void gpuFor(
const int n0,
const int n1,
const F f)
304 if ((n0 <= 0) || (n1 <= 0)) {
307 const long nl01 = long(n0) * long(n1);
308 assert(nl01 <
long(INT_MAX));
310 if (n1 > GPU_MAX_THREADS) {
311 const int b1 = (n1 + GPU_MAX_THREADS - 1) / GPU_MAX_THREADS;
312 const int t1 = (n1 + b1 - 1) / b1;
313 gpuRun2x0<<<dim3(b1, n0), dim3(t1)>>>(n1, f);
315 }
else if (nl01 > GPU_MAX_THREADS) {
316 gpuRun1x1<<<n0, n1>>>(f);
319 gpuRun0x2<<<1, dim3(n1, n0)>>>(f);
325__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun0x3(
const F f)
327 const int i0 = threadIdx.z;
328 const int i1 = threadIdx.y;
329 const int i2 = threadIdx.x;
334__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun1x2(
const F f)
336 const int i0 = blockIdx.x;
337 const int i1 = threadIdx.y;
338 const int i2 = threadIdx.x;
343__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun2x1(
const F f)
345 const int i0 = blockIdx.y;
346 const int i1 = blockIdx.x;
347 const int i2 = threadIdx.x;
352__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun3x0(
const int n2,
const F f)
354 const int i0 = blockIdx.z;
355 const int i1 = blockIdx.y;
356 const int i2 = blockIdx.x * blockDim.x + threadIdx.x;
386void gpuFor(
const int n0,
const int n1,
const int n2,
const F f)
388 if ((n0 <= 0) || (n1 <= 0) || (n2 <= 0)) {
391 const long nl12 = long(n1) * long(n2);
392 const long nl012 = long(n0) * nl12;
393 assert(nl012 <
long(INT_MAX));
395 if (n2 > GPU_MAX_THREADS) {
396 const int b2 = (n2 + GPU_MAX_THREADS - 1) / GPU_MAX_THREADS;
397 const int t2 = (n2 + b2 - 1) / b2;
398 gpuRun3x0<<<dim3(b2, n1, n0), t2>>>(n2, f);
400 }
else if (nl12 > GPU_MAX_THREADS) {
401 gpuRun2x1<<<dim3(n1, n0), n2>>>(f);
403 }
else if (nl012 > GPU_MAX_THREADS) {
404 gpuRun1x2<<<n0, dim3(n2, n1)>>>(f);
407 gpuRun0x3<<<1, dim3(n2, n1, n0)>>>(f);
413__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun1x3(
const F f)
415 const int i0 = blockIdx.x;
416 const int i1 = threadIdx.z;
417 const int i2 = threadIdx.y;
418 const int i3 = threadIdx.x;
423__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun2x2(
const F f)
425 const int i0 = blockIdx.y;
426 const int i1 = blockIdx.x;
427 const int i2 = threadIdx.y;
428 const int i3 = threadIdx.x;
433__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun3x1(
const F f)
435 const int i0 = blockIdx.z;
436 const int i1 = blockIdx.y;
437 const int i2 = blockIdx.x;
438 const int i3 = threadIdx.x;
443__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun4x0(
const int n23,
const int n3,
const F f)
445 const int i23 = blockIdx.x * blockDim.x + threadIdx.x;
447 const int i0 = blockIdx.z;
448 const int i1 = blockIdx.y;
449 const int i2 = i23 / n3;
450 const int i3 = i23 % n3;
456void gpuFor(
const int n0,
const int n1,
const int n2,
const int n3,
const F f)
458 if ((n0 <= 0) || (n1 <= 0) || (n2 <= 0) || (n3 <= 0)) {
461 const long n23_long = long(n2) * long(n3);
462 const long n123_long = long(n1) * n23_long;
463 assert(
long(n0) * n123_long <
long(INT_MAX));
465 const int n23 = int(n23_long);
466 const int n123 = int(n123_long);
467 if (n3 > GPU_MAX_THREADS) {
468 const int b23 = (n23 + GPU_MAX_THREADS - 1) / GPU_MAX_THREADS;
469 const int t23 = (n23 + b23 - 1) / b23;
470 gpuRun4x0<<<dim3(b23, n1, n0), t23>>>(n23, n3, f);
472 }
else if (n23 > GPU_MAX_THREADS) {
473 gpuRun3x1<<<dim3(n2, n1, n0), n3>>>(f);
475 }
else if (n123 > GPU_MAX_THREADS) {
476 gpuRun2x2<<<dim3(n1, n0), dim3(n3, n2)>>>(f);
479 gpuRun1x3<<<n0, dim3(n3, n2, n1)>>>(f);
485__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun2x3(
const F f)
487 const int i0 = blockIdx.y;
488 const int i1 = blockIdx.x;
489 const int i2 = threadIdx.z;
490 const int i3 = threadIdx.y;
491 const int i4 = threadIdx.x;
492 f(i0, i1, i2, i3, i4);
496__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun3x2(
const F f)
498 const int i0 = blockIdx.z;
499 const int i1 = blockIdx.y;
500 const int i2 = blockIdx.x;
501 const int i3 = threadIdx.y;
502 const int i4 = threadIdx.x;
503 f(i0, i1, i2, i3, i4);
507__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun4x1(
const int n1,
const F f)
509 const int i01 = blockIdx.z;
510 const int i0 = i01 / n1;
511 const int i1 = i01 % n1;
512 const int i2 = blockIdx.y;
513 const int i3 = blockIdx.x;
514 const int i4 = threadIdx.x;
515 f(i0, i1, i2, i3, i4);
519__global__ __launch_bounds__(GPU_MAX_THREADS)
void gpuRun5x0(
const int n1,
const int n34,
const int n4,
const F f)
521 const int i34 = blockIdx.x * blockDim.x + threadIdx.x;
523 const int i01 = blockIdx.z;
524 const int i0 = i01 / n1;
525 const int i1 = i01 % n1;
526 const int i2 = blockIdx.y;
527 const int i3 = i34 / n4;
528 const int i4 = i34 % n4;
529 f(i0, i1, i2, i3, i4);
534void gpuFor(
const int n0,
const int n1,
const int n2,
const int n3,
const int n4,
const F f)
536 if ((n0 <= 0) || (n1 <= 0) || (n2 <= 0) || (n3 <= 0) || (n4 <= 0)) {
539 const long nl01 = long(n0) * long(n1);
540 const long nl34 = long(n3) * long(n4);
541 assert(nl01 *
long(n2) * nl34 <
long(INT_MAX));
543 const int n34 = int(nl34);
544 if (n4 > GPU_MAX_THREADS) {
545 const int n01 = int(nl01);
546 const int b34 = (n34 + GPU_MAX_THREADS - 1) / GPU_MAX_THREADS;
547 const int t34 = (n34 + b34 - 1) / b34;
548 gpuRun5x0<<<dim3(b34, n2, n01), t34>>>(n1, n34, n4, f);
550 }
else if (n34 > GPU_MAX_THREADS) {
551 const int n01 = n0 * n1;
552 gpuRun4x1<<<dim3(n3, n2, n01), n4>>>(n1, f);
554 }
else if (n2 * n34 > GPU_MAX_THREADS) {
555 gpuRun3x2<<<dim3(n2, n1, n0), dim3(n4, n3)>>>(f);
558 gpuRun2x3<<<dim3(n1, n0), dim3(n4, n3, n2)>>>(f);
576 #define GPU_LAMBDA [=] __device__