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

deque: Extend support for custom execution policies #448

Merged
merged 1 commit into from
Nov 19, 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
37 changes: 36 additions & 1 deletion src/stdgpu/deque.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -245,20 +245,53 @@ public:
[[nodiscard]] STDGPU_HOST_DEVICE bool
empty() const;

/**
* \brief Checks if the object is empty
* \tparam ExecutionPolicy The type of the execution policy
* \param[in] policy The execution policy, e.g. host or device, corresponding to the allocator
* \return True if the object is empty, false otherwise
*/
template <typename ExecutionPolicy,
STDGPU_DETAIL_OVERLOAD_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
[[nodiscard]] bool
empty(ExecutionPolicy&& policy) const;

/**
* \brief Checks if the object is full
* \return True if the object is full, false otherwise
*/
STDGPU_HOST_DEVICE bool
full() const;

/**
* \brief Checks if the object is full
* \tparam ExecutionPolicy The type of the execution policy
* \param[in] policy The execution policy, e.g. host or device, corresponding to the allocator
* \return True if the object is full, false otherwise
*/
template <typename ExecutionPolicy,
STDGPU_DETAIL_OVERLOAD_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
bool
full(ExecutionPolicy&& policy) const;

/**
* \brief Returns the current size
* \return The size
*/
STDGPU_HOST_DEVICE index_t
size() const;

/**
* \brief Returns the current size
* \tparam ExecutionPolicy The type of the execution policy
* \param[in] policy The execution policy, e.g. host or device, corresponding to the allocator
* \return The size
*/
template <typename ExecutionPolicy,
STDGPU_DETAIL_OVERLOAD_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
index_t
size(ExecutionPolicy&& policy) const;

