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 };