1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 #pragma once
26 // The following looks like it is not used (at least to CLION) but it is. ;) don't remove
27 #define CL_TARGET_OPENCL_VERSION 120
28 #include <memory>
29 #ifdef __APPLE__
30 #include <opencl/opencl.h>
31 #else
32 #include <CL/cl.h>
33 #include <malloc.h>
34 #if defined (_WIN32)
35 #include "windows.h"
36 #endif
37 #endif
38 #include "shared.h"
39
40 class OpenCLSource final : public Text {
41 public:
42 explicit OpenCLSource(size_t len);
43
44 explicit OpenCLSource(char *text);
45
46 OpenCLSource();
47
48 ~OpenCLSource() override = default;
49 };
50
51 extern void __checkOpenclErrors(cl_int status, const char *functionName, const char *file, const int line);
52
53 #define OPENCL_CHECK(err, functionName) __checkOpenclErrors (err, functionName, __FILE__, __LINE__)
54
55 struct PlatformInfo;
56
57 class OpenCLBackend final : public Backend {
58 private:
59 std::unique_ptr<PlatformInfo> _platform_info;
60 bool isPlatformProfileOn;
61 public:
62 class OpenCLBuffer final : public Backend::Buffer {
63 public:
64 cl_mem clMem;
65
66 OpenCLBuffer(Backend *backend, BufferState *bufferState);
67
68 ~OpenCLBuffer() override;
69 };
70
71 class OpenCLProgram final : public Backend::CompilationUnit {
72 public:
73 class OpenCLKernel : public Backend::CompilationUnit::Kernel {
74 public:
75 cl_kernel kernel;
76
77 OpenCLKernel(Backend::CompilationUnit *compilationUnit, char *name, cl_kernel kernel);
78
79 bool setArg(KernelArg *arg) override;
80
81 bool setArg(KernelArg *arg, Buffer *buffer) override;
82
83 ~OpenCLKernel() override;
84 };
85
86 private:
87 cl_program program;
88
89 public:
90 OpenCLProgram(Backend *backend, char *src, char *log, bool ok, cl_program program);
91
92 ~OpenCLProgram() override;
93
94 OpenCLKernel *getOpenCLKernel(char *name);
95
96 OpenCLKernel *getOpenCLKernel(int nameLen, char *name);
97
98 CompilationUnit::Kernel *getKernel(int nameLen, char *name) override;
99 };
100
101 class OpenCLQueue : public Backend::ProfilableQueue {
102 public:
103 cl_command_queue command_queue;
104 cl_event *events;
105
106 cl_event *eventListPtr() const;
107
108 cl_event *nextEventPtr() const;
109
110 explicit OpenCLQueue(Backend *backend);
111
112 void wait() override;
113
114 void release() override;
115
116 void computeStart() override;
117
118 void computeEnd() override;
119
120 void showEvents(int width) override;
121
122 void inc(int bits) override;
123
124 void inc(int bits, const char *arg) override;
125
126 void marker(int bits) override;
127
128 void marker(int bits, const char *arg) override;
129
130 void markAsStartComputeAndInc() override;
131
132 void markAsEndComputeAndInc() override;
133
134 void markAsEnterKernelDispatchAndInc() override;
135
136 void markAsLeaveKernelDispatchAndInc() override;
137
138 void copyToDevice(Buffer *buffer) override;
139
140 void copyFromDevice(Buffer *buffer) override;
141
142 void dispatch(DispatchContext *dispatchContext, CompilationUnit::Kernel *kernel) override;
143
144 bool isProfileOrOutOfOrder() const;
145
146 ~OpenCLQueue() override;
147 };
148
149 cl_platform_id platform_id;
150 cl_context context;
151 cl_device_id device_id;
152
153 explicit OpenCLBackend(int configBits);
154
155 ~OpenCLBackend() override;
156
157 OpenCLBuffer *getOrCreateBuffer(BufferState *bufferState) override;
158
159 OpenCLProgram *compileProgram(OpenCLSource &openclSource);
160
161 OpenCLProgram *compileProgram(const OpenCLSource *openclSource);
162
163 OpenCLProgram *compileProgram(int len, char *source);
164
165 CompilationUnit *compile(int len, char *source, int typeModel) override;
166
167 void computeStart() override;
168
169 void computeEnd() override;
170
171 bool getBufferFromDeviceIfDirty(void *memorySegment, long memorySegmentLength) override;
172
173 void shortDeviceInfo() override;
174
175 void showDeviceInfo() override;
176
177 static const char *errorMsg(cl_int status);
178
179 const PlatformInfo& getPlatformInfo() const;
180
181 const bool isPlatformOnProfile() const;
182 };
183
184 struct PlatformInfo {
185 struct DeviceInfo {
186 OpenCLBackend *openclBackend;
187 cl_int maxComputeUnits;
188 cl_int maxWorkItemDimensions;
189 cl_device_type deviceType{};
190 size_t maxWorkGroupSize;
191 cl_ulong globalMemSize;
192 cl_ulong localMemSize;
193 cl_ulong maxMemAllocSize;
194 char *profile;
195 char *deviceVersion;
196 size_t *maxWorkItemSizes;
197 char *driverVersion;
198 char *cVersion;
199 char *name;
200 char *extensions;
201 char *builtInKernels;
202 char *deviceTypeStr;
203
204 explicit DeviceInfo(OpenCLBackend *openclBackend);
205
206 ~DeviceInfo();
207 };
208
209 OpenCLBackend *openclBackend;
210 char *versionName;
211 char *vendorName;
212 char *name;
213 DeviceInfo deviceInfo;
214
215 explicit PlatformInfo(OpenCLBackend *openclBackend);
216
217 ~PlatformInfo();
218 };