1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #ifdef OPENCL_SUPPORT
23 
24 #    include "OpenCLHelper.h"
25 #    include <stdio.h>
26 
27 #    include <U2Core/Log.h>
28 
29 namespace U2 {
30 
31 const static char *clGetPlatformIDs_n("clGetPlatformIDs");
32 const static char *clGetPlatformInfo_n("clGetPlatformInfo");
33 const static char *clGetDeviceIDs_n("clGetDeviceIDs");
34 const static char *clGetDeviceInfo_n("clGetDeviceInfo");
35 
36 const static char *clCreateContext_n("clCreateContext");
37 const static char *clCreateBuffer_n("clCreateBuffer");
38 const static char *clCreateProgramWithSource_n("clCreateProgramWithSource");
39 const static char *clGetProgramBuildInfo_n("clGetProgramBuildInfo");
40 const static char *clCreateKernel_n("clCreateKernel");
41 const static char *clSetKernelArg_n("clSetKernelArg");
42 const static char *clCreateCommandQueue_n("clCreateCommandQueue");
43 const static char *clEnqueueNDRangeKernel_n("clEnqueueNDRangeKernel");
44 const static char *clWaitForEvents_n("clWaitForEvents");
45 const static char *clEnqueueReadBuffer_n("clEnqueueReadBuffer");
46 const static char *clFlush_n("clFlush");
47 const static char *clFinish_n("clFinish");
48 const static char *clBuildProgram_n("clBuildProgram");
49 const static char *clReleaseEvent_n("clReleaseEvent");
50 
51 const static char *clReleaseKernel_n("clReleaseKernel");
52 const static char *clReleaseProgram_n("clReleaseProgram");
53 const static char *clReleaseCommandQueue_n("clReleaseCommandQueue");
54 const static char *clReleaseContext_n("clReleaseContext");
55 const static char *clReleaseMemObject_n("clReleaseMemObject");
56 
57 const static char *clGetKernelWorkGroupInfo_n("clGetKernelWorkGroupInfo");
58 const static char *clGetEventProfilingInfo_n("clGetEventProfilingInfo");
59 
OpenCLHelper()60 OpenCLHelper::OpenCLHelper()
61     : openclLib(OPENCL_DRIVER_LIB) {
62     coreLog.details(QObject::tr("Loading OPENCL driver library"));
63 
64     openclLib.load();
65     if (!openclLib.isLoaded()) {
66         coreLog.details(QObject::tr("Cannot load OpenCL library. Error while loading %1").arg(openclLib.fileName()));
67         status = Error_NoDriverLib;
68         return;
69     }
70 
71     clGetPlatformIDs_p = clGetPlatformIDs_f(openclLib.resolve(clGetPlatformIDs_n));
72     if (!clGetPlatformIDs_p) {
73         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clGetPlatformIDs_n));
74         status = Error_BadDriverLib;
75         return;
76     }
77 
78     clGetPlatformInfo_p = clGetPlatformInfo_f(openclLib.resolve(clGetPlatformInfo_n));
79     if (!clGetPlatformInfo_p) {
80         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clGetPlatformInfo_n));
81         status = Error_BadDriverLib;
82         return;
83     }
84 
85     clGetDeviceIDs_p = clGetDeviceIDs_f(openclLib.resolve(clGetDeviceIDs_n));
86     if (!clGetDeviceIDs_p) {
87         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clGetDeviceIDs_n));
88         status = Error_BadDriverLib;
89         return;
90     }
91 
92     clGetDeviceInfo_p = clGetDeviceInfo_f(openclLib.resolve(clGetDeviceInfo_n));
93     if (!clGetDeviceInfo_p) {
94         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clGetDeviceInfo_n));
95         status = Error_BadDriverLib;
96         return;
97     }
98 
99     //****************************************
100 
101     clCreateContext_p = clCreateContext_f(openclLib.resolve(clCreateContext_n));
102     if (!clCreateContext_p) {
103         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clCreateContext_n));
104         status = Error_BadDriverLib;
105         return;
106     }
107 
108     clCreateBuffer_p = clCreateBuffer_f(openclLib.resolve(clCreateBuffer_n));
109     if (!clCreateBuffer_p) {
110         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clCreateBuffer_n));
111         status = Error_BadDriverLib;
112         return;
113     }
114 
115     clCreateProgramWithSource_p = clCreateProgramWithSource_f(openclLib.resolve(clCreateProgramWithSource_n));
116     if (!clCreateProgramWithSource_p) {
117         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clCreateProgramWithSource_n));
118         status = Error_BadDriverLib;
119         return;
120     }
121 
122     clGetProgramBuildInfo_p = clGetProgramBuildInfo_f(openclLib.resolve(clGetProgramBuildInfo_n));
123     if (!clGetProgramBuildInfo_p) {
124         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clGetProgramBuildInfo_n));
125         status = Error_BadDriverLib;
126         return;
127     }
128 
129     clCreateKernel_p = clCreateKernel_f(openclLib.resolve(clCreateKernel_n));
130     if (!clCreateKernel_p) {
131         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clCreateKernel_n));
132         status = Error_BadDriverLib;
133         return;
134     }
135 
136     clSetKernelArg_p = clSetKernelArg_f(openclLib.resolve(clSetKernelArg_n));
137     if (!clSetKernelArg_p) {
138         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clSetKernelArg_n));
139         status = Error_BadDriverLib;
140         return;
141     }
142 
143     clCreateCommandQueue_p = clCreateCommandQueue_f(openclLib.resolve(clCreateCommandQueue_n));
144     if (!clCreateCommandQueue_p) {
145         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clCreateCommandQueue_n));
146         status = Error_BadDriverLib;
147         return;
148     }
149 
150     clEnqueueNDRangeKernel_p = clEnqueueNDRangeKernel_f(openclLib.resolve(clEnqueueNDRangeKernel_n));
151     if (!clEnqueueNDRangeKernel_p) {
152         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clEnqueueNDRangeKernel_n));
153         status = Error_BadDriverLib;
154         return;
155     }
156 
157     clWaitForEvents_p = clWaitForEvents_f(openclLib.resolve(clWaitForEvents_n));
158     if (!clWaitForEvents_p) {
159         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clWaitForEvents_n));
160         status = Error_BadDriverLib;
161         return;
162     }
163 
164     clEnqueueReadBuffer_p = clEnqueueReadBuffer_f(openclLib.resolve(clEnqueueReadBuffer_n));
165     if (!clEnqueueReadBuffer_p) {
166         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clEnqueueReadBuffer_n));
167         status = Error_BadDriverLib;
168         return;
169     }
170 
171     clFlush_p = clFlush_f(openclLib.resolve(clFlush_n));
172     if (!clFlush_p) {
173         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clFlush_n));
174         status = Error_BadDriverLib;
175         return;
176     }
177 
178     clFinish_p = clFinish_f(openclLib.resolve(clFinish_n));
179     if (!clFinish_p) {
180         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clFinish_n));
181         status = Error_BadDriverLib;
182         return;
183     }
184 
185     clBuildProgram_p = clBuildProgram_f(openclLib.resolve(clBuildProgram_n));
186     if (!clBuildProgram_p) {
187         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clBuildProgram_n));
188         status = Error_BadDriverLib;
189         return;
190     }
191 
192     clReleaseEvent_p = clReleaseEvent_f(openclLib.resolve(clReleaseEvent_n));
193     if (!clReleaseEvent_p) {
194         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clReleaseEvent_n));
195         status = Error_BadDriverLib;
196         return;
197     }
198 
199     clReleaseKernel_p = clReleaseKernel_f(openclLib.resolve(clReleaseKernel_n));
200     if (!clReleaseKernel_p) {
201         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clReleaseKernel_n));
202         status = Error_BadDriverLib;
203         return;
204     }
205 
206     clReleaseProgram_p = clReleaseProgram_f(openclLib.resolve(clReleaseProgram_n));
207     if (!clReleaseProgram_p) {
208         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clReleaseProgram_n));
209         status = Error_BadDriverLib;
210         return;
211     }
212 
213     clReleaseCommandQueue_p = clReleaseCommandQueue_f(openclLib.resolve(clReleaseCommandQueue_n));
214     if (!clReleaseCommandQueue_p) {
215         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clReleaseCommandQueue_n));
216         status = Error_BadDriverLib;
217         return;
218     }
219 
220     clReleaseContext_p = clReleaseContext_f(openclLib.resolve(clReleaseContext_n));
221     if (!clReleaseContext_p) {
222         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clReleaseContext_n));
223         status = Error_BadDriverLib;
224         return;
225     }
226 
227     clReleaseMemObject_p = clReleaseMemObject_f(openclLib.resolve(clReleaseMemObject_n));
228     if (!clReleaseMemObject_p) {
229         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clReleaseMemObject_n));
230         status = Error_BadDriverLib;
231         return;
232     }
233 
234     clGetKernelWorkGroupInfo_p = clGetKernelWorkGroupInfo_f(openclLib.resolve(clGetKernelWorkGroupInfo_n));
235     if (!clGetKernelWorkGroupInfo_p) {
236         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clGetKernelWorkGroupInfo_n));
237         status = Error_BadDriverLib;
238         return;
239     }
240 
241     clGetEventProfilingInfo_p = clGetEventProfilingInfo_f(openclLib.resolve(clGetEventProfilingInfo_n));
242     if (!clGetEventProfilingInfo_p) {
243         coreLog.details(QObject::tr("Cannot resolve symbol %1").arg(clGetEventProfilingInfo_n));
244         status = Error_BadDriverLib;
245         return;
246     }
247 
248     status = Error_NoError;
249 }
250 
~OpenCLHelper()251 OpenCLHelper::~OpenCLHelper() {
252     openclLib.unload();
253 }
254 
getErrorString() const255 QString OpenCLHelper::getErrorString() const {
256     switch (status) {
257         case Error_NoDriverLib: {
258             return QObject::tr("Cannot load library: %1").arg(OPENCL_DRIVER_LIB);
259         }
260         case Error_BadDriverLib: {
261             return QObject::tr("Some errors occurs in library: %1").arg(OPENCL_DRIVER_LIB);
262         }
263         case Error_NoError: {
264             return "";
265         }
266         default: {
267             return "";
268         }
269     }
270 }
271 }  // namespace U2
272 
273 #endif /* OPENCL_SUPPORT*/
274