#include #include #include #include #include "isaac/driver/device.h" #include "helpers/ocl/infos.hpp" namespace isaac { namespace driver { template int Device::cuGetInfo() const { int res; cuda::check(dispatch::cuDeviceGetAttribute(&res, attr, h_.cu())); return res; } Device::Device(int ordinal): backend_(CUDA), h_(backend_, true) { cuda::check(dispatch::cuDeviceGet(&h_.cu(), ordinal)); } Device::Device(cl_device_id const & device, bool take_ownership) : backend_(OPENCL), h_(backend_, take_ownership) { h_.cl() = device; } bool Device::operator==(Device const & other) const { return h_==other.h_; } bool Device::operator<(Device const & other) const { return h_(h_.cl()); default: throw; } return backend_; } driver::Platform Device::platform() const { switch(backend_) { case CUDA: return Platform(CUDA); case OPENCL: return Platform(ocl::info(h_.cl())); default: throw; } } std::string Device::name() const { switch(backend_) { case CUDA: char tmp[128]; cuda::check(dispatch::cuDeviceGetName(tmp, 128, h_.cu())); return std::string(tmp); case OPENCL: return ocl::info(h_.cl()); default: throw; } } std::string Device::vendor_str() const { switch(backend_) { case CUDA: return "NVidia"; case OPENCL: return ocl::info(h_.cl()); default: throw; } } std::vector Device::max_work_item_sizes() const { switch(backend_) { case CUDA: { std::vector result(3); result[0] = cuGetInfo(); result[1] = cuGetInfo(); result[2] = cuGetInfo(); return result; } case OPENCL: return ocl::info(h_.cl()); default: throw; } } Device::Type Device::type() const { switch(backend_) { case CUDA: return Type::GPU; case OPENCL: return static_cast(ocl::info(h_.cl())); default: throw; } } std::string Device::extensions() const { switch(backend_) { case CUDA: return ""; 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())); case CUDA: return std::pair(cuGetInfo(), cuGetInfo()); default: throw; } } bool Device::fp64_support() const { switch(backend_) { case OPENCL: return extensions().find("cl_khr_fp64")!=std::string::npos; case CUDA: return true; default: throw; } } std::string Device::infos() const { std::ostringstream oss; std::vector max_wi_sizes = max_work_item_sizes(); oss << "Platform: " << platform().name() << std::endl; oss << "Vendor: " << vendor_str() << std::endl; oss << "Name: " << name() << std::endl; oss << "Maximum total work-group size: " << max_work_group_size() << std::endl; oss << "Maximum individual work-group sizes: " << max_wi_sizes[0] << ", " << max_wi_sizes[1] << ", " << max_wi_sizes[2] << std::endl; oss << "Local memory size: " << local_mem_size() << std::endl; return oss.str(); } // Properties #define WRAP_ATTRIBUTE(ret, fname, CUNAME, CLNAME) \ ret Device::fname() const\ {\ switch(backend_)\ {\ case CUDA: return cuGetInfo();\ case OPENCL: return static_cast(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) } }