/**
* \brief Returns the maximal size
* \return The maximal size
Expand Down Expand Up @@ -373,8 +406,10 @@ private:
bool
occupied_count_valid(ExecutionPolicy&& policy) const;

template <typename ExecutionPolicy,
STDGPU_DETAIL_OVERLOAD_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
bool
size_valid() const;
size_valid(ExecutionPolicy&& policy) const;

using mutex_array_allocator_type =
typename stdgpu::allocator_traits<allocator_type>::template rebind_alloc<mutex_default_type>;
Expand Down
96 changes: 76 additions & 20 deletions src/stdgpu/impl/deque_detail.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -417,13 +417,31 @@
return (size() == 0);
}

template <typename T, typename Allocator>
template <typename ExecutionPolicy,
STDGPU_DETAIL_OVERLOAD_DEFINITION_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
inline bool
deque<T, Allocator>::empty(ExecutionPolicy&& policy) const
{
return (size(std::forward<ExecutionPolicy>(policy)) == 0);
}

template <typename T, typename Allocator>
inline STDGPU_HOST_DEVICE bool
deque<T, Allocator>::full() const
{
return (size() == max_size());
}

template <typename T, typename Allocator>
template <typename ExecutionPolicy,
STDGPU_DETAIL_OVERLOAD_DEFINITION_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
inline bool
deque<T, Allocator>::full(ExecutionPolicy&& policy) const
{
return (size(std::forward<ExecutionPolicy>(policy)) == max_size());
}

template <typename T, typename Allocator>
inline STDGPU_HOST_DEVICE index_t
deque<T, Allocator>::size() const
Expand Down Expand Up @@ -453,6 +471,37 @@
return current_size;
}

template <typename T, typename Allocator>
template <typename ExecutionPolicy,
STDGPU_DETAIL_OVERLOAD_DEFINITION_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
inline index_t
deque<T, Allocator>::size(ExecutionPolicy&& policy) const
{
index_t current_size = _size.load(std::forward<ExecutionPolicy>(policy));

// Check boundary cases where the push/pop caused the pointers to be overful/underful
if (current_size < 0)
{
printf("stdgpu::deque::size : Size out of bounds: %" STDGPU_PRIINDEX " not in [0, %" STDGPU_PRIINDEX

Check warning on line 485 in src/stdgpu/impl/deque_detail.cuh

View check run for this annotation

Codecov / codecov/patch

src/stdgpu/impl/deque_detail.cuh#L485

Added line #L485 was not covered by tests
"]. Clamping to 0\n",
current_size,
capacity());
return 0;

Check warning on line 489 in src/stdgpu/impl/deque_detail.cuh

View check run for this annotation

Codecov / codecov/patch

src/stdgpu/impl/deque_detail.cuh#L489

Added line #L489 was not covered by tests
}
if (current_size > capacity())
{
printf("stdgpu::deque::size : Size out of bounds: %" STDGPU_PRIINDEX " not in [0, %" STDGPU_PRIINDEX

Check warning on line 493 in src/stdgpu/impl/deque_detail.cuh

View check run for this annotation

Codecov / codecov/patch

src/stdgpu/impl/deque_detail.cuh#L493

Added line #L493 was not covered by tests
"]. Clamping to %" STDGPU_PRIINDEX "\n",
current_size,
capacity(),
capacity());
return capacity();

Check warning on line 498 in src/stdgpu/impl/deque_detail.cuh

View check run for this annotation

Codecov / codecov/patch

src/stdgpu/impl/deque_detail.cuh#L498

Added line #L498 was not covered by tests
}

STDGPU_ENSURES(current_size <= capacity());
return current_size;
}

template <typename T, typename Allocator>
inline STDGPU_HOST_DEVICE index_t
deque<T, Allocator>::max_size() const noexcept
Expand Down Expand Up @@ -501,18 +550,18 @@
inline void
deque<T, Allocator>::clear(ExecutionPolicy&& policy)
{
if (empty())
if (empty(std::forward<ExecutionPolicy>(policy)))
{
return;
}

if (!detail::is_destroy_optimizable<value_type>())
{
const index_t begin = static_cast<index_t>(_begin.load());
const index_t end = static_cast<index_t>(_end.load());
const index_t begin = static_cast<index_t>(_begin.load(std::forward<ExecutionPolicy>(policy)));
const index_t end = static_cast<index_t>(_end.load(std::forward<ExecutionPolicy>(policy)));

// Full, i.e. one large block and begin == end
if (full())
if (full(std::forward<ExecutionPolicy>(policy)))
{
detail::unoptimized_destroy(std::forward<ExecutionPolicy>(policy), device_begin(_data), device_end(_data));
}
Expand All @@ -537,12 +586,12 @@

_occupied.reset(std::forward<ExecutionPolicy>(policy));

_size.store(0);
_size.store(std::forward<ExecutionPolicy>(policy), 0);

_begin.store(0);
_end.store(0);
_begin.store(std::forward<ExecutionPolicy>(policy), 0);
_end.store(std::forward<ExecutionPolicy>(policy), 0);

STDGPU_ENSURES(empty());
STDGPU_ENSURES(empty(std::forward<ExecutionPolicy>(policy)));
STDGPU_ENSURES(valid(std::forward<ExecutionPolicy>(policy)));
}

Expand All @@ -565,7 +614,8 @@
return true;
}

return (size_valid() && occupied_count_valid(std::forward<ExecutionPolicy>(policy)) &&
return (size_valid(std::forward<ExecutionPolicy>(policy)) &&
occupied_count_valid(std::forward<ExecutionPolicy>(policy)) &&
_locks.valid(std::forward<ExecutionPolicy>(policy)));
}

Expand All @@ -582,11 +632,11 @@
stdgpu::device_indexed_range<T>
deque<T, Allocator>::device_range(ExecutionPolicy&& policy)
{
const index_t begin = static_cast<index_t>(_begin.load());
const index_t end = static_cast<index_t>(_end.load());
const index_t begin = static_cast<index_t>(_begin.load(std::forward<ExecutionPolicy>(policy)));
const index_t end = static_cast<index_t>(_end.load(std::forward<ExecutionPolicy>(policy)));

// Full, i.e. one large block and begin == end
if (full())
if (full(std::forward<ExecutionPolicy>(policy)))
{
iota(std::forward<ExecutionPolicy>(policy), device_begin(_range_indices), device_end(_range_indices), 0);
}
Expand All @@ -611,7 +661,9 @@
begin);
}

return device_indexed_range<value_type>(stdgpu::device_range<index_t>(_range_indices, size()), data());
return device_indexed_range<value_type>(
stdgpu::device_range<index_t>(_range_indices, size(std::forward<ExecutionPolicy>(policy))),
data());
}

template <typename T, typename Allocator>
Expand All @@ -627,11 +679,11 @@
stdgpu::device_indexed_range<const T>
deque<T, Allocator>::device_range(ExecutionPolicy&& policy) const
{
const index_t begin = static_cast<index_t>(_begin.load());
const index_t end = static_cast<index_t>(_end.load());
const index_t begin = static_cast<index_t>(_begin.load(std::forward<ExecutionPolicy>(policy)));
const index_t end = static_cast<index_t>(_end.load(std::forward<ExecutionPolicy>(policy)));

// Full, i.e. one large block and begin == end
if (full())
if (full(std::forward<ExecutionPolicy>(policy)))
{
iota(std::forward<ExecutionPolicy>(policy), device_begin(_range_indices), device_end(_range_indices), 0);
}
Expand All @@ -656,7 +708,9 @@
begin);
}

return device_indexed_range<const value_type>(stdgpu::device_range<index_t>(_range_indices, size()), data());
return device_indexed_range<const value_type>(
stdgpu::device_range<index_t>(_range_indices, size(std::forward<ExecutionPolicy>(policy))),
data());
}

template <typename T, typename Allocator>
Expand All @@ -672,17 +726,19 @@
bool
deque<T, Allocator>::occupied_count_valid(ExecutionPolicy&& policy) const
{
index_t size_count = size();
index_t size_count = size(std::forward<ExecutionPolicy>(policy));
index_t size_sum = _occupied.count(std::forward<ExecutionPolicy>(policy));

return (size_count == size_sum);
}

template <typename T, typename Allocator>
template <typename ExecutionPolicy,
STDGPU_DETAIL_OVERLOAD_DEFINITION_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
bool
deque<T, Allocator>::size_valid() const
deque<T, Allocator>::size_valid(ExecutionPolicy&& policy) const
{
int current_size = _size.load();
int current_size = _size.load(std::forward<ExecutionPolicy>(policy));
return (0 <= current_size && current_size <= static_cast<int>(capacity()));
}

Expand Down
8 changes: 4 additions & 4 deletions tests/stdgpu/deque.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1365,10 +1365,10 @@ TEST_F(stdgpu_deque, clear_custom_execution_policy)

pool.clear(policy);

ASSERT_EQ(pool.size(), 0);
ASSERT_TRUE(pool.empty());
ASSERT_FALSE(pool.full());
ASSERT_TRUE(pool.valid());
ASSERT_EQ(pool.size(policy), 0);
ASSERT_TRUE(pool.empty(policy));
ASSERT_FALSE(pool.full(policy));
ASSERT_TRUE(pool.valid(policy));

stdgpu::deque<int>::destroyDeviceObject(pool);
}
Expand Down