Spaces:
Runtime error
Runtime error
#include <unittest/unittest.h> | |
#include <thrust/copy.h> | |
#include <thrust/sequence.h> | |
#include <thrust/execution_policy.h> | |
template<typename T> | |
struct is_even | |
{ | |
__host__ __device__ | |
bool operator()(T x) { return (static_cast<unsigned int>(x) & 1) == 0; } | |
}; | |
template<typename T> | |
struct mod_3 | |
{ | |
__host__ __device__ | |
unsigned int operator()(T x) { return static_cast<unsigned int>(x) % 3; } | |
}; | |
template<typename ExecutionPolicy, typename Iterator1, typename Iterator2, typename Predicate, typename Iterator3> | |
__global__ void copy_if_kernel(ExecutionPolicy exec, Iterator1 first, Iterator1 last, Iterator2 result1, Predicate pred, Iterator3 result2) | |
{ | |
*result2 = thrust::copy_if(exec, first, last, result1, pred); | |
} | |
template<typename ExecutionPolicy> | |
void TestCopyIfDevice(ExecutionPolicy exec) | |
{ | |
size_t n = 1000; | |
thrust::host_vector<int> h_data = unittest::random_integers<int>(n); | |
thrust::device_vector<int> d_data = h_data; | |
typename thrust::host_vector<int>::iterator h_new_end; | |
typename thrust::device_vector<int>::iterator d_new_end; | |
thrust::device_vector< | |
typename thrust::device_vector<int>::iterator | |
> d_new_end_vec(1); | |
// test with Predicate that returns a bool | |
{ | |
thrust::host_vector<int> h_result(n); | |
thrust::device_vector<int> d_result(n); | |
h_new_end = thrust::copy_if(h_data.begin(), h_data.end(), h_result.begin(), is_even<int>()); | |
copy_if_kernel<<<1,1>>>(exec, d_data.begin(), d_data.end(), d_result.begin(), is_even<int>(), d_new_end_vec.begin()); | |
cudaError_t const err = cudaDeviceSynchronize(); | |
ASSERT_EQUAL(cudaSuccess, err); | |
d_new_end = d_new_end_vec[0]; | |
h_result.resize(h_new_end - h_result.begin()); | |
d_result.resize(d_new_end - d_result.begin()); | |
ASSERT_EQUAL(h_result, d_result); | |
} | |
// test with Predicate that returns a non-bool | |
{ | |
thrust::host_vector<int> h_result(n); | |
thrust::device_vector<int> d_result(n); | |
h_new_end = thrust::copy_if(h_data.begin(), h_data.end(), h_result.begin(), mod_3<int>()); | |
copy_if_kernel<<<1,1>>>(exec, d_data.begin(), d_data.end(), d_result.begin(), mod_3<int>(), d_new_end_vec.begin()); | |
cudaError_t const err = cudaDeviceSynchronize(); | |
ASSERT_EQUAL(cudaSuccess, err); | |
d_new_end = d_new_end_vec[0]; | |
h_result.resize(h_new_end - h_result.begin()); | |
d_result.resize(d_new_end - d_result.begin()); | |
ASSERT_EQUAL(h_result, d_result); | |
} | |
} | |
void TestCopyIfDeviceSeq() | |
{ | |
TestCopyIfDevice(thrust::seq); | |
} | |
DECLARE_UNITTEST(TestCopyIfDeviceSeq); | |
void TestCopyIfDeviceDevice() | |
{ | |
TestCopyIfDevice(thrust::device); | |
} | |
DECLARE_UNITTEST(TestCopyIfDeviceDevice); | |
void TestCopyIfCudaStreams() | |
{ | |
typedef thrust::device_vector<int> Vector; | |
Vector data(5); | |
data[0] = 1; | |
data[1] = 2; | |
data[2] = 1; | |
data[3] = 3; | |
data[4] = 2; | |
Vector result(5); | |
cudaStream_t s; | |
cudaStreamCreate(&s); | |
Vector::iterator end = thrust::copy_if(thrust::cuda::par.on(s), | |
data.begin(), | |
data.end(), | |
result.begin(), | |
is_even<int>()); | |
ASSERT_EQUAL(end - result.begin(), 2); | |
ASSERT_EQUAL(result[0], 2); | |
ASSERT_EQUAL(result[1], 2); | |
cudaStreamDestroy(s); | |
} | |
DECLARE_UNITTEST(TestCopyIfCudaStreams); | |
template<typename ExecutionPolicy, typename Iterator1, typename Iterator2, typename Iterator3, typename Predicate, typename Iterator4> | |
__global__ void copy_if_kernel(ExecutionPolicy exec, Iterator1 first, Iterator1 last, Iterator2 stencil_first, Iterator3 result1, Predicate pred, Iterator4 result2) | |
{ | |
*result2 = thrust::copy_if(exec, first, last, stencil_first, result1, pred); | |
} | |
template<typename ExecutionPolicy> | |
void TestCopyIfStencilDevice(ExecutionPolicy exec) | |
{ | |
size_t n = 1000; | |
thrust::host_vector<int> h_data(n); thrust::sequence(h_data.begin(), h_data.end()); | |
thrust::device_vector<int> d_data(n); thrust::sequence(d_data.begin(), d_data.end()); | |
thrust::host_vector<int> h_stencil = unittest::random_integers<int>(n); | |
thrust::device_vector<int> d_stencil = unittest::random_integers<int>(n); | |
thrust::host_vector<int> h_result(n); | |
thrust::device_vector<int> d_result(n); | |
typename thrust::host_vector<int>::iterator h_new_end; | |
typename thrust::device_vector<int>::iterator d_new_end; | |
thrust::device_vector< | |
typename thrust::device_vector<int>::iterator | |
> d_new_end_vec(1); | |
// test with Predicate that returns a bool | |
{ | |
thrust::host_vector<int> h_result(n); | |
thrust::device_vector<int> d_result(n); | |
h_new_end = thrust::copy_if(h_data.begin(), h_data.end(), h_result.begin(), is_even<int>()); | |
copy_if_kernel<<<1,1>>>(exec, d_data.begin(), d_data.end(), d_result.begin(), is_even<int>(), d_new_end_vec.begin()); | |
cudaError_t const err = cudaDeviceSynchronize(); | |
ASSERT_EQUAL(cudaSuccess, err); | |
d_new_end = d_new_end_vec[0]; | |
h_result.resize(h_new_end - h_result.begin()); | |
d_result.resize(d_new_end - d_result.begin()); | |
ASSERT_EQUAL(h_result, d_result); | |
} | |
// test with Predicate that returns a non-bool | |
{ | |
thrust::host_vector<int> h_result(n); | |
thrust::device_vector<int> d_result(n); | |
h_new_end = thrust::copy_if(h_data.begin(), h_data.end(), h_result.begin(), mod_3<int>()); | |
copy_if_kernel<<<1,1>>>(exec, d_data.begin(), d_data.end(), d_result.begin(), mod_3<int>(), d_new_end_vec.begin()); | |
cudaError_t const err = cudaDeviceSynchronize(); | |
ASSERT_EQUAL(cudaSuccess, err); | |
d_new_end = d_new_end_vec[0]; | |
h_result.resize(h_new_end - h_result.begin()); | |
d_result.resize(d_new_end - d_result.begin()); | |
ASSERT_EQUAL(h_result, d_result); | |
} | |
} | |
void TestCopyIfStencilDeviceSeq() | |
{ | |
TestCopyIfStencilDevice(thrust::seq); | |
} | |
DECLARE_UNITTEST(TestCopyIfStencilDeviceSeq); | |
void TestCopyIfStencilDeviceDevice() | |
{ | |
TestCopyIfStencilDevice(thrust::device); | |
} | |
DECLARE_UNITTEST(TestCopyIfStencilDeviceDevice); | |
void TestCopyIfStencilCudaStreams() | |
{ | |
typedef thrust::device_vector<int> Vector; | |
typedef Vector::value_type T; | |
Vector data(5); | |
data[0] = 1; | |
data[1] = 2; | |
data[2] = 1; | |
data[3] = 3; | |
data[4] = 2; | |
Vector result(5); | |
Vector stencil(5); | |
stencil[0] = 0; | |
stencil[1] = 1; | |
stencil[2] = 0; | |
stencil[3] = 0; | |
stencil[4] = 1; | |
cudaStream_t s; | |
cudaStreamCreate(&s); | |
Vector::iterator end = thrust::copy_if(thrust::cuda::par.on(s), | |
data.begin(), | |
data.end(), | |
stencil.begin(), | |
result.begin(), | |
thrust::identity<T>()); | |
ASSERT_EQUAL(end - result.begin(), 2); | |
ASSERT_EQUAL(result[0], 2); | |
ASSERT_EQUAL(result[1], 2); | |
cudaStreamDestroy(s); | |
} | |
DECLARE_UNITTEST(TestCopyIfStencilCudaStreams); | |