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