SkelCL
SkelCL is a high level multi GPU skeleton library developed at the university of Münster, Germany.
 All Classes Namespaces Files Functions Variables Typedefs Groups
DeviceList.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2011-2012 The SkelCL Team as listed in CREDITS.txt *
3  * http://skelcl.uni-muenster.de *
4  * *
5  * This file is part of SkelCL. *
6  * SkelCL is available under multiple licenses. *
7  * The different licenses are subject to terms and condition as provided *
8  * in the files specifying the license. See "LICENSE.txt" for details *
9  * *
10  *****************************************************************************
11  * *
12  * SkelCL is free software: you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation, either version 3 of the License, or *
15  * (at your option) any later version. See "LICENSE-gpl.txt" for details. *
16  * *
17  * SkelCL is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  *****************************************************************************
23  * *
24  * For non-commercial academic use see the license specified in the file *
25  * "LICENSE-academic.txt". *
26  * *
27  *****************************************************************************
28  * *
29  * If you are interested in other licensing models, including a commercial- *
30  * license, please contact the author at michel.steuwer@uni-muenster.de *
31  * *
32  *****************************************************************************/
33 
39 
40 #include <algorithm>
41 #include <stdexcept>
42 #include <functional>
43 #include <string>
44 #include <vector>
45 
46 #define __CL_ENABLE_EXCEPTIONS
47 #include <CL/cl.hpp>
48 #undef __CL_ENABLE_EXCEPTIONS
49 
50 #include <pvsutil/Assert.h>
51 #include <pvsutil/Logger.h>
52 
53 #include "SkelCL/detail/DeviceList.h"
54 
55 #include "SkelCL/detail/Device.h"
56 #include "SkelCL/detail/DeviceID.h"
57 #include "SkelCL/detail/DeviceProperties.h"
58 #include "SkelCL/detail/PlatformID.h"
59 #include "SkelCL/detail/skelclDll.h"
60 
61 namespace skelcl {
62 
63 namespace detail {
64 
65 SKELCL_DLL DeviceList globalDeviceList;
66 
67 DeviceList::DeviceList()
68  : _devices()
69 {
70 }
71 
72 DeviceList::DeviceList(std::initializer_list<std::shared_ptr<Device>> list)
73  : _devices(list.begin(), list.end())
74 {
75 }
76 
77 bool DeviceList::operator==(const DeviceList& rhs) const
78 {
79  return _devices == rhs._devices;
80 }
81 
82 void DeviceList::init(DeviceProperties properties)
83 {
84  ASSERT(_devices.empty()); // call only once
85  try {
86  std::vector<cl::Platform> platforms;
87  cl::Platform::get(&platforms);
88  ASSERT(platforms.size() > 0); // TODO: Throw Exception
89 
90  LOG_INFO(platforms.size(), " OpenCL platform(s) found");
91 
92  size_t deviceId = 0;
93 
94  // for each platform ...
95  for (auto& platform : platforms) {
96  // .. get all devices ..
97  std::vector<cl::Device> devices;
98  platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
99 
100  LOG_INFO(devices.size(), " device(s) for OpenCL platform `",
101  platform.getInfo<CL_PLATFORM_NAME>(), "' found");
102 
103  for (auto& device : devices) {
104  // ... if device not matches properties ..
105  if (!properties.matchAndTake(device)) {
106  LOG_INFO("Skip device `", device.getInfo<CL_DEVICE_NAME>(),
107  "' not machting given criteria for device selection.");
108  continue; // skip device
109  }
110  // ... create Device instance and push into _devices
111  _devices.push_back( std::make_shared<Device>(device,
112  platform,
113  deviceId)
114  );
115  ++deviceId;
116  }
117  }
118  } catch (cl::Error& err) {
119  ABORT_WITH_ERROR(err);
120  }
121  ASSERT_MESSAGE(!_devices.empty(), "None OpenCL device was selected.");
122  LOG_INFO("Using ", _devices.size(), " OpenCL device(s) in total");
123 }
124 
125 void DeviceList::init(PlatformID pID, DeviceID dID)
126 {
127  ASSERT(_devices.empty()); // call only once
128  try {
129  std::vector<cl::Platform> platforms;
130  cl::Platform::get(&platforms);
131  if (platforms.size() <= pID.id()) {
132  throw std::invalid_argument("Given PlatformID is invalid");
133  }
134 
135  auto& platform = platforms[pID.id()];
136 
137  std::vector<cl::Device> devices;
138  platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
139  if (devices.size() <= dID.id()) {
140  throw std::invalid_argument("Given DeviceID is invalid");
141  }
142 
143  auto& device = devices[dID.id()];
144 
145  _devices.push_back( std::make_shared<Device>(device,
146  platform,
147  0)
148  );
149 
150  } catch (cl::Error& err) {
151  ABORT_WITH_ERROR(err);
152  } catch (std::invalid_argument& ia) {
153  LOG_ERROR("Invalid arguments provided: ", ia.what());
154  abort();
155  }
156  LOG_INFO("Using ", _devices.size(), " OpenCL device(s) in total");
157 }
158 
159 void DeviceList::clear()
160 {
161  _devices.clear();
162 }
163 
164 void DeviceList::barrier() const
165 {
166  try {
167  std::for_each( _devices.begin(), _devices.end(),
168  std::mem_fn(&Device::wait) );
169  } catch (cl::Error& err) {
170  ABORT_WITH_ERROR(err);
171  }
172  LOG_DEBUG_INFO("Finished waiting for ", _devices.size(), " devices");
173 }
174 
175 DeviceList::const_iterator DeviceList::begin() const
176 {
177  return _devices.begin();
178 }
179 
180 DeviceList::const_iterator DeviceList::end() const
181 {
182  return _devices.end();
183 }
184 
185 DeviceList::const_reverse_iterator DeviceList::rbegin() const
186 {
187  return _devices.rbegin();
188 }
189 
190 DeviceList::const_reverse_iterator DeviceList::rend() const
191 {
192  return _devices.rend();
193 }
194 
195 DeviceList::size_type DeviceList::size() const
196 {
197  return _devices.size();
198 }
199 
200 bool DeviceList::empty() const
201 {
202  return _devices.empty();
203 }
204 
205 DeviceList::const_reference DeviceList::operator[](size_type n) const
206 {
207  return _devices.operator[](n);
208 }
209 
210 DeviceList::const_reference DeviceList::at(size_type n) const
211 {
212  return _devices.at(n);
213 }
214 
215 DeviceList::const_reference DeviceList::front() const
216 {
217  return _devices.front();
218 }
219 
220 DeviceList::const_reference DeviceList::back() const
221 {
222  return _devices.back();
223 }
224 
225 } // namespace detail
226 
227 } // namespace skelcl
228 
SKELCL_DLL void init(detail::DeviceProperties properties=allDevices())
Initializes the SkelCL library. This function (or another init function) has to be called prior to ev...
Definition: SkelCL.cpp:51
SKELCL_DLL detail::DeviceID device(size_t dID)
Creates an OpenCL device ID to be used as parameter of the init(detail::PlatformID, detail::DeviceID) function.
Definition: SkelCL.cpp:76
SKELCL_DLL detail::PlatformID platform(size_t pID)
Creates an OpenCL platform ID to be used as parameter of the init(detail::PlatformID, detail::DeviceID) function.
Definition: SkelCL.cpp:71