| | #include <unittest/testframework.h> |
| | #include <unittest/cuda/testframework.h> |
| | #include <thrust/system/cuda/memory.h> |
| | #include <cuda_runtime.h> |
| | #include <numeric> |
| |
|
| | __global__ void dummy_kernel() {} |
| |
|
| | bool binary_exists_for_current_device() |
| | { |
| | |
| | |
| | |
| | cudaFuncAttributes attr; |
| | cudaError_t error = cudaFuncGetAttributes(&attr, dummy_kernel); |
| |
|
| | |
| | |
| | if (cudaSuccess != error) (void)cudaGetLastError(); |
| |
|
| | return cudaSuccess == error; |
| | } |
| |
|
| | void list_devices(void) |
| | { |
| | int deviceCount; |
| | cudaGetDeviceCount(&deviceCount); |
| | if(deviceCount == 0) |
| | { |
| | std::cout << "There is no device supporting CUDA" << std::endl; |
| | } |
| |
|
| | int selected_device; |
| | cudaGetDevice(&selected_device); |
| |
|
| | for (int dev = 0; dev < deviceCount; ++dev) |
| | { |
| | cudaDeviceProp deviceProp; |
| | cudaGetDeviceProperties(&deviceProp, dev); |
| |
|
| | if(dev == 0) |
| | { |
| | if(deviceProp.major == 9999 && deviceProp.minor == 9999) |
| | std::cout << "There is no device supporting CUDA." << std::endl; |
| | else if(deviceCount == 1) |
| | std::cout << "There is 1 device supporting CUDA" << std:: endl; |
| | else |
| | std::cout << "There are " << deviceCount << " devices supporting CUDA" << std:: endl; |
| | } |
| |
|
| | std::cout << "\nDevice " << dev << ": \"" << deviceProp.name << "\""; |
| | if(dev == selected_device) |
| | std::cout << " [SELECTED]"; |
| | std::cout << std::endl; |
| |
|
| | std::cout << " Major revision number: " << deviceProp.major << std::endl; |
| | std::cout << " Minor revision number: " << deviceProp.minor << std::endl; |
| | std::cout << " Total amount of global memory: " << deviceProp.totalGlobalMem << " bytes" << std::endl; |
| | } |
| | std::cout << std::endl; |
| | } |
| |
|
| | |
| | template<typename Iterator> Iterator my_next(Iterator iter) |
| | { |
| | return ++iter; |
| | } |
| |
|
| |
|
| | std::vector<int> CUDATestDriver::target_devices(const ArgumentMap &kwargs) |
| | { |
| | std::vector<int> result; |
| |
|
| | |
| | int device_id = kwargs.count("device") ? atoi(kwargs.find("device")->second.c_str()) : -1; |
| |
|
| | if(device_id < 0) |
| | { |
| | |
| | int count = 0; |
| | cudaGetDeviceCount(&count); |
| |
|
| | result.resize(count); |
| | std::iota(result.begin(), result.end(), 0); |
| | } |
| | else |
| | { |
| | |
| | result = std::vector<int>(1,device_id); |
| | } |
| |
|
| | return result; |
| | } |
| |
|
| | bool CUDATestDriver::check_cuda_error(bool concise) |
| | { |
| | cudaError_t const error = cudaGetLastError(); |
| | if(cudaSuccess != error) |
| | { |
| | if(!concise) |
| | { |
| | std::cout << "[ERROR] CUDA error detected before running tests: [" |
| | << std::string(cudaGetErrorName(error)) |
| | << ": " |
| | << std::string(cudaGetErrorString(error)) |
| | << "]" << std::endl; |
| | } |
| | } |
| |
|
| | return cudaSuccess != error; |
| | } |
| |
|
| | bool CUDATestDriver::post_test_smoke_check(const UnitTest &test, bool concise) |
| | { |
| | cudaError_t const error = cudaDeviceSynchronize(); |
| | if(cudaSuccess != error) |
| | { |
| | if(!concise) |
| | { |
| | std::cout << "\t[ERROR] CUDA error detected after running " << test.name << ": [" |
| | << std::string(cudaGetErrorName(error)) |
| | << ": " |
| | << std::string(cudaGetErrorString(error)) |
| | << "]" << std::endl; |
| | } |
| | } |
| |
|
| | return cudaSuccess == error; |
| | } |
| |
|
| | bool CUDATestDriver::run_tests(const ArgumentSet &args, const ArgumentMap &kwargs) |
| | { |
| | bool verbose = kwargs.count("verbose"); |
| | bool concise = kwargs.count("concise"); |
| |
|
| | if(verbose && concise) |
| | { |
| | std::cout << "--verbose and --concise cannot be used together" << std::endl; |
| | exit(EXIT_FAILURE); |
| | } |
| |
|
| | |
| | if(check_cuda_error(concise)) return false; |
| |
|
| | bool result = true; |
| |
|
| | if(kwargs.count("verbose")) |
| | { |
| | list_devices(); |
| | } |
| |
|
| | |
| | std::vector<int> devices = target_devices(kwargs); |
| |
|
| | |
| | for(std::vector<int>::iterator device = devices.begin(); |
| | device != devices.end(); |
| | ++device) |
| | { |
| | cudaDeviceSynchronize(); |
| |
|
| | |
| | cudaSetDevice(*device); |
| |
|
| | |
| | |
| | if(devices.size() > 1 && !binary_exists_for_current_device()) |
| | { |
| | |
| | cudaDeviceProp deviceProp; |
| | cudaGetDeviceProperties(&deviceProp, *device); |
| |
|
| | std::cout << "Skipping Device " << *device << ": \"" << deviceProp.name << "\"" << std::endl; |
| |
|
| | continue; |
| | } |
| |
|
| | if(!concise) |
| | { |
| | |
| | cudaDeviceProp deviceProp; |
| | cudaGetDeviceProperties(&deviceProp, *device); |
| |
|
| | std::cout << "Testing Device " << *device << ": \"" << deviceProp.name << "\"" << std::endl; |
| | } |
| |
|
| | |
| | if(check_cuda_error(concise)) return false; |
| |
|
| | |
| | result &= UnitTestDriver::run_tests(args, kwargs); |
| |
|
| | if(!concise && my_next(device) != devices.end()) |
| | { |
| | |
| | std::cout << std::endl; |
| | } |
| | } |
| |
|
| | return result; |
| | } |
| |
|
| | int CUDATestDriver::current_device_architecture() const |
| | { |
| | int current = -1; |
| | cudaGetDevice(¤t); |
| | cudaDeviceProp deviceProp; |
| | cudaGetDeviceProperties(&deviceProp, current); |
| |
|
| | return 100 * deviceProp.major + 10 * deviceProp.minor; |
| | } |
| |
|
| | UnitTestDriver &driver_instance(thrust::system::cuda::tag) |
| | { |
| | static CUDATestDriver s_instance; |
| | return s_instance; |
| | } |
| |
|
| |
|