ViennaCL - The Vienna Computing Library  1.2.0
device.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_OCL_DEVICE_HPP_
2 #define VIENNACL_OCL_DEVICE_HPP_
3 
4 /* =========================================================================
5  Copyright (c) 2010-2011, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8 
9  -----------------
10  ViennaCL - The Vienna Computing Library
11  -----------------
12 
13  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
14 
15  (A list of authors and contributors can be found in the PDF manual)
16 
17  License: MIT (X11), see file LICENSE in the base directory
18 ============================================================================= */
19 
24 #ifdef __APPLE__
25 #include <OpenCL/cl.h>
26 #else
27 #include <CL/cl.h>
28 #endif
29 
30 #include<stdio.h>
31 
32 #include <vector>
33 #include <string>
34 #include <sstream>
35 #include <assert.h>
36 #include "viennacl/ocl/handle.hpp"
37 #include "viennacl/ocl/error.hpp"
38 
39 namespace viennacl
40 {
41  namespace ocl
42  {
43 
47  class device
48  {
49  public:
50  explicit device() : device_(0) {}
51 
52  explicit device(cl_device_id dev) : device_(dev)
53  {
54  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_DEVICE)
55  std::cout << "ViennaCL: Creating device object (CTOR with cl_device_id)" << std::endl;
56  #endif
57  init(dev);
58  }
59 
60  device(const device & other)
61  {
62  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_DEVICE)
63  std::cout << "ViennaCL: Creating device object (Copy CTOR)" << std::endl;
64  #endif
65  device_ = other.device_;
66  init(device_);
67  }
68 
70  void init(cl_device_id dev)
71  {
72  cl_int err;
73 
74  //query a little bit of info:
75  err = clGetDeviceInfo(dev, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &max_work_group_size_, NULL);
76  VIENNACL_ERR_CHECK(err);
77  err = clGetDeviceInfo(dev, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &compute_units_, NULL);
78  VIENNACL_ERR_CHECK(err);
79  err = clGetDeviceInfo(dev, CL_DEVICE_TYPE, sizeof(cl_device_type), &type_, NULL);
80  VIENNACL_ERR_CHECK(err);
81  err = clGetDeviceInfo(dev, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &global_memory_, NULL);
82  VIENNACL_ERR_CHECK(err);
83  err = clGetDeviceInfo(dev, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_memory_alloc_, NULL);
84  VIENNACL_ERR_CHECK(err);
85  err = clGetDeviceInfo(dev, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(cl_ulong), &local_memory_, NULL);
86  VIENNACL_ERR_CHECK(err);
87  }
88 
90  bool double_support() const
91  {
92  char buffer[1024];
93  bool ret = false;
94 
95  //get extensions and search for double precision
96  clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, sizeof(char)*1024, buffer, NULL);
97  std::string extensions(buffer);
98  if (extensions.find("cl_khr_fp64") != std::string::npos
99  || extensions.find("cl_amd_fp64") != std::string::npos)
100  {
101  ret = true;
102  }
103 
104  #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_DEVICE)
105  std::cout << "ViennaCL: Device extensions: " << std::endl;
106  std::cout << extensions << std::endl;
107  if (ret)
108  std::cout << "ViennaCL: Device " << name() << " supports double precision." << std::endl;
109  else
110  std::cout << "ViennaCL: No double precision for device " << name() << "." << std::endl;
111  #endif
112 
113  return ret;
114  }
115 
116  std::string double_support_extension() const
117  {
118  char buffer[1024];
119  clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, sizeof(char)*1024, buffer, NULL);
120  std::string extensions(buffer);
121 
122  if (extensions.find("cl_amd_fp64") != std::string::npos) //AMD extension
123  return "cl_amd_fp64";
124 
125  if (extensions.find("cl_khr_fp64") != std::string::npos) //Khronos-certified standard extension for double precision
126  return "cl_khr_fp64";
127 
128  return "";
129  }
130 
132  cl_device_id id() const
133  {
134  assert(device_ != 0);
135  return device_;
136  }
137 
139  std::string name() const
140  {
141  std::ostringstream oss;
142  char buffer[1024];
143  cl_int err;
144  err = clGetDeviceInfo(device_, CL_DEVICE_NAME, sizeof(char)*1024, &buffer, NULL);
145  VIENNACL_ERR_CHECK(err);
146  oss << buffer;
147  return oss.str();
148  }
149 
151  std::string driver_version() const
152  {
153  std::ostringstream oss;
154  char buffer[1024]; buffer[0] = 0;
155  cl_int err;
156  err = clGetDeviceInfo(device_, CL_DRIVER_VERSION, sizeof(char)*1024, buffer, NULL);
157  VIENNACL_ERR_CHECK(err);
158  oss << buffer;
159  return oss.str();
160  }
161 
163  cl_uint max_compute_units() const
164  {
165  return compute_units_;
166  }
167 
169  size_t max_workgroup_size() const
170  {
171  return max_work_group_size_;
172  }
173 
175  cl_ulong global_memory() const
176  {
177  return global_memory_;
178  }
179 
181  cl_ulong local_memory() const
182  {
183  return local_memory_;
184  }
185 
187  cl_ulong max_allocable_memory() const
188  {
189  return max_memory_alloc_;
190  }
191 
193  std::string info() const
194  {
195  std::ostringstream oss;
196  char buffer[1024]; buffer[0] = 0;
197  cl_int err;
198  cl_uint vendor_id;
199  cl_ulong local_mem_size;
200  cl_ulong global_mem_size;
201 
202  err = clGetDeviceInfo(device_, CL_DEVICE_VENDOR_ID, sizeof(cl_uint), &vendor_id, NULL);
203  VIENNACL_ERR_CHECK(err);
204  oss << "CL Device Vendor ID: " << vendor_id << std::endl;
205 
206  err = clGetDeviceInfo(device_, CL_DEVICE_NAME, sizeof(char)*1024, buffer, NULL);
207  VIENNACL_ERR_CHECK(err);
208  oss << "CL Device Name: " << buffer << std::endl;
209 
210  err = clGetDeviceInfo(device_, CL_DRIVER_VERSION, sizeof(char)*1024, buffer, NULL);
211  VIENNACL_ERR_CHECK(err);
212  std::string test = buffer;
213  oss << "CL Driver Version: " << test << std::endl;
214 
215  oss << "--------------------------------" << std::endl;
216 
217  oss << "CL Device Max Compute Units: " << compute_units_ << std::endl;
218 
219  // err = clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(char)*1024, buffer, NULL);
220  // CL_ERR_CHECK(err);
221  // oss << "CL Device Max Work Item Dimensions: " << buffer << std::endl;
222  //
223  // err = clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(char)*1024, buffer, NULL);
224  // CL_ERR_CHECK(err);
225  // oss << "CL Device Max Work Item Sizes: " << buffer << std::endl;
226 
227  oss << "CL Device Max Work Group Size: " << max_work_group_size_ << std::endl;
228 
229  err = clGetDeviceInfo(device_, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), &global_mem_size, NULL);
230  VIENNACL_ERR_CHECK(err);
231  oss << "CL Device Global Mem Size: " << global_mem_size << std::endl;
232 
233  err = clGetDeviceInfo(device_, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(cl_ulong), &local_mem_size, NULL);
234  VIENNACL_ERR_CHECK(err);
235  oss << "CL Device Local Mem Size: " << local_mem_size << std::endl;
236 
237  //return info string:
238  std::string ret(oss.str());
239  return ret;
240  }
241 
242  size_t max_work_group_size() const { return max_work_group_size_; }
243  cl_uint compute_units() const { return compute_units_; }
244  cl_device_type type() const { return type_; }
245 
246  bool operator==(device const & other) const
247  {
248  return device_ == other.device_;
249  }
250 
251  bool operator==(cl_device_id other) const
252  {
253  return device_ == other;
254  }
255 
256  private:
257 
258  cl_device_id device_;
259  size_t max_work_group_size_;
260  cl_uint compute_units_;
261  cl_device_type type_; //device type
262  cl_ulong max_memory_alloc_;
263  cl_ulong global_memory_;
264  cl_ulong local_memory_;
265  };
266 
267  } //namespace ocl
268 } //namespace viennacl
269 
270 #endif