Skip to content

Commit

Permalink
atomic: Add non-member functions for fetch_min and fetch_max
Browse files Browse the repository at this point in the history
  • Loading branch information
stotko committed Nov 18, 2024
1 parent d621e2b commit 2676d85
Show file tree
Hide file tree
Showing 3 changed files with 414 additions and 188 deletions.
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

0 comments on commit 2676d85

Please sign in to comment.