CORSIKA  @c8_version@
The framework to simulate particle cascades for astroparticle physics
uniform.hpp
1 /*
2 Copyright 2010-2011, D. E. Shaw Research.
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 are
7 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 copyright
13  notice, this list of conditions, and the following disclaimer in the
14  documentation and/or other materials provided with the distribution.
15 
16 * Neither the name of D. E. Shaw Research nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 #ifndef __r123_uniform_dot_hpp
34 #define __r123_uniform_dot_hpp
35 
88 #include <Random123/features/compilerfeatures.h>
89 #include <limits>
90 #include <cstdint>
91 #include <cstddef>
92 #if RANDOM_ITERATOR_R123_USE_CXX11_TYPE_TRAITS
93 #include <type_traits>
94 #endif
95 #if __cplusplus >= 201103L
96 #include <array>
97 #endif
98 
99 namespace random_iterator_r123 {
105 #if RANDOM_ITERATOR_R123_USE_CXX11_TYPE_TRAITS
106  using std::make_signed;
107  using std::make_unsigned;
108 #else
109  // Sigh... We could try to find another <type_traits>, e.g., from
110  // boost or TR1. Or we can do it ourselves in the r123 namespace.
111  // It's not clear which will cause less headache...
112  template <typename T>
113  struct make_signed {};
114  template <typename T>
115  struct make_unsigned {};
116 #define RANDOM_ITERATOR_R123_MK_SIGNED_UNSIGNED(ST, UT) \
117  template <> \
118  struct make_signed<ST> { \
119  typedef ST type; \
120  }; \
121  template <> \
122  struct make_signed<UT> { \
123  typedef ST type; \
124  }; \
125  template <> \
126  struct make_unsigned<ST> { \
127  typedef UT type; \
128  }; \
129  template <> \
130  struct make_unsigned<UT> { \
131  typedef UT type; \
132  }
133 
134  RANDOM_ITERATOR_R123_MK_SIGNED_UNSIGNED(int8_t, uint8_t);
135  RANDOM_ITERATOR_R123_MK_SIGNED_UNSIGNED(int16_t, uint16_t);
136  RANDOM_ITERATOR_R123_MK_SIGNED_UNSIGNED(int32_t, uint32_t);
137  RANDOM_ITERATOR_R123_MK_SIGNED_UNSIGNED(int64_t, uint64_t);
138 #if RANDOM_ITERATOR_R123_USE_GNU_UINT128
139  RANDOM_ITERATOR_R123_MK_SIGNED_UNSIGNED(__int128_t, __uint128_t);
140 #endif
141 #undef RANDOM_ITERATOR_R123_MK_SIGNED_UNSIGNED
142 #endif
143 
144 #if defined(__CUDACC__) || defined(_LIBCPP_HAS_NO_CONSTEXPR)
145  // Amazing! cuda thinks numeric_limits::max() is a __host__ function, so
146  // we can't use it in a device function.
147  //
148  // The LIBCPP_HAS_NO_CONSTEXP test catches situations where the libc++
149  // library thinks that the compiler doesn't support constexpr, but we
150  // think it does. As a consequence, the library declares
151  // numeric_limits::max without constexpr. This workaround should only
152  // affect a narrow range of compiler/library pairings.
153  //
154  // In both cases, we find max() by computing ~(unsigned)0 right-shifted
155  // by is_signed.
156  template <typename T>
157  RANDOM_ITERATOR_R123_CONSTEXPR RANDOM_ITERATOR_R123_STATIC_INLINE
158  RANDOM_ITERATOR_R123_CUDA_DEVICE T
159  maxTvalue() {
160  typedef typename make_unsigned<T>::type uT;
161  return (~uT(0)) >> std::numeric_limits<T>::is_signed;
162  }
163 #else
164  template <typename T>
165  RANDOM_ITERATOR_R123_CONSTEXPR RANDOM_ITERATOR_R123_STATIC_INLINE T maxTvalue() {
166  return std::numeric_limits<T>::max();
167  }
168 #endif
169 
173 
192  template <typename Ftype, typename Itype>
193  RANDOM_ITERATOR_R123_CUDA_DEVICE RANDOM_ITERATOR_R123_STATIC_INLINE Ftype
194  u01(Itype in) {
195  typedef typename make_unsigned<Itype>::type Utype;
196  RANDOM_ITERATOR_R123_CONSTEXPR Ftype factor =
197  Ftype(1.) / (maxTvalue<Utype>() + Ftype(1.));
198  RANDOM_ITERATOR_R123_CONSTEXPR Ftype halffactor = Ftype(0.5) * factor;
199 #if RANDOM_ITERATOR_R123_UNIFORM_FLOAT_STORE
200  volatile Ftype x = Utype(in) * factor;
201  return x + halffactor;
202 #else
203  return Utype(in) * factor + halffactor;
204 #endif
205  }
206 
208 
226  template <typename Ftype, typename Itype>
227  RANDOM_ITERATOR_R123_CUDA_DEVICE RANDOM_ITERATOR_R123_STATIC_INLINE Ftype
228  uneg11(Itype in) {
229  typedef typename make_signed<Itype>::type Stype;
230  RANDOM_ITERATOR_R123_CONSTEXPR Ftype factor =
231  Ftype(1.) / (maxTvalue<Stype>() + Ftype(1.));
232  RANDOM_ITERATOR_R123_CONSTEXPR Ftype halffactor = Ftype(0.5) * factor;
233 #if RANDOM_ITERATOR_R123_UNIFORM_FLOAT_STORE
234  volatile Ftype x = Stype(in) * factor;
235  return x + halffactor;
236 #else
237  return Stype(in) * factor + halffactor;
238 #endif
239  }
240 
242 
262  template <typename Ftype, typename Itype>
263  RANDOM_ITERATOR_R123_CUDA_DEVICE RANDOM_ITERATOR_R123_STATIC_INLINE Ftype
264  u01fixedpt(Itype in) {
265  typedef typename make_unsigned<Itype>::type Utype;
266  RANDOM_ITERATOR_R123_CONSTEXPR int excess =
267  std::numeric_limits<Utype>::digits - std::numeric_limits<Ftype>::digits;
268  if (excess >= 0) {
269  RANDOM_ITERATOR_R123_CONSTEXPR int ex_nowarn = (excess >= 0) ? excess : 0;
270  RANDOM_ITERATOR_R123_CONSTEXPR Ftype factor =
271  Ftype(1.) / (Ftype(1.) + ((maxTvalue<Utype>() >> ex_nowarn)));
272  return (1 | (Utype(in) >> ex_nowarn)) * factor;
273  } else
274  return u01<Ftype>(in);
275  }
276 
277 #if RANDOM_ITERATOR_R123_USE_CXX11_STD_ARRAY
278 
280 
285  template <typename Ftype, typename CollType>
286  static inline std::array<Ftype, CollType::static_size> u01all(CollType in) {
287  std::array<Ftype, CollType::static_size> ret;
288  size_t i = 0;
289  for (auto e : in) { ret[i++] = u01<Ftype>(e); }
290  return ret;
291  }
292 
294 
299  template <typename Ftype, typename CollType>
300  static inline std::array<Ftype, CollType::static_size> uneg11all(CollType in) {
301  std::array<Ftype, CollType::static_size> ret;
302  size_t i = 0;
303  for (auto e : in) { ret[i++] = uneg11<Ftype>(e); }
304  return ret;
305  }
306 
308 
313  template <typename Ftype, typename CollType>
314  static inline std::array<Ftype, CollType::static_size> u01fixedptall(CollType in) {
315  std::array<Ftype, CollType::static_size> ret;
316  size_t i = 0;
317  for (auto e : in) { ret[i++] = u01fixedpt<Ftype>(e); }
318  return ret;
319  }
320 #endif // __cplusplus >= 201103L
321 
322 } // namespace random_iterator_r123
323 
324 #endif
RANDOM_ITERATOR_R123_CUDA_DEVICE RANDOM_ITERATOR_R123_STATIC_INLINE Ftype u01(Itype in)
Input is a W-bit integer (signed or unsigned).
Definition: uniform.hpp:194
RANDOM_ITERATOR_R123_CUDA_DEVICE RANDOM_ITERATOR_R123_STATIC_INLINE Ftype u01fixedpt(Itype in)
Return a value in (0,1) chosen from a set of equally spaced fixed-point values.
Definition: uniform.hpp:264
RANDOM_ITERATOR_R123_CUDA_DEVICE RANDOM_ITERATOR_R123_STATIC_INLINE Ftype uneg11(Itype in)
Return a signed value in [-1,1].
Definition: uniform.hpp:228