#include #include #include #include template __global__ void sort_by_key_kernel(ExecutionPolicy exec, Iterator1 keys_first, Iterator1 keys_last, Iterator2 values_first, Compare comp, Iterator3 is_supported) { #if (__CUDA_ARCH__ >= 200) *is_supported = true; thrust::sort_by_key(exec, keys_first, keys_last, values_first, comp); #else *is_supported = false; #endif } template struct my_less { __host__ __device__ bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } }; template void TestComparisonSortByKeyDevice(ExecutionPolicy exec, const size_t n, Compare comp) { thrust::host_vector h_keys = unittest::random_integers(n); thrust::device_vector d_keys = h_keys; thrust::host_vector h_values = h_keys; thrust::device_vector d_values = d_keys; thrust::device_vector is_supported(1); sort_by_key_kernel<<<1,1>>>(exec, d_keys.begin(), d_keys.end(), d_values.begin(), comp, is_supported.begin()); cudaError_t const err = cudaDeviceSynchronize(); ASSERT_EQUAL(cudaSuccess, err); if(is_supported[0]) { thrust::sort_by_key(h_keys.begin(), h_keys.end(), h_values.begin(), comp); ASSERT_EQUAL(h_keys, d_keys); ASSERT_EQUAL(h_values, d_values); } }; template struct TestComparisonSortByKeyDeviceSeq { void operator()(const size_t n) { TestComparisonSortByKeyDevice(thrust::seq, n, my_less()); } }; VariableUnitTest< TestComparisonSortByKeyDeviceSeq, unittest::type_list > TestComparisonSortByKeyDeviceSeqInstance; template struct TestComparisonSortByKeyDeviceDevice { void operator()(const size_t n) { TestComparisonSortByKeyDevice(thrust::device, n, my_less()); } }; VariableUnitTest< TestComparisonSortByKeyDeviceDevice, unittest::type_list > TestComparisonSortByKeyDeviceDeviceDeviceInstance; template void TestSortByKeyDevice(ExecutionPolicy exec, const size_t n) { TestComparisonSortByKeyDevice(exec, n, thrust::less()); }; template struct TestSortByKeyDeviceSeq { void operator()(const size_t n) { TestSortByKeyDevice(thrust::seq, n); } }; VariableUnitTest< TestSortByKeyDeviceSeq, unittest::type_list > TestSortByKeyDeviceSeqInstance; template struct TestSortByKeyDeviceDevice { void operator()(const size_t n) { TestSortByKeyDevice(thrust::device, n); } }; VariableUnitTest< TestSortByKeyDeviceDevice, unittest::type_list > TestSortByKeyDeviceDeviceInstance; void TestComparisonSortByKeyCudaStreams() { thrust::device_vector keys(10); thrust::device_vector vals(10); keys[0] = 9; vals[0] = 9; keys[1] = 3; vals[1] = 3; keys[2] = 2; vals[2] = 2; keys[3] = 0; vals[3] = 0; keys[4] = 4; vals[4] = 4; keys[5] = 7; vals[5] = 7; keys[6] = 8; vals[6] = 8; keys[7] = 1; vals[7] = 1; keys[8] = 5; vals[8] = 5; keys[9] = 6; vals[9] = 6; cudaStream_t s; cudaStreamCreate(&s); thrust::sort_by_key(thrust::cuda::par.on(s), keys.begin(), keys.end(), vals.begin(), my_less()); cudaStreamSynchronize(s); ASSERT_EQUAL(true, thrust::is_sorted(keys.begin(), keys.end())); ASSERT_EQUAL(true, thrust::is_sorted(vals.begin(), vals.end())); cudaStreamDestroy(s); } DECLARE_UNITTEST(TestComparisonSortByKeyCudaStreams); void TestSortByKeyCudaStreams() { thrust::device_vector keys(10); thrust::device_vector vals(10); keys[0] = 9; vals[0] = 9; keys[1] = 3; vals[1] = 3; keys[2] = 2; vals[2] = 2; keys[3] = 0; vals[3] = 0; keys[4] = 4; vals[4] = 4; keys[5] = 7; vals[5] = 7; keys[6] = 8; vals[6] = 8; keys[7] = 1; vals[7] = 1; keys[8] = 5; vals[8] = 5; keys[9] = 6; vals[9] = 6; cudaStream_t s; cudaStreamCreate(&s); thrust::sort_by_key(thrust::cuda::par.on(s), keys.begin(), keys.end(), vals.begin()); cudaStreamSynchronize(s); ASSERT_EQUAL(true, thrust::is_sorted(keys.begin(), keys.end())); ASSERT_EQUAL(true, thrust::is_sorted(vals.begin(), vals.end())); cudaStreamDestroy(s); } DECLARE_UNITTEST(TestSortByKeyCudaStreams);