Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

atomic: Add non-member functions for fetch_min and fetch_max #443

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 94 additions & 44 deletions src/stdgpu/atomic.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -283,54 +283,54 @@ public:
fetch_sub(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the bitwise AND of the stored value and the given argument
* \param[in] arg The other argument of bitwise AND
* \brief Atomically computes and stores the minimum of the stored value and the given argument
* \param[in] arg The other argument of minimum
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T> || std::is_floating_point_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_and(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_min(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the bitwise OR of the stored value and the given argument
* \param[in] arg The other argument of bitwise OR
* \brief Atomically computes and stores the maximum of the stored value and the given argument
* \param[in] arg The other argument of maximum
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T> || std::is_floating_point_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_or(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_max(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the bitwise XOR of the stored value and the given argument
* \param[in] arg The other argument of bitwise XOR
* \brief Atomically computes and stores the bitwise AND of the stored value and the given argument
* \param[in] arg The other argument of bitwise AND
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_xor(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_and(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the minimum of the stored value and the given argument
* \param[in] arg The other argument of minimum
* \brief Atomically computes and stores the bitwise OR of the stored value and the given argument
* \param[in] arg The other argument of bitwise OR
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T> || std::is_floating_point_v<T>)>
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_min(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_or(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the maximum of the stored value and the given argument
* \param[in] arg The other argument of maximum
* \brief Atomically computes and stores the bitwise XOR of the stored value and the given argument
* \param[in] arg The other argument of bitwise XOR
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T> || std::is_floating_point_v<T>)>
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_max(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_xor(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the incrementation of the value and modulus with arg
Expand Down Expand Up @@ -571,54 +571,54 @@ public:
fetch_sub(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the bitwise AND of the stored value and the given argument
* \param[in] arg The other argument of bitwise AND
* \brief Atomically computes and stores the minimum of the stored value and the given argument
* \param[in] arg The other argument of minimum
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T> || std::is_floating_point_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_and(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_min(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the bitwise OR of the stored value and the given argument
* \param[in] arg The other argument of bitwise OR
* \brief Atomically computes and stores the maximum of the stored value and the given argument
* \param[in] arg The other argument of maximum
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T> || std::is_floating_point_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_or(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_max(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the bitwise XOR of the stored value and the given argument
* \param[in] arg The other argument of bitwise XOR
* \brief Atomically computes and stores the bitwise AND of the stored value and the given argument
* \param[in] arg The other argument of bitwise AND
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_xor(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_and(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the minimum of the stored value and the given argument
* \param[in] arg The other argument of minimum
* \brief Atomically computes and stores the bitwise OR of the stored value and the given argument
* \param[in] arg The other argument of bitwise OR
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T> || std::is_floating_point_v<T>)>
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_min(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_or(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the maximum of the stored value and the given argument
* \param[in] arg The other argument of maximum
* \brief Atomically computes and stores the bitwise XOR of the stored value and the given argument
* \param[in] arg The other argument of bitwise XOR
* \param[in] order The memory order
* \return The old value
*/
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T> || std::is_floating_point_v<T>)>
template <STDGPU_DETAIL_OVERLOAD_IF(std::is_integral_v<T>)>
STDGPU_DEVICE_ONLY T
fetch_max(const T arg, const memory_order order = memory_order_seq_cst) noexcept;
fetch_xor(const T arg, const memory_order order = memory_order_seq_cst) noexcept;

/**
* \brief Atomically computes and stores the incrementation of the value and modulus with arg
Expand Down Expand Up @@ -882,6 +882,56 @@ atomic_fetch_sub_explicit(atomic<T, Allocator>* obj,
const typename atomic<T, Allocator>::difference_type arg,
const memory_order order) noexcept;

/**
* \ingroup atomic
* \brief Atomically computes and stores the minimum of the stored value and the given argument
* \param[in] obj The atomic object
* \param[in] arg The other argument of minimum
* \return The old value
*/
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_min(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::value_type arg) noexcept;

/**
* \ingroup atomic
* \brief Atomically computes and stores the minimum of the stored value and the given argument
* \param[in] obj The atomic object
* \param[in] arg The other argument of minimum
* \param[in] order The memory order
* \return The old value
*/
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_min_explicit(atomic<T, Allocator>* obj,
const typename atomic<T, Allocator>::value_type arg,
const memory_order order) noexcept;

/**
* \ingroup atomic
* \brief Atomically computes and stores the maximum of the stored value and the given argument
* \param[in] obj The atomic object
* \param[in] arg The other argument of maximum
* \return The old value
*/
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_max(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::value_type arg) noexcept;

/**
* \ingroup atomic
* \brief Atomically computes and stores the maximum of the stored value and the given argument
* \param[in] obj The atomic object
* \param[in] arg The other argument of maximum
* \param[in] order The memory order
* \return The old value
*/
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_max_explicit(atomic<T, Allocator>* obj,
const typename atomic<T, Allocator>::value_type arg,
const memory_order order) noexcept;

/**
* \ingroup atomic
* \brief Atomically computes and stores the addition of the stored value and the given argument
Expand All @@ -891,7 +941,7 @@ atomic_fetch_sub_explicit(atomic<T, Allocator>* obj,
*/
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_and(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::difference_type arg) noexcept;
atomic_fetch_and(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::value_type arg) noexcept;

/**
* \ingroup atomic
Expand All @@ -904,7 +954,7 @@ atomic_fetch_and(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>:
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_and_explicit(atomic<T, Allocator>* obj,
const typename atomic<T, Allocator>::difference_type arg,
const typename atomic<T, Allocator>::value_type arg,
const memory_order order) noexcept;

/**
Expand All @@ -916,7 +966,7 @@ atomic_fetch_and_explicit(atomic<T, Allocator>* obj,
*/
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_or(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::difference_type arg) noexcept;
atomic_fetch_or(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::value_type arg) noexcept;

/**
* \ingroup atomic
Expand All @@ -929,7 +979,7 @@ atomic_fetch_or(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_or_explicit(atomic<T, Allocator>* obj,
const typename atomic<T, Allocator>::difference_type arg,
const typename atomic<T, Allocator>::value_type arg,
const memory_order order) noexcept;

/**
Expand All @@ -941,7 +991,7 @@ atomic_fetch_or_explicit(atomic<T, Allocator>* obj,
*/
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_xor(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::difference_type arg) noexcept;
atomic_fetch_xor(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>::value_type arg) noexcept;

/**
* \ingroup atomic
Expand All @@ -954,7 +1004,7 @@ atomic_fetch_xor(atomic<T, Allocator>* obj, const typename atomic<T, Allocator>:
template <typename T, typename Allocator>
STDGPU_DEVICE_ONLY T
atomic_fetch_xor_explicit(atomic<T, Allocator>* obj,
const typename atomic<T, Allocator>::difference_type arg,
const typename atomic<T, Allocator>::value_type arg,
const memory_order order) noexcept;

} // namespace stdgpu
Expand Down
Loading