/perf/kseta

To get this branch, use:
bzr branch http://darksoft.org/webbzr/perf/kseta

« back to all changes in this revision

Viewing changes to tutorials/4_pi/random123/features/compilerfeatures.h

  • Committer: Suren A. Chilingaryan
  • Date: 2013-10-08 23:53:50 UTC
  • Revision ID: csa@dside.dyndns.org-20131008235350-hsu8oukzkh05gtcm
Add tutorials

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
34
@page porting Preprocessor symbols for porting Random123 to different platforms.
 
35
 
 
36
The Random123 library is portable across C, C++, CUDA, OpenCL environments,
 
37
and multiple operating systems (Linux, Windows 7, Mac OS X, FreeBSD, Solaris).
 
38
This level of portability requires the abstraction of some features
 
39
and idioms that are either not standardized (e.g., asm statments), or for which 
 
40
different vendors have their own standards (e.g., SSE intrinsics) or for
 
41
which vendors simply refuse to conform to well-established standards (e.g., <inttypes.h>).
 
42
 
 
43
Random123/features/compilerfeatures.h
 
44
conditionally includes a compiler-or-OS-specific Random123/featires/XXXfeatures.h file which
 
45
defines appropriate values for the preprocessor symbols which can be used with
 
46
a specific compiler or OS.  Those symbols will then
 
47
be used by other header files and source files in the Random123
 
48
library (and may be used by applications) to control what actually
 
49
gets presented to the compiler.
 
50
 
 
51
Most of the symbols are boolean valued.  In general, they will
 
52
\b always be defined with value either 1 or 0, so do
 
53
\b NOT use \#ifdef.  Use \#if R123_USE_SOMETHING instead.
 
54
 
 
55
Library users can override any value by defining the pp-symbol with a compiler option,
 
56
e.g.,
 
57
 
 
58
    cc -DR123_USE_MULHILO64_C99 
 
59
 
 
60
will use a strictly c99 version of the full-width 64x64->128-bit multiplication
 
61
function, even if it would be disabled by default.
 
62
 
 
63
All boolean-valued pre-processor symbols in Random123/features/compilerfeatures.h start with the prefix R123_USE_
 
64
@verbatim
 
65
         AES_NI
 
66
         AES_OPENSSL
 
67
         SSE4_2
 
68
         SSE4_1
 
69
         SSE
 
70
 
 
71
         STD_RANDOM
 
72
 
 
73
         GNU_UINT128
 
74
         ASM_GNU
 
75
         ASM_MSASM
 
76
 
 
77
         CPUID_MSVC
 
78
 
 
79
         CXX11_RANDOM
 
80
         CXX11_TYPE_TRAITS
 
81
         CXX11_STATIC_ASSERT
 
82
         CXX11_CONSTEXPR
 
83
         CXX11_UNRESTRICTED_UNIONS
 
84
         CXX11_EXPLICIT_CONVERSIONS
 
85
         CXX11_LONG_LONG
 
86
         CXX11 
 
87
   
 
88
         X86INTRIN_H
 
89
         IA32INTRIN_H
 
90
         XMMINTRIN_H
 
91
         EMMINTRIN_H
 
92
         SMMINTRIN_H
 
93
         WMMINTRIN_H
 
94
         INTRIN_H
 
95
 
 
96
         MULHILO32_ASM
 
97
         MULHILO64_ASM
 
98
         MULHILO64_MSVC_INTRIN
 
99
         MULHILO64_CUDA_INTRIN
 
100
         MULHILO64_OPENCL_INTRIN
 
101
         MULHILO64_C99
 
102
 
 
103
         U01_DOUBLE
 
104
         
 
105
@endverbatim
 
106
Most have obvious meanings.  Some non-obvious ones:
 
107
 
 
108
AES_NI and AES_OPENSSL are not mutually exclusive.  You can have one,
 
109
both or neither.
 
110
 
 
111
GNU_UINT128 says that it's safe to use __uint128_t, but it
 
112
does not require its use.  In particular, it should be
 
113
used in mulhilo<uint64_t> only if MULHILO64_ASM is unset.
 
114
 
 
115
If the XXXINTRIN_H macros are true, then one should
 
116
@code
 
117
#include <xxxintrin.h>
 
118
@endcode
 
119
to gain accesss to compiler intrinsics.
 
120
 
 
121
The CXX11_SOME_FEATURE macros allow the code to use specific
 
122
features of the C++11 language and library.  The catchall
 
123
In the absence of a specific CXX11_SOME_FEATURE, the feature
 
124
is controlled by the catch-all R123_USE_CXX11 macro.
 
125
 
 
126
U01_DOUBLE defaults on, and can be turned off (set to 0)
 
127
if one does not want the utility functions that convert to double
 
128
(i.e. u01_*_53()), e.g. on OpenCL without the cl_khr_fp64 extension.
 
