Skip to content

Commit a2f4dd8

Browse files
committed
deque: Extend support for custom execution policies
1 parent 3cb7082 commit a2f4dd8

File tree

3 files changed

+116
-25
lines changed

3 files changed

+116
-25
lines changed

src/stdgpu/deque.cuh

+36-1
Original file line numberDiff line numberDiff line change
@@ -245,20 +245,53 @@ public:
245245
[[nodiscard]] STDGPU_HOST_DEVICE bool
246246
empty() const;
247247

248+
/**
249+
* \brief Checks if the object is empty
250+
* \tparam ExecutionPolicy The type of the execution policy
251+
* \param[in] policy The execution policy, e.g. host or device, corresponding to the allocator
252+
* \return True if the object is empty, false otherwise
253+
*/
254+
template <typename ExecutionPolicy,
255+
STDGPU_DETAIL_OVERLOAD_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
256+
[[nodiscard]] bool
257+
empty(ExecutionPolicy&& policy) const;
258+
248259
/**
249260
* \brief Checks if the object is full
250261
* \return True if the object is full, false otherwise
251262
*/
252263
STDGPU_HOST_DEVICE bool
253264
full() const;
254265

266+
/**
267+
* \brief Checks if the object is full
268+
* \tparam ExecutionPolicy The type of the execution policy
269+
* \param[in] policy The execution policy, e.g. host or device, corresponding to the allocator
270+
* \return True if the object is full, false otherwise
271+
*/
272+
template <typename ExecutionPolicy,
273+
STDGPU_DETAIL_OVERLOAD_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
274+
bool
275+
full(ExecutionPolicy&& policy) const;
276+
255277
/**
256278
* \brief Returns the current size
257279
* \return The size
258280
*/
259281
STDGPU_HOST_DEVICE index_t
260282
size() const;
261283

