#include "isaac/driver/device.h" #include #include "helpers/ocl/infos.hpp" namespace isaac { namespace driver { #ifdef ISAAC_WITH_CUDA template int Device::cuGetInfo() const { int res; cuda::check(cuDeviceGetAttribute(&res, attr, *h_.cu)); return res; } Device::Device(int ordinal, bool take_ownership): backend_(CUDA), h_(backend_, take_ownership) { cuda::check(cuDeviceGet(h_.cu.get(), ordinal)); } #endif Device::Device(cl_device_id const & device, bool take_ownership) : backend_(OPENCL), h_(backend_, take_ownership) { h_.cl() = device; } backend_type Device::backend() const { return backend_; } unsigned int Device::address_bits() const { switch(backend_) { #ifdef ISAAC_WITH_CUDA case CUDA: return sizeof(long long)*8; #endif case OPENCL: return ocl::info(h_.cl()); default: throw; } return backend_; } driver::Platform Device::platform() const { switch(backend_) { #ifdef ISAAC_WITH_CUDA case CUDA: return Platform(CUDA); #endif case OPENCL: return Platform(ocl::info(h_.cl())); default: throw; } } std::string Device::name() const { switch(backend_) { #ifdef ISAAC_WITH_CUDA case CUDA: char tmp[128]; cuda::check(cuDeviceGetName(tmp, 128, *h_.cu)); return std::string(tmp); #endif case OPENCL: return ocl::info(h_.cl()); default: throw; } } std::string Device::vendor_str() const { switch(backend_) { #ifdef ISAAC_WITH_CUDA case CUDA: return "NVidia"; #endif case OPENCL: return ocl::info(h_.cl()); default: throw; } } Device::VENDOR Device::vendor() const { std::string vname = vendor_str(); std::transform(vname.begin(), vname.end(), vname.begin(), ::tolower); if(vname.find("nvidia")!=std::string::npos) return NVIDIA; else if(vname.find("intel")!=std::string::npos) return INTEL; else if(vname.find("amd")!=std::string::npos || vname.find("advanced micro devices")!=std::string::npos) return AMD; else return UNKNOWN; } std::vector Device::max_work_item_sizes() const { switch(backend_) { #ifdef ISAAC_WITH_CUDA case CUDA: { std::vector result(3); result[0] = cuGetInfo(); result[1] = cuGetInfo(); result[2] = cuGetInfo(); return result; } #endif case OPENCL: return ocl::info(h_.cl()); default: throw; } } device_type Device::type() const { switch(backend_) { #ifdef ISAAC_WITH_CUDA case CUDA: return DEVICE_TYPE_GPU; #endif case OPENCL: return static_cast(ocl::info(h_.cl())); default: throw; } } std::string Device::extensions() const { switch(backend_) { #ifdef ISAAC_WITH_CUDA case CUDA: return ""; #endif case OPENCL: return ocl::info(h_.cl()); default: throw; } } std::pair Device::nv_compute_capability() const { switch(backend_) { case OPENCL: return std::pair(ocl::info(h_.cl()), ocl::info(h_.cl())); #ifdef ISAAC_WITH_CUDA case CUDA: return std::pair(cuGetInfo(), cuGetInfo()); #endif default: throw; } } bool Device::fp64_support() const { switch(backend_) { case OPENCL: return ocl::info(h_.cl()); #ifdef ISAAC_WITH_CUDA case CUDA: return true; #endif default: throw; } } #ifdef ISAAC_WITH_CUDA #define CUDACASE(CUNAME) case CUDA: return cuGetInfo(); #else #define CUDACASE(CUNAME) #endif\ #define WRAP_ATTRIBUTE(ret, fname, CUNAME, CLNAME) \ ret Device::fname() const\ {\ switch(backend_)\ {\ CUDACASE(CUNAME)\ case OPENCL: return ocl::info(h_.cl());\ default: throw;\ }\ }\ WRAP_ATTRIBUTE(size_t, max_work_group_size, CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK, CL_DEVICE_MAX_WORK_GROUP_SIZE) WRAP_ATTRIBUTE(size_t, local_mem_size, CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK, CL_DEVICE_LOCAL_MEM_SIZE) WRAP_ATTRIBUTE(size_t, warp_wavefront_size, CU_DEVICE_ATTRIBUTE_WARP_SIZE, CL_DEVICE_WAVEFRONT_WIDTH_AMD) WRAP_ATTRIBUTE(size_t, clock_rate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, CL_DEVICE_MAX_CLOCK_FREQUENCY) } }