[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:
EngineX CI
2026-07-30 09:35:51 +00:00
parent b4d01f481e
commit 56fd68e7dd
8871 changed files with 1454674 additions and 0 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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

View 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

View File

@@ -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

View 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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View 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>

View 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>