Core/Util: replace SMFT rng with PCG
This commit is contained in:
1 parent
6c171229e9
commit
2e47ee3f4c
31 files changed
+3675
-2457
No files matched your search
+1
-1
@@ -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)
|
||||
|
||||
@@ -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})
|
||||
@@ -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
@@ -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.
|
||||
@@ -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)
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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__
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user