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 #ifdef __APPLE__
29 #include <opencl/opencl.h>
30 #else
31 #include <CL/cl.h>
32 #include <malloc.h>
33 #if defined (_WIN32)
34 #include "windows.h"
35 #endif
36 #endif
37 #include "shared.h"
38
39 class OpenCLSource final : public Text {
40 public:
41 explicit OpenCLSource(size_t len);
42
43 explicit OpenCLSource(char *text);
44
45 OpenCLSource();
46
47 ~OpenCLSource() override = default;
48 };
49
50 extern void __checkOpenclErrors(cl_int status, const char *functionName, const char *file, const int line);
51
52 #define OPENCL_CHECK(err, functionName) __checkOpenclErrors (err, functionName, __FILE__, __LINE__)
53
54 class OpenCLBackend final : public Backend {
55 public:
56 class OpenCLBuffer final : public Backend::Buffer {
57 public:
58 cl_mem clMem;
59
60 OpenCLBuffer(Backend *backend, BufferState *bufferState);
61
62 ~OpenCLBuffer() override;
63 };
64
65 class OpenCLProgram final : public Backend::CompilationUnit {
66 public:
67 class OpenCLKernel : public Backend::CompilationUnit::Kernel {
68 public:
69 cl_kernel kernel;
70
71 OpenCLKernel(Backend::CompilationUnit *compilationUnit, char *name, cl_kernel kernel);
72
73 bool setArg(KernelArg *arg) override;
74
75 bool setArg(KernelArg *arg, Buffer *buffer) override;
76
77 ~OpenCLKernel() override;
78 };
79
80 private:
81 cl_program program;
82
83 public:
84 OpenCLProgram(Backend *backend, char *src, char *log, bool ok, cl_program program);
85
86 ~OpenCLProgram() override;
87
88 OpenCLKernel *getOpenCLKernel(char *name);
89
90 OpenCLKernel *getOpenCLKernel(int nameLen, char *name);
91
92 CompilationUnit::Kernel *getKernel(int nameLen, char *name) override;
93 };
94
95 class OpenCLQueue : public Backend::ProfilableQueue {
96 public:
97 cl_command_queue command_queue;
98 cl_event *events;
99
100 cl_event *eventListPtr() const;
101
102 cl_event *nextEventPtr() const;
103
104 explicit OpenCLQueue(Backend *backend);
105
106 void wait() override;
107
108 void release() override;
109
110 void computeStart() override;
111
112 void computeEnd() override;
113
114 void showEvents(int width) override;
115
116 void inc(int bits) override;
117
118 void inc(int bits, const char *arg) override;
119
120 void marker(int bits) override;
121
122 void marker(int bits, const char *arg) override;
123
124 void markAsStartComputeAndInc() override;
125
126 void markAsEndComputeAndInc() override;
127
128 void markAsEnterKernelDispatchAndInc() override;
129
130 void markAsLeaveKernelDispatchAndInc() override;
131
132 void copyToDevice(Buffer *buffer) override;
133
134 void copyFromDevice(Buffer *buffer) override;
135
136
137 void dispatch(KernelContext *kernelContext, CompilationUnit::Kernel *kernel) override;
138
139 ~OpenCLQueue() override;
140 };
141
142 cl_platform_id platform_id;
143 cl_context context;
144 cl_device_id device_id;
145
146 explicit OpenCLBackend(int configBits);
147
148 ~OpenCLBackend() override;
149
150 OpenCLBuffer *getOrCreateBuffer(BufferState *bufferState) override;
151
152 OpenCLProgram *compileProgram(OpenCLSource &openclSource);
153
154 OpenCLProgram *compileProgram(const OpenCLSource *openclSource);
155
156 OpenCLProgram *compileProgram(int len, char *source);
157
158 CompilationUnit *compile(int len, char *source) override;
159
160 void computeStart() override;
161
162 void computeEnd() override;
163
164 bool getBufferFromDeviceIfDirty(void *memorySegment, long memorySegmentLength) override;
165
166 void info() override;
167
168 static const char *errorMsg(cl_int status);
169 };
170
171
172 struct PlatformInfo {
173 struct DeviceInfo {
174 OpenCLBackend *openclBackend;
175 cl_int maxComputeUnits;
176 cl_int maxWorkItemDimensions;
177 cl_device_type deviceType{};
178 size_t maxWorkGroupSize;
179 cl_ulong globalMemSize;
180 cl_ulong localMemSize;
181 cl_ulong maxMemAllocSize;
182 char *profile;
183 char *deviceVersion;
184 size_t *maxWorkItemSizes;
185 char *driverVersion;
186 char *cVersion;
187 char *name;
188 char *extensions;
189 char *builtInKernels;
190 char *deviceTypeStr;
191
192 explicit DeviceInfo(OpenCLBackend *openclBackend);
193
194 ~DeviceInfo();
195 };
196
197 OpenCLBackend *openclBackend;
198 char *versionName;
199 char *vendorName;
200 char *name;
201 DeviceInfo deviceInfo;
202
203 explicit PlatformInfo(OpenCLBackend *openclBackend);
204
205 ~PlatformInfo();
206 };