diff options
| author | drepper <drepper@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-29 18:43:08 +0000 |
|---|---|---|
| committer | drepper <drepper@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-29 18:43:08 +0000 |
| commit | dcfbfb22047b41bdb97de0196c40515e3eeb0bcc (patch) | |
| tree | 99892b71173d7e412b5e38cfa5f2c399e2ef3fcf /libstdc++-v3/include/ext/random | |
| parent | 9d25877dc1e788aa07025b91ff4eacdd2060e750 (diff) | |
| download | ppe42-gcc-dcfbfb22047b41bdb97de0196c40515e3eeb0bcc.tar.gz ppe42-gcc-dcfbfb22047b41bdb97de0196c40515e3eeb0bcc.zip | |
Add simd_fast_mersenne_twister_engine class.
* include/ext/random: New file.
* include/ext/random.tcc: New file.
* include/Makefile.am (ext_headers): Add random and random.tcc.
* testsuite/26_numerics/random/simd_fast_mersenne_twister_engine/
operators/inequal.cc: New file.
* testsuite/26_numerics/random/simd_fast_mersenne_twister_engine/
operators/equal.cc: New file.
* testsuite/26_numerics/random/simd_fast_mersenne_twister_engine/
operators/serialize.cc: New file.
* testsuite/26_numerics/random/simd_fast_mersenne_twister_engine/
cons/seed2.cc: New file.
* testsuite/26_numerics/random/simd_fast_mersenne_twister_engine/
cons/default.cc: New file.
* testsuite/26_numerics/random/simd_fast_mersenne_twister_engine/
cons/seed_seq.cc: New file.
* testsuite/26_numerics/random/simd_fast_mersenne_twister_engine/
cons/copy.cc: New file.
* testsuite/26_numerics/random/simd_fast_mersenne_twister_engine/
cons/seed1.cc: New file.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190783 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/ext/random')
| -rw-r--r-- | libstdc++-v3/include/ext/random | 382 |
1 files changed, 382 insertions, 0 deletions
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random new file mode 100644 index 00000000000..05cbc8fa493 --- /dev/null +++ b/libstdc++-v3/include/ext/random @@ -0,0 +1,382 @@ +// Random number extensions -*- C++ -*- + +// Copyright (C) 2012 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file ext/random + * This file is a GNU extension to the Standard C++ Library. + */ + +#ifndef _EXT_RANDOM +#define _EXT_RANDOM 1 + +#pragma GCC system_header + +#include <random> +#ifdef __SSE2__ +# include <x86intrin.h> +#endif + + +namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /* Mersenne twister implementation optimized for vector operations. + * + * Reference: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/ + */ + template<typename _UIntType, size_t __m, + size_t __pos1, size_t __sl1, size_t __sl2, + size_t __sr1, size_t __sr2, + uint32_t __msk1, uint32_t __msk2, + uint32_t __msk3, uint32_t __msk4, + uint32_t __parity1, uint32_t __parity2, + uint32_t __parity3, uint32_t __parity4> + class simd_fast_mersenne_twister_engine + { + static_assert(std::is_unsigned<_UIntType>::value, "template argument " + "substituting _UIntType not an unsigned integral type"); + static_assert(__sr1 < 32, "first right shift too large"); + static_assert(__sr2 < 16, "second right shift too large"); + static_assert(__sl1 < 32, "first left shift too large"); + static_assert(__sl2 < 16, "second left shift too large"); + + public: + typedef _UIntType result_type; + + private: + static constexpr size_t m_w = sizeof(result_type) * 8; + static constexpr size_t _M_nstate = __m / 128 + 1; + static constexpr size_t _M_nstate32 = _M_nstate * 4; + + static_assert(std::is_unsigned<_UIntType>::value, "template argument " + "substituting _UIntType not an unsigned integral type"); + static_assert(__pos1 < _M_nstate, "POS1 not smaller than state size"); + static_assert(16 % sizeof(_UIntType) == 0, + "UIntType size must divide 16"); + + public: + static constexpr size_t state_size = _M_nstate * (16 + / sizeof(result_type)); + static constexpr result_type default_seed = 5489u; + + // constructors and member function + explicit + simd_fast_mersenne_twister_engine(result_type __sd = default_seed) + { seed(__sd); } + + template<typename _Sseq, typename = typename + std::enable_if<!std::is_same<_Sseq, simd_fast_mersenne_twister_engine>::value> + ::type> + explicit + simd_fast_mersenne_twister_engine(_Sseq& __q) + { seed(__q); } + + void + seed(result_type __sd = default_seed); + + template<typename _Sseq> + typename std::enable_if<std::is_class<_Sseq>::value>::type + seed(_Sseq& __q); + + static constexpr result_type + min() + { return 0; }; + + static constexpr result_type + max() + { return std::numeric_limits<result_type>::max(); } + + void + discard(unsigned long long __z); + + result_type + operator()() + { + if (__builtin_expect(_M_pos >= state_size, 0)) + _M_gen_rand(); + + return _M_stateT[_M_pos++]; + } + +#ifdef __SSE2__ + friend bool + operator==(const simd_fast_mersenne_twister_engine& __lhs, + const simd_fast_mersenne_twister_engine& __rhs) + { __m128i __res = _mm_cmpeq_epi8(__lhs._M_state[0], __rhs._M_state[0]); + for (size_t __i = 1; __i < __lhs._M_nstate; ++__i) + __res = _mm_and_si128(__res, _mm_cmpeq_epi8(__lhs._M_state[__i], + __rhs._M_state[__i])); + return (_mm_movemask_epi8(__res) == 0xffff + && __lhs._M_pos == __rhs._M_pos); } +#else + friend bool + operator==(const simd_fast_mersenne_twister_engine& __lhs, + const simd_fast_mersenne_twister_engine& __rhs) + { return (std::equal(__lhs._M_stateT, __lhs._M_stateT + state_size, + __rhs._M_stateT) + && __lhs._M_pos == __rhs._M_pos); } +#endif + + template<typename _UIntType_2, size_t __m_2, + size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, + size_t __sr1_2, size_t __sr2_2, + uint32_t __msk1_2, uint32_t __msk2_2, + uint32_t __msk3_2, uint32_t __msk4_2, + uint32_t __parity1_2, uint32_t __parity2_2, + uint32_t __parity3_2, uint32_t __parity4_2, + typename _CharT, typename _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __os, + const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2, + __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, + __msk1_2, __msk2_2, __msk3_2, __msk4_2, + __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); + + template<typename _UIntType_2, size_t __m_2, + size_t __pos1_2, size_t __sl1_2, size_t __sl2_2, + size_t __sr1_2, size_t __sr2_2, + uint32_t __msk1_2, uint32_t __msk2_2, + uint32_t __msk3_2, uint32_t __msk4_2, + uint32_t __parity1_2, uint32_t __parity2_2, + uint32_t __parity3_2, uint32_t __parity4_2, + typename _CharT, typename _Traits> + friend std::basic_istream<_CharT, _Traits>& + operator>>(std::basic_istream<_CharT, _Traits>& __is, + __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType_2, + __m_2, __pos1_2, __sl1_2, __sl2_2, __sr1_2, __sr2_2, + __msk1_2, __msk2_2, __msk3_2, __msk4_2, + __parity1_2, __parity2_2, __parity3_2, __parity4_2>& __x); + + private: + union + { +#ifdef __SSE2__ + __m128i _M_state[_M_nstate]; +#endif + uint32_t _M_state32[_M_nstate32]; + result_type _M_stateT[state_size]; + } __attribute__ ((__aligned__ (16))); + size_t _M_pos; + + void _M_gen_rand(void); + void _M_period_certification(); + }; + + + template<typename _UIntType, size_t __m, + size_t __pos1, size_t __sl1, size_t __sl2, + size_t __sr1, size_t __sr2, + uint32_t __msk1, uint32_t __msk2, + uint32_t __msk3, uint32_t __msk4, + uint32_t __parity1, uint32_t __parity2, + uint32_t __parity3, uint32_t __parity4> + inline bool + operator!=(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, + __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, + __msk4, __parity1, __parity2, __parity3, __parity4>& __lhs, + const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType, + __m, __pos1, __sl1, __sl2, __sr1, __sr2, __msk1, __msk2, __msk3, + __msk4, __parity1, __parity2, __parity3, __parity4>& __rhs) + { return !(__lhs == __rhs); } + + + /* Definitions for the SIMD-oriented Fast Mersenne Twister as defined + * in the C implementation by Daito and Matsumoto, as both a 32-bit + * and 64-bit version. + */ + typedef simd_fast_mersenne_twister_engine<uint32_t, 607, 2, + 15, 3, 13, 3, + 0xfdff37ffU, 0xef7f3f7dU, + 0xff777b7dU, 0x7ff7fb2fU, + 0x00000001U, 0x00000000U, + 0x00000000U, 0x5986f054U> + sfmt607; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 607, 2, + 15, 3, 13, 3, + 0xfdff37ffU, 0xef7f3f7dU, + 0xff777b7dU, 0x7ff7fb2fU, + 0x00000001U, 0x00000000U, + 0x00000000U, 0x5986f054U> + sfmt607_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 1279, 7, + 14, 3, 5, 1, + 0xf7fefffdU, 0x7fefcfffU, + 0xaff3ef3fU, 0xb5ffff7fU, + 0x00000001U, 0x00000000U, + 0x00000000U, 0x20000000U> + sfmt1279; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 1279, 7, + 14, 3, 5, 1, + 0xf7fefffdU, 0x7fefcfffU, + 0xaff3ef3fU, 0xb5ffff7fU, + 0x00000001U, 0x00000000U, + 0x00000000U, 0x20000000U> + sfmt1279_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 2281, 12, + 19, 1, 5, 1, + 0xbff7ffbfU, 0xfdfffffeU, + 0xf7ffef7fU, 0xf2f7cbbfU, + 0x00000001U, 0x00000000U, + 0x00000000U, 0x41dfa600U> + sfmt2281; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 2281, 12, + 19, 1, 5, 1, + 0xbff7ffbfU, 0xfdfffffeU, + 0xf7ffef7fU, 0xf2f7cbbfU, + 0x00000001U, 0x00000000U, + 0x00000000U, 0x41dfa600U> + sfmt2281_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 4253, 17, + 20, 1, 7, 1, + 0x9f7bffffU, 0x9fffff5fU, + 0x3efffffbU, 0xfffff7bbU, + 0xa8000001U, 0xaf5390a3U, + 0xb740b3f8U, 0x6c11486dU> + sfmt4253; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 4253, 17, + 20, 1, 7, 1, + 0x9f7bffffU, 0x9fffff5fU, + 0x3efffffbU, 0xfffff7bbU, + 0xa8000001U, 0xaf5390a3U, + 0xb740b3f8U, 0x6c11486dU> + sfmt4253_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 11213, 68, + 14, 3, 7, 3, + 0xeffff7fbU, 0xffffffefU, + 0xdfdfbfffU, 0x7fffdbfdU, + 0x00000001U, 0x00000000U, + 0xe8148000U, 0xd0c7afa3U> + sfmt11213; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 11213, 68, + 14, 3, 7, 3, + 0xeffff7fbU, 0xffffffefU, + 0xdfdfbfffU, 0x7fffdbfdU, + 0x00000001U, 0x00000000U, + 0xe8148000U, 0xd0c7afa3U> + sfmt11213_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 19937, 122, + 18, 1, 11, 1, + 0xdfffffefU, 0xddfecb7fU, + 0xbffaffffU, 0xbffffff6U, + 0x00000001U, 0x00000000U, + 0x00000000U, 0x13c9e684U> + sfmt19937; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 19937, 122, + 18, 1, 11, 1, + 0xdfffffefU, 0xddfecb7fU, + 0xbffaffffU, 0xbffffff6U, + 0x00000001U, 0x00000000U, + 0x00000000U, 0x13c9e684U> + sfmt19937_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 44497, 330, + 5, 3, 9, 3, + 0xeffffffbU, 0xdfbebfffU, + 0xbfbf7befU, 0x9ffd7bffU, + 0x00000001U, 0x00000000U, + 0xa3ac4000U, 0xecc1327aU> + sfmt44497; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 44497, 330, + 5, 3, 9, 3, + 0xeffffffbU, 0xdfbebfffU, + 0xbfbf7befU, 0x9ffd7bffU, + 0x00000001U, 0x00000000U, + 0xa3ac4000U, 0xecc1327aU> + sfmt44497_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 86243, 366, + 6, 7, 19, 1, + 0xfdbffbffU, 0xbff7ff3fU, + 0xfd77efffU, 0xbf9ff3ffU, + 0x00000001U, 0x00000000U, + 0x00000000U, 0xe9528d85U> + sfmt86243; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 86243, 366, + 6, 7, 19, 1, + 0xfdbffbffU, 0xbff7ff3fU, + 0xfd77efffU, 0xbf9ff3ffU, + 0x00000001U, 0x00000000U, + 0x00000000U, 0xe9528d85U> + sfmt86243_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 132049, 110, + 19, 1, 21, 1, + 0xffffbb5fU, 0xfb6ebf95U, + 0xfffefffaU, 0xcff77fffU, + 0x00000001U, 0x00000000U, + 0xcb520000U, 0xc7e91c7dU> + sfmt132049; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 132049, 110, + 19, 1, 21, 1, + 0xffffbb5fU, 0xfb6ebf95U, + 0xfffefffaU, 0xcff77fffU, + 0x00000001U, 0x00000000U, + 0xcb520000U, 0xc7e91c7dU> + sfmt132049_64; + + + typedef simd_fast_mersenne_twister_engine<uint32_t, 216091, 627, + 11, 3, 10, 1, + 0xbff7bff7U, 0xbfffffffU, + 0xbffffa7fU, 0xffddfbfbU, + 0xf8000001U, 0x89e80709U, + 0x3bd2b64bU, 0x0c64b1e4U> + sfmt216091; + + typedef simd_fast_mersenne_twister_engine<uint64_t, 216091, 627, + 11, 3, 10, 1, + 0xbff7bff7U, 0xbfffffffU, + 0xbffffa7fU, 0xffddfbfbU, + 0xf8000001U, 0x89e80709U, + 0x3bd2b64bU, 0x0c64b1e4U> + sfmt216091_64; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#include "random.tcc" + +#endif /* _EXT_RANDOM */ |

