/build/package/package/library/include/rocrand/rocrand_common.h Source File

/build/package/package/library/include/rocrand/rocrand_common.h Source File#

API library: /build/package/package/library/include/rocrand/rocrand_common.h Source File
rocrand_common.h
1// Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All rights reserved.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE.
20
21#ifndef ROCRAND_COMMON_H_
22#define ROCRAND_COMMON_H_
23
24#define ROCRAND_2POW16_INV (1.5258789e-05f)
25#define ROCRAND_2POW16_INV_2PI (9.58738e-05f)
26#define ROCRAND_2POW32_INV (2.3283064e-10f)
27#define ROCRAND_2POW32_INV_DOUBLE (2.3283064365386963e-10)
28#define ROCRAND_2POW64_INV (5.4210109e-20f)
29#define ROCRAND_2POW64_INV_DOUBLE (5.4210108624275221700372640043497e-20)
30#define ROCRAND_2POW32_INV_2PI (1.46291807e-09f)
31#define ROCRAND_2POW53_INV_DOUBLE (1.1102230246251565e-16)
32#define ROCRAND_PI (3.141592653f)
33#define ROCRAND_PI_DOUBLE (3.1415926535897932)
34#define ROCRAND_2PI (6.2831855f)
35#define ROCRAND_SQRT2 (1.4142135f)
36#define ROCRAND_SQRT2_DOUBLE (1.4142135623730951)
37#define ROCRAND_NAN_FLOAT (0x7fc00000)
38#define ROCRAND_NAN_DOUBLE (0x7ff8000000000000)
39
40#include <hip/hip_runtime.h>
41#include <utility>
42
43#define ROCRAND_KERNEL __global__ static
44
45#if __HIP_DEVICE_COMPILE__ \
46 && (defined(__HIP_PLATFORM_AMD__) \
47 || (defined(__HIP_PLATFORM_NVCC__) && (__CUDA_ARCH__ >= 530)))
48 #define ROCRAND_HALF_MATH_SUPPORTED
49#endif
50
51// Copyright 2001 John Maddock.
52// Copyright 2017 Peter Dimov.
53//
54// Distributed under the Boost Software License, Version 1.0.
55//
56// See http://www.boost.org/LICENSE_1_0.txt
57//
58// BOOST_STRINGIZE(X)
59#define ROCRAND_STRINGIZE(X) ROCRAND_DO_STRINGIZE(X)
60#define ROCRAND_DO_STRINGIZE(X) #X
61
62// Copyright 2017 Peter Dimov.
63//
64// Distributed under the Boost Software License, Version 1.0.
65//
66// See http://www.boost.org/LICENSE_1_0.txt
67//
68// BOOST_PRAGMA_MESSAGE("message")
69//
70// Expands to the equivalent of #pragma message("message")
71#if defined(__INTEL_COMPILER)
72 #define ROCRAND_PRAGMA_MESSAGE(x) \
73 __pragma(message(__FILE__ "(" ROCRAND_STRINGIZE(__LINE__) "): note: " x))
74#elif defined(__GNUC__)
75 #define ROCRAND_PRAGMA_MESSAGE(x) _Pragma(ROCRAND_STRINGIZE(message(x)))
76#elif defined(_MSC_VER)
77 #define ROCRAND_PRAGMA_MESSAGE(x) \
78 __pragma(message(__FILE__ "(" ROCRAND_STRINGIZE(__LINE__) "): note: " x))
79#else
80 #define ROCRAND_PRAGMA_MESSAGE(x)
81#endif
82
83#if __cplusplus >= 201402L
84 #define ROCRAND_DEPRECATED(msg) [[deprecated(msg)]]
85#elif defined(_MSC_VER) && !defined(__clang__)
86 #define ROCRAND_DEPRECATED(msg) __declspec(deprecated(msg))
87#elif defined(__clang__) || defined(__GNUC__)
88 #define ROCRAND_DEPRECATED(msg) __attribute__((deprecated(msg)))
89#else
90 #define ROCRAND_DEPRECATED(msg)
91#endif
92
93// This is an accessor macro for HIP vector types (eg. int2, float4, etc.).
94// Prior to HIP 7.0, individual elements could be accessed through the
95// data member:
96//
97// int2 vec;
98// vec.data[0] = 1;
99//
100// Beginning with HIP 7.0, the data member is hidden, and individual
101// elements must be accessed like this:
102//
103// int2 vec;
104// vec[0] = 1;
105//
106// You can use the macro like this:
107//
108// int2 vec;
109// ROCRAND_HIPVEC_ACCESS(vec)[0];
110//
111#if defined(__HIP_PLATFORM_AMD__)
112 #if HIP_VERSION_MAJOR < 7
113 #define ROCRAND_HIPVEC_ACCESS(x) x.data
114 #else
115 #define ROCRAND_HIPVEC_ACCESS(x) x
116 #endif
117#endif
118
119namespace rocrand_device {
120namespace detail {
121
122__forceinline__ __device__ __host__
123unsigned long long
124 mad_u64_u32(const unsigned int x, const unsigned int y, const unsigned long long z)
125{
126 return static_cast<unsigned long long>(x) * static_cast<unsigned long long>(y) + z;
127}
128
129__forceinline__ __device__ __host__
130unsigned long long mul_u64_u32(const unsigned int x, const unsigned int y)
131{
132 return static_cast<unsigned long long>(x) * static_cast<unsigned long long>(y);
133}
134
135// This helps access fields of engine's internal state which
136// saves floats and doubles generated using the Box–Muller transform
137template<typename Engine>
138struct engine_boxmuller_helper
139{
140 static __forceinline__ __device__ __host__ bool has_float(const Engine* engine)
141 {
142 return engine->m_state.boxmuller_float != ROCRAND_NAN_FLOAT;
143 }
144
145 static __forceinline__ __device__ __host__ float get_float(Engine* engine)
146 {
147 const float ret = engine->m_state.boxmuller_float;
148 engine->m_state.boxmuller_float = ROCRAND_NAN_FLOAT;
149 return ret;
150 }
151
152 static __forceinline__ __device__ __host__ void save_float(Engine* engine, float f)
153 {
154 engine->m_state.boxmuller_float = f;
155 }
156
157 static __forceinline__ __device__ __host__ bool has_double(const Engine* engine)
158 {
159 return engine->m_state.boxmuller_double != ROCRAND_NAN_DOUBLE;
160 }
161
162 static __forceinline__ __device__ __host__
163 double get_double(Engine* engine)
164 {
165 const double ret = engine->m_state.boxmuller_double;
166 engine->m_state.boxmuller_double = ROCRAND_NAN_DOUBLE;
167 return ret;
168 }
169
170 static __forceinline__ __device__ __host__ void save_double(Engine* engine, double d)
171 {
172 engine->m_state.boxmuller_double = d;
173 }
174};
175
176template<typename T>
177__forceinline__ __device__ __host__ void split_ull(T& lo, T& hi, unsigned long long int val);
178
179template<>
180__forceinline__ __device__ __host__ void
181 split_ull(unsigned int& lo, unsigned int& hi, unsigned long long int val)
182{
183 lo = val & 0xFFFFFFFF;
184 hi = (val >> 32) & 0xFFFFFFFF;
185}
186
187template<>
188__forceinline__ __device__ __host__ void
189 split_ull(unsigned long long int& lo, unsigned long long int& hi, unsigned long long int val)
190{
191 lo = val;
192 hi = 0;
193}
194
195} // end namespace detail
196} // end namespace rocrand_device
197
198#endif // ROCRAND_COMMON_H_