Core/Util: replace SMFT rng with PCG

This commit is contained in:
Ovahlord committed 2022-10-30 12:04:30 +01:00
1 parent 6c171229e9
commit 2e47ee3f4c
31 files changed
+3675 -2457

No files matched your search

+1 -1
View File
@@ -18,7 +18,7 @@ if(SERVERS OR TOOLS)
add_subdirectory(recastnavigation)
add_subdirectory(jemalloc)
add_subdirectory(fmt)
add_subdirectory(SFMT)
add_subdirectory(PCG)
add_subdirectory(utf8cpp)
add_subdirectory(valgrind)
add_subdirectory(openssl)
+17
View File
@@ -0,0 +1,17 @@
# This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
# Copyright 2019 Josua Mayer <josua.mayer97@gmail.com>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
add_library(pcg INTERFACE
${PCG_SRCS})
target_include_directories(pcg
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR})
+666
View File
@@ -0,0 +1,666 @@
/*
* PCG Random Number Generation for C++
*
* Copyright 2014-2017 Melissa O'Neill <oneill@pcg-random.org>,
* and the PCG Project contributors.
*
* SPDX-License-Identifier: (Apache-2.0 OR MIT)
*
* Licensed under the Apache License, Version 2.0 (provided in
* LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
* or under the MIT license (provided in LICENSE-MIT.txt and at
* http://opensource.org/licenses/MIT), at your option. This file may not
* be copied, modified, or distributed except according to those terms.
*
* Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See your chosen license for details.
*
* For additional information about the PCG random number generation scheme,
* visit http://www.pcg-random.org/.
*/
/*
* This file provides support code that is useful for random-number generation
* but not specific to the PCG generation scheme, including:
* - 128-bit int support for platforms where it isn't available natively
* - bit twiddling operations
* - I/O of 128-bit and 8-bit integers
* - Handling the evilness of SeedSeq
* - Support for efficiently producing random numbers less than a given
* bound
*/
#ifndef PCG_EXTRAS_HPP_INCLUDED
#define PCG_EXTRAS_HPP_INCLUDED 1
#include <cinttypes>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <limits>
#include <iostream>
#include <type_traits>
#include <utility>
#include <locale>
#include <iterator>
#ifdef __GNUC__
#include <cxxabi.h>
#endif
/*
* Abstractions for compiler-specific directives
*/
#ifdef __GNUC__
#define PCG_NOINLINE __attribute__((noinline))
#else
#define PCG_NOINLINE
#endif
/*
* Some members of the PCG library use 128-bit math. When compiling on 64-bit
* platforms, both GCC and Clang provide 128-bit integer types that are ideal
* for the job.
*
* On 32-bit platforms (or with other compilers), we fall back to a C++
* class that provides 128-bit unsigned integers instead. It may seem
* like we're reinventing the wheel here, because libraries already exist
* that support large integers, but most existing libraries provide a very
* generic multiprecision code, but here we're operating at a fixed size.
* Also, most other libraries are fairly heavyweight. So we use a direct
* implementation. Sadly, it's much slower than hand-coded assembly or
* direct CPU support.
*
*/
#if __SIZEOF_INT128__ && !PCG_FORCE_EMULATED_128BIT_MATH
namespace pcg_extras {
typedef __uint128_t pcg128_t;
}
#define PCG_128BIT_CONSTANT(high,low) \
((pcg_extras::pcg128_t(high) << 64) + low)
#else
#include "pcg_uint128.hpp"
namespace pcg_extras {
typedef pcg_extras::uint_x4<uint32_t,uint64_t> pcg128_t;
}
#define PCG_128BIT_CONSTANT(high,low) \
pcg_extras::pcg128_t(high,low)
#define PCG_EMULATED_128BIT_MATH 1
#endif
namespace pcg_extras {
/*
* We often need to represent a "number of bits". When used normally, these
* numbers are never greater than 128, so an unsigned char is plenty.
* If you're using a nonstandard generator of a larger size, you can set
* PCG_BITCOUNT_T to have it define it as a larger size. (Some compilers
* might produce faster code if you set it to an unsigned int.)
*/
#ifndef PCG_BITCOUNT_T
typedef uint8_t bitcount_t;
#else
typedef PCG_BITCOUNT_T bitcount_t;
#endif
/*
* C++ requires us to be able to serialize RNG state by printing or reading
* it from a stream. Because we use 128-bit ints, we also need to be able
* ot print them, so here is code to do so.
*
* This code provides enough functionality to print 128-bit ints in decimal
* and zero-padded in hex. It's not a full-featured implementation.
*/
template <typename CharT, typename Traits>
std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& out, pcg128_t value)
{
auto desired_base = out.flags() & out.basefield;
bool want_hex = desired_base == out.hex;
if (want_hex) {
uint64_t highpart = uint64_t(value >> 64);
uint64_t lowpart = uint64_t(value);
auto desired_width = out.width();
if (desired_width > 16) {
out.width(desired_width - 16);
}
if (highpart != 0 || desired_width > 16)
out << highpart;
CharT oldfill = '\0';
if (highpart != 0) {
out.width(16);
oldfill = out.fill('0');
}
auto oldflags = out.setf(decltype(desired_base){}, out.showbase);
out << lowpart;
out.setf(oldflags);
if (highpart != 0) {
out.fill(oldfill);
}
return out;
}
constexpr size_t MAX_CHARS_128BIT = 40;
char buffer[MAX_CHARS_128BIT];
char* pos = buffer+sizeof(buffer);
*(--pos) = '\0';
constexpr auto BASE = pcg128_t(10ULL);
do {
auto div = value / BASE;
auto mod = uint32_t(value - (div * BASE));
*(--pos) = '0' + char(mod);
value = div;
} while(value != pcg128_t(0ULL));
return out << pos;
}
template <typename CharT, typename Traits>
std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& in, pcg128_t& value)
{
typename std::basic_istream<CharT,Traits>::sentry s(in);
if (!s)
return in;
constexpr auto BASE = pcg128_t(10ULL);
pcg128_t current(0ULL);
bool did_nothing = true;
bool overflow = false;
for(;;) {
CharT wide_ch = in.get();
if (!in.good()) {
in.clear(std::ios::eofbit);
break;
}
auto ch = in.narrow(wide_ch, '\0');
if (ch < '0' || ch > '9') {
in.unget();
break;
}
did_nothing = false;
pcg128_t digit(uint32_t(ch - '0'));
pcg128_t timesbase = current*BASE;
overflow = overflow || timesbase < current;
current = timesbase + digit;
overflow = overflow || current < digit;
}
if (did_nothing || overflow) {
in.setstate(std::ios::failbit);
if (overflow)
current = ~pcg128_t(0ULL);
}
value = current;
return in;
}
/*
* Likewise, if people use tiny rngs, we'll be serializing uint8_t.
* If we just used the provided IO operators, they'd read/write chars,
* not ints, so we need to define our own. We *can* redefine this operator
* here because we're in our own namespace.
*/
template <typename CharT, typename Traits>
std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>&out, uint8_t value)
{
return out << uint32_t(value);
}
template <typename CharT, typename Traits>
std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& in, uint8_t& target)
{
uint32_t value = 0xdecea5edU;
in >> value;
if (!in && value == 0xdecea5edU)
return in;
if (value > uint8_t(~0)) {
in.setstate(std::ios::failbit);
value = ~0U;
}
target = uint8_t(value);
return in;
}
/* Unfortunately, the above functions don't get found in preference to the
* built in ones, so we create some more specific overloads that will.
* Ugh.
*/
inline std::ostream& operator<<(std::ostream& out, uint8_t value)
{
return pcg_extras::operator<< <char>(out, value);
}
inline std::istream& operator>>(std::istream& in, uint8_t& value)
{
return pcg_extras::operator>> <char>(in, value);
}
/*
* Useful bitwise operations.
*/
/*
* XorShifts are invertable, but they are someting of a pain to invert.
* This function backs them out. It's used by the whacky "inside out"
* generator defined later.
*/
template <typename itype>
inline itype unxorshift(itype x, bitcount_t bits, bitcount_t shift)
{
if (2*shift >= bits) {
return x ^ (x >> shift);
}
itype lowmask1 = (itype(1U) << (bits - shift*2)) - 1;
itype highmask1 = ~lowmask1;
itype top1 = x;
itype bottom1 = x & lowmask1;
top1 ^= top1 >> shift;
top1 &= highmask1;
x = top1 | bottom1;
itype lowmask2 = (itype(1U) << (bits - shift)) - 1;
itype bottom2 = x & lowmask2;
bottom2 = unxorshift(bottom2, bits - shift, shift);
bottom2 &= lowmask1;
return top1 | bottom2;
}
/*
* Rotate left and right.
*
* In ideal world, compilers would spot idiomatic rotate code and convert it
* to a rotate instruction. Of course, opinions vary on what the correct
* idiom is and how to spot it. For clang, sometimes it generates better
* (but still crappy) code if you define PCG_USE_ZEROCHECK_ROTATE_IDIOM.
*/
template <typename itype>
inline itype rotl(itype value, bitcount_t rot)
{
constexpr bitcount_t bits = sizeof(itype) * 8;
constexpr bitcount_t mask = bits - 1;
#if PCG_USE_ZEROCHECK_ROTATE_IDIOM
return rot ? (value << rot) | (value >> (bits - rot)) : value;
#else
return (value << rot) | (value >> ((- rot) & mask));
#endif
}
template <typename itype>
inline itype rotr(itype value, bitcount_t rot)
{
constexpr bitcount_t bits = sizeof(itype) * 8;
constexpr bitcount_t mask = bits - 1;
#if PCG_USE_ZEROCHECK_ROTATE_IDIOM
return rot ? (value >> rot) | (value << (bits - rot)) : value;
#else
return (value >> rot) | (value << ((- rot) & mask));
#endif
}
/* Unfortunately, both Clang and GCC sometimes perform poorly when it comes
* to properly recognizing idiomatic rotate code, so for we also provide
* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss.
* (I hope that these compilers get better so that this code can die.)
*
* These overloads will be preferred over the general template code above.
*/
#if PCG_USE_INLINE_ASM && __GNUC__ && (__x86_64__ || __i386__)
inline uint8_t rotr(uint8_t value, bitcount_t rot)
{
asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
}
inline uint16_t rotr(uint16_t value, bitcount_t rot)
{
asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
}
inline uint32_t rotr(uint32_t value, bitcount_t rot)
{
asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
}
#if __x86_64__
inline uint64_t rotr(uint64_t value, bitcount_t rot)
{
asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
return value;
}
#endif // __x86_64__
#elif defined(_MSC_VER)
// Use MSVC++ bit rotation intrinsics
#pragma intrinsic(_rotr, _rotr64, _rotr8, _rotr16)
inline uint8_t rotr(uint8_t value, bitcount_t rot)
{
return _rotr8(value, rot);
}
inline uint16_t rotr(uint16_t value, bitcount_t rot)
{
return _rotr16(value, rot);
}
inline uint32_t rotr(uint32_t value, bitcount_t rot)
{
return _rotr(value, rot);
}
inline uint64_t rotr(uint64_t value, bitcount_t rot)
{
return _rotr64(value, rot);
}
#endif // PCG_USE_INLINE_ASM
/*
* The C++ SeedSeq concept (modelled by seed_seq) can fill an array of
* 32-bit integers with seed data, but sometimes we want to produce
* larger or smaller integers.
*
* The following code handles this annoyance.
*
* uneven_copy will copy an array of 32-bit ints to an array of larger or
* smaller ints (actually, the code is general it only needing forward
* iterators). The copy is identical to the one that would be performed if
* we just did memcpy on a standard little-endian machine, but works
* regardless of the endian of the machine (or the weirdness of the ints
* involved).
*
* generate_to initializes an array of integers using a SeedSeq
* object. It is given the size as a static constant at compile time and
* tries to avoid memory allocation. If we're filling in 32-bit constants
* we just do it directly. If we need a separate buffer and it's small,
* we allocate it on the stack. Otherwise, we fall back to heap allocation.
* Ugh.
*
* generate_one produces a single value of some integral type using a
* SeedSeq object.
*/
/* uneven_copy helper, case where destination ints are less than 32 bit. */
template<class SrcIter, class DestIter>
SrcIter uneven_copy_impl(
SrcIter src_first, DestIter dest_first, DestIter dest_last,
std::true_type)
{
typedef typename std::iterator_traits<SrcIter>::value_type src_t;
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr bitcount_t SRC_SIZE = sizeof(src_t);
constexpr bitcount_t DEST_SIZE = sizeof(dest_t);
constexpr bitcount_t DEST_BITS = DEST_SIZE * 8;
constexpr bitcount_t SCALE = SRC_SIZE / DEST_SIZE;
size_t count = 0;
src_t value = 0;
while (dest_first != dest_last) {
if ((count++ % SCALE) == 0)
value = *src_first++; // Get more bits
else
value >>= DEST_BITS; // Move down bits
*dest_first++ = dest_t(value); // Truncates, ignores high bits.
}
return src_first;
}
/* uneven_copy helper, case where destination ints are more than 32 bit. */
template<class SrcIter, class DestIter>
SrcIter uneven_copy_impl(
SrcIter src_first, DestIter dest_first, DestIter dest_last,
std::false_type)
{
typedef typename std::iterator_traits<SrcIter>::value_type src_t;
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr auto SRC_SIZE = sizeof(src_t);
constexpr auto SRC_BITS = SRC_SIZE * 8;
constexpr auto DEST_SIZE = sizeof(dest_t);
constexpr auto SCALE = (DEST_SIZE+SRC_SIZE-1) / SRC_SIZE;
while (dest_first != dest_last) {
dest_t value(0UL);
unsigned int shift = 0;
for (size_t i = 0; i < SCALE; ++i) {
value |= dest_t(*src_first++) << shift;
shift += SRC_BITS;
}
*dest_first++ = value;
}
return src_first;
}
/* uneven_copy, call the right code for larger vs. smaller */
template<class SrcIter, class DestIter>
inline SrcIter uneven_copy(SrcIter src_first,
DestIter dest_first, DestIter dest_last)
{
typedef typename std::iterator_traits<SrcIter>::value_type src_t;
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr bool DEST_IS_SMALLER = sizeof(dest_t) < sizeof(src_t);
return uneven_copy_impl(src_first, dest_first, dest_last,
std::integral_constant<bool, DEST_IS_SMALLER>{});
}
/* generate_to, fill in a fixed-size array of integral type using a SeedSeq
* (actually works for any random-access iterator)
*/
template <size_t size, typename SeedSeq, typename DestIter>
inline void generate_to_impl(SeedSeq&& generator, DestIter dest,
std::true_type)
{
generator.generate(dest, dest+size);
}
template <size_t size, typename SeedSeq, typename DestIter>
void generate_to_impl(SeedSeq&& generator, DestIter dest,
std::false_type)
{
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr auto DEST_SIZE = sizeof(dest_t);
constexpr auto GEN_SIZE = sizeof(uint32_t);
constexpr bool GEN_IS_SMALLER = GEN_SIZE < DEST_SIZE;
constexpr size_t FROM_ELEMS =
GEN_IS_SMALLER
? size * ((DEST_SIZE+GEN_SIZE-1) / GEN_SIZE)
: (size + (GEN_SIZE / DEST_SIZE) - 1)
/ ((GEN_SIZE / DEST_SIZE) + GEN_IS_SMALLER);
// this odd code ^^^^^^^^^^^^^^^^^ is work-around for
// a bug: http://llvm.org/bugs/show_bug.cgi?id=21287
if (FROM_ELEMS <= 1024) {
uint32_t buffer[FROM_ELEMS];
generator.generate(buffer, buffer+FROM_ELEMS);
uneven_copy(buffer, dest, dest+size);
} else {
uint32_t* buffer = static_cast<uint32_t*>(malloc(GEN_SIZE * FROM_ELEMS));
generator.generate(buffer, buffer+FROM_ELEMS);
uneven_copy(buffer, dest, dest+size);
free(static_cast<void*>(buffer));
}
}
template <size_t size, typename SeedSeq, typename DestIter>
inline void generate_to(SeedSeq&& generator, DestIter dest)
{
typedef typename std::iterator_traits<DestIter>::value_type dest_t;
constexpr bool IS_32BIT = sizeof(dest_t) == sizeof(uint32_t);
generate_to_impl<size>(std::forward<SeedSeq>(generator), dest,
std::integral_constant<bool, IS_32BIT>{});
}
/* generate_one, produce a value of integral type using a SeedSeq
* (optionally, we can have it produce more than one and pick which one
* we want)
*/
template <typename UInt, size_t i = 0UL, size_t N = i+1UL, typename SeedSeq>
inline UInt generate_one(SeedSeq&& generator)
{
UInt result[N];
generate_to<N>(std::forward<SeedSeq>(generator), result);
return result[i];
}
template <typename RngType>
auto bounded_rand(RngType& rng, typename RngType::result_type upper_bound)
-> typename RngType::result_type
{
typedef typename RngType::result_type rtype;
rtype threshold = (RngType::max() - RngType::min() + rtype(1) - upper_bound)
% upper_bound;
for (;;) {
rtype r = rng() - RngType::min();
if (r >= threshold)
return r % upper_bound;
}
}
template <typename Iter, typename RandType>
void shuffle(Iter from, Iter to, RandType&& rng)
{
typedef typename std::iterator_traits<Iter>::difference_type delta_t;
typedef typename std::remove_reference<RandType>::type::result_type result_t;
auto count = to - from;
while (count > 1) {
delta_t chosen = delta_t(bounded_rand(rng, result_t(count)));
--count;
--to;
using std::swap;
swap(*(from + chosen), *to);
}
}
/*
* Although std::seed_seq is useful, it isn't everything. Often we want to
* initialize a random-number generator some other way, such as from a random
* device.
*
* Technically, it does not meet the requirements of a SeedSequence because
* it lacks some of the rarely-used member functions (some of which would
* be impossible to provide). However the C++ standard is quite specific
* that actual engines only called the generate method, so it ought not to be
* a problem in practice.
*/
template <typename RngType>
class seed_seq_from {
private:
RngType rng_;
typedef uint_least32_t result_type;
public:
template<typename... Args>
seed_seq_from(Args&&... args) :
rng_(std::forward<Args>(args)...)
{
// Nothing (else) to do...
}
template<typename Iter>
void generate(Iter start, Iter finish)
{
for (auto i = start; i != finish; ++i)
*i = result_type(rng_());
}
constexpr size_t size() const
{
return (sizeof(typename RngType::result_type) > sizeof(result_type)
&& RngType::max() > ~size_t(0UL))
? ~size_t(0UL)
: size_t(RngType::max());
}
};
/*
* Sometimes you might want a distinct seed based on when the program
* was compiled. That way, a particular instance of the program will
* behave the same way, but when recompiled it'll produce a different
* value.
*/
template <typename IntType>
struct static_arbitrary_seed {
private:
static constexpr IntType fnv(IntType hash, const char* pos) {
return *pos == '\0'
? hash
: fnv((hash * IntType(16777619U)) ^ *pos, (pos+1));
}
public:
static constexpr IntType value = fnv(IntType(2166136261U ^ sizeof(IntType)),
__DATE__ __TIME__ __FILE__);
};
// Sometimes, when debugging or testing, it's handy to be able print the name
// of a (in human-readable form). This code allows the idiom:
//
// cout << printable_typename<my_foo_type_t>()
//
// to print out my_foo_type_t (or its concrete type if it is a synonym)
#if __cpp_rtti || __GXX_RTTI
template <typename T>
struct printable_typename {};
template <typename T>
std::ostream& operator<<(std::ostream& out, printable_typename<T>) {
const char *implementation_typename = typeid(T).name();
#ifdef __GNUC__
int status;
char* pretty_name =
abi::__cxa_demangle(implementation_typename, nullptr, nullptr, &status);
if (status == 0)
out << pretty_name;
free(static_cast<void*>(pretty_name));
if (status == 0)
return out;
#endif
out << implementation_typename;
return out;
}
#endif // __cpp_rtti || __GXX_RTTI
} // namespace pcg_extras
#endif // PCG_EXTRAS_HPP_INCLUDED
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-69
View File
@@ -1,69 +0,0 @@
ver 1.5
-------
bug fix to_res53 reported by Akio Takahashi.
ver 1.4.1
-------
fix MSC compile error reported by Dirk Steenpass.
ver 1.4
-------
internal state of SFMT is kept in structure.
function and macro names are changed to have sfmt_ prefix.
ALTIVEC OR BIGENDIAN ARE NOT TESTED AT ALL.
ver 1.3.3
-------
change condition compile of do_recursion in SFMT.c
ver 1.3.2
-------
bug fix to_res53_mix and genrand_res53_mix.
ver 1.3.1
-------
gcc compile option changed from -O9 to -O3.
add functions genrand_res53_mix and to_res53_mix.
bug fix about definition of ALWAYS_INLINE.
add new definition PRE_ALWAYS for MSC.
ver 1.3
-------
bug fixed: -DONLY64 without -DBIG_ENIAN64 had been generating
wrong sequence.
bug fixed: There is no documentation about BIG_ENDIAN64.
add automatic endian check by __BIG_ENDIAN__ predefined macro.
bug fixed: change == in check.sh to =
add SFMT-params216091.h
add AltiVec parameter format for systems which are not osx.
change Makefile for systems which are not osx and support AltiVec.
change sample2 of howto-compile for Free BSD.
change source files for BORLANDC and Visual Studio.
change period certification code more smart.
add params directory.
ver 1.2.1
-------
Fix typo in SFMT-alti.c SFMT-sse2.c
marge SFMT-alti.c and SFMT-alti.h into SFMT-alti.h
marge SFMT-sse2.c and SFMT-sse2.h into SFMT-sse2.h
This version is not released.
ver 1.2
-------
Support many periods: 2^{607}, 2^{1279}, 2^{2281}, 2^{4253}, 2^{11213},
2^{19937}, 2^{44497}, 2^{86243}, 2^{132049}
Fix typo in LICENSE.txt.
Add cast to vec_perm for SFMT-alti.c, SFMT-alti64.c.
combine source codes.
ver 1.1
-------
The period certification method is changed from constant to function.
The convert functions from 32-bit and 64-bit integer to double are added.
The documentation is changed.
Sample programs are added.
ver 1.0
-------
The first version.
-80
View File
@@ -1,80 +0,0 @@
# This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
# Copyright 2019 Josua Mayer <josua.mayer97@gmail.com>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
set(SFMT_SOURCES
SFMT.c
SFMT.h
SFMT-alti.h
SFMT-common.h
SFMT-neon.h
SFMT-params.h
SFMT-params607.h
SFMT-params1279.h
SFMT-params2281.h
SFMT-params4253.h
SFMT-params11213.h
SFMT-params19937.h
SFMT-params44497.h
SFMT-params86243.h
SFMT-params132049.h
SFMT-params216091.h
SFMT-sse2.h
SFMT-sse2-msc.h)
add_library(sfmt STATIC ${SFMT_SOURCES})
target_include_directories(sfmt
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR})
# using the standard Mersenne exponent 19937
target_compile_definitions(sfmt PUBLIC -DSFMT_MEXP=19937)
# enable SIMD instructions if available
include(CheckCCompilerFlag)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(powerpc|ppc)64|(powerpc|ppc)64le")
check_c_compiler_flag("-maltivec" HAVE_ALTIVEC)
if (HAVE_ALTIVEC)
target_compile_options(sfmt PRIVATE -mabi=altivec -maltivec)
target_compile_definitions(sfmt PUBLIC -DHAVE_ALTIVEC)
else ()
message(WARNING "Altivec not available - performance will be poor!")
endif ()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM")
check_c_compiler_flag(-mfpu=neon HAVE_NEON)
if (HAVE_NEON)
target_compile_options(sfmt PRIVATE -mfpu=neon -ftree-vectorize)
target_compile_definitions(sfmt PUBLIC -DHAVE_NEON)
else ()
message(WARNING "Neon not available - performance will be poor!")
endif ()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64")
check_c_compiler_flag(-march=armv8-a+simd HAVE_NEON)
if (HAVE_NEON)
target_compile_options(sfmt PRIVATE -ftree-vectorize)
target_compile_definitions(sfmt PUBLIC -DHAVE_NEON)
else ()
message(WARNING "Neon not available - performance will be poor!")
endif ()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "i686|amd64|x86_64|AMD64")
#SSE2 is always available
set(HAVE_SSE2 1)
if (NOT CMAKE_C_COMPILER_ID MATCHES "MSVC")
target_compile_options(sfmt PRIVATE -msse2)
endif ()
target_compile_definitions(sfmt PUBLIC -DHAVE_SSE2)
endif ()
set_target_properties(sfmt PROPERTIES LINKER_LANGUAGE CXX)
# inherit trinitycore generic build options (e.g. fPIC)
target_link_libraries(sfmt PRIVATE trinity-dependency-interface)
-32
View File
@@ -1,32 +0,0 @@
Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
University.
Copyright (c) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima University
and The University of Tokyo.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the names of Hiroshima University, The University of
Tokyo nor the names of its contributors may be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-27
View File
@@ -1,27 +0,0 @@
=================================================================
SFMT ver. 1.5
SIMD oriented Fast Mersenne Twister(SFMT)
Mutsuo Saito (Hiroshima University) and
Makoto Matsumoto (The University of Tokyo)
Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
University.
Copyright (c) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima University
and The University of Tokyo.
All rights reserved.
The (modified) BSD License is applied to this software, see LICENSE.txt
=================================================================
CAUTION:
BIGENDIAN OR ALTIVEC FEATURES ARE NOT TESTED AT ALL.
To see documents, see html/index.html.
To make test program, see html/howto-compile.html
If you want to redistribute and/or change source files, see LICENSE.txt.
When you change these files and redistribute them, PLEASE write your
e-mail address in redistribution and write to contact YOU first if
users of your changed source encounter troubles.
-156
View File
@@ -1,156 +0,0 @@
#pragma once
/**
* @file SFMT-alti.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
* pseudorandom number generator
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software.
* see LICENSE.txt
*/
#ifndef SFMT_ALTI_H
#define SFMT_ALTI_H
inline static vector unsigned int vec_recursion(vector unsigned int a,
vector unsigned int b,
vector unsigned int c,
vector unsigned int d);
/**
* This function represents the recursion formula in AltiVec and BIG ENDIAN.
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
* @return output
*/
inline static vector unsigned int vec_recursion(vector unsigned int a,
vector unsigned int b,
vector unsigned int c,
vector unsigned int d) {
const vector unsigned int sl1 = SFMT_ALTI_SL1;
const vector unsigned int sr1 = SFMT_ALTI_SR1;
#ifdef ONLY64
const vector unsigned int mask = SFMT_ALTI_MSK64;
const vector unsigned char perm_sl = SFMT_ALTI_SL2_PERM64;
const vector unsigned char perm_sr = SFMT_ALTI_SR2_PERM64;
#else
const vector unsigned int mask = SFMT_ALTI_MSK;
const vector unsigned char perm_sl = SFMT_ALTI_SL2_PERM;
const vector unsigned char perm_sr = SFMT_ALTI_SR2_PERM;
#endif
vector unsigned int v, w, x, y, z;
x = vec_perm(a, (vector unsigned int)perm_sl, perm_sl);
v = a;
y = vec_sr(b, sr1);
z = vec_perm(c, (vector unsigned int)perm_sr, perm_sr);
w = vec_sl(d, sl1);
z = vec_xor(z, w);
y = vec_and(y, mask);
v = vec_xor(v, x);
z = vec_xor(z, y);
z = vec_xor(z, v);
return z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
vector unsigned int r, r1, r2;
r1 = sfmt->state[N - 2].s;
r2 = sfmt->state[N - 1].s;
for (i = 0; i < N - POS1; i++) {
r = vec_recursion(sfmt->state[i].s, sfmt->state[i + POS1].s, r1, r2);
sfmt->state[i].s = r;
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = vec_recursion(sfmt->state[i].s, sfmt->state[i + POS1 - N].s, r1, r2);
sfmt->state[i].s = r;
r1 = r2;
r2 = r;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pesudorandom numbers to be generated.
*/
inline static void gen_rand_array(sfmt_t * sfmt, w128_t *array, int size) {
int i, j;
vector unsigned int r, r1, r2;
r1 = sfmt->state[N - 2].s;
r2 = sfmt->state[N - 1].s;
for (i = 0; i < N - POS1; i++) {
r = vec_recursion(sfmt->state[i].s, sfmt->state[i + POS1].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = vec_recursion(sfmt->state[i].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
/* main loop */
for (; i < size - N; i++) {
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
for (j = 0; j < 2 * N - size; j++) {
sfmt->state[j].s = array[j + size - N].s;
}
for (; i < size; i++) {
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
sfmt->state[j++].s = r;
r1 = r2;
r2 = r;
}
}
#ifndef ONLY64
#if defined(__APPLE__)
#define SFMT_ALTI_SWAP (vector unsigned char) \
(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11)
#else
#define SFMT_ALTI_SWAP {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}
#endif
/**
* This function swaps high and low 32-bit of 64-bit integers in user
* specified array.
*
* @param array an 128-bit array to be swaped.
* @param size size of 128-bit array.
*/
inline static void swap(w128_t *array, int size) {
int i;
const vector unsigned char perm = SFMT_ALTI_SWAP;
for (i = 0; i < size; i++) {
array[i].s = vec_perm(array[i].s, (vector unsigned int)perm, perm);
}
}
#endif
#endif
-164
View File
@@ -1,164 +0,0 @@
#pragma once
/**
* @file SFMT-common.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
* number generator with jump function. This file includes common functions
* used in random number generation and jump.
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (The University of Tokyo)
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
* Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima
* University and The University of Tokyo.
* All rights reserved.
*
* The 3-clause BSD License is applied to this software, see
* LICENSE.txt
*/
#ifndef SFMT_COMMON_H
#define SFMT_COMMON_H
#if defined(__cplusplus)
extern "C" {
#endif
#include "SFMT.h"
inline static void do_recursion(w128_t * r, w128_t * a, w128_t * b,
w128_t * c, w128_t * d);
inline static void rshift128(w128_t *out, w128_t const *in, int shift);
inline static void lshift128(w128_t *out, w128_t const *in, int shift);
/**
* This function simulates SIMD 128-bit right shift by the standard C.
* The 128-bit integer given in in is shifted by (shift * 8) bits.
* This function simulates the LITTLE ENDIAN SIMD.
* @param out the output of this function
* @param in the 128-bit data to be shifted
* @param shift the shift value
*/
#ifdef ONLY64
inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
oh = th >> (shift * 8);
ol = tl >> (shift * 8);
ol |= th << (64 - shift * 8);
out->u[0] = (uint32_t)(ol >> 32);
out->u[1] = (uint32_t)ol;
out->u[2] = (uint32_t)(oh >> 32);
out->u[3] = (uint32_t)oh;
}
#else
inline static void rshift128(w128_t *out, w128_t const *in, int shift)
{
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
oh = th >> (shift * 8);
ol = tl >> (shift * 8);
ol |= th << (64 - shift * 8);
out->u[1] = (uint32_t)(ol >> 32);
out->u[0] = (uint32_t)ol;
out->u[3] = (uint32_t)(oh >> 32);
out->u[2] = (uint32_t)oh;
}
#endif
/**
* This function simulates SIMD 128-bit left shift by the standard C.
* The 128-bit integer given in in is shifted by (shift * 8) bits.
* This function simulates the LITTLE ENDIAN SIMD.
* @param out the output of this function
* @param in the 128-bit data to be shifted
* @param shift the shift value
*/
#ifdef ONLY64
inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
oh = th << (shift * 8);
ol = tl << (shift * 8);
oh |= tl >> (64 - shift * 8);
out->u[0] = (uint32_t)(ol >> 32);
out->u[1] = (uint32_t)ol;
out->u[2] = (uint32_t)(oh >> 32);
out->u[3] = (uint32_t)oh;
}
#else
inline static void lshift128(w128_t *out, w128_t const *in, int shift)
{
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
oh = th << (shift * 8);
ol = tl << (shift * 8);
oh |= tl >> (64 - shift * 8);
out->u[1] = (uint32_t)(ol >> 32);
out->u[0] = (uint32_t)ol;
out->u[3] = (uint32_t)(oh >> 32);
out->u[2] = (uint32_t)oh;
}
#endif
/**
* This function represents the recursion formula.
* @param r output
* @param a a 128-bit part of the internal state array
* @param b a 128-bit part of the internal state array
* @param c a 128-bit part of the internal state array
* @param d a 128-bit part of the internal state array
*/
#ifdef ONLY64
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
w128_t *d) {
w128_t x;
w128_t y;
lshift128(&x, a, SFMT_SL2);
rshift128(&y, c, SFMT_SR2);
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK2) ^ y.u[0]
^ (d->u[0] << SFMT_SL1);
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK1) ^ y.u[1]
^ (d->u[1] << SFMT_SL1);
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK4) ^ y.u[2]
^ (d->u[2] << SFMT_SL1);
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK3) ^ y.u[3]
^ (d->u[3] << SFMT_SL1);
}
#else
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b,
w128_t *c, w128_t *d)
{
w128_t x;
w128_t y;
lshift128(&x, a, SFMT_SL2);
rshift128(&y, c, SFMT_SR2);
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK1)
^ y.u[0] ^ (d->u[0] << SFMT_SL1);
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK2)
^ y.u[1] ^ (d->u[1] << SFMT_SL1);
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK3)
^ y.u[2] ^ (d->u[2] << SFMT_SL1);
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK4)
^ y.u[3] ^ (d->u[3] << SFMT_SL1);
}
#endif
#if defined(__cplusplus)
}
#endif
#endif // SFMT_COMMON_H
-111
View File
@@ -1,111 +0,0 @@
/**
* @file SFMT-neon.h
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for ARM with 128b NEON
*
* @author Masaki Ota
*
* @note We assume LITTLE ENDIAN in this file
*/
#ifndef SFMT_NEON_H
#define SFMT_NEON_H
inline static void neon_recursion(uint32x4_t * r, uint32x4_t a, uint32x4_t b,
uint32x4_t c, uint32x4_t d);
/**
* This function represents the recursion formula.
* @param r an output
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
*/
inline static void neon_recursion(uint32x4_t * r, uint32x4_t a, uint32x4_t b,
uint32x4_t c, uint32x4_t d)
{
uint32x4_t v, x, y, z;
static const uint32x4_t vzero = {0,0,0,0};
static const uint32x4_t vmask = {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4};
#define rotate_bytes(A, B, C) vreinterpretq_u32_u8(vextq_u8(vreinterpretq_u8_u32(A),vreinterpretq_u8_u32(B),(C)))
y = vshrq_n_u32(b, SFMT_SR1);
z = rotate_bytes(c, vzero, SFMT_SR2);
v = vshlq_n_u32(d, SFMT_SL1);
z = veorq_u32(z, a);
z = veorq_u32(z, v);
x = rotate_bytes(vzero, a, 16-SFMT_SL2);
y = vandq_u32(y, vmask);
z = veorq_u32(z, x);
z = veorq_u32(z, y);
*r = z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
uint32x4_t r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
neon_recursion(&pstate[i].si, pstate[i].si, pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
neon_recursion(&pstate[i].si, pstate[i].si, pstate[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
uint32x4_t r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
neon_recursion(&array[i].si, pstate[i].si, pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
neon_recursion(&array[i].si, pstate[i].si, array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
neon_recursion(&array[i].si, array[i - SFMT_N].si, array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
neon_recursion(&array[i].si, array[i - SFMT_N].si, array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = pstate[j].si = array[i].si;
}
}
#endif
-98
View File
@@ -1,98 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS_H
#define SFMT_PARAMS_H
#if !defined(SFMT_MEXP)
#if defined(__GNUC__) && !defined(__ICC)
#warning "SFMT_MEXP is not defined. I assume MEXP is 19937."
#endif
#define SFMT_MEXP 19937
#endif
/*-----------------
BASIC DEFINITIONS
-----------------*/
/** Mersenne Exponent. The period of the sequence
* is a multiple of 2^MEXP-1.
* #define SFMT_MEXP 19937 */
/** SFMT generator has an internal state array of 128-bit integers,
* and N is its size. */
#define SFMT_N (SFMT_MEXP / 128 + 1)
/** N32 is the size of internal state array when regarded as an array
* of 32-bit integers.*/
#define SFMT_N32 (SFMT_N * 4)
/** N64 is the size of internal state array when regarded as an array
* of 64-bit integers.*/
#define SFMT_N64 (SFMT_N * 2)
/*----------------------
the parameters of SFMT
following definitions are in paramsXXXX.h file.
----------------------*/
/** the pick up position of the array.
#define SFMT_POS1 122
*/
/** the parameter of shift left as four 32-bit registers.
#define SFMT_SL1 18
*/
/** the parameter of shift left as one 128-bit register.
* The 128-bit integer is shifted by (SFMT_SL2 * 8) bits.
#define SFMT_SL2 1
*/
/** the parameter of shift right as four 32-bit registers.
#define SFMT_SR1 11
*/
/** the parameter of shift right as one 128-bit register.
* The 128-bit integer is shifted by (SFMT_SR2 * 8) bits.
#define SFMT_SR2 1
*/
/** A bitmask, used in the recursion. These parameters are introduced
* to break symmetry of SIMD.
#define SFMT_MSK1 0xdfffffefU
#define SFMT_MSK2 0xddfecb7fU
#define SFMT_MSK3 0xbffaffffU
#define SFMT_MSK4 0xbffffff6U
*/
/** These definitions are part of a 128-bit period certification vector.
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0xc98e126aU
*/
#if SFMT_MEXP == 607
#include "SFMT-params607.h"
#elif SFMT_MEXP == 1279
#include "SFMT-params1279.h"
#elif SFMT_MEXP == 2281
#include "SFMT-params2281.h"
#elif SFMT_MEXP == 4253
#include "SFMT-params4253.h"
#elif SFMT_MEXP == 11213
#include "SFMT-params11213.h"
#elif SFMT_MEXP == 19937
#include "SFMT-params19937.h"
#elif SFMT_MEXP == 44497
#include "SFMT-params44497.h"
#elif SFMT_MEXP == 86243
#include "SFMT-params86243.h"
#elif SFMT_MEXP == 132049
#include "SFMT-params132049.h"
#elif SFMT_MEXP == 216091
#include "SFMT-params216091.h"
#else
#if defined(__GNUC__) && !defined(__ICC)
#error "SFMT_MEXP is not valid."
#undef SFMT_MEXP
#else
#undef SFMT_MEXP
#endif
#endif
#endif /* SFMT_PARAMS_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS11213_H
#define SFMT_PARAMS11213_H
#define SFMT_POS1 68
#define SFMT_SL1 14
#define SFMT_SL2 3
#define SFMT_SR1 7
#define SFMT_SR2 3
#define SFMT_MSK1 0xeffff7fbU
#define SFMT_MSK2 0xffffffefU
#define SFMT_MSK3 0xdfdfbfffU
#define SFMT_MSK4 0x7fffdbfdU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0xe8148000U
#define SFMT_PARITY4 0xd0c7afa3U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define SFMT_ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-11213:68-14-3-7-3:effff7fb-ffffffef-dfdfbfff-7fffdbfd"
#endif /* SFMT_PARAMS11213_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS1279_H
#define SFMT_PARAMS1279_H
#define SFMT_POS1 7
#define SFMT_SL1 14
#define SFMT_SL2 3
#define SFMT_SR1 5
#define SFMT_SR2 1
#define SFMT_MSK1 0xf7fefffdU
#define SFMT_MSK2 0x7fefcfffU
#define SFMT_MSK3 0xaff3ef3fU
#define SFMT_MSK4 0xb5ffff7fU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0x20000000U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-1279:7-14-3-5-1:f7fefffd-7fefcfff-aff3ef3f-b5ffff7f"
#endif /* SFMT_PARAMS1279_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS132049_H
#define SFMT_PARAMS132049_H
#define SFMT_POS1 110
#define SFMT_SL1 19
#define SFMT_SL2 1
#define SFMT_SR1 21
#define SFMT_SR2 1
#define SFMT_MSK1 0xffffbb5fU
#define SFMT_MSK2 0xfb6ebf95U
#define SFMT_MSK3 0xfffefffaU
#define SFMT_MSK4 0xcff77fffU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0xcb520000U
#define SFMT_PARITY4 0xc7e91c7dU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define SFMT_ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-132049:110-19-1-21-1:ffffbb5f-fb6ebf95-fffefffa-cff77fff"
#endif /* SFMT_PARAMS132049_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS19937_H
#define SFMT_PARAMS19937_H
#define SFMT_POS1 122
#define SFMT_SL1 18
#define SFMT_SL2 1
#define SFMT_SR1 11
#define SFMT_SR2 1
#define SFMT_MSK1 0xdfffffefU
#define SFMT_MSK2 0xddfecb7fU
#define SFMT_MSK3 0xbffaffffU
#define SFMT_MSK4 0xbffffff6U
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0x13c9e684U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define SFMT_ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"
#endif /* SFMT_PARAMS19937_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS216091_H
#define SFMT_PARAMS216091_H
#define SFMT_POS1 627
#define SFMT_SL1 11
#define SFMT_SL2 3
#define SFMT_SR1 10
#define SFMT_SR2 1
#define SFMT_MSK1 0xbff7bff7U
#define SFMT_MSK2 0xbfffffffU
#define SFMT_MSK3 0xbffffa7fU
#define SFMT_MSK4 0xffddfbfbU
#define SFMT_PARITY1 0xf8000001U
#define SFMT_PARITY2 0x89e80709U
#define SFMT_PARITY3 0x3bd2b64bU
#define SFMT_PARITY4 0x0c64b1e4U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-216091:627-11-3-10-1:bff7bff7-bfffffff-bffffa7f-ffddfbfb"
#endif /* SFMT_PARAMS216091_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS2281_H
#define SFMT_PARAMS2281_H
#define SFMT_POS1 12
#define SFMT_SL1 19
#define SFMT_SL2 1
#define SFMT_SR1 5
#define SFMT_SR2 1
#define SFMT_MSK1 0xbff7ffbfU
#define SFMT_MSK2 0xfdfffffeU
#define SFMT_MSK3 0xf7ffef7fU
#define SFMT_MSK4 0xf2f7cbbfU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0x41dfa600U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define SFMT_ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-2281:12-19-1-5-1:bff7ffbf-fdfffffe-f7ffef7f-f2f7cbbf"
#endif /* SFMT_PARAMS2281_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS4253_H
#define SFMT_PARAMS4253_H
#define SFMT_POS1 17
#define SFMT_SL1 20
#define SFMT_SL2 1
#define SFMT_SR1 7
#define SFMT_SR2 1
#define SFMT_MSK1 0x9f7bffffU
#define SFMT_MSK2 0x9fffff5fU
#define SFMT_MSK3 0x3efffffbU
#define SFMT_MSK4 0xfffff7bbU
#define SFMT_PARITY1 0xa8000001U
#define SFMT_PARITY2 0xaf5390a3U
#define SFMT_PARITY3 0xb740b3f8U
#define SFMT_PARITY4 0x6c11486dU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define SFMT_ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-4253:17-20-1-7-1:9f7bffff-9fffff5f-3efffffb-fffff7bb"
#endif /* SFMT_PARAMS4253_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS44497_H
#define SFMT_PARAMS44497_H
#define SFMT_POS1 330
#define SFMT_SL1 5
#define SFMT_SL2 3
#define SFMT_SR1 9
#define SFMT_SR2 3
#define SFMT_MSK1 0xeffffffbU
#define SFMT_MSK2 0xdfbebfffU
#define SFMT_MSK3 0xbfbf7befU
#define SFMT_MSK4 0x9ffd7bffU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0xa3ac4000U
#define SFMT_PARITY4 0xecc1327aU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define SFMT_ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-44497:330-5-3-9-3:effffffb-dfbebfff-bfbf7bef-9ffd7bff"
#endif /* SFMT_PARAMS44497_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS607_H
#define SFMT_PARAMS607_H
#define SFMT_POS1 2
#define SFMT_SL1 15
#define SFMT_SL2 3
#define SFMT_SR1 13
#define SFMT_SR2 3
#define SFMT_MSK1 0xfdff37ffU
#define SFMT_MSK2 0xef7f3f7dU
#define SFMT_MSK3 0xff777b7dU
#define SFMT_MSK4 0x7ff7fb2fU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0x5986f054U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define SFMT_ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-607:2-15-3-13-3:fdff37ff-ef7f3f7d-ff777b7d-7ff7fb2f"
#endif /* SFMT_PARAMS607_H */
-50
View File
@@ -1,50 +0,0 @@
#pragma once
#ifndef SFMT_PARAMS86243_H
#define SFMT_PARAMS86243_H
#define SFMT_POS1 366
#define SFMT_SL1 6
#define SFMT_SL2 7
#define SFMT_SR1 19
#define SFMT_SR2 1
#define SFMT_MSK1 0xfdbffbffU
#define SFMT_MSK2 0xbff7ff3fU
#define SFMT_MSK3 0xfd77efffU
#define SFMT_MSK4 0xbf9ff3ffU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0xe9528d85U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6}
#define SFMT_ALTI_SL2_PERM64 {7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-86243:366-6-7-19-1:fdbffbff-bff7ff3f-fd77efff-bf9ff3ff"
#endif /* SFMT_PARAMS86243_H */
-321
View File
@@ -1,321 +0,0 @@
#pragma once
/**
* @file SFMT-sse2-msc.h
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2 for MSC
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* @note We assume LITTLE ENDIAN in this file
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
* Copyright (C) 2013 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
*
* The new BSD License is applied to this software, see LICENSE.txt
*/
#ifndef SFMT_SSE2_MSC_H
#define SFMT_SSE2_MSC_H
/* This header file is included only when _MSC_VER is defined. */
#if _MSC_VER > 1700
inline static __m128i __vectorcall mm_recursion(__m128i a, __m128i b,
__m128i c, __m128i d);
/**
* This function represents the recursion formula.
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
* @return new value
*/
inline static __m128i __vectorcall mm_recursion(__m128i a, __m128i b,
__m128i c, __m128i d)
{
__m128i v, x, y, z;
y = _mm_srli_epi32(b, SFMT_SR1);
z = _mm_srli_si128(c, SFMT_SR2);
v = _mm_slli_epi32(d, SFMT_SL1);
z = _mm_xor_si128(z, a);
z = _mm_xor_si128(z, v);
x = _mm_slli_si128(a, SFMT_SL2);
y = _mm_and_si128(y, sse2_param_mask.si);
z = _mm_xor_si128(z, x);
return _mm_xor_si128(z, y);
}
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
pstate[i].si = mm_recursion(pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
pstate[i].si = mm_recursion(pstate[i].si,
pstate[i + SFMT_POS1 - SFMT_N].si,
r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
array[i].si = mm_recursion(pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
array[i].si = mm_recursion(pstate[i].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
array[i].si = mm_recursion(array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
array[i].si = mm_recursion(array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
pstate[j] = array[i];
}
}
#elif defined(SFMT_USE_MACRO_FUNCTION_FOR_MSC)
/**
* This function represents the recursion formula.
* @param r an output
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
*/
#define mm_recursion(r, a, b, c, d) \
do { \
__m128i v, x, y, z; \
\
y = _mm_srli_epi32((b), SFMT_SR1); \
z = _mm_srli_si128((c), SFMT_SR2); \
v = _mm_slli_epi32((d), SFMT_SL1); \
z = _mm_xor_si128(z, (a)); \
z = _mm_xor_si128(z, v); \
x = _mm_slli_si128((a), SFMT_SL2); \
y = _mm_and_si128(y, sse2_param_mask.si); \
z = _mm_xor_si128(z, x); \
r = _mm_xor_si128(z, y); \
} while (0)
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1 - SFMT_N].si,
r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(array[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(array[i].si, pstate[i].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
mm_recursion(array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
mm_recursion(array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
pstate[j] = array[i];
}
}
#else
inline static void mm_recursion(__m128i * r, __m128i a, __m128i b,
__m128i c, __m128i * d);
/**
* This function represents the recursion formula.
* @param r an output
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
*/
inline static void mm_recursion(__m128i * r, __m128i a, __m128i b,
__m128i c, __m128i * d)
{
__m128i v, x, y, z;
y = _mm_srli_epi32(b, SFMT_SR1);
z = _mm_srli_si128(c, SFMT_SR2);
v = _mm_slli_epi32(*d, SFMT_SL1);
z = _mm_xor_si128(z, a);
z = _mm_xor_si128(z, v);
x = _mm_slli_si128(a, SFMT_SL2);
y = _mm_and_si128(y, sse2_param_mask.si);
z = _mm_xor_si128(z, x);
z = _mm_xor_si128(z, y);
*r = z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(&pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, &r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(&pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1 - SFMT_N].si,
r1, &r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(&array[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, &r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(&array[i].si, pstate[i].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, &r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
mm_recursion(&array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, &r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
mm_recursion(&array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, &r2);
r1 = r2;
r2 = array[i].si;
pstate[j] = array[i];
}
}
#endif
#endif
-121
View File
@@ -1,121 +0,0 @@
#pragma once
/**
* @file SFMT-sse2.h
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* @note We assume LITTLE ENDIAN in this file
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software, see LICENSE.txt
*/
#ifndef SFMT_SSE2_H
#define SFMT_SSE2_H
inline static void mm_recursion(__m128i * r, __m128i a, __m128i b,
__m128i c, __m128i d);
/**
* This function represents the recursion formula.
* @param r an output
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
*/
inline static void mm_recursion(__m128i * r, __m128i a, __m128i b,
__m128i c, __m128i d)
{
__m128i v, x, y, z;
y = _mm_srli_epi32(b, SFMT_SR1);
z = _mm_srli_si128(c, SFMT_SR2);
v = _mm_slli_epi32(d, SFMT_SL1);
z = _mm_xor_si128(z, a);
z = _mm_xor_si128(z, v);
x = _mm_slli_si128(a, SFMT_SL2);
y = _mm_and_si128(y, sse2_param_mask.si);
z = _mm_xor_si128(z, x);
z = _mm_xor_si128(z, y);
*r = z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(&pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(&pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1 - SFMT_N].si,
r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(&array[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(&array[i].si, pstate[i].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
mm_recursion(&array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
mm_recursion(&array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
pstate[j] = array[i];
}
}
#endif
-437
View File
@@ -1,437 +0,0 @@
/**
* @file SFMT.c
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
* Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima
* University and The University of Tokyo.
* Copyright (C) 2013 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
* All rights reserved.
*
* The 3-clause BSD License is applied to this software, see
* LICENSE.txt
*/
#if defined(__cplusplus)
extern "C" {
#endif
#include <string.h>
#include <assert.h>
#include "SFMT.h"
#include "SFMT-params.h"
#include "SFMT-common.h"
#if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
#define BIG_ENDIAN64 1
#endif
#if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
#define BIG_ENDIAN64 1
#endif
#if defined(ONLY64) && !defined(BIG_ENDIAN64)
#if defined(__GNUC__)
#error "-DONLY64 must be specified with -DBIG_ENDIAN64"
#endif
#undef ONLY64
#endif
/*----------------
STATIC FUNCTIONS
----------------*/
inline static int idxof(int i);
inline static void gen_rand_array(sfmt_t * sfmt, w128_t *array, int size);
inline static uint32_t func1(uint32_t x);
inline static uint32_t func2(uint32_t x);
static void period_certification(sfmt_t * sfmt);
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
inline static void swap(w128_t *array, int size);
#endif
#if defined(HAVE_ALTIVEC)
#include "SFMT-alti.h"
#elif defined(HAVE_SSE2)
/**
* parameters used by sse2.
*/
static const w128_t sse2_param_mask = {{SFMT_MSK1, SFMT_MSK2,
SFMT_MSK3, SFMT_MSK4}};
#if defined(_MSC_VER)
#include "SFMT-sse2-msc.h"
#else
#include "SFMT-sse2.h"
#endif
#elif defined(HAVE_NEON)
#include "SFMT-neon.h"
#endif
/**
* This function simulate a 64-bit index of LITTLE ENDIAN
* in BIG ENDIAN machine.
*/
#ifdef ONLY64
inline static int idxof(int i) {
return i ^ 1;
}
#else
inline static int idxof(int i) {
return i;
}
#endif
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2)) && (!defined(HAVE_NEON))
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param sfmt SFMT internal state
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
inline static void gen_rand_array(sfmt_t * sfmt, w128_t *array, int size) {
int i, j;
w128_t *r1, *r2;
r1 = &sfmt->state[SFMT_N - 2];
r2 = &sfmt->state[SFMT_N - 1];
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
do_recursion(&array[i], &sfmt->state[i], &sfmt->state[i + SFMT_POS1], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (; i < SFMT_N; i++) {
do_recursion(&array[i], &sfmt->state[i],
&array[i + SFMT_POS1 - SFMT_N], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (; i < size - SFMT_N; i++) {
do_recursion(&array[i], &array[i - SFMT_N],
&array[i + SFMT_POS1 - SFMT_N], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
sfmt->state[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
do_recursion(&array[i], &array[i - SFMT_N],
&array[i + SFMT_POS1 - SFMT_N], r1, r2);
r1 = r2;
r2 = &array[i];
sfmt->state[j] = array[i];
}
}
#endif
#if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
inline static void swap(w128_t *array, int size) {
int i;
uint32_t x, y;
for (i = 0; i < size; i++) {
x = array[i].u[0];
y = array[i].u[2];
array[i].u[0] = array[i].u[1];
array[i].u[2] = array[i].u[3];
array[i].u[1] = x;
array[i].u[3] = y;
}
}
#endif
/**
* This function represents a function used in the initialization
* by init_by_array
* @param x 32-bit integer
* @return 32-bit integer
*/
static uint32_t func1(uint32_t x) {
return (x ^ (x >> 27)) * (uint32_t)1664525UL;
}
/**
* This function represents a function used in the initialization
* by init_by_array
* @param x 32-bit integer
* @return 32-bit integer
*/
static uint32_t func2(uint32_t x) {
return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
}
/**
* This function certificate the period of 2^{MEXP}
* @param sfmt SFMT internal state
*/
static void period_certification(sfmt_t * sfmt) {
uint32_t inner = 0;
int i, j;
uint32_t work;
uint32_t *psfmt32 = &sfmt->state[0].u[0];
const uint32_t parity[4] = {SFMT_PARITY1, SFMT_PARITY2,
SFMT_PARITY3, SFMT_PARITY4};
for (i = 0; i < 4; i++) {
inner ^= psfmt32[idxof(i)] & parity[i];
}
for (i = 16; i > 0; i >>= 1) {
inner ^= inner >> i;
}
inner &= 1;
/* check OK */
if (inner == 1) {
return;
}
/* check NG, and modification */
for (i = 0; i < 4; i++) {
work = 1;
for (j = 0; j < 32; j++) {
if ((work & parity[i]) != 0) {
psfmt32[idxof(i)] ^= work;
return;
}
work = work << 1;
}
}
}
/*----------------
PUBLIC FUNCTIONS
----------------*/
#define UNUSED_VARIABLE(x) (void)(x)
/**
* This function returns the identification string.
* The string shows the word size, the Mersenne exponent,
* and all parameters of this generator.
* @param sfmt SFMT internal state
*/
const char *sfmt_get_idstring(sfmt_t * sfmt) {
UNUSED_VARIABLE(sfmt);
return SFMT_IDSTR;
}
/**
* This function returns the minimum size of array used for \b
* fill_array32() function.
* @param sfmt SFMT internal state
* @return minimum size of array used for fill_array32() function.
*/
int sfmt_get_min_array_size32(sfmt_t * sfmt) {
UNUSED_VARIABLE(sfmt);
return SFMT_N32;
}
/**
* This function returns the minimum size of array used for \b
* fill_array64() function.
* @param sfmt SFMT internal state
* @return minimum size of array used for fill_array64() function.
*/
int sfmt_get_min_array_size64(sfmt_t * sfmt) {
UNUSED_VARIABLE(sfmt);
return SFMT_N64;
}
#if !defined(HAVE_SSE2) && !defined(HAVE_ALTIVEC) && !defined(HAVE_NEON)
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
w128_t *r1, *r2;
r1 = &sfmt->state[SFMT_N - 2];
r2 = &sfmt->state[SFMT_N - 1];
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
do_recursion(&sfmt->state[i], &sfmt->state[i],
&sfmt->state[i + SFMT_POS1], r1, r2);
r1 = r2;
r2 = &sfmt->state[i];
}
for (; i < SFMT_N; i++) {
do_recursion(&sfmt->state[i], &sfmt->state[i],
&sfmt->state[i + SFMT_POS1 - SFMT_N], r1, r2);
r1 = r2;
r2 = &sfmt->state[i];
}
}
#endif
#ifndef ONLY64
/**
* This function generates pseudorandom 32-bit integers in the
* specified array[] by one call. The number of pseudorandom integers
* is specified by the argument size, which must be at least 624 and a
* multiple of four. The generation by this function is much faster
* than the following gen_rand function.
*
* For initialization, init_gen_rand or init_by_array must be called
* before the first call of this function. This function can not be
* used after calling gen_rand function, without initialization.
*
* @param sfmt SFMT internal state
* @param array an array where pseudorandom 32-bit integers are filled
* by this function. The pointer to the array must be \b "aligned"
* (namely, must be a multiple of 16) in the SIMD version, since it
* refers to the address of a 128-bit integer. In the standard C
* version, the pointer is arbitrary.
*
* @param size the number of 32-bit pseudorandom integers to be
* generated. size must be a multiple of 4, and greater than or equal
* to (MEXP / 128 + 1) * 4.
*
* @note \b memalign or \b posix_memalign is available to get aligned
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
* returns the pointer to the aligned memory block.
*/
void sfmt_fill_array32(sfmt_t * sfmt, uint32_t *array, int size) {
assert(sfmt->idx == SFMT_N32);
assert(size % 4 == 0);
assert(size >= SFMT_N32);
gen_rand_array(sfmt, (w128_t *)array, size / 4);
sfmt->idx = SFMT_N32;
}
#endif
/**
* This function generates pseudorandom 64-bit integers in the
* specified array[] by one call. The number of pseudorandom integers
* is specified by the argument size, which must be at least 312 and a
* multiple of two. The generation by this function is much faster
* than the following gen_rand function.
*
* @param sfmt SFMT internal state
* For initialization, init_gen_rand or init_by_array must be called
* before the first call of this function. This function can not be
* used after calling gen_rand function, without initialization.
*
* @param array an array where pseudorandom 64-bit integers are filled
* by this function. The pointer to the array must be "aligned"
* (namely, must be a multiple of 16) in the SIMD version, since it
* refers to the address of a 128-bit integer. In the standard C
* version, the pointer is arbitrary.
*
* @param size the number of 64-bit pseudorandom integers to be
* generated. size must be a multiple of 2, and greater than or equal
* to (MEXP / 128 + 1) * 2
*
* @note \b memalign or \b posix_memalign is available to get aligned
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
* returns the pointer to the aligned memory block.
*/
void sfmt_fill_array64(sfmt_t * sfmt, uint64_t *array, int size) {
assert(sfmt->idx == SFMT_N32);
assert(size % 2 == 0);
assert(size >= SFMT_N64);
gen_rand_array(sfmt, (w128_t *)array, size / 2);
sfmt->idx = SFMT_N32;
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
swap((w128_t *)array, size /2);
#endif
}
/**
* This function initializes the internal state array with a 32-bit
* integer seed.
*
* @param sfmt SFMT internal state
* @param seed a 32-bit integer used as the seed.
*/
void sfmt_init_gen_rand(sfmt_t * sfmt, uint32_t seed) {
int i;
uint32_t *psfmt32 = &sfmt->state[0].u[0];
psfmt32[idxof(0)] = seed;
for (i = 1; i < SFMT_N32; i++) {
psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
^ (psfmt32[idxof(i - 1)] >> 30))
+ i;
}
sfmt->idx = SFMT_N32;
period_certification(sfmt);
}
/**
* This function initializes the internal state array,
* with an array of 32-bit integers used as the seeds
* @param sfmt SFMT internal state
* @param init_key the array of 32-bit integers, used as a seed.
* @param key_length the length of init_key.
*/
void sfmt_init_by_array(sfmt_t * sfmt, uint32_t *init_key, int key_length) {
int i, j, count;
uint32_t r;
int lag;
int mid;
int size = SFMT_N * 4;
uint32_t *psfmt32 = &sfmt->state[0].u[0];
if (size >= 623) {
lag = 11;
} else if (size >= 68) {
lag = 7;
} else if (size >= 39) {
lag = 5;
} else {
lag = 3;
}
mid = (size - lag) / 2;
memset(sfmt, 0x8b, sizeof(sfmt_t));
if (key_length + 1 > SFMT_N32) {
count = key_length + 1;
} else {
count = SFMT_N32;
}
r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
^ psfmt32[idxof(SFMT_N32 - 1)]);
psfmt32[idxof(mid)] += r;
r += key_length;
psfmt32[idxof(mid + lag)] += r;
psfmt32[idxof(0)] = r;
count--;
for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % SFMT_N32)]
^ psfmt32[idxof((i + SFMT_N32 - 1) % SFMT_N32)]);
psfmt32[idxof((i + mid) % SFMT_N32)] += r;
r += init_key[j] + i;
psfmt32[idxof((i + mid + lag) % SFMT_N32)] += r;
psfmt32[idxof(i)] = r;
i = (i + 1) % SFMT_N32;
}
for (; j < count; j++) {
r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % SFMT_N32)]
^ psfmt32[idxof((i + SFMT_N32 - 1) % SFMT_N32)]);
psfmt32[idxof((i + mid) % SFMT_N32)] += r;
r += i;
psfmt32[idxof((i + mid + lag) % SFMT_N32)] += r;
psfmt32[idxof(i)] = r;
i = (i + 1) % SFMT_N32;
}
for (j = 0; j < SFMT_N32; j++) {
r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % SFMT_N32)]
+ psfmt32[idxof((i + SFMT_N32 - 1) % SFMT_N32)]);
psfmt32[idxof((i + mid) % SFMT_N32)] ^= r;
r -= i;
psfmt32[idxof((i + mid + lag) % SFMT_N32)] ^= r;
psfmt32[idxof(i)] = r;
i = (i + 1) % SFMT_N32;
}
sfmt->idx = SFMT_N32;
period_certification(sfmt);
}
#if defined(__cplusplus)
}
#endif
-304
View File
@@ -1,304 +0,0 @@
#pragma once
/**
* @file SFMT.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
* number generator using C structure.
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (The University of Tokyo)
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
* Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima
* University and The University of Tokyo.
* All rights reserved.
*
* The 3-clause BSD License is applied to this software, see
* LICENSE.txt
*
* @note We assume that your system has inttypes.h. If your system
* doesn't have inttypes.h, you have to typedef uint32_t and uint64_t,
* and you have to define PRIu64 and PRIx64 in this file as follows:
* @verbatim
typedef unsigned int uint32_t
typedef unsigned long long uint64_t
#define PRIu64 "llu"
#define PRIx64 "llx"
@endverbatim
* uint32_t must be exactly 32-bit unsigned integer type (no more, no
* less), and uint64_t must be exactly 64-bit unsigned integer type.
* PRIu64 and PRIx64 are used for printf function to print 64-bit
* unsigned int and 64-bit unsigned int in hexadecimal format.
*/
#ifndef SFMTST_H
#define SFMTST_H
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdio.h>
#include <assert.h>
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#include <inttypes.h>
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#define inline __inline
#else
#include <inttypes.h>
#if defined(__GNUC__)
#define inline __inline__
#endif
#endif
#ifndef PRIu64
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#else
#define PRIu64 "llu"
#define PRIx64 "llx"
#endif
#endif
#include "SFMT-params.h"
/*------------------------------------------
128-bit SIMD like data type for standard C
------------------------------------------*/
#if defined(HAVE_ALTIVEC)
#if !defined(__APPLE__)
#include <altivec.h>
#endif
/** 128-bit data structure */
union W128_T {
vector unsigned int s;
uint32_t u[4];
uint64_t u64[2];
};
#elif defined(HAVE_NEON)
#include <arm_neon.h>
/** 128-bit data structure */
union W128_T {
uint32_t u[4];
uint64_t u64[2];
uint32x4_t si;
};
#elif defined(HAVE_SSE2)
#include <emmintrin.h>
/** 128-bit data structure */
union W128_T {
uint32_t u[4];
uint64_t u64[2];
__m128i si;
};
#else
/** 128-bit data structure */
union W128_T {
uint32_t u[4];
uint64_t u64[2];
};
#endif
/** 128-bit data type */
typedef union W128_T w128_t;
/**
* SFMT internal state
*/
struct SFMT_T {
/** the 128-bit internal state array */
w128_t state[SFMT_N];
/** index counter to the 32-bit internal state array */
int idx;
};
typedef struct SFMT_T sfmt_t;
void sfmt_fill_array32(sfmt_t * sfmt, uint32_t * array, int size);
void sfmt_fill_array64(sfmt_t * sfmt, uint64_t * array, int size);
void sfmt_init_gen_rand(sfmt_t * sfmt, uint32_t seed);
void sfmt_init_by_array(sfmt_t * sfmt, uint32_t * init_key, int key_length);
const char * sfmt_get_idstring(sfmt_t * sfmt);
int sfmt_get_min_array_size32(sfmt_t * sfmt);
int sfmt_get_min_array_size64(sfmt_t * sfmt);
void sfmt_gen_rand_all(sfmt_t * sfmt);
#ifndef ONLY64
/**
* This function generates and returns 32-bit pseudorandom number.
* init_gen_rand or init_by_array must be called before this function.
* @param sfmt SFMT internal state
* @return 32-bit pseudorandom number
*/
inline static uint32_t sfmt_genrand_uint32(sfmt_t * sfmt) {
uint32_t r;
uint32_t * psfmt32 = &sfmt->state[0].u[0];
if (sfmt->idx >= SFMT_N32) {
sfmt_gen_rand_all(sfmt);
sfmt->idx = 0;
}
r = psfmt32[sfmt->idx++];
return r;
}
#endif
/**
* This function generates and returns 64-bit pseudorandom number.
* init_gen_rand or init_by_array must be called before this function.
* The function gen_rand64 should not be called after gen_rand32,
* unless an initialization is again executed.
* @param sfmt SFMT internal state
* @return 64-bit pseudorandom number
*/
inline static uint64_t sfmt_genrand_uint64(sfmt_t * sfmt) {
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
uint32_t * psfmt32 = &sfmt->state[0].u[0];
uint32_t r1, r2;
#else
uint64_t r;
#endif
uint64_t * psfmt64 = &sfmt->state[0].u64[0];
assert(sfmt->idx % 2 == 0);
if (sfmt->idx >= SFMT_N32) {
sfmt_gen_rand_all(sfmt);
sfmt->idx = 0;
}
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
r1 = psfmt32[sfmt->idx];
r2 = psfmt32[sfmt->idx + 1];
sfmt->idx += 2;
return ((uint64_t)r2 << 32) | r1;
#else
r = psfmt64[sfmt->idx / 2];
sfmt->idx += 2;
return r;
#endif
}
/* =================================================
The following real versions are due to Isaku Wada
================================================= */
/**
* converts an unsigned 32-bit number to a double on [0,1]-real-interval.
* @param v 32-bit unsigned integer
* @return double on [0,1]-real-interval
*/
inline static double sfmt_to_real1(uint32_t v)
{
return v * (1.0/4294967295.0);
/* divided by 2^32-1 */
}
/**
* generates a random number on [0,1]-real-interval
* @param sfmt SFMT internal state
* @return double on [0,1]-real-interval
*/
inline static double sfmt_genrand_real1(sfmt_t * sfmt)
{
return sfmt_to_real1(sfmt_genrand_uint32(sfmt));
}
/**
* converts an unsigned 32-bit integer to a double on [0,1)-real-interval.
* @param v 32-bit unsigned integer
* @return double on [0,1)-real-interval
*/
inline static double sfmt_to_real2(uint32_t v)
{
return v * (1.0/4294967296.0);
/* divided by 2^32 */
}
/**
* generates a random number on [0,1)-real-interval
* @param sfmt SFMT internal state
* @return double on [0,1)-real-interval
*/
inline static double sfmt_genrand_real2(sfmt_t * sfmt)
{
return sfmt_to_real2(sfmt_genrand_uint32(sfmt));
}
/**
* converts an unsigned 32-bit integer to a double on (0,1)-real-interval.
* @param v 32-bit unsigned integer
* @return double on (0,1)-real-interval
*/
inline static double sfmt_to_real3(uint32_t v)
{
return (((double)v) + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/**
* generates a random number on (0,1)-real-interval
* @param sfmt SFMT internal state
* @return double on (0,1)-real-interval
*/
inline static double sfmt_genrand_real3(sfmt_t * sfmt)
{
return sfmt_to_real3(sfmt_genrand_uint32(sfmt));
}
/**
* converts an unsigned 32-bit integer to double on [0,1)
* with 53-bit resolution.
* @param v 32-bit unsigned integer
* @return double on [0,1)-real-interval with 53-bit resolution.
*/
inline static double sfmt_to_res53(uint64_t v)
{
return (v >> 11) * (1.0/9007199254740992.0);
}
/**
* generates a random number on [0,1) with 53-bit resolution
* @param sfmt SFMT internal state
* @return double on [0,1) with 53-bit resolution
*/
inline static double sfmt_genrand_res53(sfmt_t * sfmt)
{
return sfmt_to_res53(sfmt_genrand_uint64(sfmt));
}
/* =================================================
The following function are added by Saito.
================================================= */
/**
* generates a random number on [0,1) with 53-bit resolution from two
* 32 bit integers
*/
inline static double sfmt_to_res53_mix(uint32_t x, uint32_t y)
{
return sfmt_to_res53(x | ((uint64_t)y << 32));
}
/**
* generates a random number on [0,1) with 53-bit resolution
* using two 32bit integers.
* @param sfmt SFMT internal state
* @return double on [0,1) with 53-bit resolution
*/
inline static double sfmt_genrand_res53_mix(sfmt_t * sfmt)
{
uint32_t x, y;
x = sfmt_genrand_uint32(sfmt);
y = sfmt_genrand_uint32(sfmt);
return sfmt_to_res53_mix(x, y);
}
#if defined(__cplusplus)
}
#endif
#endif
+1 -1
View File
@@ -66,7 +66,7 @@ target_link_libraries(common
fmt
g3dlib
Detour
sfmt
pcg
utf8cpp
openssl
valgrind
@@ -15,7 +15,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "SFMTRand.h"
#include "PCGRand.h"
#include <algorithm>
#include <array>
#include <functional>
@@ -23,61 +23,57 @@
#include <emmintrin.h>
#include <ctime>
SFMTRand::SFMTRand()
PCGRand::PCGRand()
{
std::random_device dev;
if (dev.entropy() > 0)
{
std::array<uint32, SFMT_N32> seed;
std::generate(seed.begin(), seed.end(), std::ref(dev));
sfmt_init_by_array(&_state, seed.data(), seed.size());
}
_state.seed(pcg_extras::seed_seq_from<std::random_device>());
else
sfmt_init_gen_rand(&_state, uint32(time(nullptr)));
_state.seed(uint64(time(nullptr)));
}
uint32 SFMTRand::RandomUInt32() // Output random bits
uint32 PCGRand::RandomUInt32() // Output random bits
{
return sfmt_genrand_uint32(&_state);
std::uniform_int_distribution<uint32> dist;
return dist(_state);
}
void* SFMTRand::operator new(size_t size, std::nothrow_t const&)
void* PCGRand::operator new(size_t size, std::nothrow_t const&)
{
return _mm_malloc(size, 16);
}
void SFMTRand::operator delete(void* ptr, std::nothrow_t const&)
void PCGRand::operator delete(void* ptr, std::nothrow_t const&)
{
_mm_free(ptr);
}
void* SFMTRand::operator new(size_t size)
void* PCGRand::operator new(size_t size)
{
return _mm_malloc(size, 16);
}
void SFMTRand::operator delete(void* ptr)
void PCGRand::operator delete(void* ptr)
{
_mm_free(ptr);
}
void* SFMTRand::operator new[](size_t size, std::nothrow_t const&)
void* PCGRand::operator new[](size_t size, std::nothrow_t const&)
{
return _mm_malloc(size, 16);
}
void SFMTRand::operator delete[](void* ptr, std::nothrow_t const&)
void PCGRand::operator delete[](void* ptr, std::nothrow_t const&)
{
_mm_free(ptr);
}
void* SFMTRand::operator new[](size_t size)
void* PCGRand::operator new[](size_t size)
{
return _mm_malloc(size, 16);
}
void SFMTRand::operator delete[](void* ptr)
void PCGRand::operator delete[](void* ptr)
{
_mm_free(ptr);
}
@@ -15,19 +15,20 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SFMTRand_h__
#define SFMTRand_h__
#ifndef PCGRand_h__
#define PCGRand_h__
#include "Define.h"
#include <SFMT.h>
#include "pcg_random.hpp"
#include <new>
/*
* C++ Wrapper for SFMT
*/
class SFMTRand {
/*
* C++ Wrapper for PCG
*/
class PCGRand
{
public:
SFMTRand();
PCGRand();
uint32 RandomUInt32(); // Output random bits
void* operator new(size_t size, std::nothrow_t const&);
void operator delete(void* ptr, std::nothrow_t const&);
@@ -38,7 +39,8 @@ public:
void* operator new[](size_t size);
void operator delete[](void* ptr);
private:
sfmt_t _state;
pcg32 _state;
};
#endif // SFMTRand_h__
#endif // PCGRand_h__
+6 -6
View File
@@ -17,19 +17,19 @@
#include "Random.h"
#include "Errors.h"
#include "SFMTRand.h"
#include "PCGRand.h"
#include <memory>
#include <random>
static thread_local std::unique_ptr<SFMTRand> sfmtRand;
static thread_local std::unique_ptr<PCGRand> pcgRand;
static RandomEngine engine;
static SFMTRand* GetRng()
static PCGRand* GetRng()
{
if (!sfmtRand)
sfmtRand = std::make_unique<SFMTRand>();
if (!pcgRand)
pcgRand = std::make_unique<PCGRand>();
return sfmtRand.get();
return pcgRand.get();
}
int32 irand(int32 min, int32 max)