Preprocessor symbols for porting Random123 to different platforms.

The Random123 library is portable across C, C++, CUDA, OpenCL environments, and multiple operating systems (Linux, Windows 7, Mac OS X, FreeBSD, Solaris). This level of portability requires the abstraction of some features and idioms that are either not standardized (e.g., asm statments), or for which different vendors have their own standards (e.g., SSE intrinsics) or for which vendors simply refuse to conform to well-established standards (e.g., <inttypes.h>).

Random123/features/compilerfeatures.h conditionally includes a compiler-or-OS-specific Random123/featires/XXXfeatures.h file which defines appropriate values for the preprocessor symbols which can be used with a specific compiler or OS. Those symbols will then be used by other header files and source files in the Random123 library (and may be used by applications) to control what actually gets presented to the compiler.

Most of the symbols are boolean valued. In general, they will always be defined with value either 1 or 0, so do NOT use #ifdef. Use #if R123_USE_SOMETHING instead.

Library users can override any value by defining the pp-symbol with a compiler option, e.g.,

cc -DR123_USE_MULHILO64_C99

will use a strictly c99 version of the full-width 64x64->128-bit multiplication function, even if it would be disabled by default.

All boolean-valued pre-processor symbols in Random123/features/compilerfeatures.h start with the prefix R123_USE_

         AES_NI
         AES_OPENSSL
         SSE4_2
         SSE4_1
         SSE

         STD_RANDOM

         GNU_UINT128
         ASM_GNU
         ASM_MSASM

         CPUID_MSVC

         CXX0X

         X86INTRIN_H
         IA32INTRIN_H
         EMMINTRIN_H
         SMMINTRIN_H
         WMMINTRIN_H
         INTRIN_H

         MULHILO32_ASM
         MULHILO64_ASM
         MULHILO64_MSVC_INTRIN
         MULHILO64_CUDA_INTRIN
         MULHILO64_OPENCL_INTRIN
         MULHILO64_C99

Most have obvious meanings. Some non-obvious ones:

AES_NI and AES_OPENSSL are not mutually exclusive. You can have one, both or neither.

GNU_UINT128 says that it's safe to use __uint128_t, but it does not require its use. In particular, it should be used in mulhilo<uint64_t> only if MULHILO64_ASM is unset.

If the XXXINTRIN_H macros are true, then one should

#include <xxxintrin.h>

to gain accesss to compiler intrinsics.

R123_USE_CXX0X says that C++0x features are available. It is therefore safe to use things like static_assert and defaulted and deleted constructors. Specific C++0x features, e.g., <random> may be under the control of other macros.

There are a number of invariants that are always true. Application code may choose to rely on these:

There are also non-boolean valued symbols:

 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines