/search.css" rel="stylesheet" type="text/css"/> /search.js">
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
uniform.hpp
Go to the documentation of this file.
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 
89 #include <limits>
90 #if R123_USE_CXX11_TYPE_TRAITS
91 #include <type_traits>
92 #endif
93 #if __cplusplus >= 201103L
94 #include <array>
95 #endif
96 
97 namespace r123{
103 #if R123_USE_CXX11_TYPE_TRAITS
104 using std::make_signed;
105 using std::make_unsigned;
106 #else
107 // Sigh... We could try to find another <type_traits>, e.g., from
108 // boost or TR1. Or we can do it ourselves in the r123 namespace.
109 // It's not clear which will cause less headache...
110 template <typename T> struct make_signed{};
111 template <typename T> struct make_unsigned{};
112 #define R123_MK_SIGNED_UNSIGNED(ST, UT) \
113 template<> struct make_signed<ST>{ typedef ST type; }; \
114 template<> struct make_signed<UT>{ typedef ST type; }; \
115 template<> struct make_unsigned<ST>{ typedef UT type; }; \
116 template<> struct make_unsigned<UT>{ typedef UT type; }
117 
118 R123_MK_SIGNED_UNSIGNED(int8_t, uint8_t);
119 R123_MK_SIGNED_UNSIGNED(int16_t, uint16_t);
120 R123_MK_SIGNED_UNSIGNED(int32_t, uint32_t);
121 R123_MK_SIGNED_UNSIGNED(int64_t, uint64_t);
122 #if R123_USE_GNU_UINT128
123 R123_MK_SIGNED_UNSIGNED(__int128_t, __uint128_t);
124 #endif
125 #undef R123_MK_SIGNED_UNSIGNED
126 #endif
127 
128 #if defined(__CUDACC__) || defined(_LIBCPP_HAS_NO_CONSTEXPR)
129 // Amazing! cuda thinks numeric_limits::max() is a __host__ function, so
130 // we can't use it in a device function.
131 //
132 // The LIBCPP_HAS_NO_CONSTEXP test catches situations where the libc++
133 // library thinks that the compiler doesn't support constexpr, but we
134 // think it does. As a consequence, the library declares
135 // numeric_limits::max without constexpr. This workaround should only
136 // affect a narrow range of compiler/library pairings.
137 //
138 // In both cases, we find max() by computing ~(unsigned)0 right-shifted
139 // by is_signed.
140 template <typename T>
141 R123_CONSTEXPR R123_STATIC_INLINE R123_CUDA_DEVICE T maxTvalue(){
142  typedef typename make_unsigned<T>::type uT;
143  return (~uT(0)) >> std::numeric_limits<T>::is_signed;
144  }
145 #else
146 template <typename T>
147 R123_CONSTEXPR R123_STATIC_INLINE T maxTvalue(){
148  return std::numeric_limits<T>::max();
149 }
150 #endif
151 
155 
174 template <typename Ftype, typename Itype>
175 R123_CUDA_DEVICE R123_STATIC_INLINE Ftype u01(Itype in){
176  typedef typename make_unsigned<Itype>::type Utype;
177  R123_CONSTEXPR Ftype factor = Ftype(1.)/(maxTvalue<Utype>() + Ftype(1.));
178  R123_CONSTEXPR Ftype halffactor = Ftype(0.5)*factor;
179 #if R123_UNIFORM_FLOAT_STORE
180  volatile Ftype x = Utype(in)*factor; return x+halffactor;
181 #else
182  return Utype(in)*factor + halffactor;
183 #endif
184 }
185 
187 
205 template <typename Ftype, typename Itype>
206 R123_CUDA_DEVICE R123_STATIC_INLINE Ftype uneg11(Itype in){
207  typedef typename make_signed<Itype>::type Stype;
208  R123_CONSTEXPR Ftype factor = Ftype(1.)/(maxTvalue<Stype>() + Ftype(1.));
209  R123_CONSTEXPR Ftype halffactor = Ftype(0.5)*factor;
210 #if R123_UNIFORM_FLOAT_STORE
211  volatile Ftype x = Stype(in)*factor; return x+halffactor;
212 #else
213  return Stype(in)*factor + halffactor;
214 #endif
215 }
216 
218 
238 template <typename Ftype, typename Itype>
239 R123_CUDA_DEVICE R123_STATIC_INLINE Ftype u01fixedpt(Itype in){
240  typedef typename make_unsigned<Itype>::type Utype;
241  R123_CONSTEXPR int excess = std::numeric_limits<Utype>::digits - std::numeric_limits<Ftype>::digits;
242  if(excess>=0){
243  R123_CONSTEXPR int ex_nowarn = (excess>=0) ? excess : 0;
244  R123_CONSTEXPR Ftype factor = Ftype(1.)/(Ftype(1.) + ((maxTvalue<Utype>()>>ex_nowarn)));
245  return (1 | (Utype(in)>>ex_nowarn)) * factor;
246  }else
247  return u01<Ftype>(in);
248 }
249 
250 #if R123_USE_CXX11_STD_ARRAY
251 
253 
258 template <typename Ftype, typename CollType>
259 static inline
260 std::array<Ftype, CollType::static_size> u01all(CollType in)
261 {
262  std::array<Ftype, CollType::static_size> ret;
263  size_t i=0;
264  for(auto e : in){
265  ret[i++] = u01<Ftype>(e);
266  }
267  return ret;
268 }
269 
271 
276 template <typename Ftype, typename CollType>
277 static inline
278 std::array<Ftype, CollType::static_size> uneg11all(CollType in)
279 {
280  std::array<Ftype, CollType::static_size> ret;
281  size_t i=0;
282  for(auto e : in){
283  ret[i++] = uneg11<Ftype>(e);
284  }
285  return ret;
286 }
287 
289 
294 template <typename Ftype, typename CollType>
295 static inline
296 std::array<Ftype, CollType::static_size> u01fixedptall(CollType in)
297 {
298  std::array<Ftype, CollType::static_size> ret;
299  size_t i=0;
300  for(auto e : in){
301  ret[i++] = u01fixedpt<Ftype>(e);
302  }
303  return ret;
304 }
305 #endif // __cplusplus >= 201103L
306 
307 } // namespace r123
308 
309 #endif
310 
static Ftype uneg11(Itype in)
Return a signed value in [-1,1].
Definition: uniform.hpp:206
static Ftype u01fixedpt(Itype in)
Return a value in (0,1) chosen from a set of equally spaced fixed-point values.
Definition: uniform.hpp:239
static Ftype u01(Itype in)
Return a uniform real value in (0, 1].
Definition: uniform.hpp:175
static std::array< Ftype, CollType::static_size > uneg11all(CollType in)
Apply uneg11 to every item in an r123array, returning a std::array.
Definition: uniform.hpp:278
static std::array< Ftype, CollType::static_size > u01fixedptall(CollType in)
Apply u01fixedpt to every item in an r123array, returning a std::array.
Definition: uniform.hpp:296
static std::array< Ftype, CollType::static_size > u01all(CollType in)
Apply u01 to every item in an r123array, returning a std::array.
Definition: uniform.hpp:260