129
 
 
130
There are a number of invariants that are always true.  Application code may
 
131
choose to rely on these:
 
132
 
 
133
<ul>
 
134
<li>ASM_GNU and ASM_MASM are mutually exclusive
 
135
<li>The "higher" SSE values imply the lower ones.
 
136
</ul>
 
137
 
 
138
There are also non-boolean valued symbols:
 
139
 
 
140
<ul>
 
141
<li>R123_STATIC_INLINE -
 
142
  According to both C99 and GNU99, the 'static inline' declaration allows
 
143
  the compiler to not emit code if the function is not used.  
 
144
  Note that the semantics of 'inline', 'static' and 'extern' in
 
145
  gcc have changed over time and are subject to modification by
 
146
  command line options, e.g., -std=gnu89, -fgnu-inline.
 
147
  Nevertheless, it appears that the meaning of 'static inline' 
 
148
  has not changed over time and (with a little luck) the use of 'static inline'
 
149
  here will be portable between versions of gcc and to other C99
 
150
  compilers.
 
151
  See: http://gcc.gnu.org/onlinedocs/gcc/Inline.html
 
152
       http://www.greenend.org.uk/rjk/2003/03/inline.html
 
153
 
 
154
<li>R123_FORCE_INLINE(decl) -
 
155
  which expands to 'decl', adorned with the compiler-specific
 
156
  embellishments to strongly encourage that the declared function be
 
157
  inlined.  If there is no such compiler-specific magic, it should
 
158
  expand to decl, unadorned.
 
159
   
 
160
<li>R123_CUDA_DEVICE - which expands to __device__ (or something else with
 
161
  sufficiently similar semantics) when CUDA is in use, and expands
 
162
  to nothing in other cases.
 
163
 
 
164
<li>R123_ASSERT(x) - which expands to assert(x), or maybe to nothing at
 
165
  all if we're in an environment so feature-poor that you can't even
 
