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
157 lines
4.8 KiB
Plaintext
157 lines
4.8 KiB
Plaintext
#include <thrust/iterator/reverse_iterator.h>
|
|
#include <thrust/scan.h>
|
|
#include <thrust/sequence.h>
|
|
|
|
#include <cuda/std/iterator>
|
|
#include <cuda/std/type_traits>
|
|
|
|
#include <unittest/unittest.h>
|
|
|
|
// ensure that we properly support thrust::reverse_iterator from cuda::std
|
|
void TestReverseIteratorTraits()
|
|
{
|
|
using base_it = thrust::host_vector<int>::iterator;
|
|
|
|
using it = thrust::reverse_iterator<base_it>;
|
|
using traits = cuda::std::iterator_traits<it>;
|
|
using category = ::cuda::std::random_access_iterator_tag;
|
|
|
|
static_assert(cuda::std::is_same_v<traits::difference_type, ptrdiff_t>);
|
|
static_assert(cuda::std::is_same_v<traits::value_type, int>);
|
|
static_assert(cuda::std::is_same_v<traits::pointer, void>);
|
|
static_assert(cuda::std::is_same_v<traits::reference, int&>);
|
|
static_assert(cuda::std::is_same_v<traits::iterator_category, category>);
|
|
|
|
static_assert(cuda::std::is_same_v<thrust::iterator_traversal_t<it>, thrust::random_access_traversal_tag>);
|
|
|
|
static_assert(cuda::std::__has_random_access_traversal<it>);
|
|
|
|
static_assert(cuda::std::output_iterator<it, int>);
|
|
static_assert(cuda::std::input_iterator<it>);
|
|
static_assert(cuda::std::forward_iterator<it>);
|
|
static_assert(cuda::std::bidirectional_iterator<it>);
|
|
static_assert(cuda::std::random_access_iterator<it>);
|
|
static_assert(!cuda::std::contiguous_iterator<it>);
|
|
}
|
|
DECLARE_UNITTEST(TestReverseIteratorTraits);
|
|
|
|
void TestReverseIteratorCopyConstructor()
|
|
{
|
|
thrust::host_vector<int> h_v(1, 13);
|
|
|
|
thrust::reverse_iterator<thrust::host_vector<int>::iterator> h_iter0(h_v.end());
|
|
thrust::reverse_iterator<thrust::host_vector<int>::iterator> h_iter1(h_iter0);
|
|
|
|
ASSERT_EQUAL_QUIET(h_iter0, h_iter1);
|
|
ASSERT_EQUAL(*h_iter0, *h_iter1);
|
|
|
|
thrust::device_vector<int> d_v(1, 13);
|
|
|
|
thrust::reverse_iterator<thrust::device_vector<int>::iterator> d_iter2(d_v.end());
|
|
thrust::reverse_iterator<thrust::device_vector<int>::iterator> d_iter3(d_iter2);
|
|
|
|
ASSERT_EQUAL_QUIET(d_iter2, d_iter3);
|
|
ASSERT_EQUAL(*d_iter2, *d_iter3);
|
|
}
|
|
DECLARE_UNITTEST(TestReverseIteratorCopyConstructor);
|
|
static_assert(cuda::std::is_trivially_copy_constructible<thrust::reverse_iterator<int*>>::value);
|
|
static_assert(cuda::std::is_trivially_copyable<thrust::reverse_iterator<int*>>::value);
|
|
|
|
void TestReverseIteratorIncrement()
|
|
{
|
|
thrust::host_vector<int> h_v(4);
|
|
thrust::sequence(h_v.begin(), h_v.end());
|
|
|
|
thrust::reverse_iterator<thrust::host_vector<int>::iterator> h_iter(h_v.end());
|
|
|
|
ASSERT_EQUAL(*h_iter, 3);
|
|
|
|
h_iter++;
|
|
ASSERT_EQUAL(*h_iter, 2);
|
|
|
|
h_iter++;
|
|
ASSERT_EQUAL(*h_iter, 1);
|
|
|
|
h_iter++;
|
|
ASSERT_EQUAL(*h_iter, 0);
|
|
|
|
thrust::device_vector<int> d_v(4);
|
|
thrust::sequence(d_v.begin(), d_v.end());
|
|
|
|
thrust::reverse_iterator<thrust::device_vector<int>::iterator> d_iter(d_v.end());
|
|
|
|
ASSERT_EQUAL(*d_iter, 3);
|
|
|
|
d_iter++;
|
|
ASSERT_EQUAL(*d_iter, 2);
|
|
|
|
d_iter++;
|
|
ASSERT_EQUAL(*d_iter, 1);
|
|
|
|
d_iter++;
|
|
ASSERT_EQUAL(*d_iter, 0);
|
|
}
|
|
DECLARE_UNITTEST(TestReverseIteratorIncrement);
|
|
|
|
template <typename Vector>
|
|
void TestReverseIteratorCopy()
|
|
{
|
|
Vector source{10, 20, 30, 40};
|
|
|
|
Vector destination(8, 0); // arm gcc is complaining here
|
|
|
|
thrust::copy(
|
|
thrust::make_reverse_iterator(source.end()), thrust::make_reverse_iterator(source.begin()), destination.begin());
|
|
|
|
destination.resize(4);
|
|
Vector ref{40, 30, 20, 10};
|
|
ASSERT_EQUAL(destination, ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestReverseIteratorCopy);
|
|
|
|
void TestReverseIteratorExclusiveScanSimple()
|
|
{
|
|
using T = int;
|
|
const size_t n = 10;
|
|
|
|
thrust::host_vector<T> h_data(n);
|
|
thrust::sequence(h_data.begin(), h_data.end());
|
|
|
|
thrust::device_vector<T> d_data = h_data;
|
|
|
|
thrust::host_vector<T> h_result(h_data.size());
|
|
thrust::device_vector<T> d_result(d_data.size());
|
|
|
|
thrust::exclusive_scan(
|
|
thrust::make_reverse_iterator(h_data.end()), thrust::make_reverse_iterator(h_data.begin()), h_result.begin());
|
|
|
|
thrust::exclusive_scan(
|
|
thrust::make_reverse_iterator(d_data.end()), thrust::make_reverse_iterator(d_data.begin()), d_result.begin());
|
|
|
|
ASSERT_EQUAL_QUIET(h_result, d_result);
|
|
}
|
|
DECLARE_UNITTEST(TestReverseIteratorExclusiveScanSimple);
|
|
|
|
template <typename T>
|
|
struct TestReverseIteratorExclusiveScan
|
|
{
|
|
void operator()(const size_t n)
|
|
{
|
|
thrust::host_vector<T> h_data = unittest::random_samples<T>(n);
|
|
|
|
thrust::device_vector<T> d_data = h_data;
|
|
|
|
thrust::host_vector<T> h_result(n);
|
|
thrust::device_vector<T> d_result(n);
|
|
|
|
thrust::exclusive_scan(
|
|
thrust::make_reverse_iterator(h_data.end()), thrust::make_reverse_iterator(h_data.begin()), h_result.begin());
|
|
|
|
thrust::exclusive_scan(
|
|
thrust::make_reverse_iterator(d_data.end()), thrust::make_reverse_iterator(d_data.begin()), d_result.begin());
|
|
|
|
ASSERT_EQUAL_QUIET(h_result, d_result);
|
|
}
|
|
};
|
|
VariableUnitTest<TestReverseIteratorExclusiveScan, IntegralTypes> TestReverseIteratorExclusiveScanInstance;
|