00001 #ifndef VIENNACL_OCL_DEVICE_HPP_
00002 #define VIENNACL_OCL_DEVICE_HPP_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024 #ifdef __APPLE__
00025 #include <OpenCL/cl.h>
00026 #else
00027 #include <CL/cl.h>
00028 #endif
00029
00030 #include<stdio.h>
00031
00032 #include <vector>
00033 #include <string>
00034 #include <sstream>
00035 #include <assert.h>
00036 #include "viennacl/ocl/handle.hpp"
00037 #include "viennacl/ocl/error.hpp"
00038
00039 namespace viennacl
00040 {
00041 namespace ocl
00042 {
00043
00047 class device
00048 {
00049 public:
00050 explicit device() : device_(0) {}
00051
00052 explicit device(cl_device_id dev) : device_(dev)
00053 {
00054 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_DEVICE)
00055 std::cout << "ViennaCL: Creating device object (CTOR with cl_device_id)" << std::endl;
00056 #endif
00057 init(dev);
00058 }
00059
00060 device(const device & other)
00061 {
00062 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_DEVICE)
00063 std::cout << "ViennaCL: Creating device object (Copy CTOR)" << std::endl;
00064 #endif
00065 device_ = other.device_;
00066 init(device_);
00067 }
00068
00070 void init(cl_device_id dev)
00071 {
00072 cl_int err;
00073
00074
00075 err = clGetDeviceInfo(dev, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &max_work_group_size_, NULL);
00076 VIENNACL_ERR_CHECK(err);
00077 err = clGetDeviceInfo(dev, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &compute_units_, NULL);
00078 VIENNACL_ERR_CHECK(err);
00079 err = clGetDeviceInfo(dev, CL_DEVICE_TYPE, sizeof(cl_device_type), &type_, NULL);
00080 VIENNACL_ERR_CHECK(err);
00081 err = clGetDeviceInfo(dev, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &global_memory_, NULL);
00082 VIENNACL_ERR_CHECK(err);
00083 err = clGetDeviceInfo(dev, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_memory_alloc_, NULL);
00084 VIENNACL_ERR_CHECK(err);
00085 err = clGetDeviceInfo(dev, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(cl_ulong), &local_memory_, NULL);
00086 VIENNACL_ERR_CHECK(err);
00087 }
00088
00090 bool double_support() const
00091 {
00092 char buffer[1024];
00093 bool ret = false;
00094
00095
00096 clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, sizeof(char)*1024, buffer, NULL);
00097 std::string extensions(buffer);
00098 if (extensions.find("cl_khr_fp64") != std::string::npos
00099 || extensions.find("cl_amd_fp64") != std::string::npos)
00100 {
00101 ret = true;
00102 }
00103
00104 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_DEVICE)
00105 std::cout << "ViennaCL: Device extensions: " << std::endl;
00106 std::cout << extensions << std::endl;
00107 if (ret)
00108 std::cout << "ViennaCL: Device " << name() << " supports double precision." << std::endl;
00109 else
00110 std::cout << "ViennaCL: No double precision for device " << name() << "." << std::endl;
00111 #endif
00112
00113 return ret;
00114 }
00115
00116 std::string double_support_extension() const
00117 {
00118 char buffer[1024];
00119 clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, sizeof(char)*1024, buffer, NULL);
00120 std::string extensions(buffer);
00121
00122 if (extensions.find("cl_amd_fp64") != std::string::npos)
00123 return "cl_amd_fp64";
00124
00125 if (extensions.find("cl_khr_fp64") != std::string::npos)
00126 return "cl_khr_fp64";
00127
00128 return "";
00129 }
00130
00132 cl_device_id id() const
00133 {
00134 assert(device_ != 0);
00135 return device_;
00136 }
00137
00139 std::string name() const
00140 {
00141 std::ostringstream oss;
00142 char buffer[1024];
00143 cl_int err;
00144 err = clGetDeviceInfo(device_, CL_DEVICE_NAME, sizeof(char)*1024, &buffer, NULL);
00145 VIENNACL_ERR_CHECK(err);
00146 oss << buffer;
00147 return oss.str();
00148 }
00149
00151 std::string driver_version() const
00152 {
00153 std::ostringstream oss;
00154 char buffer[1024]; buffer[0] = 0;
00155 cl_int err;
00156 err = clGetDeviceInfo(device_, CL_DRIVER_VERSION, sizeof(char)*1024, buffer, NULL);
00157 VIENNACL_ERR_CHECK(err);
00158 oss << buffer;
00159 return oss.str();
00160 }
00161
00163 cl_uint max_compute_units() const
00164 {
00165 return compute_units_;
00166 }
00167
00169 size_t max_workgroup_size() const
00170 {
00171 return max_work_group_size_;
00172 }
00173
00175 cl_ulong global_memory() const
00176 {
00177 return global_memory_;
00178 }
00179
00181 cl_ulong local_memory() const
00182 {
00183 return local_memory_;
00184 }
00185
00187 cl_ulong max_allocable_memory() const
00188 {
00189 return max_memory_alloc_;
00190 }
00191
00193 std::string info() const
00194 {
00195 std::ostringstream oss;
00196 char buffer[1024]; buffer[0] = 0;
00197 cl_int err;
00198 cl_uint vendor_id;
00199 cl_ulong local_mem_size;
00200 cl_ulong global_mem_size;
00201
00202 err = clGetDeviceInfo(device_, CL_DEVICE_VENDOR_ID, sizeof(cl_uint), &vendor_id, NULL);
00203 VIENNACL_ERR_CHECK(err);
00204 oss << "CL Device Vendor ID: " << vendor_id << std::endl;
00205
00206 err = clGetDeviceInfo(device_, CL_DEVICE_NAME, sizeof(char)*1024, buffer, NULL);
00207 VIENNACL_ERR_CHECK(err);
00208 oss << "CL Device Name: " << buffer << std::endl;
00209
00210 err = clGetDeviceInfo(device_, CL_DRIVER_VERSION, sizeof(char)*1024, buffer, NULL);
00211 VIENNACL_ERR_CHECK(err);
00212 std::string test = buffer;
00213 oss << "CL Driver Version: " << test << std::endl;
00214
00215 oss << "--------------------------------" << std::endl;
00216
00217 oss << "CL Device Max Compute Units: " << compute_units_ << std::endl;
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 oss << "CL Device Max Work Group Size: " << max_work_group_size_ << std::endl;
00228
00229 err = clGetDeviceInfo(device_, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &global_mem_size, NULL);
00230 VIENNACL_ERR_CHECK(err);
00231 oss << "CL Device Global Mem Size: " << global_mem_size << std::endl;
00232
00233 err = clGetDeviceInfo(device_, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(cl_ulong), &local_mem_size, NULL);
00234 VIENNACL_ERR_CHECK(err);
00235 oss << "CL Device Local Mem Size: " << local_mem_size << std::endl;
00236
00237
00238 std::string ret(oss.str());
00239 return ret;
00240 }
00241
00242 size_t max_work_group_size() const { return max_work_group_size_; }
00243 cl_uint compute_units() const { return compute_units_; }
00244 cl_device_type type() const { return type_; }
00245
00246 bool operator==(device const & other) const
00247 {
00248 return device_ == other.device_;
00249 }
00250
00251 bool operator==(cl_device_id other) const
00252 {
00253 return device_ == other;
00254 }
00255
00256 private:
00257
00258 cl_device_id device_;
00259 size_t max_work_group_size_;
00260 cl_uint compute_units_;
00261 cl_device_type type_;
00262 cl_ulong max_memory_alloc_;
00263 cl_ulong global_memory_;
00264 cl_ulong local_memory_;
00265 };
00266
00267 }
00268 }
00269
00270 #endif