284+
/**
285+
* \brief Returns the current size
286+
* \tparam ExecutionPolicy The type of the execution policy
287+
* \param[in] policy The execution policy, e.g. host or device, corresponding to the allocator
288+
* \return The size
289+
*/
290+
template <typename ExecutionPolicy,
291+
STDGPU_DETAIL_OVERLOAD_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
292+
index_t
293+
size(ExecutionPolicy&& policy) const;
294+
262295
/**
263296
* \brief Returns the maximal size
264297
* \return The maximal size
@@ -373,8 +406,10 @@ private:
373406
bool
374407
occupied_count_valid(ExecutionPolicy&& policy) const;
375408

409+
template <typename ExecutionPolicy,
410+
STDGPU_DETAIL_OVERLOAD_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
376411
bool
377-
size_valid() const;
412+
size_valid(ExecutionPolicy&& policy) const;
378413

379414
using mutex_array_allocator_type =
380415
typename stdgpu::allocator_traits<allocator_type>::template rebind_alloc<mutex_default_type>;

src/stdgpu/impl/deque_detail.cuh

+76-20
Original file line numberDiff line numberDiff line change
@@ -417,13 +417,31 @@ deque<T, Allocator>::empty() const
417417
return (size() == 0);
418418
}
419419

420+
template <typename T, typename Allocator>
421+
template <typename ExecutionPolicy,
422+
STDGPU_DETAIL_OVERLOAD_DEFINITION_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
423+
inline bool
424+
deque<T, Allocator>::empty(ExecutionPolicy&& policy) const
425+
{
426+
return (size(std::forward<ExecutionPolicy>(policy)) == 0);
427+
}
428+
420429
template <typename T, typename Allocator>
421430
inline STDGPU_HOST_DEVICE bool
422431
deque<T, Allocator>::full() const
423432
{
424433
return (size() == max_size());
425434
}
426435

436+
template <typename T, typename Allocator>
437+
template <typename ExecutionPolicy,
438+
STDGPU_DETAIL_OVERLOAD_DEFINITION_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
439+
inline bool
440+
deque<T, Allocator>::full(ExecutionPolicy&& policy) const
441+
{
442+
return (size(std::forward<ExecutionPolicy>(policy)) == max_size());
443+
}
444+
427445
template <typename T, typename Allocator>
428446
inline STDGPU_HOST_DEVICE index_t
429447
deque<T, Allocator>::size() const
@@ -453,6 +471,37 @@ deque<T, Allocator>::size() const
453471
return current_size;
454472
}
455473

474+
template <typename T, typename Allocator>
475+
template <typename ExecutionPolicy,
476+
STDGPU_DETAIL_OVERLOAD_DEFINITION_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
477+
inline index_t
478+
deque<T, Allocator>::size(ExecutionPolicy&& policy) const
479+
{
480+
index_t current_size = _size.load(std::forward<ExecutionPolicy>(policy));
481+
482+
// Check boundary cases where the push/pop caused the pointers to be overful/underful
483+
if (current_size < 0)
484+
{
485+
printf("stdgpu::deque::size : Size out of bounds: %" STDGPU_PRIINDEX " not in [0, %" STDGPU_PRIINDEX
486+
"]. Clamping to 0\n",
487+
current_size,
488+
capacity());
489+
return 0;
490+
}
491+
if (current_size > capacity())
492+
{
493+
printf("stdgpu::deque::size : Size out of bounds: %" STDGPU_PRIINDEX " not in [0, %" STDGPU_PRIINDEX
494+
"]. Clamping to %" STDGPU_PRIINDEX "\n",
495+
current_size,
496+
capacity(),
497+
capacity());
498+
return capacity();
499+
}
500+
501+
STDGPU_ENSURES(current_size <= capacity());
502+
return current_size;
503+
}
504+
456505
template <typename T, typename Allocator>
457506
inline STDGPU_HOST_DEVICE index_t
458507
deque<T, Allocator>::max_size() const noexcept
@@ -501,18 +550,18 @@ template <typename ExecutionPolicy,
501550
inline void
502551
deque<T, Allocator>::clear(ExecutionPolicy&& policy)
503552
{
504-
if (empty())
553+
if (empty(std::forward<ExecutionPolicy>(policy)))
505554
{
506555
return;
507556
}
508557

509558
if (!detail::is_destroy_optimizable<value_type>())
510559
{
511-
const index_t begin = static_cast<index_t>(_begin.load());
512-
const index_t end = static_cast<index_t>(_end.load());
560+
const index_t begin = static_cast<index_t>(_begin.load(std::forward<ExecutionPolicy>(policy)));
561+
const index_t end = static_cast<index_t>(_end.load(std::forward<ExecutionPolicy>(policy)));
513562

514563
// Full, i.e. one large block and begin == end
515-
if (full())
564+
if (full(std::forward<ExecutionPolicy>(policy)))
516565
{
517566
detail::unoptimized_destroy(std::forward<ExecutionPolicy>(policy), device_begin(_data), device_end(_data));
518567
}
@@ -537,12 +586,12 @@ deque<T, Allocator>::clear(ExecutionPolicy&& policy)
537586

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

540-
_size.store(0);
589+
_size.store(std::forward<ExecutionPolicy>(policy), 0);
541590

542-
_begin.store(0);
543-
_end.store(0);
591+
_begin.store(std::forward<ExecutionPolicy>(policy), 0);
592+
_end.store(std::forward<ExecutionPolicy>(policy), 0);
544593

545-
STDGPU_ENSURES(empty());
594+
STDGPU_ENSURES(empty(std::forward<ExecutionPolicy>(policy)));
546595
STDGPU_ENSURES(valid(std::forward<ExecutionPolicy>(policy)));
547596
}
548597

@@ -565,7 +614,8 @@ deque<T, Allocator>::valid(ExecutionPolicy&& policy) const
565614
return true;
566615
}
567616

568-
return (size_valid() && occupied_count_valid(std::forward<ExecutionPolicy>(policy)) &&
617+
return (size_valid(std::forward<ExecutionPolicy>(policy)) &&
618+
occupied_count_valid(std::forward<ExecutionPolicy>(policy)) &&
569619
_locks.valid(std::forward<ExecutionPolicy>(policy)));
570620
}
571621

@@ -582,11 +632,11 @@ template <typename ExecutionPolicy,
582632
stdgpu::device_indexed_range<T>
583633
deque<T, Allocator>::device_range(ExecutionPolicy&& policy)
584634
{
585-
const index_t begin = static_cast<index_t>(_begin.load());
586-
const index_t end = static_cast<index_t>(_end.load());
635+
const index_t begin = static_cast<index_t>(_begin.load(std::forward<ExecutionPolicy>(policy)));
636+
const index_t end = static_cast<index_t>(_end.load(std::forward<ExecutionPolicy>(policy)));
587637

588638
// Full, i.e. one large block and begin == end
589-
if (full())
639+
if (full(std::forward<ExecutionPolicy>(policy)))
590640
{
591641
iota(std::forward<ExecutionPolicy>(policy), device_begin(_range_indices), device_end(_range_indices), 0);
592642
}
@@ -611,7 +661,9 @@ deque<T, Allocator>::device_range(ExecutionPolicy&& policy)
611661
begin);
612662
}
613663

614-
return device_indexed_range<value_type>(stdgpu::device_range<index_t>(_range_indices, size()), data());
664+
return device_indexed_range<value_type>(
665+
stdgpu::device_range<index_t>(_range_indices, size(std::forward<ExecutionPolicy>(policy))),
666+
data());
615667
}
616668

617669
template <typename T, typename Allocator>
@@ -627,11 +679,11 @@ template <typename ExecutionPolicy,
627679
stdgpu::device_indexed_range<const T>
628680
deque<T, Allocator>::device_range(ExecutionPolicy&& policy) const
629681
{
630-
const index_t begin = static_cast<index_t>(_begin.load());
631-
const index_t end = static_cast<index_t>(_end.load());
682+
const index_t begin = static_cast<index_t>(_begin.load(std::forward<ExecutionPolicy>(policy)));
683+
const index_t end = static_cast<index_t>(_end.load(std::forward<ExecutionPolicy>(policy)));
632684

633685
// Full, i.e. one large block and begin == end
634-
if (full())
686+
if (full(std::forward<ExecutionPolicy>(policy)))
635687
{
636688
iota(std::forward<ExecutionPolicy>(policy), device_begin(_range_indices), device_end(_range_indices), 0);
637689
}
@@ -656,7 +708,9 @@ deque<T, Allocator>::device_range(ExecutionPolicy&& policy) const
656708
begin);
657709
}
658710

659-
return device_indexed_range<const value_type>(stdgpu::device_range<index_t>(_range_indices, size()), data());
711+
return device_indexed_range<const value_type>(
712+
stdgpu::device_range<index_t>(_range_indices, size(std::forward<ExecutionPolicy>(policy))),
713+
data());
660714
}
661715

662716
template <typename T, typename Allocator>
@@ -672,17 +726,19 @@ template <typename ExecutionPolicy,
672726
bool
673727
deque<T, Allocator>::occupied_count_valid(ExecutionPolicy&& policy) const
674728
{
675-
index_t size_count = size();
729+
index_t size_count = size(std::forward<ExecutionPolicy>(policy));
676730
index_t size_sum = _occupied.count(std::forward<ExecutionPolicy>(policy));
677731

678732
return (size_count == size_sum);
679733
}
680734

681735
template <typename T, typename Allocator>
736+
template <typename ExecutionPolicy,
737+
STDGPU_DETAIL_OVERLOAD_DEFINITION_IF(is_execution_policy_v<remove_cvref_t<ExecutionPolicy>>)>
682738
bool
683-
deque<T, Allocator>::size_valid() const
739+
deque<T, Allocator>::size_valid(ExecutionPolicy&& policy) const
684740
{
685-
int current_size = _size.load();
741+
int current_size = _size.load(std::forward<ExecutionPolicy>(policy));
686742
return (0 <= current_size && current_size <= static_cast<int>(capacity()));
687743
}
688744

tests/stdgpu/deque.inc

+4-4
Original file line numberDiff line numberDiff line change
@@ -1365,10 +1365,10 @@ TEST_F(stdgpu_deque, clear_custom_execution_policy)
13651365

13661366
pool.clear(policy);
13671367

1368-
ASSERT_EQ(pool.size(), 0);
1369-
ASSERT_TRUE(pool.empty());
1370-
ASSERT_FALSE(pool.full());
1371-
ASSERT_TRUE(pool.valid());
1368+
ASSERT_EQ(pool.size(policy), 0);
1369+
ASSERT_TRUE(pool.empty(policy));
1370+
ASSERT_FALSE(pool.full(policy));
1371+
ASSERT_TRUE(pool.valid(policy));
13721372

13731373
stdgpu::deque<int>::destroyDeviceObject(pool);
13741374
}

0 commit comments

Comments
 (0)