1 /* Copyright (C) 2018 Federico Simmross Wattenberg,
2 * Manuel Rodríguez Cayetano,
3 * Javier Royuela del Val,
4 * Elena Martín González,
6 * Marcos Martín Fernández and
7 * Carlos Alberola López
9 * This file is part of OpenCLIPER.
11 * OpenCLIPER is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 3 of the License.
15 * OpenCLIPER is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with OpenCLIPER; If not, see <http://www.gnu.org/licenses/>.
26 * Federico Simmross Wattenberg
27 * E.T.S.I. Telecomunicación
28 * Universidad de Valladolid
30 * 47011 Valladolid, Spain.
36 #define CL_HPP_ENABLE_EXCEPTIONS
37 #define CL_HPP_TARGET_OPENCL_VERSION 120
38 #define CL_HPP_MINIMUM_OPENCL_VERSION 120
40 #if defined(__APPLE__) || defined(__MACOSX)
41 #include<OpenCL/cl.hpp>
48 // For gethostname POSIX function
54 #include<OpenCLIPER/OpenCLIPERDataModelCommonDefs.hpp>
55 #include<LPISupport/Utils.hpp>
56 #include<LPISupport/InfoItems.hpp>
57 #include<OpenCLIPER/Process.hpp>
59 // cl2.hpp includes the | operator but not &
60 // We need it to test for supported command queue properties
61 inline cl::QueueProperties operator&(cl::QueueProperties lhs, cl::QueueProperties rhs) {
62 return static_cast<cl::QueueProperties>(static_cast<cl_command_queue_properties>(lhs) & static_cast<cl_command_queue_properties>(rhs));
65 namespace OpenCLIPER {
69 /// Data type for a list of OpenCL kernels
70 typedef std::map<std::string,cl::Kernel> kernelListT;
73 * @brief Class representing an application with an OpenCL device bound
76 * * infomation about available and selected devices
77 * * a list of Process subclasses objects (representing algorithms to be executed on selected device)
78 * * a list of Data subclasses objects (used as input and/or output data for Process subclasses objects).
80 class CLapp: public std::enable_shared_from_this<CLapp>{
83 /// Enumerated type with the device type options
85 DEVICE_TYPE_ANY=CL_DEVICE_TYPE_ALL, ///< any device is valid CPU or GPU
86 DEVICE_TYPE_CPU=CL_DEVICE_TYPE_CPU, ///< only CPU devices are valid
87 DEVICE_TYPE_GPU=CL_DEVICE_TYPE_GPU ///< only GPU devices are valid
90 /// Struct with options for selection of OpenCL platform
91 struct PlatformTraits {
98 /// platform required extensions
99 std::vector<std::string> extensions;
102 /// Struct with options for selection of OpenCL device
103 struct DeviceTraits {
104 /// type of device (CPU, GPU, etc.)
112 /// device required extensions
113 std::vector<std::string> extensions;
114 /// device queue properties
115 cl::QueueProperties queueProperties;
118 * @brief Default constructor for struct fields initialization.
121 DeviceTraits(DeviceType t=DEVICE_TYPE_ANY,cl::QueueProperties p=cl::QueueProperties::None):
122 type(t), queueProperties(p) {}
125 /// @brief Default constructor (empty).
127 CLapp(const PlatformTraits& platformTraits,const DeviceTraits& deviceTraits);
130 static const char* getOpenCLErrorCodeStr(const cl_int err);
132 * @brief Sets error text explantation from error code (integer)
133 * @param[in] err error code
134 * @param[out] errStr text message for the error code
136 void setOpenCLErrorCodeStr(const cl_int err,const char* errStr) { errStrings[err]=errStr; }
137 static int dumpInfo();
139 void init(const PlatformTraits& platformTraits, const DeviceTraits& deviceTraits);
140 void loadKernels(const std::string& filename, const char* compilerOptionsArg=nullptr);
141 void loadKernels(const std::vector<std::string> & filenames,const char* compilerOptionsArg=nullptr);
144 * @brief Gets OpenCL context
145 * @return reference to the OpenCL context
147 const cl::Context& getContext() const {return context;}
150 * @brief Gets OpenCL device from list of devices
151 * @param[in] i position of device in the list of devices
152 * @return reference to selected device
154 const cl::Device& getDevice(const size_t i=0) const {return devices[i];}
157 * @brief Gets OpenCL command queue from list of command queues
158 * @param[in] i position of queue in the list of queues
159 * @return reference to selected queue
161 cl::CommandQueue& getCommandQueue(const size_t i=0) {return commandQueues[i];}
164 * @brief Gets OpenCL program from list of programs
165 * @param[in] i position of program in the list of programs
166 * @return reference to selected program
168 const cl::Program& getProgram(const size_t i=0) const {return programs[i];}
171 * @brief Gets kernel (type cl::Kernel) from list of kernels
172 * @param[in] i index of the kernel in the kernels list
173 * @return reference to selected kernel
175 cl::Kernel& getKernel(const size_t i=0) {kernelListT::iterator j(kernels.begin()); std::advance(j,i); return j->second;} // Warning: no bounds checking!
178 * @brief Gets kernel (type cl::Kernel) from name
179 * @param[in] name name of the kernel
180 * @return reference to selected kernel
182 cl::Kernel& getKernel(const char* name) {return getKernel(std::string(name));}
183 cl::Kernel& getKernel(const std::string& name);
184 static cl_uint roundUp(cl_uint numToRound, cl_uint baseNumber);
185 ProcessHandle addProcess(Process*& pProcess);
186 void checkProcessHandle(ProcessHandle handle, string specificMessage);
187 void delProcess(ProcessHandle handle);
188 std::shared_ptr<Process> getProcess (ProcessHandle handle);
189 DataHandle addData(Data*& pData, SyncSource hostDeviceSync = SYNCSOURCEDEFAULT);
190 DataHandle addData(shared_ptr<Data> pData, SyncSource hostDeviceSync = SYNCSOURCEDEFAULT);
191 void checkDataHandle(DataHandle handle, string specificMessage);
192 void delData(DataHandle handle);
193 std::shared_ptr<Data> getData (DataHandle handle);
194 void host2Device(DataHandle handle, SyncSource host2DeviceSyncSource = SYNCSOURCEDEFAULT);
195 void device2Host(DataHandle handle, SyncSource device2HostSyncSource);
196 std::string getDeviceTypeAsString(size_t i=0);
197 LPISupport::InfoItems getHWSWInfo(size_t i=0);
198 std::string getDeviceName(size_t i=0);
199 std::string getDeviceVendor(size_t i=0);
200 cl::NDRange getMaxLocalWorkItemSizes(cl::NDRange globalSizes);
202 cl::Buffer* getDeviceBuffer(DataHandle handle, dimIndexType NDArrayIndex) ;
203 cl::Buffer* getDeviceBuffer(DataHandle handle);
204 cl::Image* getDeviceImage(DataHandle handle, dimIndexType NDArrayIndex);
205 void* getHostBuffer(DataHandle handle, dimIndexType NDArrayIndex);
206 void* getHostImage(DataHandle handle, dimIndexType NDArrayIndex);
210 cl::Platform platform;
213 /// List of OpenCL devices
214 std::vector<cl::Device> devices;
215 /// List of OpenCL command queues
216 std::vector<cl::CommandQueue> commandQueues;
218 std::vector<cl::Program> programs;
223 /// Map with process handles as keys and smart shared pointers to processes as values
224 std::map<ProcessHandle, std::shared_ptr<Process>> processMap;
225 /// Map with process handles as keys and smart shared pointers to Data objects as values
226 std::map<DataHandle, std::shared_ptr<Data>> dataMap;
227 /// Current valid value for process keys (initially not valid)
228 ProcessHandle nextProcessKey = FIRSTVALIDPROCESSHANDLE;
229 /// Current valid value for data keys (initially not valid)
230 DataHandle nextDataKey = FIRSTVALIDDATAHANDLE;
231 static std::map<const cl_int,const char*> errStrings;
234 } //namespace OpenCLIPER
235 #endif //__OpenCLIPER