166
  call assert (I'm looking at you, CUDA and OpenCL), or even include
 
167
  assert.h safely (OpenCL).
 
168
 
 
169
<li>R123_STATIC_ASSERT(expr,msg) - which expands to
 
170
  static_assert(expr,msg), or to an expression that
 
171
  will raise a compile-time exception if expr is not true.
 
172
 
 
173
<li>R123_ULONG_LONG - which expands to a declaration of the longest available
 
174
  unsigned integer.
 
175
 
 
176
<li>R123_64BIT(x) - expands to something equivalent to
 
177
  UINT64_C(x) from <stdint.h>, even in environments where <stdint.h>
 
178
  is not available, e.g., MSVC and OpenCL.
 
179
 
 
180
<li>R123_BUILTIN_EXPECT(expr,likely_value) - expands to something with
 
181
  the semantics of gcc's __builtin_expect(expr,likely_value).  If
 
182
  the environment has nothing like __builtin_expect, it should expand
 
183
  to just expr.
 
184
</ul>
 
185
 
 
186
 
 
187
\cond HIDDEN_FROM_DOXYGEN
 
188
*/
 
189
 
 
190
/* 
 
191
N.B.  When something is added to the list of features, it should be
 
192
added to each of the *features.h files, AND to examples/ut_features.cpp.
 
193
*/
 
194
 
 
195
/* N.B.  most other compilers (icc, nvcc, open64, llvm) will also define __GNUC__, so order matters. */
 
196
#if defined(__OPENCL_VERSION__) && __OPENCL_VERSION__ > 0
 
197
#include "openclfeatures.h"
 
198
#elif defined(__CUDACC__)
 
199
#include "nvccfeatures.h"
 
200
#elif defined(__ICC)
 
201
#include "iccfeatures.h"
 
202
#elif defined(__xlC__)
 
203
#include "xlcfeatures.h"
 
204
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
 
205
#include "sunprofeatures.h"
 
206
#elif defined(__OPEN64__)
 
207
#include "open64features.h"
 
208
#elif defined(__clang__)
 
209
#include "clangfeatures.h"
 
210
#elif defined(__GNUC__)
 
211
#include "gccfeatures.h"
 
212
#elif defined(__PGI)
 
213
#include "pgccfeatures.h"
 
214
#elif defined(_MSC_FULL_VER)
 
215
#include "msvcfeatures.h"
 
216
#else
 
217
#error "Can't identify compiler.  You'll need to add a new xxfeatures.hpp"
 
218
{ /* maybe an unbalanced brace will terminate the compilation */
 
219
#endif
 
220
 
 
221
#ifndef R123_USE_CXX11
 
222
#define R123_USE_CXX11 (__cplusplus >= 201103L)
 
223
#endif
 
224
 
 
225
#ifndef R123_USE_CXX11_UNRESTRICTED_UNIONS
 
226
#define R123_USE_CXX11_UNRESTRICTED_UNIONS R123_USE_CXX11
 
227
#endif
 
228
 
 
229
#ifndef R123_USE_CXX11_STATIC_ASSERT
 
230
#define R123_USE_CXX11_STATIC_ASSERT R123_USE_CXX11
 
231
#endif
 
232
 
 
233
#ifndef R123_USE_CXX11_CONSTEXPR
 
234
#define R123_USE_CXX11_CONSTEXPR R123_USE_CXX11
 
235
#endif
 
236
 
 
237
#ifndef R123_USE_CXX11_EXPLICIT_CONVERSIONS
 
238
#define R123_USE_CXX11_EXPLICIT_CONVERSIONS R123_USE_CXX11
 
239
#endif
 
240
 
 
241
#ifndef R123_USE_CXX11_RANDOM
 
242
#define R123_USE_CXX11_RANDOM R123_USE_CXX11
 
243
#endif
 
244
 
 
245
#ifndef R123_USE_CXX11_TYPE_TRAITS
 
246
#define R123_USE_CXX11_TYPE_TRAITS R123_USE_CXX11
 
247
#endif
 
248
 
 
249
#ifndef R123_USE_CXX11_LONG_LONG
 
250
#define R123_USE_CXX11_LONG_LONG R123_USE_CXX11
 
251
#endif
 
252
 
 
253
#ifndef R123_USE_MULHILO64_C99
 
254
#define R123_USE_MULHILO64_C99 0
 
255
#endif
 
256
 
 
257
#ifndef R123_USE_MULHILO64_MULHI_INTRIN
 
258
#define R123_USE_MULHILO64_MULHI_INTRIN 0
 
259
#endif
 
260
 
 
261
#ifndef R123_USE_MULHILO32_MULHI_INTRIN
 
262
#define R123_USE_MULHILO32_MULHI_INTRIN 0
 
263
#endif
 
264
 
 
265
#ifndef R123_STATIC_ASSERT
 
266
#if R123_USE_CXX11_STATIC_ASSERT
 
267
#define R123_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
 
268
#else
 
269
    /* if msg always_looked_like_this, we could paste it into the name.  Worth it? */
 
270
#define R123_STATIC_ASSERT(expr, msg) typedef char static_assertion[(!!(expr))*2-1]
 
271
#endif
 
272
#endif
 
273
 
 
274
#ifndef R123_CONSTEXPR
 
275
#if R123_USE_CXX11_CONSTEXPR
 
276
#define R123_CONSTEXPR constexpr
 
277
#else
 
278
#define R123_CONSTEXPR
 
279
#endif
 
280
#endif
 
281
 
 
282
#ifndef R123_USE_PHILOX_64BIT
 
283
#define R123_USE_PHILOX_64BIT (R123_USE_MULHILO64_ASM || R123_USE_MULHILO64_MSVC_INTRIN || R123_USE_MULHILO64_CUDA_INTRIN || R123_USE_GNU_UINT128 || R123_USE_MULHILO64_C99 || R123_USE_MULHILO64_OPENCL_INTRIN || R123_USE_MULHILO64_MULHI_INTRIN)
 
284
#endif
 
285
 
 
286
#ifndef R123_ULONG_LONG
 
287
#if defined(__cplusplus) && !R123_USE_CXX11_LONG_LONG
 
288
/* C++98 doesn't have long long.  It doesn't have uint64_t either, but
 
289
   we will have typedef'ed uint64_t to something in the xxxfeatures.h.
 
290
   With luck, it won't elicit complaints from -pedantic.  Cross your
 
291
   fingers... */
 
292
#define R123_ULONG_LONG uint64_t
 
293
#else
 
294
#define R123_ULONG_LONG unsigned long long
 
295
#endif
 
296
#endif
 
297
 
 
298
/* UINT64_C should have been #defined by XXXfeatures.h, either by
 
299
   #include <stdint.h> or through compiler-dependent hacks */
 
300
#ifndef R123_64BIT
 
301
#define R123_64BIT(x) UINT64_C(x)
 
302
#endif
 
303
 
 
304
#ifndef R123_THROW
 
305
#define R123_THROW(x)    throw (x)
 
306
#endif
 
307
 
 
308
/*
 
309
 * Windows.h (and perhaps other "well-meaning" code define min and
 
310
 * max, so there's a high chance that our definition of min, max
 
311
 * methods or use of std::numeric_limits min and max will cause
 
312
 * complaints in any program that happened to include Windows.h or
 
313
 * suchlike first.  We use the null macro below in our own header
 
314
 * files definition or use of min, max to defensively preclude
 
315
 * this problem.  It may not be enough; one might need to #define
 
316
 * NOMINMAX before including Windows.h or compile with -DNOMINMAX.
 
317
 */
 
318
#define R123_NO_MACRO_SUBST
 
319
 
 
320
/** \endcond */