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
1026 lines
24 KiB
Plaintext
1026 lines
24 KiB
Plaintext
#include <thrust/detail/config.h>
|
|
|
|
#include <thrust/device_malloc_allocator.h>
|
|
#include <thrust/sequence.h>
|
|
|
|
#include <initializer_list>
|
|
#include <limits>
|
|
#include <list>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include <unittest/unittest.h>
|
|
|
|
template <class Vector>
|
|
void TestVectorZeroSize()
|
|
{
|
|
Vector v;
|
|
ASSERT_EQUAL(v.size(), 0lu);
|
|
ASSERT_EQUAL((v.begin() == v.end()), true);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorZeroSize);
|
|
|
|
void TestVectorBool()
|
|
{
|
|
thrust::host_vector<bool> h{true, false, true};
|
|
thrust::device_vector<bool> d{true, false, true};
|
|
|
|
thrust::host_vector<bool> h_ref{true, false, true};
|
|
thrust::device_vector<bool> d_ref{true, false, true};
|
|
ASSERT_EQUAL(h, h_ref);
|
|
ASSERT_EQUAL(d, d_ref);
|
|
}
|
|
DECLARE_UNITTEST(TestVectorBool);
|
|
|
|
template <class Vector>
|
|
void TestVectorInitializerList()
|
|
{
|
|
Vector v{1, 2, 3};
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
Vector ref{1, 2, 3};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v = {1, 2, 3, 4};
|
|
ASSERT_EQUAL(v.size(), 4lu);
|
|
Vector v_ref = {1, 2, 3, 4};
|
|
ASSERT_EQUAL(v, v_ref);
|
|
|
|
const auto alloc = v.get_allocator();
|
|
Vector v2{{1, 2, 3}, alloc};
|
|
ASSERT_EQUAL(v2.size(), 3lu);
|
|
Vector v2_ref = {1, 2, 3};
|
|
ASSERT_EQUAL(v2, v2_ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorInitializerList);
|
|
|
|
template <class Vector>
|
|
void TestVectorFrontBack()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
Vector v{0, 1, 2};
|
|
|
|
ASSERT_EQUAL(v.front(), T(0));
|
|
ASSERT_EQUAL(v.back(), T(2));
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorFrontBack);
|
|
|
|
template <class Vector>
|
|
void TestVectorData()
|
|
{
|
|
using PointerT = typename Vector::pointer;
|
|
using PointerConstT = typename Vector::const_pointer;
|
|
|
|
Vector v{0, 1, 2};
|
|
|
|
ASSERT_EQUAL(0, *v.data());
|
|
ASSERT_EQUAL(1, *(v.data() + 1));
|
|
ASSERT_EQUAL(2, *(v.data() + 2));
|
|
ASSERT_EQUAL(PointerT(&v.front()), v.data());
|
|
ASSERT_EQUAL(PointerT(&*v.begin()), v.data());
|
|
ASSERT_EQUAL(PointerT(&v[0]), v.data());
|
|
|
|
const Vector& c_v = v;
|
|
|
|
ASSERT_EQUAL(0, *c_v.data());
|
|
ASSERT_EQUAL(1, *(c_v.data() + 1));
|
|
ASSERT_EQUAL(2, *(c_v.data() + 2));
|
|
ASSERT_EQUAL(PointerConstT(&c_v.front()), c_v.data());
|
|
ASSERT_EQUAL(PointerConstT(&*c_v.begin()), c_v.data());
|
|
ASSERT_EQUAL(PointerConstT(&c_v[0]), c_v.data());
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorData);
|
|
|
|
template <class Vector>
|
|
void TestVectorElementAssignment()
|
|
{
|
|
Vector v{0, 1, 2};
|
|
|
|
Vector ref{0, 1, 2};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v = {10, 11, 12};
|
|
ref = {10, 11, 12};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
Vector w = v;
|
|
ASSERT_EQUAL(v, w);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorElementAssignment);
|
|
|
|
template <class Vector>
|
|
void TestVectorFromSTLVector()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
std::vector<T> stl_vector{0, 1, 2};
|
|
|
|
thrust::host_vector<T> v(stl_vector);
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
thrust::host_vector<T> ref{0, 1, 2};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v = stl_vector;
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorFromSTLVector);
|
|
|
|
template <class Vector>
|
|
void TestVectorFillAssign()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
thrust::host_vector<T> v;
|
|
v.assign(3, 13);
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
thrust::host_vector<T> ref{13, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorFillAssign);
|
|
|
|
template <class Vector>
|
|
void TestVectorFillInsert()
|
|
{
|
|
{ // Insert into empty vector
|
|
Vector v;
|
|
v.insert(v.end(), 3, 13);
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
Vector ref{13, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector at end
|
|
Vector v{13, 13, 13};
|
|
v.insert(v.end(), 2, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 5lu);
|
|
Vector ref{13, 13, 13, 42, 42};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector at front, existing elements inserted before end
|
|
Vector v{13, 13, 13};
|
|
v.insert(v.begin(), 2, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 5lu);
|
|
Vector ref{42, 42, 13, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector at front, existing elements inserted after end
|
|
Vector v{13, 13, 13};
|
|
v.insert(v.begin(), 4, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 7lu);
|
|
Vector ref{42, 42, 42, 42, 13, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector in middle, existing elements inserted before end
|
|
Vector v{13, 13, 13};
|
|
v.insert(v.begin() + 1, 1, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 4lu);
|
|
Vector ref{13, 42, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector in middle, existing elements inserted at end
|
|
Vector v{13, 13, 13};
|
|
v.insert(v.begin() + 1, 2, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 5lu);
|
|
Vector ref{13, 42, 42, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector in middle, existing elements inserted after end
|
|
Vector v{13, 13, 13};
|
|
v.insert(v.begin() + 1, 4, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 7lu);
|
|
Vector ref{13, 42, 42, 42, 42, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into empty vector, with sufficient capacity
|
|
Vector v;
|
|
v.reserve(42);
|
|
v.insert(v.end(), 3, 13);
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
Vector ref{13, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector at end, with sufficient capacity
|
|
Vector v{13, 13, 13};
|
|
v.reserve(42);
|
|
v.insert(v.end(), 2, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 5lu);
|
|
Vector ref{13, 13, 13, 42, 42};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector at front, existing elements inserted after end, with sufficient capacity
|
|
Vector v{13, 13, 13};
|
|
v.reserve(42);
|
|
v.insert(v.begin(), 4, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 7lu);
|
|
Vector ref{42, 42, 42, 42, 13, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector in middle, existing elements inserted before end, with sufficient capacity
|
|
Vector v{13, 13, 13};
|
|
v.reserve(42);
|
|
v.insert(v.begin() + 1, 1, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 4lu);
|
|
Vector ref{13, 42, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector in middle, existing elements inserted at end, with sufficient capacity
|
|
Vector v{13, 13, 13};
|
|
v.reserve(42);
|
|
v.insert(v.begin() + 1, 2, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 5lu);
|
|
Vector ref{13, 42, 42, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
|
|
{ // Insert into non-empty vector in middle, existing elements inserted after end, with sufficient capacity
|
|
Vector v{13, 13, 13};
|
|
v.reserve(42);
|
|
v.insert(v.begin() + 1, 4, 42);
|
|
|
|
ASSERT_EQUAL(v.size(), 7lu);
|
|
Vector ref{13, 42, 42, 42, 42, 13, 13};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorFillInsert);
|
|
|
|
template <class Vector>
|
|
void TestVectorAssignFromSTLVector()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
std::vector<T> stl_vector{0, 1, 2};
|
|
|
|
thrust::host_vector<T> v;
|
|
v.assign(stl_vector.begin(), stl_vector.end());
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
thrust::host_vector<T> ref{0, 1, 2};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorAssignFromSTLVector);
|
|
|
|
template <class Vector>
|
|
void TestVectorFromBiDirectionalIterator()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
std::list<T> stl_list;
|
|
stl_list.push_back(0);
|
|
stl_list.push_back(1);
|
|
stl_list.push_back(2);
|
|
|
|
Vector v(stl_list.begin(), stl_list.end());
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
Vector ref{0, 1, 2};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorFromBiDirectionalIterator);
|
|
|
|
template <class Vector>
|
|
void TestVectorAssignFromBiDirectionalIterator()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
std::list<T> stl_list;
|
|
stl_list.push_back(0);
|
|
stl_list.push_back(1);
|
|
stl_list.push_back(2);
|
|
|
|
Vector v;
|
|
v.assign(stl_list.begin(), stl_list.end());
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
Vector ref{0, 1, 2};
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorAssignFromBiDirectionalIterator);
|
|
|
|
template <class Vector>
|
|
void TestVectorAssignFromHostVector()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
thrust::host_vector<T> h{0, 1, 2};
|
|
|
|
Vector v;
|
|
v.assign(h.begin(), h.end());
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorAssignFromHostVector);
|
|
|
|
_CCCL_DIAG_PUSH
|
|
_CCCL_DIAG_SUPPRESS_CLANG("-Wself-assign")
|
|
|
|
template <class Vector>
|
|
void TestVectorToAndFromHostVector()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
thrust::host_vector<T> h{0, 1, 2};
|
|
|
|
Vector v(h);
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
|
|
v = v;
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
|
|
v = {10, 11, 12};
|
|
Vector v_ref{10, 11, 12};
|
|
ASSERT_EQUAL(v, v_ref);
|
|
|
|
Vector h_ref{0, 1, 2};
|
|
ASSERT_EQUAL(h, h_ref);
|
|
|
|
h = v;
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
|
|
h[1] = 11;
|
|
|
|
v = h;
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorToAndFromHostVector);
|
|
|
|
_CCCL_DIAG_POP
|
|
|
|
template <class Vector>
|
|
void TestVectorAssignFromDeviceVector()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
thrust::device_vector<T> d{0, 1, 2};
|
|
|
|
Vector v;
|
|
v.assign(d.begin(), d.end());
|
|
|
|
ASSERT_EQUAL(v, d);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorAssignFromDeviceVector);
|
|
|
|
_CCCL_DIAG_PUSH
|
|
_CCCL_DIAG_SUPPRESS_CLANG("-Wself-assign")
|
|
|
|
template <class Vector>
|
|
void TestVectorToAndFromDeviceVector()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
thrust::device_vector<T> h{0, 1, 2};
|
|
|
|
Vector v(h);
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
|
|
v = v;
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
|
|
v = {10, 11, 12};
|
|
Vector v_ref{10, 11, 12};
|
|
ASSERT_EQUAL(v, v_ref);
|
|
|
|
Vector h_ref{0, 1, 2};
|
|
ASSERT_EQUAL(h, h_ref);
|
|
|
|
h = v;
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
|
|
h[1] = 11;
|
|
|
|
v = h;
|
|
|
|
ASSERT_EQUAL(v, h);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorToAndFromDeviceVector);
|
|
_CCCL_DIAG_POP
|
|
|
|
template <class Vector>
|
|
void TestVectorWithInitialValue()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
const T init = 17;
|
|
|
|
Vector v(3, init);
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
Vector ref(3, init);
|
|
ASSERT_EQUAL(v, ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorWithInitialValue);
|
|
|
|
template <class Vector>
|
|
void TestVectorSwap()
|
|
{
|
|
Vector v{0, 1, 2};
|
|
Vector u{10, 11, 12};
|
|
|
|
v.swap(u);
|
|
|
|
Vector u_ref{0, 1, 2};
|
|
ASSERT_EQUAL(u, u_ref);
|
|
|
|
Vector v_ref{10, 11, 12};
|
|
ASSERT_EQUAL(v, v_ref);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorSwap);
|
|
|
|
template <class Vector>
|
|
void TestVectorErasePosition()
|
|
{
|
|
Vector v{0, 1, 2, 3, 4};
|
|
|
|
v.erase(v.begin() + 2);
|
|
|
|
ASSERT_EQUAL(v.size(), 4lu);
|
|
Vector ref{0, 1, 3, 4};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v.erase(v.begin() + 0);
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
ref = {1, 3, 4};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v.erase(v.begin() + 2);
|
|
|
|
ASSERT_EQUAL(v.size(), 2lu);
|
|
ref = {1, 3};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v.erase(v.begin() + 1);
|
|
|
|
ASSERT_EQUAL(v.size(), 1lu);
|
|
ASSERT_EQUAL(v[0], 1);
|
|
|
|
v.erase(v.begin() + 0);
|
|
|
|
ASSERT_EQUAL(v.size(), 0lu);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorErasePosition);
|
|
|
|
template <class Vector>
|
|
void TestVectorEraseRange()
|
|
{
|
|
Vector v{0, 1, 2, 3, 4, 5};
|
|
|
|
v.erase(v.begin() + 1, v.begin() + 3);
|
|
|
|
ASSERT_EQUAL(v.size(), 4lu);
|
|
Vector ref{0, 3, 4, 5};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v.erase(v.begin() + 2, v.end());
|
|
|
|
ASSERT_EQUAL(v.size(), 2lu);
|
|
ref = {0, 3};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v.erase(v.begin() + 0, v.begin() + 1);
|
|
|
|
ASSERT_EQUAL(v.size(), 1lu);
|
|
ASSERT_EQUAL(v[0], 3);
|
|
|
|
v.erase(v.begin(), v.end());
|
|
|
|
ASSERT_EQUAL(v.size(), 0lu);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorEraseRange);
|
|
|
|
void TestVectorEquality()
|
|
{
|
|
thrust::host_vector<int> h_a{0, 1, 2};
|
|
thrust::host_vector<int> h_b{0, 1, 3};
|
|
thrust::host_vector<int> h_c(3);
|
|
|
|
thrust::device_vector<int> d_a{0, 1, 2};
|
|
thrust::device_vector<int> d_b{0, 1, 3};
|
|
thrust::device_vector<int> d_c(3);
|
|
|
|
std::vector<int> s_a{0, 1, 2};
|
|
std::vector<int> s_b{0, 1, 3};
|
|
std::vector<int> s_c(3);
|
|
|
|
ASSERT_EQUAL((h_a == h_a), true);
|
|
ASSERT_EQUAL((h_a == d_a), true);
|
|
ASSERT_EQUAL((d_a == h_a), true);
|
|
ASSERT_EQUAL((d_a == d_a), true);
|
|
ASSERT_EQUAL((h_b == h_b), true);
|
|
ASSERT_EQUAL((h_b == d_b), true);
|
|
ASSERT_EQUAL((d_b == h_b), true);
|
|
ASSERT_EQUAL((d_b == d_b), true);
|
|
ASSERT_EQUAL((h_c == h_c), true);
|
|
ASSERT_EQUAL((h_c == d_c), true);
|
|
ASSERT_EQUAL((d_c == h_c), true);
|
|
ASSERT_EQUAL((d_c == d_c), true);
|
|
|
|
// test vector vs device_vector
|
|
ASSERT_EQUAL((s_a == d_a), true);
|
|
ASSERT_EQUAL((d_a == s_a), true);
|
|
ASSERT_EQUAL((s_b == d_b), true);
|
|
ASSERT_EQUAL((d_b == s_b), true);
|
|
ASSERT_EQUAL((s_c == d_c), true);
|
|
ASSERT_EQUAL((d_c == s_c), true);
|
|
|
|
// test vector vs host_vector
|
|
ASSERT_EQUAL((s_a == h_a), true);
|
|
ASSERT_EQUAL((h_a == s_a), true);
|
|
ASSERT_EQUAL((s_b == h_b), true);
|
|
ASSERT_EQUAL((h_b == s_b), true);
|
|
ASSERT_EQUAL((s_c == h_c), true);
|
|
ASSERT_EQUAL((h_c == s_c), true);
|
|
|
|
ASSERT_EQUAL((h_a == h_b), false);
|
|
ASSERT_EQUAL((h_a == d_b), false);
|
|
ASSERT_EQUAL((d_a == h_b), false);
|
|
ASSERT_EQUAL((d_a == d_b), false);
|
|
ASSERT_EQUAL((h_b == h_a), false);
|
|
ASSERT_EQUAL((h_b == d_a), false);
|
|
ASSERT_EQUAL((d_b == h_a), false);
|
|
ASSERT_EQUAL((d_b == d_a), false);
|
|
ASSERT_EQUAL((h_a == h_c), false);
|
|
ASSERT_EQUAL((h_a == d_c), false);
|
|
ASSERT_EQUAL((d_a == h_c), false);
|
|
ASSERT_EQUAL((d_a == d_c), false);
|
|
ASSERT_EQUAL((h_c == h_a), false);
|
|
ASSERT_EQUAL((h_c == d_a), false);
|
|
ASSERT_EQUAL((d_c == h_a), false);
|
|
ASSERT_EQUAL((d_c == d_a), false);
|
|
ASSERT_EQUAL((h_b == h_c), false);
|
|
ASSERT_EQUAL((h_b == d_c), false);
|
|
ASSERT_EQUAL((d_b == h_c), false);
|
|
ASSERT_EQUAL((d_b == d_c), false);
|
|
ASSERT_EQUAL((h_c == h_b), false);
|
|
ASSERT_EQUAL((h_c == d_b), false);
|
|
ASSERT_EQUAL((d_c == h_b), false);
|
|
ASSERT_EQUAL((d_c == d_b), false);
|
|
|
|
// test vector vs device_vector
|
|
ASSERT_EQUAL((s_a == d_b), false);
|
|
ASSERT_EQUAL((d_a == s_b), false);
|
|
ASSERT_EQUAL((s_b == d_a), false);
|
|
ASSERT_EQUAL((d_b == s_a), false);
|
|
ASSERT_EQUAL((s_a == d_c), false);
|
|
ASSERT_EQUAL((d_a == s_c), false);
|
|
ASSERT_EQUAL((s_c == d_a), false);
|
|
ASSERT_EQUAL((d_c == s_a), false);
|
|
ASSERT_EQUAL((s_b == d_c), false);
|
|
ASSERT_EQUAL((d_b == s_c), false);
|
|
ASSERT_EQUAL((s_c == d_b), false);
|
|
ASSERT_EQUAL((d_c == s_b), false);
|
|
|
|
// test vector vs host_vector
|
|
ASSERT_EQUAL((s_a == h_b), false);
|
|
ASSERT_EQUAL((h_a == s_b), false);
|
|
ASSERT_EQUAL((s_b == h_a), false);
|
|
ASSERT_EQUAL((h_b == s_a), false);
|
|
ASSERT_EQUAL((s_a == h_c), false);
|
|
ASSERT_EQUAL((h_a == s_c), false);
|
|
ASSERT_EQUAL((s_c == h_a), false);
|
|
ASSERT_EQUAL((h_c == s_a), false);
|
|
ASSERT_EQUAL((s_b == h_c), false);
|
|
ASSERT_EQUAL((h_b == s_c), false);
|
|
ASSERT_EQUAL((s_c == h_b), false);
|
|
ASSERT_EQUAL((h_c == s_b), false);
|
|
}
|
|
DECLARE_UNITTEST(TestVectorEquality);
|
|
|
|
void TestVectorInequality()
|
|
{
|
|
thrust::host_vector<int> h_a{0, 1, 2};
|
|
thrust::host_vector<int> h_b{0, 1, 3};
|
|
thrust::host_vector<int> h_c(3);
|
|
|
|
thrust::device_vector<int> d_a{0, 1, 2};
|
|
thrust::device_vector<int> d_b{0, 1, 3};
|
|
thrust::device_vector<int> d_c(3);
|
|
|
|
std::vector<int> s_a{0, 1, 2};
|
|
std::vector<int> s_b{0, 1, 3};
|
|
std::vector<int> s_c(3);
|
|
|
|
ASSERT_EQUAL((h_a != h_a), false);
|
|
ASSERT_EQUAL((h_a != d_a), false);
|
|
ASSERT_EQUAL((d_a != h_a), false);
|
|
ASSERT_EQUAL((d_a != d_a), false);
|
|
ASSERT_EQUAL((h_b != h_b), false);
|
|
ASSERT_EQUAL((h_b != d_b), false);
|
|
ASSERT_EQUAL((d_b != h_b), false);
|
|
ASSERT_EQUAL((d_b != d_b), false);
|
|
ASSERT_EQUAL((h_c != h_c), false);
|
|
ASSERT_EQUAL((h_c != d_c), false);
|
|
ASSERT_EQUAL((d_c != h_c), false);
|
|
ASSERT_EQUAL((d_c != d_c), false);
|
|
|
|
// test vector vs device_vector
|
|
ASSERT_EQUAL((s_a != d_a), false);
|
|
ASSERT_EQUAL((d_a != s_a), false);
|
|
ASSERT_EQUAL((s_b != d_b), false);
|
|
ASSERT_EQUAL((d_b != s_b), false);
|
|
ASSERT_EQUAL((s_c != d_c), false);
|
|
ASSERT_EQUAL((d_c != s_c), false);
|
|
|
|
// test vector vs host_vector
|
|
ASSERT_EQUAL((s_a != h_a), false);
|
|
ASSERT_EQUAL((h_a != s_a), false);
|
|
ASSERT_EQUAL((s_b != h_b), false);
|
|
ASSERT_EQUAL((h_b != s_b), false);
|
|
ASSERT_EQUAL((s_c != h_c), false);
|
|
ASSERT_EQUAL((h_c != s_c), false);
|
|
|
|
ASSERT_EQUAL((h_a != h_b), true);
|
|
ASSERT_EQUAL((h_a != d_b), true);
|
|
ASSERT_EQUAL((d_a != h_b), true);
|
|
ASSERT_EQUAL((d_a != d_b), true);
|
|
ASSERT_EQUAL((h_b != h_a), true);
|
|
ASSERT_EQUAL((h_b != d_a), true);
|
|
ASSERT_EQUAL((d_b != h_a), true);
|
|
ASSERT_EQUAL((d_b != d_a), true);
|
|
ASSERT_EQUAL((h_a != h_c), true);
|
|
ASSERT_EQUAL((h_a != d_c), true);
|
|
ASSERT_EQUAL((d_a != h_c), true);
|
|
ASSERT_EQUAL((d_a != d_c), true);
|
|
ASSERT_EQUAL((h_c != h_a), true);
|
|
ASSERT_EQUAL((h_c != d_a), true);
|
|
ASSERT_EQUAL((d_c != h_a), true);
|
|
ASSERT_EQUAL((d_c != d_a), true);
|
|
ASSERT_EQUAL((h_b != h_c), true);
|
|
ASSERT_EQUAL((h_b != d_c), true);
|
|
ASSERT_EQUAL((d_b != h_c), true);
|
|
ASSERT_EQUAL((d_b != d_c), true);
|
|
ASSERT_EQUAL((h_c != h_b), true);
|
|
ASSERT_EQUAL((h_c != d_b), true);
|
|
ASSERT_EQUAL((d_c != h_b), true);
|
|
ASSERT_EQUAL((d_c != d_b), true);
|
|
|
|
// test vector vs device_vector
|
|
ASSERT_EQUAL((s_a != d_b), true);
|
|
ASSERT_EQUAL((d_a != s_b), true);
|
|
ASSERT_EQUAL((s_b != d_a), true);
|
|
ASSERT_EQUAL((d_b != s_a), true);
|
|
ASSERT_EQUAL((s_a != d_c), true);
|
|
ASSERT_EQUAL((d_a != s_c), true);
|
|
ASSERT_EQUAL((s_c != d_a), true);
|
|
ASSERT_EQUAL((d_c != s_a), true);
|
|
ASSERT_EQUAL((s_b != d_c), true);
|
|
ASSERT_EQUAL((d_b != s_c), true);
|
|
ASSERT_EQUAL((s_c != d_b), true);
|
|
ASSERT_EQUAL((d_c != s_b), true);
|
|
|
|
// test vector vs host_vector
|
|
ASSERT_EQUAL((s_a != h_b), true);
|
|
ASSERT_EQUAL((h_a != s_b), true);
|
|
ASSERT_EQUAL((s_b != h_a), true);
|
|
ASSERT_EQUAL((h_b != s_a), true);
|
|
ASSERT_EQUAL((s_a != h_c), true);
|
|
ASSERT_EQUAL((h_a != s_c), true);
|
|
ASSERT_EQUAL((s_c != h_a), true);
|
|
ASSERT_EQUAL((h_c != s_a), true);
|
|
ASSERT_EQUAL((s_b != h_c), true);
|
|
ASSERT_EQUAL((h_b != s_c), true);
|
|
ASSERT_EQUAL((s_c != h_b), true);
|
|
ASSERT_EQUAL((h_c != s_b), true);
|
|
}
|
|
DECLARE_UNITTEST(TestVectorInequality);
|
|
|
|
template <class Vector>
|
|
void TestVectorResizing()
|
|
{
|
|
Vector v;
|
|
|
|
v.resize(3);
|
|
|
|
ASSERT_EQUAL(v.size(), 3lu);
|
|
|
|
v = {0, 1, 2};
|
|
v.resize(5);
|
|
|
|
ASSERT_EQUAL(v.size(), 5lu);
|
|
|
|
Vector ref{0, 1, 2, v[3], v[4]};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v[3] = 3;
|
|
v[4] = 4;
|
|
|
|
v.resize(4);
|
|
|
|
ASSERT_EQUAL(v.size(), 4lu);
|
|
|
|
ref = {0, 1, 2, 3};
|
|
ASSERT_EQUAL(v, ref);
|
|
|
|
v.resize(0);
|
|
|
|
ASSERT_EQUAL(v.size(), 0lu);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorResizing);
|
|
|
|
template <class Vector>
|
|
void TestVectorReserving()
|
|
{
|
|
Vector v;
|
|
|
|
v.reserve(3);
|
|
|
|
ASSERT_GEQUAL(v.capacity(), 3lu);
|
|
|
|
size_t old_capacity = v.capacity();
|
|
|
|
v.reserve(0);
|
|
|
|
ASSERT_EQUAL(v.capacity(), old_capacity);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorReserving)
|
|
|
|
template <class Vector>
|
|
void TestVectorUninitialisedCopy()
|
|
{
|
|
thrust::device_vector<int> v;
|
|
std::vector<int> std_vector;
|
|
|
|
v = std_vector;
|
|
|
|
ASSERT_EQUAL(v.size(), static_cast<size_t>(0));
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorUninitialisedCopy);
|
|
|
|
template <class Vector>
|
|
void TestVectorShrinkToFit()
|
|
{
|
|
using T = typename Vector::value_type;
|
|
|
|
Vector v;
|
|
|
|
v.reserve(200);
|
|
|
|
ASSERT_GEQUAL(v.capacity(), 200lu);
|
|
|
|
v.push_back(1);
|
|
v.push_back(2);
|
|
v.push_back(3);
|
|
|
|
v.shrink_to_fit();
|
|
|
|
ASSERT_EQUAL(T(1), v[0]);
|
|
ASSERT_EQUAL(T(2), v[1]);
|
|
ASSERT_EQUAL(T(3), v[2]);
|
|
ASSERT_EQUAL(3lu, v.size());
|
|
ASSERT_EQUAL(3lu, v.capacity());
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorShrinkToFit)
|
|
|
|
template <int N>
|
|
struct LargeStruct
|
|
{
|
|
int data[N];
|
|
|
|
_CCCL_HOST_DEVICE bool operator==(const LargeStruct& ls) const
|
|
{
|
|
for (int i = 0; i < N; i++)
|
|
{
|
|
if (data[i] != ls.data[i])
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void TestVectorContainingLargeType()
|
|
{
|
|
// Thrust issue #5
|
|
// http://code.google.com/p/thrust/issues/detail?id=5
|
|
const static int N = 100;
|
|
using T = LargeStruct<N>;
|
|
|
|
thrust::device_vector<T> dv1;
|
|
thrust::host_vector<T> hv1;
|
|
|
|
ASSERT_EQUAL_QUIET(dv1, hv1);
|
|
|
|
thrust::device_vector<T> dv2(20);
|
|
thrust::host_vector<T> hv2(20);
|
|
|
|
ASSERT_EQUAL_QUIET(dv2, hv2);
|
|
|
|
// initialize tofirst element to something nonzero
|
|
T ls;
|
|
|
|
for (int i = 0; i < N; i++)
|
|
{
|
|
ls.data[i] = i;
|
|
}
|
|
|
|
thrust::device_vector<T> dv3(20, ls);
|
|
thrust::host_vector<T> hv3(20, ls);
|
|
|
|
ASSERT_EQUAL_QUIET(dv3, hv3);
|
|
|
|
// change first element
|
|
ls.data[0] = -13;
|
|
|
|
dv3[2] = ls;
|
|
hv3[2] = ls;
|
|
|
|
ASSERT_EQUAL_QUIET(dv3, hv3);
|
|
}
|
|
DECLARE_UNITTEST(TestVectorContainingLargeType);
|
|
|
|
template <typename Vector>
|
|
void TestVectorReversed()
|
|
{
|
|
Vector v{0, 1, 2};
|
|
|
|
ASSERT_EQUAL(3, v.rend() - v.rbegin());
|
|
ASSERT_EQUAL(3, static_cast<const Vector&>(v).rend() - static_cast<const Vector&>(v).rbegin());
|
|
ASSERT_EQUAL(3, v.crend() - v.crbegin());
|
|
|
|
ASSERT_EQUAL(2, *v.rbegin());
|
|
ASSERT_EQUAL(2, *static_cast<const Vector&>(v).rbegin());
|
|
ASSERT_EQUAL(2, *v.crbegin());
|
|
|
|
ASSERT_EQUAL(1, *(v.rbegin() + 1));
|
|
ASSERT_EQUAL(0, *(v.rbegin() + 2));
|
|
|
|
ASSERT_EQUAL(0, *(v.rend() - 1));
|
|
ASSERT_EQUAL(1, *(v.rend() - 2));
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorReversed);
|
|
|
|
template <class Vector>
|
|
void TestVectorMove()
|
|
{
|
|
// test move construction
|
|
Vector v1{0, 1, 2};
|
|
|
|
const auto ptr1 = v1.data();
|
|
const auto size1 = v1.size();
|
|
|
|
Vector v2(std::move(v1));
|
|
const auto ptr2 = v2.data();
|
|
const auto size2 = v2.size();
|
|
|
|
// ensure v1 was left empty
|
|
ASSERT_EQUAL(true, v1.empty()); // NOLINT(bugprone-use-after-move)
|
|
|
|
// ensure v2 received the data from before
|
|
Vector ref{0, 1, 2};
|
|
ASSERT_EQUAL(v2, ref);
|
|
ASSERT_EQUAL(size1, size2);
|
|
|
|
// ensure v2 received the pointer from before
|
|
ASSERT_EQUAL(ptr1, ptr2);
|
|
|
|
// test move assignment
|
|
Vector v3{3, 4, 5};
|
|
|
|
const auto ptr3 = v3.data();
|
|
const auto size3 = v3.size();
|
|
|
|
v2 = std::move(v3);
|
|
const auto ptr4 = v2.data();
|
|
const auto size4 = v2.size();
|
|
|
|
// ensure v3 was left empty
|
|
ASSERT_EQUAL(true, v3.empty()); // NOLINT(bugprone-use-after-move)
|
|
|
|
// ensure v2 received the data from before
|
|
ref = {3, 4, 5};
|
|
ASSERT_EQUAL(v2, ref);
|
|
ASSERT_EQUAL(size3, size4);
|
|
|
|
// ensure v2 received the pointer from before
|
|
ASSERT_EQUAL(ptr3, ptr4);
|
|
}
|
|
DECLARE_VECTOR_UNITTEST(TestVectorMove);
|
|
|
|
struct IntWithInit
|
|
{
|
|
int value = 42;
|
|
};
|
|
|
|
void TestVectorDefaultInitCtor()
|
|
{
|
|
// trivially-constructible type: just compilation test, since we cannot check that initialization was skipped
|
|
{
|
|
thrust::host_vector<int> hv(10, thrust::default_init);
|
|
thrust::device_vector<int> dv(10, thrust::default_init);
|
|
}
|
|
|
|
// non-trivially-constructible type: check that initialization was performed
|
|
{
|
|
thrust::host_vector<IntWithInit> hv(10, thrust::default_init);
|
|
for (auto e : hv)
|
|
{
|
|
ASSERT_EQUAL(e.value, 42);
|
|
}
|
|
|
|
thrust::device_vector<IntWithInit> dv(10, thrust::default_init);
|
|
for (auto e : dv)
|
|
{
|
|
ASSERT_EQUAL(static_cast<IntWithInit>(e).value, 42);
|
|
}
|
|
}
|
|
}
|
|
DECLARE_UNITTEST(TestVectorDefaultInitCtor);
|
|
|
|
void TestVectorNoInitCtor()
|
|
{
|
|
// trivially-constructible type: just compilation test, since we cannot check that initialization was skipped
|
|
{
|
|
thrust::host_vector<int> hv(10, thrust::no_init);
|
|
thrust::device_vector<int> dv(10, thrust::no_init);
|
|
}
|
|
|
|
// non-trivially-constructible type: those should fail to compile
|
|
// thrust::host_vector<IntWithInit> hv(10, thrust::no_init);
|
|
// thrust::device_vector<IntWithInit> dv(10, thrust::no_init);
|
|
}
|
|
DECLARE_UNITTEST(TestVectorNoInitCtor);
|
|
|
|
void TestVectorDefaultInitResize()
|
|
{
|
|
// trivially-constructible type: just compilation test, since we cannot check that initialization was skipped
|
|
{
|
|
thrust::host_vector<int> hv(5);
|
|
hv.resize(10, thrust::default_init);
|
|
}
|
|
{
|
|
thrust::device_vector<int> dv(5);
|
|
dv.resize(10, thrust::default_init);
|
|
}
|
|
|
|
// non-trivially-constructible type: check that initialization was performed
|
|
{
|
|
thrust::host_vector<IntWithInit> hv(5);
|
|
hv.resize(10, thrust::default_init);
|
|
for (auto e : hv)
|
|
{
|
|
ASSERT_EQUAL(e.value, 42);
|
|
}
|
|
}
|
|
{
|
|
thrust::device_vector<IntWithInit> dv(5, thrust::default_init);
|
|
dv.resize(10, thrust::default_init);
|
|
for (auto e : dv)
|
|
{
|
|
ASSERT_EQUAL(static_cast<IntWithInit>(e).value, 42);
|
|
}
|
|
}
|
|
}
|
|
DECLARE_UNITTEST(TestVectorDefaultInitResize);
|
|
|
|
void TestVectorNoInitResize()
|
|
{
|
|
// trivially-constructible type: just compilation test, since we cannot check that initialization was skipped
|
|
{
|
|
thrust::host_vector<int> hv(5);
|
|
hv.resize(10, thrust::no_init);
|
|
}
|
|
{
|
|
thrust::device_vector<int> dv(5);
|
|
dv.resize(10, thrust::no_init);
|
|
}
|
|
|
|
// non-trivially-constructible type: those should fail to compile
|
|
// thrust::host_vector<IntWithInit>(5).resize(10, thrust::no_init);
|
|
// thrust::device_vector<IntWithInit>(5).resize(10, thrust::no_init);
|
|
}
|
|
DECLARE_UNITTEST(TestVectorNoInitResize);
|