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 *file, const int line);
 51 
 52 #define checkOpenCLErrors(err)  __checkOpenclErrors (err, __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 };