[INFRA] Import NVIDIA/CCCL upstream as optimization reference library
CCCL (CUDA C++ Core Libraries) provides: - CUB: device/block/warp-level GPU primitives (reduce, scan, sort, topk) - Thrust: high-level parallel algorithms (transform_reduce, sort, scan) - libcudacxx: CUDA C++ standard library (atomics, barriers, memory) - cudax: experimental features (memory resources, allocators) - Tuning policies: per-SM hardware-specific algorithm parameters Competition optimization vectors mapped to CCCL: - Output TPS (83% weight): warp_reduce, block_reduce, device_topk - Input TPS (14% weight): device_scan, block_load, prefetch - Cache TPS (3% weight): prefix caching strategy patterns - Memory (0.9 util): pooled/cached/buddy allocators Source: https://github.com/NVIDIA/cccl (shallow clone, HEAD only) License: Apache-2.0
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2021, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/discard_block_engine.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE discard_block_engine<Engine, p, r>::discard_block_engine()
|
||||
: m_e()
|
||||
, m_n(0)
|
||||
{}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE discard_block_engine<Engine, p, r>::discard_block_engine(result_type s)
|
||||
: m_e(s)
|
||||
, m_n(0)
|
||||
{}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE discard_block_engine<Engine, p, r>::discard_block_engine(const base_type& urng)
|
||||
: m_e(urng)
|
||||
, m_n(0)
|
||||
{}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE void discard_block_engine<Engine, p, r>::seed()
|
||||
{
|
||||
m_e.seed();
|
||||
m_n = 0;
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE void discard_block_engine<Engine, p, r>::seed(result_type s)
|
||||
{
|
||||
m_e.seed(s);
|
||||
m_n = 0;
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE typename discard_block_engine<Engine, p, r>::result_type
|
||||
discard_block_engine<Engine, p, r>::operator()()
|
||||
{
|
||||
if (m_n >= used_block)
|
||||
{
|
||||
m_e.discard(block_size - m_n);
|
||||
// for(; m_n < block_size; ++m_n)
|
||||
// m_e();
|
||||
m_n = 0;
|
||||
}
|
||||
|
||||
++m_n;
|
||||
|
||||
return m_e();
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE void discard_block_engine<Engine, p, r>::discard(unsigned long long z)
|
||||
{
|
||||
// XXX this should be accelerated
|
||||
for (; z > 0; --z)
|
||||
{
|
||||
this->operator()();
|
||||
} // end for
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE const typename discard_block_engine<Engine, p, r>::base_type&
|
||||
discard_block_engine<Engine, p, r>::base() const
|
||||
{
|
||||
return m_e;
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
discard_block_engine<Engine, p, r>::stream_out(std::basic_ostream<CharT, Traits>& os) const
|
||||
{
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
using ios_base = typename ostream_type::ios_base;
|
||||
|
||||
// save old flags & fill character
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
|
||||
const CharT space = os.widen(' ');
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(space);
|
||||
|
||||
// output the base engine followed by n
|
||||
os << m_e << space << m_n;
|
||||
|
||||
// restore flags & fill character
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& discard_block_engine<Engine, p, r>::stream_in(std::basic_istream<CharT, Traits>& is)
|
||||
{
|
||||
using istream_type = std::basic_istream<CharT, Traits>;
|
||||
using ios_base = typename istream_type::ios_base;
|
||||
|
||||
// save old flags
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
|
||||
is.flags(ios_base::skipws);
|
||||
|
||||
// input the base engine and then n
|
||||
is >> m_e >> m_n;
|
||||
|
||||
// restore old flags
|
||||
is.flags(flags);
|
||||
return is;
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE bool discard_block_engine<Engine, p, r>::equal(const discard_block_engine<Engine, p, r>& rhs) const
|
||||
{
|
||||
return (m_e == rhs.m_e) && (m_n == rhs.m_n);
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const discard_block_engine<Engine, p, r>& e)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_out(os, e);
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, discard_block_engine<Engine, p, r>& e)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_in(is, e);
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator==(const discard_block_engine<Engine, p, r>& lhs, const discard_block_engine<Engine, p, r>& rhs)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::equal(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator!=(const discard_block_engine<Engine, p, r>& lhs, const discard_block_engine<Engine, p, r>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,140 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2021, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/detail/mod.h>
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
#include <thrust/random/linear_congruential_engine.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
_CCCL_HOST_DEVICE linear_congruential_engine<UIntType, a, c, m>::linear_congruential_engine(result_type s)
|
||||
{
|
||||
seed(s);
|
||||
} // end linear_congruential_engine::linear_congruential_engine()
|
||||
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
_CCCL_HOST_DEVICE void linear_congruential_engine<UIntType, a, c, m>::seed(result_type s)
|
||||
{
|
||||
if ((detail::mod<UIntType, 1, 0, m>(c) == 0) && (detail::mod<UIntType, 1, 0, m>(s) == 0))
|
||||
{
|
||||
m_x = detail::mod<UIntType, 1, 0, m>(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_x = detail::mod<UIntType, 1, 0, m>(s);
|
||||
}
|
||||
} // end linear_congruential_engine::seed()
|
||||
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
_CCCL_HOST_DEVICE typename linear_congruential_engine<UIntType, a, c, m>::result_type
|
||||
linear_congruential_engine<UIntType, a, c, m>::operator()()
|
||||
{
|
||||
m_x = detail::mod<UIntType, a, c, m>(m_x);
|
||||
return m_x;
|
||||
} // end linear_congruential_engine::operator()()
|
||||
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
_CCCL_HOST_DEVICE void linear_congruential_engine<UIntType, a, c, m>::discard(unsigned long long z)
|
||||
{
|
||||
thrust::random::detail::linear_congruential_engine_discard::discard(*this, z);
|
||||
} // end linear_congruential_engine::discard()
|
||||
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
linear_congruential_engine<UIntType, a, c, m>::stream_out(std::basic_ostream<CharT, Traits>& os) const
|
||||
{
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
using ios_base = typename ostream_type::ios_base;
|
||||
|
||||
// save old flags & fill character
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(os.widen(' '));
|
||||
|
||||
// output one word of state
|
||||
os << m_x;
|
||||
|
||||
// restore flags & fill character
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
linear_congruential_engine<UIntType, a, c, m>::stream_in(std::basic_istream<CharT, Traits>& is)
|
||||
{
|
||||
using istream_type = std::basic_istream<CharT, Traits>;
|
||||
using ios_base = typename istream_type::ios_base;
|
||||
|
||||
// save old flags
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
|
||||
is.flags(ios_base::dec);
|
||||
|
||||
// input one word of state
|
||||
is >> m_x;
|
||||
|
||||
// restore flags
|
||||
is.flags(flags);
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
linear_congruential_engine<UIntType, a, c, m>::equal(const linear_congruential_engine<UIntType, a, c, m>& rhs) const
|
||||
{
|
||||
return m_x == rhs.m_x;
|
||||
}
|
||||
|
||||
template <typename UIntType_, UIntType_ a_, UIntType_ c_, UIntType_ m_>
|
||||
_CCCL_HOST_DEVICE bool operator==(const linear_congruential_engine<UIntType_, a_, c_, m_>& lhs,
|
||||
const linear_congruential_engine<UIntType_, a_, c_, m_>& rhs)
|
||||
{
|
||||
return detail::random_core_access::equal(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const linear_congruential_engine<UIntType, a, c, m>& lhs,
|
||||
const linear_congruential_engine<UIntType, a, c, m>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename UIntType_, UIntType_ a_, UIntType_ c_, UIntType_ m_, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const linear_congruential_engine<UIntType_, a_, c_, m_>& e)
|
||||
{
|
||||
return detail::random_core_access::stream_out(os, e);
|
||||
}
|
||||
|
||||
template <typename UIntType_, UIntType_ a_, UIntType_ c_, UIntType_ m_, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, linear_congruential_engine<UIntType_, a_, c_, m_>& e)
|
||||
{
|
||||
return detail::random_core_access::stream_in(is, e);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,84 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/detail/mod.h>
|
||||
|
||||
#include <cuda/std/cstdint>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random::detail
|
||||
{
|
||||
template <typename UIntType, UIntType a, unsigned long long c, UIntType m>
|
||||
struct linear_congruential_engine_discard_implementation
|
||||
{
|
||||
_CCCL_HOST_DEVICE static void discard(UIntType& state, unsigned long long z)
|
||||
{
|
||||
for (; z > 0; --z)
|
||||
{
|
||||
state = detail::mod<UIntType, a, c, m>(state);
|
||||
}
|
||||
}
|
||||
}; // end linear_congruential_engine_discard
|
||||
|
||||
// specialize for small integers and c == 0
|
||||
// XXX figure out a robust implementation of this for any unsigned integer type later
|
||||
template <std::uint32_t a, std::uint32_t m>
|
||||
struct linear_congruential_engine_discard_implementation<std::uint32_t, a, 0, m>
|
||||
{
|
||||
_CCCL_HOST_DEVICE static void discard(std::uint32_t& state, unsigned long long z)
|
||||
{
|
||||
const std::uint32_t modulus = m;
|
||||
|
||||
// XXX we need to use unsigned long long here or we will encounter overflow in the
|
||||
// multiplies below
|
||||
// figure out a robust implementation of this later
|
||||
unsigned long long multiplier = a;
|
||||
unsigned long long multiplier_to_z = 1;
|
||||
|
||||
// see http://en.wikipedia.org/wiki/Modular_exponentiation
|
||||
while (z > 0)
|
||||
{
|
||||
if (z & 1)
|
||||
{
|
||||
// multiply in this bit's contribution while using modulus to keep result small
|
||||
multiplier_to_z = (multiplier_to_z * multiplier) % modulus;
|
||||
}
|
||||
|
||||
// move to the next bit of the exponent, square (and mod) the base accordingly
|
||||
z >>= 1;
|
||||
multiplier = (multiplier * multiplier) % modulus;
|
||||
}
|
||||
|
||||
state = static_cast<std::uint32_t>((multiplier_to_z * state) % modulus);
|
||||
}
|
||||
}; // end linear_congruential_engine_discard
|
||||
|
||||
struct linear_congruential_engine_discard
|
||||
{
|
||||
template <typename LinearCongruentialEngine>
|
||||
_CCCL_HOST_DEVICE static void discard(LinearCongruentialEngine& lcg, unsigned long long z)
|
||||
{
|
||||
using result_type = typename LinearCongruentialEngine::result_type;
|
||||
[[maybe_unused]] const result_type c = LinearCongruentialEngine::increment;
|
||||
[[maybe_unused]] const result_type a = LinearCongruentialEngine::multiplier;
|
||||
[[maybe_unused]] const result_type m = LinearCongruentialEngine::modulus;
|
||||
|
||||
linear_congruential_engine_discard_implementation<result_type, a, c, m>::discard(lcg.m_x, z);
|
||||
}
|
||||
}; // end linear_congruential_engine_discard
|
||||
} // namespace random::detail
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,136 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2021, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/linear_feedback_shift_engine.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
_CCCL_HOST_DEVICE linear_feedback_shift_engine<UIntType, w, k, q, s>::linear_feedback_shift_engine(result_type value)
|
||||
{
|
||||
seed(value);
|
||||
} // end linear_feedback_shift_engine::linear_feedback_shift_engine()
|
||||
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
_CCCL_HOST_DEVICE void linear_feedback_shift_engine<UIntType, w, k, q, s>::seed(result_type value)
|
||||
{
|
||||
m_value = value;
|
||||
} // end linear_feedback_shift_engine::seed()
|
||||
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
_CCCL_HOST_DEVICE typename linear_feedback_shift_engine<UIntType, w, k, q, s>::result_type
|
||||
linear_feedback_shift_engine<UIntType, w, k, q, s>::operator()()
|
||||
{
|
||||
const UIntType b = (((m_value << q) ^ m_value) & wordmask) >> (k - s);
|
||||
const UIntType mask = ((~static_cast<UIntType>(0)) << (w - k)) & wordmask;
|
||||
m_value = ((m_value & mask) << s) ^ b;
|
||||
return m_value;
|
||||
} // end linear_feedback_shift_engine::operator()()
|
||||
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
_CCCL_HOST_DEVICE void linear_feedback_shift_engine<UIntType, w, k, q, s>::discard(unsigned long long z)
|
||||
{
|
||||
for (; z > 0; --z)
|
||||
{
|
||||
this->operator()();
|
||||
} // end for
|
||||
} // end linear_feedback_shift_engine::discard()
|
||||
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
linear_feedback_shift_engine<UIntType, w, k, q, s>::stream_out(std::basic_ostream<CharT, Traits>& os) const
|
||||
{
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
using ios_base = typename ostream_type::ios_base;
|
||||
|
||||
// save old flags & fill character
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(os.widen(' '));
|
||||
|
||||
// output one word of state
|
||||
os << m_value;
|
||||
|
||||
// restore flags & fill character
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
linear_feedback_shift_engine<UIntType, w, k, q, s>::stream_in(std::basic_istream<CharT, Traits>& is)
|
||||
{
|
||||
using istream_type = std::basic_istream<CharT, Traits>;
|
||||
using ios_base = typename istream_type::ios_base;
|
||||
|
||||
// save old flags
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
|
||||
is.flags(ios_base::skipws);
|
||||
|
||||
// input one word of state
|
||||
is >> m_value;
|
||||
|
||||
// restore flags
|
||||
is.flags(flags);
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
_CCCL_HOST_DEVICE bool linear_feedback_shift_engine<UIntType, w, k, q, s>::equal(
|
||||
const linear_feedback_shift_engine<UIntType, w, k, q, s>& rhs) const
|
||||
{
|
||||
return m_value == rhs.m_value;
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
_CCCL_HOST_DEVICE bool operator==(const linear_feedback_shift_engine<UIntType, w, k, q, s>& lhs,
|
||||
const linear_feedback_shift_engine<UIntType, w, k, q, s>& rhs)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::equal(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const linear_feedback_shift_engine<UIntType, w, k, q, s>& lhs,
|
||||
const linear_feedback_shift_engine<UIntType, w, k, q, s>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename UIntType_, size_t w_, size_t k_, size_t q_, size_t s_, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const linear_feedback_shift_engine<UIntType_, w_, k_, q_, s_>& e)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_out(os, e);
|
||||
}
|
||||
|
||||
template <typename UIntType_, size_t w_, size_t k_, size_t q_, size_t s_, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, linear_feedback_shift_engine<UIntType_, w_, k_, q_, s_>& e)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_in(is, e);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,33 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random::detail
|
||||
{
|
||||
template <typename T, int w, int i = w - 1>
|
||||
struct linear_feedback_shift_engine_wordmask
|
||||
{
|
||||
static const T value = (T(1u) << i) | linear_feedback_shift_engine_wordmask<T, w, i - 1>::value;
|
||||
}; // end linear_feedback_shift_engine_wordmask
|
||||
|
||||
template <typename T, int w>
|
||||
struct linear_feedback_shift_engine_wordmask<T, w, 0>
|
||||
{
|
||||
static const T value = 0;
|
||||
}; // end linear_feedback_shift_engine_wordmask
|
||||
} // namespace random::detail
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
81
cccl_upstream/thrust/thrust/random/detail/mod.h
Normal file
81
cccl_upstream/thrust/thrust/random/detail/mod.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random::detail
|
||||
{
|
||||
template <typename T, T a, T c, T m, bool = (m == 0)>
|
||||
struct static_mod
|
||||
{
|
||||
static const T q = m / a;
|
||||
static const T r = m % a;
|
||||
|
||||
_CCCL_HOST_DEVICE T operator()(T x) const
|
||||
{
|
||||
if constexpr (a == 1)
|
||||
{
|
||||
x %= m;
|
||||
}
|
||||
else
|
||||
{
|
||||
T t1 = a * (x % q);
|
||||
T t2 = r * (x / q);
|
||||
if (t1 >= t2)
|
||||
{
|
||||
x = t1 - t2;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = m - t2 + t1;
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (c != 0)
|
||||
{
|
||||
const T d = m - x;
|
||||
if (d > c)
|
||||
{
|
||||
x += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = c - d;
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
}; // end static_mod
|
||||
|
||||
// Rely on machine overflow handling
|
||||
template <typename T, T a, T c, T m>
|
||||
struct static_mod<T, a, c, m, true>
|
||||
{
|
||||
_CCCL_HOST_DEVICE T operator()(T x) const
|
||||
{
|
||||
return a * x + c;
|
||||
}
|
||||
}; // end static_mod
|
||||
|
||||
template <typename T, T a, T c, T m>
|
||||
_CCCL_HOST_DEVICE T mod(T x)
|
||||
{
|
||||
static_mod<T, a, c, m> f;
|
||||
return f(x);
|
||||
} // end static_mod
|
||||
} // namespace random::detail
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,172 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2021, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/normal_distribution.h>
|
||||
#include <thrust/random/uniform_real_distribution.h>
|
||||
|
||||
#include <cuda/std/cstdint>
|
||||
#include <cuda/std/limits>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE normal_distribution<RealType>::normal_distribution(RealType a, RealType b)
|
||||
: super_t()
|
||||
, m_param(a, b)
|
||||
{} // end normal_distribution::normal_distribution()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE normal_distribution<RealType>::normal_distribution(const param_type& parm)
|
||||
: super_t()
|
||||
, m_param(parm)
|
||||
{} // end normal_distribution::normal_distribution()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE void normal_distribution<RealType>::reset()
|
||||
{
|
||||
super_t::reset();
|
||||
} // end normal_distribution::reset()
|
||||
|
||||
template <typename RealType>
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE typename normal_distribution<RealType>::result_type
|
||||
normal_distribution<RealType>::operator()(UniformRandomNumberGenerator& urng)
|
||||
{
|
||||
return operator()(urng, m_param);
|
||||
} // end normal_distribution::operator()()
|
||||
|
||||
template <typename RealType>
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE typename normal_distribution<RealType>::result_type
|
||||
normal_distribution<RealType>::operator()(UniformRandomNumberGenerator& urng, const param_type& parm)
|
||||
{
|
||||
return super_t::sample(urng, parm.first, parm.second);
|
||||
} // end normal_distribution::operator()()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename normal_distribution<RealType>::param_type normal_distribution<RealType>::param() const
|
||||
{
|
||||
return m_param;
|
||||
} // end normal_distribution::param()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE void normal_distribution<RealType>::param(const param_type& parm)
|
||||
{
|
||||
m_param = parm;
|
||||
} // end normal_distribution::param()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename normal_distribution<RealType>::result_type normal_distribution<RealType>::min
|
||||
THRUST_PREVENT_MACRO_SUBSTITUTION() const
|
||||
{
|
||||
return ::cuda::std::numeric_limits<RealType>::lowest();
|
||||
} // end normal_distribution::min()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename normal_distribution<RealType>::result_type normal_distribution<RealType>::max
|
||||
THRUST_PREVENT_MACRO_SUBSTITUTION() const
|
||||
{
|
||||
return ::cuda::std::numeric_limits<RealType>::max();
|
||||
} // end normal_distribution::max()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename normal_distribution<RealType>::result_type normal_distribution<RealType>::mean() const
|
||||
{
|
||||
return m_param.first;
|
||||
} // end normal_distribution::mean()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename normal_distribution<RealType>::result_type normal_distribution<RealType>::stddev() const
|
||||
{
|
||||
return m_param.second;
|
||||
} // end normal_distribution::stddev()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool normal_distribution<RealType>::equal(const normal_distribution& rhs) const
|
||||
{
|
||||
return m_param == rhs.param();
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& normal_distribution<RealType>::stream_out(std::basic_ostream<CharT, Traits>& os) const
|
||||
{
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
using ios_base = typename ostream_type::ios_base;
|
||||
|
||||
// save old flags and fill character
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
|
||||
const CharT space = os.widen(' ');
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(space);
|
||||
|
||||
os << mean() << space << stddev();
|
||||
|
||||
// restore old flags and fill character
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& normal_distribution<RealType>::stream_in(std::basic_istream<CharT, Traits>& is)
|
||||
{
|
||||
using istream_type = std::basic_istream<CharT, Traits>;
|
||||
using ios_base = typename istream_type::ios_base;
|
||||
|
||||
// save old flags
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
|
||||
is.flags(ios_base::skipws);
|
||||
|
||||
is >> m_param.first >> m_param.second;
|
||||
|
||||
// restore old flags
|
||||
is.flags(flags);
|
||||
return is;
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool operator==(const normal_distribution<RealType>& lhs, const normal_distribution<RealType>& rhs)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::equal(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const normal_distribution<RealType>& lhs, const normal_distribution<RealType>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename RealType, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const normal_distribution<RealType>& d)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_out(os, d);
|
||||
}
|
||||
|
||||
template <typename RealType, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is, normal_distribution<RealType>& d)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_in(is, d);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,134 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*
|
||||
* Copyright Jens Maurer 2000-2001
|
||||
* Distributed under the Boost Software License, Version 1.0. (See
|
||||
* accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/detail/urng_traits.h>
|
||||
#include <thrust/random/uniform_real_distribution.h>
|
||||
|
||||
#include <cuda/std/__cmath/logarithms.h>
|
||||
#include <cuda/std/__cmath/roots.h>
|
||||
#include <cuda/std/__cmath/trigonometric_functions.h>
|
||||
#include <cuda/std/limits>
|
||||
#include <cuda/std/numbers>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
namespace random::detail
|
||||
{
|
||||
// this version samples the normal distribution directly
|
||||
// and uses the non-standard math function erfcinv
|
||||
template <typename RealType>
|
||||
class normal_distribution_nvcc
|
||||
{
|
||||
protected:
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE RealType sample(UniformRandomNumberGenerator& urng, const RealType mean, const RealType stddev)
|
||||
{
|
||||
using uint_type = typename UniformRandomNumberGenerator::result_type;
|
||||
using traits = thrust::random::detail::urng_traits<UniformRandomNumberGenerator>;
|
||||
constexpr uint_type urng_range = (traits::max) () - (traits::min) ();
|
||||
|
||||
// Constants for conversion
|
||||
constexpr RealType S1 = static_cast<RealType>(1. / static_cast<double>(urng_range));
|
||||
constexpr RealType S2 = S1 / 2;
|
||||
|
||||
auto S3 = -::cuda::std::__numbers<RealType>::__sqrt2();
|
||||
|
||||
// Get the integer value
|
||||
uint_type u = urng() - (traits::min) ();
|
||||
|
||||
// Ensure the conversion to float will give a value in the range [0,0.5)
|
||||
if (u > (urng_range / 2))
|
||||
{
|
||||
u = urng_range - u;
|
||||
S3 = -S3;
|
||||
}
|
||||
|
||||
// Convert to floating point in [0,0.5)
|
||||
RealType p = u * S1 + S2;
|
||||
|
||||
// Apply inverse error function
|
||||
return mean + stddev * S3 * erfcinv(2 * p);
|
||||
}
|
||||
|
||||
// no-op
|
||||
_CCCL_HOST_DEVICE void reset() {}
|
||||
};
|
||||
|
||||
// this version samples the normal distribution using
|
||||
// Marsaglia's "polar method"
|
||||
template <typename RealType>
|
||||
class normal_distribution_portable
|
||||
{
|
||||
protected:
|
||||
void reset()
|
||||
{
|
||||
m_valid = false;
|
||||
}
|
||||
|
||||
// note that we promise to call this member function with the same mean and stddev
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE RealType sample(UniformRandomNumberGenerator& urng, const RealType mean, const RealType stddev)
|
||||
{
|
||||
// implementation from Boost
|
||||
// allow for Koenig lookup
|
||||
using ::cuda::std::cos;
|
||||
using ::cuda::std::log;
|
||||
using ::cuda::std::sin;
|
||||
using ::cuda::std::sqrt;
|
||||
|
||||
if (!m_valid)
|
||||
{
|
||||
uniform_real_distribution<RealType> u01;
|
||||
m_r1 = u01(urng);
|
||||
m_r2 = u01(urng);
|
||||
m_cached_rho = sqrt(-RealType(2) * log(RealType(1) - m_r2));
|
||||
|
||||
m_valid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_valid = false;
|
||||
}
|
||||
|
||||
constexpr auto pi = ::cuda::std::__numbers<RealType>::__pi();
|
||||
|
||||
RealType result = m_cached_rho * (m_valid ? cos(RealType(2) * pi * m_r1) : sin(RealType(2) * pi * m_r1));
|
||||
|
||||
return mean + stddev * result;
|
||||
}
|
||||
|
||||
private:
|
||||
RealType m_r1{}, m_r2{}, m_cached_rho{};
|
||||
bool m_valid{false};
|
||||
};
|
||||
|
||||
template <typename RealType>
|
||||
struct normal_distribution_base
|
||||
{
|
||||
#if _CCCL_CUDA_COMPILATION() && !_CCCL_CUDA_COMPILER(NVHPC)
|
||||
using type = normal_distribution_nvcc<RealType>;
|
||||
#else // ^^^ _CCCL_CUDA_COMPILATION() && !_CCCL_CUDA_COMPILER(NVHPC) ^^^ /
|
||||
// vvv !_CCCL_CUDA_COMPILATION() || _CCCL_CUDA_COMPILER(NVHPC) vvv
|
||||
using type = normal_distribution_portable<RealType>;
|
||||
#endif // ^^^ !_CCCL_CUDA_COMPILATION() || _CCCL_CUDA_COMPILER(NVHPC) ^^^
|
||||
};
|
||||
} // namespace random::detail
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,43 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random::detail
|
||||
{
|
||||
struct random_core_access
|
||||
{
|
||||
template <typename OStream, typename EngineOrDistribution>
|
||||
static OStream& stream_out(OStream& os, const EngineOrDistribution& x)
|
||||
{
|
||||
return x.stream_out(os);
|
||||
}
|
||||
|
||||
template <typename IStream, typename EngineOrDistribution>
|
||||
static IStream& stream_in(IStream& is, EngineOrDistribution& x)
|
||||
{
|
||||
return x.stream_in(is);
|
||||
}
|
||||
|
||||
template <typename EngineOrDistribution>
|
||||
_CCCL_HOST_DEVICE static bool equal(const EngineOrDistribution& lhs, const EngineOrDistribution& rhs)
|
||||
{
|
||||
return lhs.equal(rhs);
|
||||
}
|
||||
|
||||
}; // end random_core_access
|
||||
} // namespace random::detail
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,186 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2021, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/detail/mod.h>
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
#include <thrust/random/linear_congruential_engine.h>
|
||||
#include <thrust/random/subtract_with_carry_engine.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
_CCCL_HOST_DEVICE subtract_with_carry_engine<UIntType, w, s, r>::subtract_with_carry_engine(result_type value)
|
||||
{
|
||||
seed(value);
|
||||
} // end subtract_with_carry_engine::subtract_with_carry_engine()
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
_CCCL_HOST_DEVICE void subtract_with_carry_engine<UIntType, w, s, r>::seed(result_type value)
|
||||
{
|
||||
thrust::random::linear_congruential_engine<result_type, 40014u, 0u, 2147483563u> e(
|
||||
value == 0u ? default_seed : value);
|
||||
|
||||
// initialize state
|
||||
for (size_t i = 0; i < long_lag; ++i)
|
||||
{
|
||||
m_x[i] = detail::mod<UIntType, 1, 0, modulus>(e());
|
||||
} // end for i
|
||||
|
||||
m_carry = (m_x[long_lag - 1] == 0);
|
||||
m_k = 0;
|
||||
} // end subtract_with_carry_engine::seed()
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
_CCCL_HOST_DEVICE typename subtract_with_carry_engine<UIntType, w, s, r>::result_type
|
||||
subtract_with_carry_engine<UIntType, w, s, r>::operator()()
|
||||
{
|
||||
// XXX we probably need to cache these m_x[m_k] in a register
|
||||
// maybe we need to cache the use of all member variables
|
||||
int short_index = m_k - short_lag;
|
||||
if (short_index < 0)
|
||||
{
|
||||
short_index += long_lag;
|
||||
}
|
||||
result_type xi;
|
||||
if (m_x[short_index] >= m_x[m_k] + m_carry)
|
||||
{
|
||||
// x(n) >= 0
|
||||
xi = m_x[short_index] - m_x[m_k] - m_carry;
|
||||
m_carry = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// x(n) < 0
|
||||
xi = modulus - m_x[m_k] - m_carry + m_x[short_index];
|
||||
m_carry = 1;
|
||||
}
|
||||
m_x[m_k] = xi;
|
||||
++m_k;
|
||||
if (m_k >= long_lag)
|
||||
{
|
||||
m_k = 0;
|
||||
}
|
||||
return xi;
|
||||
} // end subtract_with_carry_engine::operator()()
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
_CCCL_HOST_DEVICE void subtract_with_carry_engine<UIntType, w, s, r>::discard(unsigned long long z)
|
||||
{
|
||||
for (; z > 0; --z)
|
||||
{
|
||||
this->operator()();
|
||||
} // end for
|
||||
} // end subtract_with_carry_engine::discard()
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
subtract_with_carry_engine<UIntType, w, s, r>::stream_out(std::basic_ostream<CharT, Traits>& os) const
|
||||
{
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
using ios_base = typename ostream_type::ios_base;
|
||||
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
const CharT space = os.widen(' ');
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(space);
|
||||
|
||||
const UIntType long_lag_ = r;
|
||||
|
||||
for (size_t i = 0; i < r; ++i)
|
||||
{
|
||||
os << m_x[(i + m_k) % long_lag_] << space;
|
||||
}
|
||||
os << m_carry;
|
||||
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
template <typename CharType, typename Traits>
|
||||
std::basic_istream<CharType, Traits>&
|
||||
subtract_with_carry_engine<UIntType, w, s, r>::stream_in(std::basic_istream<CharType, Traits>& is)
|
||||
{
|
||||
using istream_type = std::basic_istream<CharType, Traits>;
|
||||
using ios_base = typename istream_type::ios_base;
|
||||
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
is.flags(ios_base::dec | ios_base::skipws);
|
||||
|
||||
for (size_t i = 0; i < r; ++i)
|
||||
{
|
||||
is >> m_x[i];
|
||||
}
|
||||
is >> m_carry;
|
||||
|
||||
m_k = 0;
|
||||
|
||||
is.flags(flags);
|
||||
return is;
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
subtract_with_carry_engine<UIntType, w, s, r>::equal(const subtract_with_carry_engine<UIntType, w, s, r>& rhs) const
|
||||
{
|
||||
const UIntType long_lag_ = r;
|
||||
|
||||
bool result = true;
|
||||
for (size_t i = 0; i < r; ++i)
|
||||
{
|
||||
result &= (m_x[(i + m_k) % long_lag_] == rhs.m_x[(i + rhs.m_k) % long_lag_]);
|
||||
}
|
||||
|
||||
// XXX not sure if this last check is necessary
|
||||
result &= (m_carry == rhs.m_carry);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const subtract_with_carry_engine<UIntType, w, s, r>& e)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_out(os, e);
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r, typename CharType, typename Traits>
|
||||
std::basic_istream<CharType, Traits>&
|
||||
operator>>(std::basic_istream<CharType, Traits>& is, subtract_with_carry_engine<UIntType, w, s, r>& e)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_in(is, e);
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
_CCCL_HOST_DEVICE bool operator==(const subtract_with_carry_engine<UIntType, w, s, r>& lhs,
|
||||
const subtract_with_carry_engine<UIntType, w, s, r>& rhs)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::equal(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const subtract_with_carry_engine<UIntType, w, s, r>& lhs,
|
||||
const subtract_with_carry_engine<UIntType, w, s, r>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,183 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2021, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/detail/type_traits.h>
|
||||
#include <thrust/random/uniform_int_distribution.h>
|
||||
#include <thrust/random/uniform_real_distribution.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE uniform_int_distribution<IntType>::uniform_int_distribution(IntType a, IntType b)
|
||||
: m_param(a, b)
|
||||
{} // end uniform_int_distribution::uniform_int_distribution()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE uniform_int_distribution<IntType>::uniform_int_distribution(const param_type& parm)
|
||||
: m_param(parm)
|
||||
{} // end uniform_int_distribution::uniform_int_distribution()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE void uniform_int_distribution<IntType>::reset()
|
||||
{} // end uniform_int_distribution::reset()
|
||||
|
||||
template <typename IntType>
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE typename uniform_int_distribution<IntType>::result_type
|
||||
uniform_int_distribution<IntType>::operator()(UniformRandomNumberGenerator& urng)
|
||||
{
|
||||
return operator()(urng, m_param);
|
||||
} // end uniform_int_distribution::operator()()
|
||||
|
||||
template <typename IntType>
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE typename uniform_int_distribution<IntType>::result_type
|
||||
uniform_int_distribution<IntType>::operator()(UniformRandomNumberGenerator& urng, const param_type& parm)
|
||||
{
|
||||
// XXX this implementation is somewhat hacky and will skip
|
||||
// values if the range of the RNG is smaller than the range of the distribution
|
||||
// we should improve this implementation in a later version
|
||||
|
||||
using float_type = typename thrust::detail::largest_available_float::type;
|
||||
|
||||
const float_type real_min(static_cast<float_type>(parm.first));
|
||||
const float_type real_max(static_cast<float_type>(parm.second));
|
||||
|
||||
// add one to the right end of the interval because it is half-open
|
||||
// XXX adding 1.0 to a potentially large floating point number seems like a bad idea
|
||||
uniform_real_distribution<float_type> real_dist(real_min, real_max + float_type(1));
|
||||
|
||||
return static_cast<result_type>(real_dist(urng));
|
||||
} // end uniform_int_distribution::operator()()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE typename uniform_int_distribution<IntType>::result_type uniform_int_distribution<IntType>::a() const
|
||||
{
|
||||
return m_param.first;
|
||||
} // end uniform_int_distribution<IntType>::a()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE typename uniform_int_distribution<IntType>::result_type uniform_int_distribution<IntType>::b() const
|
||||
{
|
||||
return m_param.second;
|
||||
} // end uniform_int_distribution::b()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE typename uniform_int_distribution<IntType>::param_type uniform_int_distribution<IntType>::param() const
|
||||
{
|
||||
return m_param;
|
||||
} // end uniform_int_distribution::param()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE void uniform_int_distribution<IntType>::param(const param_type& parm)
|
||||
{
|
||||
m_param = parm;
|
||||
} // end uniform_int_distribution::param()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE typename uniform_int_distribution<IntType>::result_type uniform_int_distribution<IntType>::min
|
||||
THRUST_PREVENT_MACRO_SUBSTITUTION() const
|
||||
{
|
||||
return a();
|
||||
} // end uniform_int_distribution::min()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE typename uniform_int_distribution<IntType>::result_type uniform_int_distribution<IntType>::max
|
||||
THRUST_PREVENT_MACRO_SUBSTITUTION() const
|
||||
{
|
||||
return b();
|
||||
} // end uniform_int_distribution::max()
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE bool uniform_int_distribution<IntType>::equal(const uniform_int_distribution& rhs) const
|
||||
{
|
||||
return param() == rhs.param();
|
||||
}
|
||||
|
||||
template <typename IntType>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
uniform_int_distribution<IntType>::stream_out(std::basic_ostream<CharT, Traits>& os) const
|
||||
{
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
using ios_base = typename ostream_type::ios_base;
|
||||
|
||||
// save old flags and fill character
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
|
||||
const CharT space = os.widen(' ');
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(space);
|
||||
|
||||
os << a() << space << b();
|
||||
|
||||
// restore old flags and fill character
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename IntType>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& uniform_int_distribution<IntType>::stream_in(std::basic_istream<CharT, Traits>& is)
|
||||
{
|
||||
using istream_type = std::basic_istream<CharT, Traits>;
|
||||
using ios_base = typename istream_type::ios_base;
|
||||
|
||||
// save old flags
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
|
||||
is.flags(ios_base::skipws);
|
||||
|
||||
is >> m_param.first >> m_param.second;
|
||||
|
||||
// restore old flags
|
||||
is.flags(flags);
|
||||
return is;
|
||||
}
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator==(const uniform_int_distribution<IntType>& lhs, const uniform_int_distribution<IntType>& rhs)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::equal(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator!=(const uniform_int_distribution<IntType>& lhs, const uniform_int_distribution<IntType>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename IntType, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const uniform_int_distribution<IntType>& d)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_out(os, d);
|
||||
}
|
||||
|
||||
template <typename IntType, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, uniform_int_distribution<IntType>& d)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_in(is, d);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,187 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2021, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/detail/urng_traits.h>
|
||||
#include <thrust/random/uniform_real_distribution.h>
|
||||
|
||||
#include <cuda/std/__cmath/lerp.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE uniform_real_distribution<RealType>::uniform_real_distribution(RealType a, RealType b)
|
||||
: m_param(a, b)
|
||||
{} // end uniform_real_distribution::uniform_real_distribution()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE uniform_real_distribution<RealType>::uniform_real_distribution(const param_type& parm)
|
||||
: m_param(parm)
|
||||
{} // end uniform_real_distribution::uniform_real_distribution()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE void uniform_real_distribution<RealType>::reset()
|
||||
{} // end uniform_real_distribution::reset()
|
||||
|
||||
template <typename RealType>
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE typename uniform_real_distribution<RealType>::result_type
|
||||
uniform_real_distribution<RealType>::operator()(UniformRandomNumberGenerator& urng)
|
||||
{
|
||||
return operator()(urng, m_param);
|
||||
} // end uniform_real::operator()()
|
||||
|
||||
template <typename RealType>
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE typename uniform_real_distribution<RealType>::result_type
|
||||
uniform_real_distribution<RealType>::operator()(UniformRandomNumberGenerator& urng, const param_type& parm)
|
||||
{
|
||||
using traits = thrust::random::detail::urng_traits<UniformRandomNumberGenerator>;
|
||||
|
||||
// call the urng & map its result to [0,1)
|
||||
result_type result = static_cast<result_type>(urng() - (traits::min) ());
|
||||
|
||||
// adding one to the denominator ensures that the interval is half-open at 1.0
|
||||
// XXX adding 1.0 to a potentially large floating point number seems like a bad idea
|
||||
// XXX OTOH adding 1 to what is potentially UINT_MAX also seems like a bad idea
|
||||
// XXX we could statically check if 1u + (max - min) is representable and do that, otherwise use the current
|
||||
// implementation
|
||||
result /= (result_type(1) + static_cast<result_type>((traits::max) () - (traits::min) ()));
|
||||
|
||||
return ::cuda::std::lerp(parm.first, parm.second, result);
|
||||
} // end uniform_real::operator()()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename uniform_real_distribution<RealType>::result_type
|
||||
uniform_real_distribution<RealType>::a() const
|
||||
{
|
||||
return m_param.first;
|
||||
} // end uniform_real::a()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename uniform_real_distribution<RealType>::result_type
|
||||
uniform_real_distribution<RealType>::b() const
|
||||
{
|
||||
return m_param.second;
|
||||
} // end uniform_real_distribution::b()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename uniform_real_distribution<RealType>::param_type
|
||||
uniform_real_distribution<RealType>::param() const
|
||||
{
|
||||
return m_param;
|
||||
;
|
||||
} // end uniform_real_distribution::param()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE void uniform_real_distribution<RealType>::param(const param_type& parm)
|
||||
{
|
||||
m_param = parm;
|
||||
} // end uniform_real_distribution::param()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename uniform_real_distribution<RealType>::result_type uniform_real_distribution<RealType>::min
|
||||
THRUST_PREVENT_MACRO_SUBSTITUTION() const
|
||||
{
|
||||
return a();
|
||||
} // end uniform_real_distribution::min()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE typename uniform_real_distribution<RealType>::result_type uniform_real_distribution<RealType>::max
|
||||
THRUST_PREVENT_MACRO_SUBSTITUTION() const
|
||||
{
|
||||
return b();
|
||||
} // end uniform_real_distribution::max()
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool uniform_real_distribution<RealType>::equal(const uniform_real_distribution& rhs) const
|
||||
{
|
||||
return m_param == rhs.param();
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
uniform_real_distribution<RealType>::stream_out(std::basic_ostream<CharT, Traits>& os) const
|
||||
{
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
using ios_base = typename ostream_type::ios_base;
|
||||
|
||||
// save old flags and fill character
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
|
||||
const CharT space = os.widen(' ');
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(space);
|
||||
|
||||
os << a() << space << b();
|
||||
|
||||
// restore old flags and fill character
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& uniform_real_distribution<RealType>::stream_in(std::basic_istream<CharT, Traits>& is)
|
||||
{
|
||||
using istream_type = std::basic_istream<CharT, Traits>;
|
||||
using ios_base = typename istream_type::ios_base;
|
||||
|
||||
// save old flags
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
|
||||
is.flags(ios_base::skipws);
|
||||
|
||||
is >> m_param.first >> m_param.second;
|
||||
|
||||
// restore old flags
|
||||
is.flags(flags);
|
||||
return is;
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator==(const uniform_real_distribution<RealType>& lhs, const uniform_real_distribution<RealType>& rhs)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::equal(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator!=(const uniform_real_distribution<RealType>& lhs, const uniform_real_distribution<RealType>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template <typename RealType, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const uniform_real_distribution<RealType>& d)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_out(os, d);
|
||||
}
|
||||
|
||||
template <typename RealType, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, uniform_real_distribution<RealType>& d)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_in(is, d);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
87
cccl_upstream/thrust/thrust/random/detail/urng_traits.h
Normal file
87
cccl_upstream/thrust/thrust/random/detail/urng_traits.h
Normal file
@@ -0,0 +1,87 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/std/__type_traits/enable_if.h>
|
||||
#include <cuda/std/__type_traits/is_convertible.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random::detail
|
||||
{
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
using urng_result_t = typename UniformRandomNumberGenerator::result_type;
|
||||
|
||||
template <typename UniformRandomNumberGenerator, typename = void>
|
||||
inline constexpr bool has_static_min_member_v = false;
|
||||
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
inline constexpr bool has_static_min_member_v<
|
||||
UniformRandomNumberGenerator,
|
||||
::cuda::std::enable_if_t<::cuda::std::is_convertible_v<decltype(UniformRandomNumberGenerator::min),
|
||||
urng_result_t<UniformRandomNumberGenerator>>>> = true;
|
||||
|
||||
template <typename UniformRandomNumberGenerator, typename = void>
|
||||
inline constexpr bool has_static_max_member_v = false;
|
||||
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
inline constexpr bool has_static_max_member_v<
|
||||
UniformRandomNumberGenerator,
|
||||
::cuda::std::enable_if_t<::cuda::std::is_convertible_v<decltype(UniformRandomNumberGenerator::max),
|
||||
urng_result_t<UniformRandomNumberGenerator>>>> = true;
|
||||
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE constexpr typename UniformRandomNumberGenerator::result_type uniform_random_number_generator_min()
|
||||
{
|
||||
if constexpr (has_static_min_member_v<UniformRandomNumberGenerator>)
|
||||
{
|
||||
return UniformRandomNumberGenerator::min;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (UniformRandomNumberGenerator::min) ();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE constexpr typename UniformRandomNumberGenerator::result_type uniform_random_number_generator_max()
|
||||
{
|
||||
if constexpr (has_static_max_member_v<UniformRandomNumberGenerator>)
|
||||
{
|
||||
return UniformRandomNumberGenerator::max;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (UniformRandomNumberGenerator::max) ();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
struct urng_traits
|
||||
{
|
||||
using result_type = typename UniformRandomNumberGenerator::result_type;
|
||||
|
||||
_CCCL_HOST_DEVICE static constexpr result_type min THRUST_PREVENT_MACRO_SUBSTITUTION()
|
||||
{
|
||||
return uniform_random_number_generator_min<UniformRandomNumberGenerator>();
|
||||
}
|
||||
|
||||
_CCCL_HOST_DEVICE static constexpr result_type max THRUST_PREVENT_MACRO_SUBSTITUTION()
|
||||
{
|
||||
return uniform_random_number_generator_max<UniformRandomNumberGenerator>();
|
||||
}
|
||||
};
|
||||
} // namespace random::detail
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
168
cccl_upstream/thrust/thrust/random/detail/xor_combine_engine.inl
Normal file
168
cccl_upstream/thrust/thrust/random/detail/xor_combine_engine.inl
Normal file
@@ -0,0 +1,168 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2021, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
#include <thrust/random/xor_combine_engine.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE xor_combine_engine<Engine1, s1, Engine2, s2>::xor_combine_engine()
|
||||
: m_b1()
|
||||
, m_b2()
|
||||
{} // end xor_combine_engine::xor_combine_engine()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE
|
||||
xor_combine_engine<Engine1, s1, Engine2, s2>::xor_combine_engine(const base1_type& urng1, const base2_type& urng2)
|
||||
: m_b1(urng1)
|
||||
, m_b2(urng2)
|
||||
{} // end xor_combine_engine::xor_combine_engine()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE xor_combine_engine<Engine1, s1, Engine2, s2>::xor_combine_engine(result_type s)
|
||||
: m_b1(s)
|
||||
, m_b2(s)
|
||||
{} // end xor_combine_engine::xor_combine_engine()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE void xor_combine_engine<Engine1, s1, Engine2, s2>::seed()
|
||||
{
|
||||
m_b1.seed();
|
||||
m_b2.seed();
|
||||
} // end xor_combine_engine::seed()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE void xor_combine_engine<Engine1, s1, Engine2, s2>::seed(result_type s)
|
||||
{
|
||||
m_b1.seed(s);
|
||||
m_b2.seed(s);
|
||||
} // end xor_combine_engine::seed()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE const typename xor_combine_engine<Engine1, s1, Engine2, s2>::base1_type&
|
||||
xor_combine_engine<Engine1, s1, Engine2, s2>::base1() const
|
||||
{
|
||||
return m_b1;
|
||||
} // end xor_combine_engine::base1()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE const typename xor_combine_engine<Engine1, s1, Engine2, s2>::base2_type&
|
||||
xor_combine_engine<Engine1, s1, Engine2, s2>::base2() const
|
||||
{
|
||||
return m_b2;
|
||||
} // end xor_combine_engine::base2()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE typename xor_combine_engine<Engine1, s1, Engine2, s2>::result_type
|
||||
xor_combine_engine<Engine1, s1, Engine2, s2>::operator()()
|
||||
{
|
||||
return (result_type(m_b1() - base1_type::min) << shift1) ^ (result_type(m_b2() - base2_type::min) << shift2);
|
||||
} // end xor_combine_engine::operator()()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE void xor_combine_engine<Engine1, s1, Engine2, s2>::discard(unsigned long long z)
|
||||
{
|
||||
for (; z > 0; --z)
|
||||
{
|
||||
this->operator()();
|
||||
} // end for
|
||||
} // end xor_combine_engine::discard()
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
xor_combine_engine<Engine1, s1, Engine2, s2>::stream_out(std::basic_ostream<CharT, Traits>& os) const
|
||||
{
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
using ios_base = typename ostream_type::ios_base;
|
||||
|
||||
// save old flags and fill character
|
||||
const typename ios_base::fmtflags flags = os.flags();
|
||||
const CharT fill = os.fill();
|
||||
|
||||
const CharT space = os.widen(' ');
|
||||
os.flags(ios_base::dec | ios_base::fixed | ios_base::left);
|
||||
os.fill(space);
|
||||
|
||||
// output each base engine in turn
|
||||
os << base1() << space << base2();
|
||||
|
||||
// restore old flags and fill character
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
xor_combine_engine<Engine1, s1, Engine2, s2>::stream_in(std::basic_istream<CharT, Traits>& is)
|
||||
{
|
||||
using istream_type = std::basic_istream<CharT, Traits>;
|
||||
using ios_base = typename istream_type::ios_base;
|
||||
|
||||
// save old flags
|
||||
const typename ios_base::fmtflags flags = is.flags();
|
||||
|
||||
is.flags(ios_base::skipws);
|
||||
|
||||
// input each base engine in turn
|
||||
is >> m_b1 >> m_b2;
|
||||
|
||||
// restore old flags
|
||||
is.flags(flags);
|
||||
return is;
|
||||
}
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
xor_combine_engine<Engine1, s1, Engine2, s2>::equal(const xor_combine_engine<Engine1, s1, Engine2, s2>& rhs) const
|
||||
{
|
||||
return (m_b1 == rhs.m_b1) && (m_b2 == rhs.m_b2);
|
||||
}
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const xor_combine_engine<Engine1, s1, Engine2, s2>& e)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_out(os, e);
|
||||
}
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, xor_combine_engine<Engine1, s1, Engine2, s2>& e)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::stream_in(is, e);
|
||||
}
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE bool operator==(const xor_combine_engine<Engine1, s1, Engine2, s2>& lhs,
|
||||
const xor_combine_engine<Engine1, s1, Engine2, s2>& rhs)
|
||||
{
|
||||
return thrust::random::detail::random_core_access::equal(lhs, rhs);
|
||||
}
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const xor_combine_engine<Engine1, s1, Engine2, s2>& lhs,
|
||||
const xor_combine_engine<Engine1, s1, Engine2, s2>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
@@ -0,0 +1,173 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/detail/type_traits.h>
|
||||
|
||||
#include <cuda/std/__algorithm/max.h>
|
||||
#include <cuda/std/__algorithm/min.h>
|
||||
#include <cuda/std/cstddef>
|
||||
#include <cuda/std/limits>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
namespace random::detail
|
||||
{
|
||||
template <typename UIntType>
|
||||
_CCCL_HOST_DEVICE constexpr auto lshift(UIntType lhs, UIntType rhs) -> UIntType
|
||||
{
|
||||
const bool shift_will_overflow = rhs >= ::cuda::std::numeric_limits<UIntType>::digits;
|
||||
if (shift_will_overflow)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return lhs << rhs;
|
||||
}
|
||||
|
||||
template <typename UIntType>
|
||||
_CCCL_HOST_DEVICE constexpr auto two_to_the_power(UIntType p) -> UIntType
|
||||
{
|
||||
return lshift(UIntType{1}, p);
|
||||
}
|
||||
|
||||
template <typename UIntType>
|
||||
_CCCL_HOST_DEVICE constexpr auto log2(UIntType n) -> UIntType
|
||||
{
|
||||
UIntType cur = 0;
|
||||
while (n > 1)
|
||||
{
|
||||
n /= 2;
|
||||
cur++;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d>
|
||||
class xor_combine_engine_max_aux_constants
|
||||
{
|
||||
public:
|
||||
static constexpr result_type two_to_the_d = two_to_the_power(d);
|
||||
static constexpr result_type c = lshift(a, result_type(d));
|
||||
static constexpr result_type t = (::cuda::std::max) (c, b);
|
||||
static constexpr result_type u = (::cuda::std::min) (c, b);
|
||||
static constexpr result_type p = log2(u);
|
||||
static constexpr result_type two_to_the_p = two_to_the_power(p);
|
||||
static constexpr result_type k = t / two_to_the_p;
|
||||
};
|
||||
|
||||
template <typename result_type, result_type, result_type, int>
|
||||
struct xor_combine_engine_max_aux;
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d>
|
||||
struct xor_combine_engine_max_aux_case4
|
||||
{
|
||||
using constants = xor_combine_engine_max_aux_constants<result_type, a, b, d>;
|
||||
|
||||
static constexpr result_type k_plus_1_times_two_to_the_p = lshift(constants::k + 1, constants::p);
|
||||
|
||||
static constexpr result_type M =
|
||||
xor_combine_engine_max_aux<result_type,
|
||||
(constants::u % constants::two_to_the_p) / constants::two_to_the_p,
|
||||
constants::t % constants::two_to_the_p,
|
||||
d>::value;
|
||||
|
||||
static constexpr result_type value = k_plus_1_times_two_to_the_p + M;
|
||||
};
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d>
|
||||
struct xor_combine_engine_max_aux_case3
|
||||
{
|
||||
using constants = xor_combine_engine_max_aux_constants<result_type, a, b, d>;
|
||||
|
||||
static constexpr result_type k_plus_1_times_two_to_the_p = lshift(constants::k + 1, constants::p);
|
||||
|
||||
static constexpr result_type M =
|
||||
xor_combine_engine_max_aux<result_type,
|
||||
(constants::t % constants::two_to_the_p) / constants::two_to_the_p,
|
||||
constants::u % constants::two_to_the_p,
|
||||
d>::value;
|
||||
|
||||
static constexpr result_type value = k_plus_1_times_two_to_the_p + M;
|
||||
};
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d>
|
||||
struct xor_combine_engine_max_aux_case2
|
||||
{
|
||||
using constants = xor_combine_engine_max_aux_constants<result_type, a, b, d>;
|
||||
|
||||
static constexpr result_type k_plus_1_times_two_to_the_p = lshift(constants::k + 1, constants::p);
|
||||
static constexpr result_type value = k_plus_1_times_two_to_the_p - 1;
|
||||
};
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d>
|
||||
struct xor_combine_engine_max_aux_case1
|
||||
{
|
||||
static constexpr result_type c = lshift(a, result_type(d));
|
||||
static constexpr result_type value = c + b;
|
||||
};
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d>
|
||||
struct xor_combine_engine_max_aux_2
|
||||
{
|
||||
using constants = xor_combine_engine_max_aux_constants<result_type, a, b, d>;
|
||||
|
||||
_CCCL_HOST_DEVICE static constexpr result_type compute_value()
|
||||
{
|
||||
// if k is odd...
|
||||
if constexpr (constants::k % 2 == 1)
|
||||
{
|
||||
return xor_combine_engine_max_aux_case2<result_type, a, b, d>::value;
|
||||
}
|
||||
// otherwise if a * 2^3 >= b, then case 3
|
||||
else if constexpr (a * constants::two_to_the_d >= b)
|
||||
{
|
||||
return xor_combine_engine_max_aux_case3<result_type, a, b, d>::value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, case 4
|
||||
return xor_combine_engine_max_aux_case4<result_type, a, b, d>::value;
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr result_type value = compute_value();
|
||||
};
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d, bool use_case1 = (a == 0) || (b < two_to_the_power(d))>
|
||||
struct xor_combine_engine_max_aux_1 : xor_combine_engine_max_aux_case1<result_type, a, b, d>
|
||||
{};
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d>
|
||||
struct xor_combine_engine_max_aux_1<result_type, a, b, d, false> : xor_combine_engine_max_aux_2<result_type, a, b, d>
|
||||
{};
|
||||
|
||||
template <typename result_type, result_type a, result_type b, int d>
|
||||
struct xor_combine_engine_max_aux : xor_combine_engine_max_aux_1<result_type, a, b, d>
|
||||
{};
|
||||
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2, typename result_type>
|
||||
struct xor_combine_engine_max
|
||||
{
|
||||
static constexpr size_t w = ::cuda::std::numeric_limits<result_type>::digits;
|
||||
static constexpr result_type m1 =
|
||||
(::cuda::std::min) (result_type(Engine1::max - Engine1::min), result_type(two_to_the_power(w - s1) - 1));
|
||||
static constexpr result_type m2 =
|
||||
(::cuda::std::min) (result_type(Engine2::max - Engine2::min), result_type(two_to_the_power(w - s2) - 1));
|
||||
static constexpr result_type s = s1 - s2;
|
||||
static constexpr result_type M = xor_combine_engine_max_aux<result_type, m1, m2, s>::value;
|
||||
// the value is M(m1,m2,s) lshift_w s2
|
||||
static constexpr result_type value = lshift(M, result_type(s2));
|
||||
};
|
||||
} // namespace random::detail
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
225
cccl_upstream/thrust/thrust/random/discard_block_engine.h
Normal file
225
cccl_upstream/thrust/thrust/random/discard_block_engine.h
Normal file
@@ -0,0 +1,225 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! \file discard_block_engine.h
|
||||
* \brief A random number engine which adapts a base engine and produces
|
||||
* numbers by discarding all but a contiguous blocks of its values.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
|
||||
#include <cuda/std/__host_stdlib/istream>
|
||||
#include <cuda/std/__host_stdlib/ostream>
|
||||
#include <cuda/std/cstdint>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
/*! \addtogroup random_number_engine_adaptors Random Number Engine Adaptor Class Templates
|
||||
* \ingroup random
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! \class discard_block_engine
|
||||
* \brief A \p discard_block_engine adapts an existing base random number engine and produces
|
||||
* random values by discarding some of the values returned by its base engine.
|
||||
* Each cycle of the compound engine begins by returning \c r values successively produced
|
||||
* by the base engine and ends by discarding <tt>p-r</tt> such values. The engine's state
|
||||
* is the state of its base engine followed by the number of calls to <tt>operator()</tt>
|
||||
* that have occurred since the beginning of the current cycle.
|
||||
*
|
||||
* \tparam Engine The type of the base random number engine to adapt.
|
||||
* \tparam p The discard cycle length.
|
||||
* \tparam r The number of values to return of the base engine. Because <tt>p-r</tt> will be
|
||||
* discarded, <tt>r <= p</tt>.
|
||||
*
|
||||
* The following code snippet shows an example of using a \p discard_block_engine instance:
|
||||
*
|
||||
* \code
|
||||
* #include <thrust/random/linear_congruential_engine.h>
|
||||
* #include <thrust/random/discard_block_engine.h>
|
||||
* #include <iostream>
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* // create a discard_block_engine from minstd_rand, with a cycle length of 13
|
||||
* // keep every first 10 values, and discard the next 3
|
||||
* thrust::discard_block_engine<thrust::minstd_rand, 13, 10> rng;
|
||||
*
|
||||
* // print a random number to standard output
|
||||
* std::cout << rng() << '\n';
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
class discard_block_engine
|
||||
{
|
||||
public:
|
||||
// types
|
||||
|
||||
/*! \typedef base_type
|
||||
* \brief The type of the adapted base random number engine.
|
||||
*/
|
||||
using base_type = Engine;
|
||||
|
||||
/*! \typedef result_type
|
||||
* \brief The type of the unsigned integer produced by this \p linear_congruential_engine.
|
||||
*/
|
||||
using result_type = typename base_type::result_type;
|
||||
|
||||
// engine characteristics
|
||||
|
||||
/*! The length of the production cycle.
|
||||
*/
|
||||
static const size_t block_size = p;
|
||||
|
||||
/*! The number of used numbers per production cycle.
|
||||
*/
|
||||
static const size_t used_block = r;
|
||||
|
||||
/*! The smallest value this \p discard_block_engine may potentially produce.
|
||||
*/
|
||||
static const result_type min = base_type::min;
|
||||
|
||||
/*! The largest value this \p discard_block_engine may potentially produce.
|
||||
*/
|
||||
static const result_type max = base_type::max;
|
||||
|
||||
// constructors and seeding functions
|
||||
|
||||
/*! This constructor constructs a new \p discard_block_engine and constructs
|
||||
* its \p base_type engine using its null constructor.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE discard_block_engine();
|
||||
|
||||
/*! This constructor constructs a new \p discard_block_engine using
|
||||
* a given \p base_type engine to initialize its adapted base engine.
|
||||
*
|
||||
* \param urng A \p base_type to use to initialize this \p discard_block_engine's
|
||||
* adapted base engine.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit discard_block_engine(const base_type& urng);
|
||||
|
||||
/*! This constructor initializes a new \p discard_block_engine with a given seed.
|
||||
*
|
||||
* \param s The seed used to initialize this \p discard_block_engine's adapted base engine.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit discard_block_engine(result_type s);
|
||||
|
||||
/*! This method initializes the state of this \p discard_block_engine's adapted base engine
|
||||
* by using its \p default_seed value.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void seed();
|
||||
|
||||
/*! This method initializes the state of this \p discard_block_engine's adapted base engine
|
||||
* by using the given seed.
|
||||
*
|
||||
* \param s The seed with which to initialize this \p discard_block_engine's adapted base engine.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void seed(result_type s);
|
||||
|
||||
// generating functions
|
||||
|
||||
/*! This member function produces a new random value and updates this \p discard_block_engine's state.
|
||||
* \return A new random number.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type operator()();
|
||||
|
||||
/*! This member function advances this \p discard_block_engine's state a given number of times
|
||||
* and discards the results.
|
||||
*
|
||||
* \param z The number of random values to discard.
|
||||
* \note This function is provided because an implementation may be able to accelerate it.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void discard(unsigned long long z);
|
||||
|
||||
// property functions
|
||||
|
||||
/*! This member function returns a const reference to this \p discard_block_engine's
|
||||
* adapted base engine.
|
||||
*
|
||||
* \return A const reference to the base engine this \p discard_block_engine adapts.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE const base_type& base() const;
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
base_type m_e;
|
||||
unsigned int m_n;
|
||||
|
||||
friend struct thrust::random::detail::random_core_access;
|
||||
|
||||
_CCCL_HOST_DEVICE bool equal(const discard_block_engine& rhs) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& stream_out(std::basic_ostream<CharT, Traits>& os) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& stream_in(std::basic_istream<CharT, Traits>& is);
|
||||
/*! \endcond
|
||||
*/
|
||||
}; // end discard_block_engine
|
||||
|
||||
/*! This function checks two \p discard_block_engines for equality.
|
||||
* \param lhs The first \p discard_block_engine to test.
|
||||
* \param rhs The second \p discard_block_engine to test.
|
||||
* \return \c true if \p lhs is equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator==(const discard_block_engine<Engine, p, r>& lhs, const discard_block_engine<Engine, p, r>& rhs);
|
||||
|
||||
/*! This function checks two \p discard_block_engines for inequality.
|
||||
* \param lhs The first \p discard_block_engine to test.
|
||||
* \param rhs The second \p discard_block_engine to test.
|
||||
* \return \c true if \p lhs is not equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename Engine, size_t p, size_t r>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator!=(const discard_block_engine<Engine, p, r>& lhs, const discard_block_engine<Engine, p, r>& rhs);
|
||||
|
||||
/*! This function streams a discard_block_engine to a \p std::basic_ostream.
|
||||
* \param os The \p basic_ostream to stream out to.
|
||||
* \param e The \p discard_block_engine to stream out.
|
||||
* \return \p os
|
||||
*/
|
||||
template <typename Engine, size_t p, size_t r, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const discard_block_engine<Engine, p, r>& e);
|
||||
|
||||
/*! This function streams a discard_block_engine in from a std::basic_istream.
|
||||
* \param is The \p basic_istream to stream from.
|
||||
* \param e The \p discard_block_engine to stream in.
|
||||
* \return \p is
|
||||
*/
|
||||
template <typename Engine, size_t p, size_t r, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, discard_block_engine<Engine, p, r>& e);
|
||||
|
||||
/*! \} // end random_number_engine_adaptors
|
||||
*/
|
||||
} // namespace random
|
||||
|
||||
// import names into thrust::
|
||||
using random::discard_block_engine;
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
|
||||
#include <thrust/random/detail/discard_block_engine.inl>
|
||||
274
cccl_upstream/thrust/thrust/random/linear_congruential_engine.h
Normal file
274
cccl_upstream/thrust/thrust/random/linear_congruential_engine.h
Normal file
@@ -0,0 +1,274 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! \file linear_congruential_engine.h
|
||||
* \brief A linear congruential pseudorandom number engine.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
#include <thrust/random/detail/linear_congruential_engine_discard.h>
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
|
||||
#include <cuda/std/__host_stdlib/istream>
|
||||
#include <cuda/std/__host_stdlib/ostream>
|
||||
#include <cuda/std/cstdint>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
/*! \addtogroup random_number_engine_templates Random Number Engine Class Templates
|
||||
* \ingroup random
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! \class linear_congruential_engine
|
||||
* \brief A \p linear_congruential_engine random number engine produces unsigned integer
|
||||
* random numbers using a linear congruential random number generation algorithm.
|
||||
*
|
||||
* The generation algorithm has the form <tt>x_i = (a * x_{i-1} + c) mod m</tt>.
|
||||
*
|
||||
* \tparam UIntType The type of unsigned integer to produce.
|
||||
* \tparam a The multiplier used in the generation algorithm.
|
||||
* \tparam c The increment used in the generation algorithm.
|
||||
* \tparam m The modulus used in the generation algorithm.
|
||||
*
|
||||
* \note Inexperienced users should not use this class template directly. Instead, use
|
||||
* \p minstd_rand or \p minstd_rand0.
|
||||
*
|
||||
* The following code snippet shows examples of use of a \p linear_congruential_engine instance:
|
||||
*
|
||||
* \code
|
||||
* #include <thrust/random/linear_congruential_engine.h>
|
||||
* #include <iostream>
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* // create a minstd_rand object, which is an instance of linear_congruential_engine
|
||||
* thrust::minstd_rand rng1;
|
||||
*
|
||||
* // output some random values to cout
|
||||
* std::cout << rng1() << '\n';
|
||||
*
|
||||
* // a random value is printed
|
||||
*
|
||||
* // create a new minstd_rand from a seed
|
||||
* thrust::minstd_rand rng2(13);
|
||||
*
|
||||
* // discard some random values
|
||||
* rng2.discard(13);
|
||||
*
|
||||
* // stream the object to an iostream
|
||||
* std::cout << rng2 << '\n';
|
||||
*
|
||||
* // rng2's current state is printed
|
||||
*
|
||||
* // print the minimum and maximum values that minstd_rand can produce
|
||||
* std::cout << thrust::minstd_rand::min << '\n';
|
||||
* std::cout << thrust::minstd_rand::max << '\n';
|
||||
*
|
||||
* // the range of minstd_rand is printed
|
||||
*
|
||||
* // save the state of rng2 to a different object
|
||||
* thrust::minstd_rand rng3 = rng2;
|
||||
*
|
||||
* // compare rng2 and rng3
|
||||
* std::cout << (rng2 == rng3) << '\n';
|
||||
*
|
||||
* // 1 is printed
|
||||
*
|
||||
* // re-seed rng2 with a different seed
|
||||
* rng2.seed(7);
|
||||
*
|
||||
* // compare rng2 and rng3
|
||||
* std::cout << (rng2 == rng3) << '\n';
|
||||
*
|
||||
* // 0 is printed
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* \see thrust::random::minstd_rand
|
||||
* \see thrust::random::minstd_rand0
|
||||
*/
|
||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
||||
class linear_congruential_engine
|
||||
{
|
||||
public:
|
||||
// types
|
||||
|
||||
/*! \typedef result_type
|
||||
* \brief The type of the unsigned integer produced by this \p linear_congruential_engine.
|
||||
*/
|
||||
using result_type = UIntType;
|
||||
|
||||
// engine characteristics
|
||||
|
||||
/*! The multiplier used in the generation algorithm.
|
||||
*/
|
||||
static const result_type multiplier = a;
|
||||
|
||||
/*! The increment used in the generation algorithm.
|
||||
*/
|
||||
static const result_type increment = c;
|
||||
|
||||
/*! The modulus used in the generation algorithm.
|
||||
*/
|
||||
static const result_type modulus = m;
|
||||
|
||||
/*! The smallest value this \p linear_congruential_engine may potentially produce.
|
||||
*/
|
||||
#ifndef _CCCL_DOXYGEN_INVOKED // Doxygen breaks on the ternary :shrug:
|
||||
static const result_type min = c == 0u ? 1u : 0u;
|
||||
#else
|
||||
static const result_type min = 0u;
|
||||
#endif // _CCCL_DOXYGEN_INVOKED
|
||||
|
||||
/*! The largest value this \p linear_congruential_engine may potentially produce.
|
||||
*/
|
||||
static const result_type max = m - 1u;
|
||||
|
||||
/*! The default seed of this \p linear_congruential_engine.
|
||||
*/
|
||||
static const result_type default_seed = 1u;
|
||||
|
||||
// constructors and seeding functions
|
||||
|
||||
/*! This constructor, which optionally accepts a seed, initializes a new
|
||||
* \p linear_congruential_engine.
|
||||
*
|
||||
* \param s The seed used to initialize this \p linear_congruential_engine's state.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit linear_congruential_engine(result_type s = default_seed);
|
||||
|
||||
/*! This method initializes this \p linear_congruential_engine's state, and optionally accepts
|
||||
* a seed value.
|
||||
*
|
||||
* \param s The seed used to initializes this \p linear_congruential_engine's state.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void seed(result_type s = default_seed);
|
||||
|
||||
// generating functions
|
||||
|
||||
/*! This member function produces a new random value and updates this \p linear_congruential_engine's state.
|
||||
* \return A new random number.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type operator()();
|
||||
|
||||
/*! This member function advances this \p linear_congruential_engine's state a given number of times
|
||||
* and discards the results.
|
||||
*
|
||||
* \param z The number of random values to discard.
|
||||
* \note This function is provided because an implementation may be able to accelerate it.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void discard(unsigned long long z);
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
result_type m_x;
|
||||
|
||||
static void transition(result_type& state);
|
||||
|
||||
friend struct thrust::random::detail::random_core_access;
|
||||
|
||||
friend struct thrust::random::detail::linear_congruential_engine_discard;
|
||||
|
||||
_CCCL_HOST_DEVICE bool equal(const linear_congruential_engine& rhs) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& stream_out(std::basic_ostream<CharT, Traits>& os) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& stream_in(std::basic_istream<CharT, Traits>& is);
|
||||
|
||||
/*! \endcond
|
||||
*/
|
||||
}; // end linear_congruential_engine
|
||||
|
||||
/*! This function checks two \p linear_congruential_engines for equality.
|
||||
* \param lhs The first \p linear_congruential_engine to test.
|
||||
* \param rhs The second \p linear_congruential_engine to test.
|
||||
* \return \c true if \p lhs is equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename UIntType_, UIntType_ a_, UIntType_ c_, UIntType_ m_>
|
||||
_CCCL_HOST_DEVICE bool operator==(const linear_congruential_engine<UIntType_, a_, c_, m_>& lhs,
|
||||
const linear_congruential_engine<UIntType_, a_, c_, m_>& rhs);
|
||||
|
||||
/*! This function checks two \p linear_congruential_engines for inequality.
|
||||
* \param lhs The first \p linear_congruential_engine to test.
|
||||
* \param rhs The second \p linear_congruential_engine to test.
|
||||
* \return \c true if \p lhs is not equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename UIntType_, UIntType_ a_, UIntType_ c_, UIntType_ m_>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const linear_congruential_engine<UIntType_, a_, c_, m_>& lhs,
|
||||
const linear_congruential_engine<UIntType_, a_, c_, m_>& rhs);
|
||||
|
||||
/*! This function streams a linear_congruential_engine to a \p std::basic_ostream.
|
||||
* \param os The \p basic_ostream to stream out to.
|
||||
* \param e The \p linear_congruential_engine to stream out.
|
||||
* \return \p os
|
||||
*/
|
||||
template <typename UIntType_, UIntType_ a_, UIntType_ c_, UIntType_ m_, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const linear_congruential_engine<UIntType_, a_, c_, m_>& e);
|
||||
|
||||
/*! This function streams a linear_congruential_engine in from a std::basic_istream.
|
||||
* \param is The \p basic_istream to stream from.
|
||||
* \param e The \p linear_congruential_engine to stream in.
|
||||
* \return \p is
|
||||
*/
|
||||
template <typename UIntType_, UIntType_ a_, UIntType_ c_, UIntType_ m_, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, linear_congruential_engine<UIntType_, a_, c_, m_>& e);
|
||||
|
||||
/*! \} // random_number_engine_templates
|
||||
*/
|
||||
|
||||
/*! \addtogroup predefined_random
|
||||
* \{
|
||||
*/
|
||||
|
||||
// XXX the type N2111 used here was uint_fast32_t
|
||||
|
||||
/*! \typedef minstd_rand0
|
||||
* \brief A random number engine with predefined parameters which implements a version of
|
||||
* the Minimal Standard random number generation algorithm.
|
||||
* \note The 10000th consecutive invocation of a default-constructed object of type \p minstd_rand0
|
||||
* shall produce the value \c 1043618065 .
|
||||
*/
|
||||
using minstd_rand0 = linear_congruential_engine<std::uint32_t, 16807, 0, 2147483647>;
|
||||
|
||||
/*! \typedef minstd_rand
|
||||
* \brief A random number engine with predefined parameters which implements a version of
|
||||
* the Minimal Standard random number generation algorithm.
|
||||
* \note The 10000th consecutive invocation of a default-constructed object of type \p minstd_rand
|
||||
* shall produce the value \c 399268537 .
|
||||
*/
|
||||
using minstd_rand = linear_congruential_engine<std::uint32_t, 48271, 0, 2147483647>;
|
||||
|
||||
/*! \} // predefined_random
|
||||
*/
|
||||
} // namespace random
|
||||
|
||||
// import names into thrust::
|
||||
using random::linear_congruential_engine;
|
||||
using random::minstd_rand;
|
||||
using random::minstd_rand0;
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
|
||||
#include <thrust/random/detail/linear_congruential_engine.inl>
|
||||
@@ -0,0 +1,202 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! \file linear_feedback_shift_engine.h
|
||||
* \brief A linear feedback shift pseudorandom number generator.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright Jens Maurer 2002
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying NOTICE file for the complete license)
|
||||
*
|
||||
* For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
#include <thrust/random/detail/linear_feedback_shift_engine_wordmask.h>
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
|
||||
#include <cuda/std/__host_stdlib/istream>
|
||||
#include <cuda/std/__host_stdlib/ostream>
|
||||
#include <cuda/std/cstddef> // for size_t
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
/*! \addtogroup random_number_engine_templates
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! \class linear_feedback_shift_engine
|
||||
* \brief A \p linear_feedback_shift_engine random number engine produces
|
||||
* unsigned integer random values using a linear feedback shift random number
|
||||
* generation algorithm.
|
||||
*
|
||||
* \tparam UIntType The type of unsigned integer to produce.
|
||||
* \tparam w The word size of the produced values (<tt>w <= sizeof(UIntType)</tt>).
|
||||
* \tparam k The k parameter of Tausworthe's 1965 algorithm.
|
||||
* \tparam q The q exponent of Tausworthe's 1965 algorithm.
|
||||
* \tparam s The step size of Tausworthe's 1965 algorithm.
|
||||
*
|
||||
* \note linear_feedback_shift_engine is based on the Boost Template Library's linear_feedback_shift.
|
||||
*/
|
||||
template <typename UIntType, size_t w, size_t k, size_t q, size_t s>
|
||||
class linear_feedback_shift_engine
|
||||
{
|
||||
public:
|
||||
// types
|
||||
|
||||
/*! \typedef result_type
|
||||
* \brief The type of the unsigned integer produced by this \p linear_feedback_shift_engine.
|
||||
*/
|
||||
using result_type = UIntType;
|
||||
|
||||
// engine characteristics
|
||||
|
||||
/*! The word size of the produced values.
|
||||
*/
|
||||
static const size_t word_size = w;
|
||||
|
||||
/*! A constant used in the generation algorithm.
|
||||
*/
|
||||
static const size_t exponent1 = k;
|
||||
|
||||
/*! A constant used in the generation algorithm.
|
||||
*/
|
||||
static const size_t exponent2 = q;
|
||||
|
||||
/*! The step size used in the generation algorithm.
|
||||
*/
|
||||
static const size_t step_size = s;
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
static const result_type wordmask = detail::linear_feedback_shift_engine_wordmask<result_type, w>::value;
|
||||
/*! \endcond
|
||||
*/
|
||||
|
||||
public:
|
||||
/*! The smallest value this \p linear_feedback_shift_engine may potentially produce.
|
||||
*/
|
||||
static const result_type min = 0;
|
||||
|
||||
/*! The largest value this \p linear_feedback_shift_engine may potentially produce.
|
||||
*/
|
||||
static const result_type max = wordmask;
|
||||
|
||||
/*! The default seed of this \p linear_feedback_shift_engine.
|
||||
*/
|
||||
static const result_type default_seed = 341u;
|
||||
|
||||
// constructors and seeding functions
|
||||
|
||||
/*! This constructor, which optionally accepts a seed, initializes a new
|
||||
* \p linear_feedback_shift_engine.
|
||||
*
|
||||
* \param value The seed used to initialize this \p linear_feedback_shift_engine's state.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit linear_feedback_shift_engine(result_type value = default_seed);
|
||||
|
||||
/*! This method initializes this \p linear_feedback_shift_engine's state, and optionally accepts
|
||||
* a seed value.
|
||||
*
|
||||
* \param value The seed used to initializes this \p linear_feedback_shift_engine's state.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void seed(result_type value = default_seed);
|
||||
|
||||
// generating functions
|
||||
|
||||
/*! This member function produces a new random value and updates this \p linear_feedback_shift_engine's state.
|
||||
* \return A new random number.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type operator()();
|
||||
|
||||
/*! This member function advances this \p linear_feedback_shift_engine's state a given number of times
|
||||
* and discards the results.
|
||||
*
|
||||
* \param z The number of random values to discard.
|
||||
* \note This function is provided because an implementation may be able to accelerate it.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void discard(unsigned long long z);
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
result_type m_value;
|
||||
|
||||
friend struct thrust::random::detail::random_core_access;
|
||||
|
||||
_CCCL_HOST_DEVICE bool equal(const linear_feedback_shift_engine& rhs) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& stream_out(std::basic_ostream<CharT, Traits>& os) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& stream_in(std::basic_istream<CharT, Traits>& is);
|
||||
|
||||
/*! \endcond
|
||||
*/
|
||||
}; // end linear_feedback_shift_engine
|
||||
|
||||
/*! This function checks two \p linear_feedback_shift_engines for equality.
|
||||
* \param lhs The first \p linear_feedback_shift_engine to test.
|
||||
* \param rhs The second \p linear_feedback_shift_engine to test.
|
||||
* \return \c true if \p lhs is equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename UIntType_, size_t w_, size_t k_, size_t q_, size_t s_>
|
||||
_CCCL_HOST_DEVICE bool operator==(const linear_feedback_shift_engine<UIntType_, w_, k_, q_, s_>& lhs,
|
||||
const linear_feedback_shift_engine<UIntType_, w_, k_, q_, s_>& rhs);
|
||||
|
||||
/*! This function checks two \p linear_feedback_shift_engines for inequality.
|
||||
* \param lhs The first \p linear_feedback_shift_engine to test.
|
||||
* \param rhs The second \p linear_feedback_shift_engine to test.
|
||||
* \return \c true if \p lhs is not equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename UIntType_, size_t w_, size_t k_, size_t q_, size_t s_>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const linear_feedback_shift_engine<UIntType_, w_, k_, q_, s_>& lhs,
|
||||
const linear_feedback_shift_engine<UIntType_, w_, k_, q_, s_>& rhs);
|
||||
|
||||
/*! This function streams a linear_feedback_shift_engine to a \p std::basic_ostream.
|
||||
* \param os The \p basic_ostream to stream out to.
|
||||
* \param e The \p linear_feedback_shift_engine to stream out.
|
||||
* \return \p os
|
||||
*/
|
||||
template <typename UIntType_, size_t w_, size_t k_, size_t q_, size_t s_, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const linear_feedback_shift_engine<UIntType_, w_, k_, q_, s_>& e);
|
||||
|
||||
/*! This function streams a linear_feedback_shift_engine in from a std::basic_istream.
|
||||
* \param is The \p basic_istream to stream from.
|
||||
* \param e The \p linear_feedback_shift_engine to stream in.
|
||||
* \return \p is
|
||||
*/
|
||||
template <typename UIntType_, size_t w_, size_t k_, size_t q_, size_t s_, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, linear_feedback_shift_engine<UIntType_, w_, k_, q_, s_>& e);
|
||||
|
||||
/*! \} // end random_number_engine_templates
|
||||
*/
|
||||
} // namespace random
|
||||
|
||||
// import names into thrust::
|
||||
using random::linear_feedback_shift_engine;
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
|
||||
#include <thrust/random/detail/linear_feedback_shift_engine.inl>
|
||||
243
cccl_upstream/thrust/thrust/random/normal_distribution.h
Normal file
243
cccl_upstream/thrust/thrust/random/normal_distribution.h
Normal file
@@ -0,0 +1,243 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! \file normal_distribution.h
|
||||
* \brief A normal (Gaussian) distribution of real-valued numbers.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
#include <thrust/random/detail/normal_distribution_base.h>
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
|
||||
#include <cuda/std/__host_stdlib/istream>
|
||||
#include <cuda/std/__host_stdlib/ostream>
|
||||
#include <cuda/std/__utility/pair.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
/*! \addtogroup random_number_distributions
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! \class normal_distribution
|
||||
* \brief A \p normal_distribution random number distribution produces floating point
|
||||
* Normally distributed random numbers.
|
||||
*
|
||||
* \tparam RealType The type of floating point number to produce.
|
||||
*
|
||||
* The following code snippet demonstrates examples of using a \p normal_distribution with a
|
||||
* random number engine to produce random values drawn from the Normal distribution with a given
|
||||
* mean and variance:
|
||||
*
|
||||
* \code
|
||||
* #include <thrust/random/linear_congruential_engine.h>
|
||||
* #include <thrust/random/normal_distribution.h>
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* // create a minstd_rand object to act as our source of randomness
|
||||
* thrust::minstd_rand rng;
|
||||
*
|
||||
* // create a normal_distribution to produce floats from the Normal distribution
|
||||
* // with mean 2.0 and standard deviation 3.5
|
||||
* thrust::random::normal_distribution<float> dist(2.0f, 3.5f);
|
||||
*
|
||||
* // write a random number to standard output
|
||||
* std::cout << dist(rng) << '\n';
|
||||
*
|
||||
* // write the mean of the distribution, just in case we forgot
|
||||
* std::cout << dist.mean() << '\n';
|
||||
*
|
||||
* // 2.0 is printed
|
||||
*
|
||||
* // and the standard deviation
|
||||
* std::cout << dist.stddev() << '\n';
|
||||
*
|
||||
* // 3.5 is printed
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
template <typename RealType = double>
|
||||
class normal_distribution : public detail::normal_distribution_base<RealType>::type
|
||||
{
|
||||
private:
|
||||
using super_t = typename detail::normal_distribution_base<RealType>::type;
|
||||
|
||||
public:
|
||||
// types
|
||||
|
||||
/*! \typedef result_type
|
||||
* \brief The type of the floating point number produced by this \p normal_distribution.
|
||||
*/
|
||||
using result_type = RealType;
|
||||
|
||||
/*! \typedef param_type
|
||||
* \brief The type of the object encapsulating this \p normal_distribution's parameters.
|
||||
*/
|
||||
using param_type = ::cuda::std::pair<RealType, RealType>;
|
||||
|
||||
// constructors and reset functions
|
||||
|
||||
/*! This constructor creates a new \p normal_distribution from two values defining the
|
||||
* half-open interval of the distribution.
|
||||
*
|
||||
* \param mean The mean (expected value) of the distribution. Defaults to \c 0.0.
|
||||
* \param stddev The standard deviation of the distribution. Defaults to \c 1.0.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0);
|
||||
|
||||
/*! This constructor creates a new \p normal_distribution from a \p param_type object
|
||||
* encapsulating the range of the distribution.
|
||||
*
|
||||
* \param parm A \p param_type object encapsulating the parameters (i.e., the mean and standard deviation) of the
|
||||
* distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit normal_distribution(const param_type& parm);
|
||||
|
||||
/*! Calling this member function guarantees that subsequent uses of this
|
||||
* \p normal_distribution do not depend on values produced by any random
|
||||
* number generator prior to invoking this function.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void reset();
|
||||
|
||||
// generating functions
|
||||
|
||||
/*! This method produces a new Normal random integer drawn from this \p normal_distribution's
|
||||
* range using a \p UniformRandomNumberGenerator as a source of randomness.
|
||||
*
|
||||
* \param urng The \p UniformRandomNumberGenerator to use as a source of randomness.
|
||||
*/
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE result_type operator()(UniformRandomNumberGenerator& urng);
|
||||
|
||||
/*! This method produces a new Normal random integer as if by creating a new \p normal_distribution
|
||||
* from the given \p param_type object, and calling its <tt>operator()</tt> method with the given
|
||||
* \p UniformRandomNumberGenerator as a source of randomness.
|
||||
*
|
||||
* \param urng The \p UniformRandomNumberGenerator to use as a source of randomness.
|
||||
* \param parm A \p param_type object encapsulating the parameters of the \p normal_distribution
|
||||
* to draw from.
|
||||
*/
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE result_type operator()(UniformRandomNumberGenerator& urng, const param_type& parm);
|
||||
|
||||
// property functions
|
||||
|
||||
/*! This method returns the value of the parameter with which this \p normal_distribution
|
||||
* was constructed.
|
||||
*
|
||||
* \return The mean (expected value) of this \p normal_distribution's output.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type mean() const;
|
||||
|
||||
/*! This method returns the value of the parameter with which this \p normal_distribution
|
||||
* was constructed.
|
||||
*
|
||||
* \return The standard deviation of this \p uniform_real_distribution's output.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type stddev() const;
|
||||
|
||||
/*! This method returns a \p param_type object encapsulating the parameters with which this
|
||||
* \p normal_distribution was constructed.
|
||||
*
|
||||
* \return A \p param_type object encapsulating the parameters (i.e., the mean and standard deviation) of this \p
|
||||
* normal_distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE param_type param() const;
|
||||
|
||||
/*! This method changes the parameters of this \p normal_distribution using the values encapsulated
|
||||
* in a given \p param_type object.
|
||||
*
|
||||
* \param parm A \p param_type object encapsulating the new parameters (i.e., the mean and variance) of this \p
|
||||
* normal_distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void param(const param_type& parm);
|
||||
|
||||
/*! This method returns the smallest floating point number this \p normal_distribution can potentially produce.
|
||||
*
|
||||
* \return The lower bound of this \p normal_distribution's half-open interval.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type min THRUST_PREVENT_MACRO_SUBSTITUTION() const;
|
||||
|
||||
/*! This method returns the smallest number larger than largest floating point number this \p
|
||||
* uniform_real_distribution can potentially produce.
|
||||
*
|
||||
* \return The upper bound of this \p normal_distribution's half-open interval.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type max THRUST_PREVENT_MACRO_SUBSTITUTION() const;
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
param_type m_param;
|
||||
|
||||
friend struct thrust::random::detail::random_core_access;
|
||||
|
||||
_CCCL_HOST_DEVICE bool equal(const normal_distribution& rhs) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& stream_out(std::basic_ostream<CharT, Traits>& os) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& stream_in(std::basic_istream<CharT, Traits>& is);
|
||||
/*! \endcond
|
||||
*/
|
||||
}; // end normal_distribution
|
||||
|
||||
/*! This function checks two \p normal_distributions for equality.
|
||||
* \param lhs The first \p normal_distribution to test.
|
||||
* \param rhs The second \p normal_distribution to test.
|
||||
* \return \c true if \p lhs is equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool operator==(const normal_distribution<RealType>& lhs, const normal_distribution<RealType>& rhs);
|
||||
|
||||
/*! This function checks two \p normal_distributions for inequality.
|
||||
* \param lhs The first \p normal_distribution to test.
|
||||
* \param rhs The second \p normal_distribution to test.
|
||||
* \return \c true if \p lhs is not equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const normal_distribution<RealType>& lhs, const normal_distribution<RealType>& rhs);
|
||||
|
||||
/*! This function streams a normal_distribution to a \p std::basic_ostream.
|
||||
* \param os The \p basic_ostream to stream out to.
|
||||
* \param d The \p normal_distribution to stream out.
|
||||
* \return \p os
|
||||
*/
|
||||
template <typename RealType, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const normal_distribution<RealType>& d);
|
||||
|
||||
/*! This function streams a normal_distribution in from a std::basic_istream.
|
||||
* \param is The \p basic_istream to stream from.
|
||||
* \param d The \p normal_distribution to stream in.
|
||||
* \return \p is
|
||||
*/
|
||||
template <typename RealType, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& is, normal_distribution<RealType>& d);
|
||||
|
||||
/*! \} // end random_number_distributions
|
||||
*/
|
||||
} // namespace random
|
||||
|
||||
using random::normal_distribution;
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
|
||||
#include <thrust/random/detail/normal_distribution.inl>
|
||||
232
cccl_upstream/thrust/thrust/random/subtract_with_carry_engine.h
Normal file
232
cccl_upstream/thrust/thrust/random/subtract_with_carry_engine.h
Normal file
@@ -0,0 +1,232 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! \file subtract_with_carry_engine.h
|
||||
* \brief A subtract-with-carry pseudorandom number generator
|
||||
* based on Marsaglia & Zaman.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
|
||||
#include <cuda/std/__host_stdlib/istream>
|
||||
#include <cuda/std/__host_stdlib/ostream>
|
||||
#include <cuda/std/cstddef> // for size_t
|
||||
#include <cuda/std/cstdint>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
/*! \addtogroup random_number_engine_templates
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! \class subtract_with_carry_engine
|
||||
* \brief A \p subtract_with_carry_engine random number engine produces unsigned
|
||||
* integer random numbers using the subtract with carry algorithm of Marsaglia & Zaman.
|
||||
*
|
||||
* The generation algorithm is performed as follows:
|
||||
* -# Let <tt>Y = X_{i-s}- X_{i-r} - c</tt>.
|
||||
* -# Set <tt>X_i</tt> to <tt>y = T mod m</tt>. Set \c c to \c 1 if <tt>Y < 0</tt>, otherwise set \c c to \c 0.
|
||||
*
|
||||
* This algorithm corresponds to a modular linear function of the form
|
||||
*
|
||||
* <tt>TA(x_i) = (a * x_i) mod b</tt>, where \c b is of the form <tt>m^r - m^s + 1</tt> and
|
||||
* <tt>a = b - (b-1)/m</tt>.
|
||||
*
|
||||
* \tparam UIntType The type of unsigned integer to produce.
|
||||
* \tparam w The word size of the produced values (<tt> w <= sizeof(UIntType)</tt>).
|
||||
* \tparam s The short lag of the generation algorithm.
|
||||
* \tparam r The long lag of the generation algorithm.
|
||||
*
|
||||
* \note Inexperienced users should not use this class template directly. Instead, use
|
||||
* \p ranlux24_base or \p ranlux48_base, which are instances of \p subtract_with_carry_engine.
|
||||
*
|
||||
* \see thrust::random::ranlux24_base
|
||||
* \see thrust::random::ranlux48_base
|
||||
*/
|
||||
template <typename UIntType, size_t w, size_t s, size_t r>
|
||||
class subtract_with_carry_engine
|
||||
{
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
static const UIntType modulus = UIntType(1) << w;
|
||||
/*! \endcond
|
||||
*/
|
||||
|
||||
public:
|
||||
// types
|
||||
|
||||
/*! \typedef result_type
|
||||
* \brief The type of the unsigned integer produced by this \p subtract_with_carry_engine.
|
||||
*/
|
||||
using result_type = UIntType;
|
||||
|
||||
// engine characteristics
|
||||
|
||||
/*! The word size of the produced values.
|
||||
*/
|
||||
static const size_t word_size = w;
|
||||
|
||||
/*! The size of the short lag used in the generation algorithm.
|
||||
*/
|
||||
static const size_t short_lag = s;
|
||||
|
||||
/*! The size of the long lag used in the generation algorithm.
|
||||
*/
|
||||
static const size_t long_lag = r;
|
||||
|
||||
/*! The smallest value this \p subtract_with_carry_engine may potentially produce.
|
||||
*/
|
||||
static const result_type min = 0;
|
||||
|
||||
/*! The largest value this \p subtract_with_carry_engine may potentially produce.
|
||||
*/
|
||||
static const result_type max = modulus - 1;
|
||||
|
||||
/*! The default seed of this \p subtract_with_carry_engine.
|
||||
*/
|
||||
static const result_type default_seed = 19780503u;
|
||||
|
||||
// constructors and seeding functions
|
||||
|
||||
/*! This constructor, which optionally accepts a seed, initializes a new
|
||||
* \p subtract_with_carry_engine.
|
||||
*
|
||||
* \param value The seed used to initialize this \p subtract_with_carry_engine's state.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit subtract_with_carry_engine(result_type value = default_seed);
|
||||
|
||||
/*! This method initializes this \p subtract_with_carry_engine's state, and optionally accepts
|
||||
* a seed value.
|
||||
*
|
||||
* \param value The seed used to initializes this \p subtract_with_carry_engine's state.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void seed(result_type value = default_seed);
|
||||
|
||||
// generating functions
|
||||
|
||||
/*! This member function produces a new random value and updates this \p subtract_with_carry_engine's state.
|
||||
* \return A new random number.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type operator()();
|
||||
|
||||
/*! This member function advances this \p subtract_with_carry_engine's state a given number of times
|
||||
* and discards the results.
|
||||
*
|
||||
* \param z The number of random values to discard.
|
||||
* \note This function is provided because an implementation may be able to accelerate it.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void discard(unsigned long long z);
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
result_type m_x[long_lag];
|
||||
unsigned int m_k;
|
||||
int m_carry;
|
||||
|
||||
friend struct thrust::random::detail::random_core_access;
|
||||
|
||||
_CCCL_HOST_DEVICE bool equal(const subtract_with_carry_engine& rhs) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& stream_out(std::basic_ostream<CharT, Traits>& os) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& stream_in(std::basic_istream<CharT, Traits>& is);
|
||||
|
||||
/*! \endcond
|
||||
*/
|
||||
}; // end subtract_with_carry_engine
|
||||
|
||||
/*! This function checks two \p subtract_with_carry_engines for equality.
|
||||
* \param lhs The first \p subtract_with_carry_engine to test.
|
||||
* \param rhs The second \p subtract_with_carry_engine to test.
|
||||
* \return \c true if \p lhs is equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename UIntType_, size_t w_, size_t s_, size_t r_>
|
||||
_CCCL_HOST_DEVICE bool operator==(const subtract_with_carry_engine<UIntType_, w_, s_, r_>& lhs,
|
||||
const subtract_with_carry_engine<UIntType_, w_, s_, r_>& rhs);
|
||||
|
||||
/*! This function checks two \p subtract_with_carry_engines for inequality.
|
||||
* \param lhs The first \p subtract_with_carry_engine to test.
|
||||
* \param rhs The second \p subtract_with_carry_engine to test.
|
||||
* \return \c true if \p lhs is not equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename UIntType_, size_t w_, size_t s_, size_t r_>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const subtract_with_carry_engine<UIntType_, w_, s_, r_>& lhs,
|
||||
const subtract_with_carry_engine<UIntType_, w_, s_, r_>& rhs);
|
||||
|
||||
/*! This function streams a subtract_with_carry_engine to a \p std::basic_ostream.
|
||||
* \param os The \p basic_ostream to stream out to.
|
||||
* \param e The \p subtract_with_carry_engine to stream out.
|
||||
* \return \p os
|
||||
*/
|
||||
template <typename UIntType_, size_t w_, size_t s_, size_t r_, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const subtract_with_carry_engine<UIntType_, w_, s_, r_>& e);
|
||||
|
||||
/*! This function streams a subtract_with_carry_engine in from a std::basic_istream.
|
||||
* \param is The \p basic_istream to stream from.
|
||||
* \param e The \p subtract_with_carry_engine to stream in.
|
||||
* \return \p is
|
||||
*/
|
||||
template <typename UIntType_, size_t w_, size_t s_, size_t r_, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, subtract_with_carry_engine<UIntType_, w_, s_, r_>& e);
|
||||
|
||||
/*! \} // end random_number_engine_templates
|
||||
*/
|
||||
|
||||
/*! \addtogroup predefined_random
|
||||
* \{
|
||||
*/
|
||||
|
||||
// XXX N2111 uses uint_fast32_t here
|
||||
|
||||
/*! \typedef ranlux24_base
|
||||
* \brief A random number engine with predefined parameters which implements the
|
||||
* base engine of the \p ranlux24 random number engine.
|
||||
* \note The 10000th consecutive invocation of a default-constructed object of type \p ranlux24_base
|
||||
* shall produce the value \c 7937952 .
|
||||
*/
|
||||
using ranlux24_base = subtract_with_carry_engine<std::uint32_t, 24, 10, 24>;
|
||||
|
||||
// XXX N2111 uses uint_fast64_t here
|
||||
|
||||
/*! \typedef ranlux48_base
|
||||
* \brief A random number engine with predefined parameters which implements the
|
||||
* base engine of the \p ranlux48 random number engine.
|
||||
* \note The 10000th consecutive invocation of a default-constructed object of type \p ranlux48_base
|
||||
* shall produce the value \c 192113843633948 .
|
||||
*/
|
||||
using ranlux48_base = subtract_with_carry_engine<std::uint64_t, 48, 5, 12>;
|
||||
|
||||
/*! \} // end predefined_random
|
||||
*/
|
||||
} // namespace random
|
||||
|
||||
// import names into thrust::
|
||||
using random::ranlux24_base;
|
||||
using random::ranlux48_base;
|
||||
using random::subtract_with_carry_engine;
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
|
||||
#include <thrust/random/detail/subtract_with_carry_engine.inl>
|
||||
246
cccl_upstream/thrust/thrust/random/uniform_int_distribution.h
Normal file
246
cccl_upstream/thrust/thrust/random/uniform_int_distribution.h
Normal file
@@ -0,0 +1,246 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! \file uniform_int_distribution.h
|
||||
* \brief A uniform distribution of integer-valued numbers
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
|
||||
#include <cuda/std/__host_stdlib/istream>
|
||||
#include <cuda/std/__host_stdlib/ostream>
|
||||
#include <cuda/std/__utility/pair.h>
|
||||
#include <cuda/std/limits>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
/*! \addtogroup random_number_distributions Random Number Distributions Class Templates
|
||||
* \ingroup random
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! \class uniform_int_distribution
|
||||
* \brief A \p uniform_int_distribution random number distribution produces signed or unsigned integer
|
||||
* uniform random numbers from a given range.
|
||||
*
|
||||
* \tparam IntType The type of integer to produce.
|
||||
*
|
||||
* The following code snippet demonstrates examples of using a \p uniform_int_distribution with a
|
||||
* random number engine to produce random integers drawn from a given range:
|
||||
*
|
||||
* \code
|
||||
* #include <thrust/random/linear_congruential_engine.h>
|
||||
* #include <thrust/random/uniform_int_distribution.h>
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* // create a minstd_rand object to act as our source of randomness
|
||||
* thrust::minstd_rand rng;
|
||||
*
|
||||
* // create a uniform_int_distribution to produce ints from [-7,13]
|
||||
* thrust::uniform_int_distribution<int> dist(-7,13);
|
||||
*
|
||||
* // write a random number from the range [-7,13] to standard output
|
||||
* std::cout << dist(rng) << '\n';
|
||||
*
|
||||
* // write the range of the distribution, just in case we forgot
|
||||
* std::cout << dist.min() << '\n';
|
||||
*
|
||||
* // -7 is printed
|
||||
*
|
||||
* std::cout << dist.max() << '\n';
|
||||
*
|
||||
* // 13 is printed
|
||||
*
|
||||
* // write the parameters of the distribution (which happen to be the bounds) to standard output
|
||||
* std::cout << dist.a() << '\n';
|
||||
*
|
||||
* // -7 is printed
|
||||
*
|
||||
* std::cout << dist.b() << '\n';
|
||||
*
|
||||
* // 13 is printed
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
template <typename IntType = int>
|
||||
class uniform_int_distribution
|
||||
{
|
||||
public:
|
||||
// types
|
||||
|
||||
/*! \typedef result_type
|
||||
* \brief The type of the integer produced by this \p uniform_int_distribution.
|
||||
*/
|
||||
using result_type = IntType;
|
||||
|
||||
/*! \typedef param_type
|
||||
* \brief The type of the object encapsulating this \p uniform_int_distribution's parameters.
|
||||
*/
|
||||
using param_type = ::cuda::std::pair<IntType, IntType>;
|
||||
|
||||
// constructors and reset functions
|
||||
|
||||
/*! This constructor creates a new \p uniform_int_distribution from two values defining the
|
||||
* range of the distribution.
|
||||
*
|
||||
* \param a The smallest integer to potentially produce. Defaults to \c 0.
|
||||
* \param b The largest integer to potentially produce. Defaults to the largest representable integer in
|
||||
* the platform.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit uniform_int_distribution(
|
||||
IntType a = 0, IntType b = ::cuda::std::numeric_limits<IntType>::max());
|
||||
|
||||
/*! This constructor creates a new \p uniform_int_distribution from a \p param_type object
|
||||
* encapsulating the range of the distribution.
|
||||
*
|
||||
* \param parm A \p param_type object encapsulating the parameters (i.e., the range) of the distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit uniform_int_distribution(const param_type& parm);
|
||||
|
||||
/*! This does nothing. It is included to conform to the requirements of the RandomDistribution concept.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void reset();
|
||||
|
||||
// generating functions
|
||||
|
||||
/*! This method produces a new uniform random integer drawn from this \p uniform_int_distribution's
|
||||
* range using a \p UniformRandomNumberGenerator as a source of randomness.
|
||||
*
|
||||
* \param urng The \p UniformRandomNumberGenerator to use as a source of randomness.
|
||||
*/
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE result_type operator()(UniformRandomNumberGenerator& urng);
|
||||
|
||||
/*! This method produces a new uniform random integer as if by creating a new \p uniform_int_distribution
|
||||
* from the given \p param_type object, and calling its <tt>operator()</tt> method with the given
|
||||
* \p UniformRandomNumberGenerator as a source of randomness.
|
||||
*
|
||||
* \param urng The \p UniformRandomNumberGenerator to use as a source of randomness.
|
||||
* \param parm A \p param_type object encapsulating the parameters of the \p uniform_int_distribution
|
||||
* to draw from.
|
||||
*/
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE result_type operator()(UniformRandomNumberGenerator& urng, const param_type& parm);
|
||||
|
||||
// property functions
|
||||
|
||||
/*! This method returns the value of the parameter with which this \p uniform_int_distribution
|
||||
* was constructed.
|
||||
*
|
||||
* \return The lower bound of this \p uniform_int_distribution's range.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type a() const;
|
||||
|
||||
/*! This method returns the value of the parameter with which this \p uniform_int_distribution
|
||||
* was constructed.
|
||||
*
|
||||
* \return The upper bound of this \p uniform_int_distribution's range.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type b() const;
|
||||
|
||||
/*! This method returns a \p param_type object encapsulating the parameters with which this
|
||||
* \p uniform_int_distribution was constructed.
|
||||
*
|
||||
* \return A \p param_type object enapsulating the range of this \p uniform_int_distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE param_type param() const;
|
||||
|
||||
/*! This method changes the parameters of this \p uniform_int_distribution using the values encapsulated
|
||||
* in a given \p param_type object.
|
||||
*
|
||||
* \param parm A \p param_type object encapsulating the new range of this \p uniform_int_distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void param(const param_type& parm);
|
||||
|
||||
/*! This method returns the smallest integer this \p uniform_int_distribution can potentially produce.
|
||||
*
|
||||
* \return The lower bound of this \p uniform_int_distribution's range.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type min THRUST_PREVENT_MACRO_SUBSTITUTION() const;
|
||||
|
||||
/*! This method returns the largest integer this \p uniform_int_distribution can potentially produce.
|
||||
*
|
||||
* \return The upper bound of this \p uniform_int_distribution's range.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type max THRUST_PREVENT_MACRO_SUBSTITUTION() const;
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
param_type m_param;
|
||||
|
||||
friend struct thrust::random::detail::random_core_access;
|
||||
|
||||
_CCCL_HOST_DEVICE bool equal(const uniform_int_distribution& rhs) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& stream_out(std::basic_ostream<CharT, Traits>& os) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& stream_in(std::basic_istream<CharT, Traits>& is);
|
||||
/*! \endcond
|
||||
*/
|
||||
}; // end uniform_int_distribution
|
||||
|
||||
/*! This function checks two \p uniform_int_distributions for equality.
|
||||
* \param lhs The first \p uniform_int_distribution to test.
|
||||
* \param rhs The second \p uniform_int_distribution to test.
|
||||
* \return \c true if \p lhs is equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator==(const uniform_int_distribution<IntType>& lhs, const uniform_int_distribution<IntType>& rhs);
|
||||
|
||||
/*! This function checks two \p uniform_int_distributions for inequality.
|
||||
* \param lhs The first \p uniform_int_distribution to test.
|
||||
* \param rhs The second \p uniform_int_distribution to test.
|
||||
* \return \c true if \p lhs is not equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename IntType>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator!=(const uniform_int_distribution<IntType>& lhs, const uniform_int_distribution<IntType>& rhs);
|
||||
|
||||
/*! This function streams a uniform_int_distribution to a \p std::basic_ostream.
|
||||
* \param os The \p basic_ostream to stream out to.
|
||||
* \param d The \p uniform_int_distribution to stream out.
|
||||
* \return \p os
|
||||
*/
|
||||
template <typename IntType, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const uniform_int_distribution<IntType>& d);
|
||||
|
||||
/*! This function streams a uniform_int_distribution in from a std::basic_istream.
|
||||
* \param is The \p basic_istream to stream from.
|
||||
* \param d The \p uniform_int_distribution to stream in.
|
||||
* \return \p is
|
||||
*/
|
||||
template <typename IntType, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, uniform_int_distribution<IntType>& d);
|
||||
|
||||
/*! \} // end random_number_distributions
|
||||
*/
|
||||
} // namespace random
|
||||
|
||||
using random::uniform_int_distribution;
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
|
||||
#include <thrust/random/detail/uniform_int_distribution.inl>
|
||||
244
cccl_upstream/thrust/thrust/random/uniform_real_distribution.h
Normal file
244
cccl_upstream/thrust/thrust/random/uniform_real_distribution.h
Normal file
@@ -0,0 +1,244 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! \file uniform_real_distribution.h
|
||||
* \brief A uniform distribution of real-valued numbers
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
|
||||
#include <cuda/std/__host_stdlib/istream>
|
||||
#include <cuda/std/__host_stdlib/ostream>
|
||||
#include <cuda/std/__utility/pair.h>
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
/*! \addtogroup random_number_distributions
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! \class uniform_real_distribution
|
||||
* \brief A \p uniform_real_distribution random number distribution produces floating point
|
||||
* uniform random numbers from a half-open interval.
|
||||
*
|
||||
* \tparam RealType The type of floating point number to produce.
|
||||
*
|
||||
* The following code snippet demonstrates examples of using a \p uniform_real_distribution with a
|
||||
* random number engine to produce random integers drawn from a given range:
|
||||
*
|
||||
* \code
|
||||
* #include <thrust/random/linear_congruential_engine.h>
|
||||
* #include <thrust/random/uniform_real_distribution.h>
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* // create a minstd_rand object to act as our source of randomness
|
||||
* thrust::minstd_rand rng;
|
||||
*
|
||||
* // create a uniform_real_distribution to produce floats from [-7,13)
|
||||
* thrust::uniform_real_distribution<float> dist(-7,13);
|
||||
*
|
||||
* // write a random number from the range [-7,13) to standard output
|
||||
* std::cout << dist(rng) << '\n';
|
||||
*
|
||||
* // write the range of the distribution, just in case we forgot
|
||||
* std::cout << dist.min() << '\n';
|
||||
*
|
||||
* // -7.0 is printed
|
||||
*
|
||||
* std::cout << dist.max() << '\n';
|
||||
*
|
||||
* // 13.0 is printed
|
||||
*
|
||||
* // write the parameters of the distribution (which happen to be the bounds) to standard output
|
||||
* std::cout << dist.a() << '\n';
|
||||
*
|
||||
* // -7.0 is printed
|
||||
*
|
||||
* std::cout << dist.b() << '\n';
|
||||
*
|
||||
* // 13.0 is printed
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
template <typename RealType = double>
|
||||
class uniform_real_distribution
|
||||
{
|
||||
public:
|
||||
// types
|
||||
|
||||
/*! \typedef result_type
|
||||
* \brief The type of the floating point number produced by this \p uniform_real_distribution.
|
||||
*/
|
||||
using result_type = RealType;
|
||||
|
||||
/*! \typedef param_type
|
||||
* \brief The type of the object encapsulating this \p uniform_real_distribution's parameters.
|
||||
*/
|
||||
using param_type = ::cuda::std::pair<RealType, RealType>;
|
||||
|
||||
// constructors and reset functions
|
||||
|
||||
/*! This constructor creates a new \p uniform_real_distribution from two values defining the
|
||||
* half-open interval of the distribution.
|
||||
*
|
||||
* \param a The smallest floating point number to potentially produce. Defaults to \c 0.0.
|
||||
* \param b The smallest number larger than the largest floating point number to potentially produce. Defaults to
|
||||
* \c 1.0.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);
|
||||
|
||||
/*! This constructor creates a new \p uniform_real_distribution from a \p param_type object
|
||||
* encapsulating the range of the distribution.
|
||||
*
|
||||
* \param parm A \p param_type object encapsulating the parameters (i.e., the range) of the distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE explicit uniform_real_distribution(const param_type& parm);
|
||||
|
||||
/*! This does nothing. It is included to conform to the requirements of the RandomDistribution concept.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void reset();
|
||||
|
||||
// generating functions
|
||||
|
||||
/*! This method produces a new uniform random integer drawn from this \p uniform_real_distribution's
|
||||
* range using a \p UniformRandomNumberGenerator as a source of randomness.
|
||||
*
|
||||
* \param urng The \p UniformRandomNumberGenerator to use as a source of randomness.
|
||||
*/
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE result_type operator()(UniformRandomNumberGenerator& urng);
|
||||
|
||||
/*! This method produces a new uniform random integer as if by creating a new \p uniform_real_distribution
|
||||
* from the given \p param_type object, and calling its <tt>operator()</tt> method with the given
|
||||
* \p UniformRandomNumberGenerator as a source of randomness.
|
||||
*
|
||||
* \param urng The \p UniformRandomNumberGenerator to use as a source of randomness.
|
||||
* \param parm A \p param_type object encapsulating the parameters of the \p uniform_real_distribution
|
||||
* to draw from.
|
||||
*/
|
||||
template <typename UniformRandomNumberGenerator>
|
||||
_CCCL_HOST_DEVICE result_type operator()(UniformRandomNumberGenerator& urng, const param_type& parm);
|
||||
|
||||
// property functions
|
||||
|
||||
/*! This method returns the value of the parameter with which this \p uniform_real_distribution
|
||||
* was constructed.
|
||||
*
|
||||
* \return The lower bound of this \p uniform_real_distribution's half-open interval.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type a() const;
|
||||
|
||||
/*! This method returns the value of the parameter with which this \p uniform_real_distribution
|
||||
* was constructed.
|
||||
*
|
||||
* \return The upper bound of this \p uniform_real_distribution's half-open interval.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type b() const;
|
||||
|
||||
/*! This method returns a \p param_type object encapsulating the parameters with which this
|
||||
* \p uniform_real_distribution was constructed.
|
||||
*
|
||||
* \return A \p param_type object enapsulating the half-open interval of this \p uniform_real_distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE param_type param() const;
|
||||
|
||||
/*! This method changes the parameters of this \p uniform_real_distribution using the values encapsulated
|
||||
* in a given \p param_type object.
|
||||
*
|
||||
* \param parm A \p param_type object encapsulating the new half-open interval of this \p uniform_real_distribution.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void param(const param_type& parm);
|
||||
|
||||
/*! This method returns the smallest floating point number this \p uniform_real_distribution can potentially produce.
|
||||
*
|
||||
* \return The lower bound of this \p uniform_real_distribution's half-open interval.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type min THRUST_PREVENT_MACRO_SUBSTITUTION() const;
|
||||
|
||||
/*! This method returns the smallest number larger than largest floating point number this \p
|
||||
* uniform_real_distribution can potentially produce.
|
||||
*
|
||||
* \return The upper bound of this \p uniform_real_distribution's half-open interval.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type max THRUST_PREVENT_MACRO_SUBSTITUTION() const;
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
param_type m_param;
|
||||
|
||||
friend struct thrust::random::detail::random_core_access;
|
||||
|
||||
_CCCL_HOST_DEVICE bool equal(const uniform_real_distribution& rhs) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& stream_out(std::basic_ostream<CharT, Traits>& os) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& stream_in(std::basic_istream<CharT, Traits>& is);
|
||||
/*! \endcond
|
||||
*/
|
||||
}; // end uniform_real_distribution
|
||||
|
||||
/*! This function checks two \p uniform_real_distributions for equality.
|
||||
* \param lhs The first \p uniform_real_distribution to test.
|
||||
* \param rhs The second \p uniform_real_distribution to test.
|
||||
* \return \c true if \p lhs is equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator==(const uniform_real_distribution<RealType>& lhs, const uniform_real_distribution<RealType>& rhs);
|
||||
|
||||
/*! This function checks two \p uniform_real_distributions for inequality.
|
||||
* \param lhs The first \p uniform_real_distribution to test.
|
||||
* \param rhs The second \p uniform_real_distribution to test.
|
||||
* \return \c true if \p lhs is not equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename RealType>
|
||||
_CCCL_HOST_DEVICE bool
|
||||
operator!=(const uniform_real_distribution<RealType>& lhs, const uniform_real_distribution<RealType>& rhs);
|
||||
|
||||
/*! This function streams a uniform_real_distribution to a \p std::basic_ostream.
|
||||
* \param os The \p basic_ostream to stream out to.
|
||||
* \param d The \p uniform_real_distribution to stream out.
|
||||
* \return \p os
|
||||
*/
|
||||
template <typename RealType, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const uniform_real_distribution<RealType>& d);
|
||||
|
||||
/*! This function streams a uniform_real_distribution in from a std::basic_istream.
|
||||
* \param is The \p basic_istream to stream from.
|
||||
* \param d The \p uniform_real_distribution to stream in.
|
||||
* \return \p is
|
||||
*/
|
||||
template <typename RealType, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, uniform_real_distribution<RealType>& d);
|
||||
|
||||
/*! \} // end random_number_distributions
|
||||
*/
|
||||
} // namespace random
|
||||
|
||||
using random::uniform_real_distribution;
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
|
||||
#include <thrust/random/detail/uniform_real_distribution.inl>
|
||||
240
cccl_upstream/thrust/thrust/random/xor_combine_engine.h
Normal file
240
cccl_upstream/thrust/thrust/random/xor_combine_engine.h
Normal file
@@ -0,0 +1,240 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2008-2013, NVIDIA Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/*! \file xor_combine_engine.h
|
||||
* \brief A pseudorandom number generator which produces pseudorandom
|
||||
* numbers from two integer base engines by merging their
|
||||
* pseudorandom numbers with bitwise exclusive-or.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thrust/detail/config.h>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <thrust/detail/type_traits.h>
|
||||
#include <thrust/random/detail/random_core_access.h>
|
||||
#include <thrust/random/detail/xor_combine_engine_max.h>
|
||||
|
||||
#include <cuda/std/__host_stdlib/istream>
|
||||
#include <cuda/std/__host_stdlib/ostream>
|
||||
#include <cuda/std/__type_traits/type_identity.h>
|
||||
#include <cuda/std/cstddef> // for size_t
|
||||
|
||||
THRUST_NAMESPACE_BEGIN
|
||||
|
||||
namespace random
|
||||
{
|
||||
/*! \addtogroup random_number_engine_adaptors
|
||||
* \{
|
||||
*/
|
||||
|
||||
/*! \class xor_combine_engine
|
||||
* \brief An \p xor_combine_engine adapts two existing base random number engines and
|
||||
* produces random values by combining the values produced by each.
|
||||
*
|
||||
* \tparam Engine1 The type of the first base random number engine to adapt.
|
||||
* \tparam s1 The size of the first shift to use in the generation algorithm.
|
||||
* \tparam Engine2 The type of the second base random number engine to adapt.
|
||||
* \tparam s2 The second of the second shift to use in the generation algorithm. Defaults to \c 0.
|
||||
*
|
||||
* The following code snippet shows an example of using an \p xor_combine_engine instance:
|
||||
*
|
||||
* \code
|
||||
* #include <thrust/random/linear_congruential_engine.h>
|
||||
* #include <thrust/random/xor_combine_engine.h>
|
||||
* #include <iostream>
|
||||
*
|
||||
* int main()
|
||||
* {
|
||||
* // create an xor_combine_engine from minstd_rand and minstd_rand0
|
||||
* // use a shift of 0 for each
|
||||
* thrust::xor_combine_engine<thrust::minstd_rand,0,thrust::minstd_rand0,0> rng;
|
||||
*
|
||||
* // print a random number to standard output
|
||||
* std::cout << rng() << '\n';
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*/
|
||||
template <typename Engine1, size_t s1, typename Engine2, size_t s2 = 0u>
|
||||
class xor_combine_engine
|
||||
{
|
||||
public:
|
||||
// types
|
||||
|
||||
/*! \typedef base1_type
|
||||
* \brief The type of the first adapted base random number engine.
|
||||
*/
|
||||
using base1_type = Engine1;
|
||||
|
||||
/*! \typedef base2_type
|
||||
* \brief The type of the second adapted base random number engine.
|
||||
*/
|
||||
using base2_type = Engine2;
|
||||
|
||||
/*! \typedef result_type
|
||||
* \brief The type of the unsigned integer produced by this \p xor_combine_engine.
|
||||
*/
|
||||
using result_type = typename thrust::detail::eval_if<
|
||||
(sizeof(typename base2_type::result_type) > sizeof(typename base1_type::result_type)),
|
||||
::cuda::std::type_identity<typename base2_type::result_type>,
|
||||
::cuda::std::type_identity<typename base1_type::result_type>>::type;
|
||||
|
||||
/*! The size of the first shift used in the generation algorithm.
|
||||
*/
|
||||
static const size_t shift1 = s1;
|
||||
|
||||
/*! The size of the second shift used in the generation algorithm.
|
||||
*/
|
||||
static const size_t shift2 = s2;
|
||||
|
||||
/*! The smallest value this \p xor_combine_engine may potentially produce.
|
||||
*/
|
||||
static const result_type min = 0;
|
||||
|
||||
/*! The largest value this \p xor_combine_engine may potentially produce.
|
||||
*/
|
||||
static const result_type max = detail::xor_combine_engine_max<Engine1, s1, Engine2, s2, result_type>::value;
|
||||
|
||||
// constructors and seeding functions
|
||||
|
||||
/*! This constructor constructs a new \p xor_combine_engine and constructs
|
||||
* its adapted engines using their null constructors.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE xor_combine_engine();
|
||||
|
||||
/*! This constructor constructs a new \p xor_combine_engine using
|
||||
* given \p base1_type and \p base2_type engines to initialize its adapted base engines.
|
||||
*
|
||||
* \param urng1 A \p base1_type to use to initialize this \p xor_combine_engine's
|
||||
* first adapted base engine.
|
||||
* \param urng2 A \p base2_type to use to initialize this \p xor_combine_engine's
|
||||
* first adapted base engine.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE xor_combine_engine(const base1_type& urng1, const base2_type& urng2);
|
||||
|
||||
/*! This constructor initializes a new \p xor_combine_engine with a given seed.
|
||||
*
|
||||
* \param s The seed used to initialize this \p xor_combine_engine's adapted base engines.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE xor_combine_engine(result_type s);
|
||||
|
||||
/*! This method initializes the state of this \p xor_combine_engine's adapted base engines
|
||||
* by using their \p default_seed values.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void seed();
|
||||
|
||||
/*! This method initializes the state of this \p xor_combine_engine's adapted base engines
|
||||
* by using the given seed.
|
||||
*
|
||||
* \param s The seed with which to initialize this \p xor_combine_engine's adapted base engines.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void seed(result_type s);
|
||||
|
||||
// generating functions
|
||||
|
||||
/*! This member function produces a new random value and updates this \p xor_combine_engine's state.
|
||||
* \return A new random number.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE result_type operator()();
|
||||
|
||||
/*! This member function advances this \p xor_combine_engine's state a given number of times
|
||||
* and discards the results.
|
||||
*
|
||||
* \param z The number of random values to discard.
|
||||
* \note This function is provided because an implementation may be able to accelerate it.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE void discard(unsigned long long z);
|
||||
|
||||
// property functions
|
||||
|
||||
/*! This member function returns a const reference to this \p xor_combine_engine's
|
||||
* first adapted base engine.
|
||||
*
|
||||
* \return A const reference to the first base engine this \p xor_combine_engine adapts.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE const base1_type& base1() const;
|
||||
|
||||
/*! This member function returns a const reference to this \p xor_combine_engine's
|
||||
* second adapted base engine.
|
||||
*
|
||||
* \return A const reference to the second base engine this \p xor_combine_engine adapts.
|
||||
*/
|
||||
_CCCL_HOST_DEVICE const base2_type& base2() const;
|
||||
|
||||
/*! \cond
|
||||
*/
|
||||
|
||||
private:
|
||||
base1_type m_b1;
|
||||
base2_type m_b2;
|
||||
|
||||
friend struct thrust::random::detail::random_core_access;
|
||||
|
||||
_CCCL_HOST_DEVICE bool equal(const xor_combine_engine& rhs) const;
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>& stream_in(std::basic_istream<CharT, Traits>& is);
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>& stream_out(std::basic_ostream<CharT, Traits>& os) const;
|
||||
|
||||
/*! \endcond
|
||||
*/
|
||||
}; // end xor_combine_engine
|
||||
|
||||
/*! This function checks two \p xor_combine_engines for equality.
|
||||
* \param lhs The first \p xor_combine_engine to test.
|
||||
* \param rhs The second \p xor_combine_engine to test.
|
||||
* \return \c true if \p lhs is equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename Engine1_, size_t s1_, typename Engine2_, size_t s2_>
|
||||
_CCCL_HOST_DEVICE bool operator==(const xor_combine_engine<Engine1_, s1_, Engine2_, s2_>& lhs,
|
||||
const xor_combine_engine<Engine1_, s1_, Engine2_, s2_>& rhs);
|
||||
|
||||
/*! This function checks two \p xor_combine_engines for inequality.
|
||||
* \param lhs The first \p xor_combine_engine to test.
|
||||
* \param rhs The second \p xor_combine_engine to test.
|
||||
* \return \c true if \p lhs is not equal to \p rhs; \c false, otherwise.
|
||||
*/
|
||||
template <typename Engine1_, size_t s1_, typename Engine2_, size_t s2_>
|
||||
_CCCL_HOST_DEVICE bool operator!=(const xor_combine_engine<Engine1_, s1_, Engine2_, s2_>& lhs,
|
||||
const xor_combine_engine<Engine1_, s1_, Engine2_, s2_>& rhs);
|
||||
|
||||
/*! This function streams a xor_combine_engine to a \p std::basic_ostream.
|
||||
* \param os The \p basic_ostream to stream out to.
|
||||
* \param e The \p xor_combine_engine to stream out.
|
||||
* \return \p os
|
||||
*/
|
||||
template <typename Engine1_, size_t s1_, typename Engine2_, size_t s2_, typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
operator<<(std::basic_ostream<CharT, Traits>& os, const xor_combine_engine<Engine1_, s1_, Engine2_, s2_>& e);
|
||||
|
||||
/*! This function streams a xor_combine_engine in from a std::basic_istream.
|
||||
* \param is The \p basic_istream to stream from.
|
||||
* \param e The \p xor_combine_engine to stream in.
|
||||
* \return \p is
|
||||
*/
|
||||
template <typename Engine1_, size_t s1_, typename Engine2_, size_t s2_, typename CharT, typename Traits>
|
||||
std::basic_istream<CharT, Traits>&
|
||||
operator>>(std::basic_istream<CharT, Traits>& is, xor_combine_engine<Engine1_, s1_, Engine2_, s2_>& e);
|
||||
|
||||
/*! \} // end random_number_engine_adaptors
|
||||
*/
|
||||
} // namespace random
|
||||
|
||||
// import names into thrust::
|
||||
using random::xor_combine_engine;
|
||||
|
||||
THRUST_NAMESPACE_END
|
||||
|
||||
#include <thrust/random/detail/xor_combine_engine.inl>
|
||||
Reference in New Issue
Block a user