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 #define CL_TARGET_OPENCL_VERSION 120
 27 
 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 
 38 #include "shared.h"
 39 
 40 extern void __checkOpenclErrors(cl_int status, const char *file, const int line);
 41 
 42 #define checkOpenCLErrors(err)  __checkOpenclErrors (err, __FILE__, __LINE__)
 43 
 44 class OpenCLBackend : public Backend {
 45 public:
 46     class OpenCLConfig{
 47     public:
 48         const static  int GPU_BIT =1<<1;
 49         const static  int CPU_BIT =1<<2;
 50         const static  int MINIMIZE_COPIES_BIT =1<<3;
 51         const static  int TRACE_BIT =1<<4;
 52         const static  int PROFILE_BIT =1<<5;
 53         const static  int SHOW_CODE_BIT = 1 << 6;
 54         const static  int SHOW_KERNEL_MODEL_BIT = 1 << 7;
 55         const static  int SHOW_COMPUTE_MODEL_BIT = 1 <<8;
 56         const static  int INFO_BIT = 1 <<9;
 57         const static  int TRACE_COPIES_BIT = 1 <<10;
 58         int mode;
 59         bool gpu;
 60         bool cpu;
 61         bool minimizeCopies;
 62         bool trace;
 63         bool profile;
 64         bool showCode;
 65         bool info;
 66         bool traceCopies;
 67         OpenCLConfig(int mode);
 68         virtual ~OpenCLConfig();
 69     };
 70     class OpenCLQueue {
 71     public:
 72        static const int CopyToDeviceBits= 1<<20;
 73        static const int CopyFromDeviceBits= 1<<21;
 74        static const int NDRangeBits =1<<22;
 75        static const int StartComputeBits= 1<<23;
 76        static const int EndComputeBits= 1<<24;
 77        static const int EnterKernelDispatchBits= 1<<25;
 78        static const int LeaveKernelDispatchBits= 1<<26;
 79        static const int HasConstCharPtrArgBits = 1<<27;
 80        static const int hasIntArgBits = 1<<28;
 81        OpenCLBackend *openclBackend;
 82        size_t eventMax;
 83        cl_event *events;
 84        int *eventInfoBits;
 85        const char **eventInfoConstCharPtrArgs;
 86        size_t eventc;
 87        cl_command_queue command_queue;
 88 
 89        OpenCLQueue(OpenCLBackend *openclBackend);
 90        cl_event *eventListPtr();
 91        cl_event *nextEventPtr();
 92        void showEvents(int width);
 93        void wait();
 94        void release();
 95        void computeStart();
 96        void computeEnd();
 97        void inc(int bits);
 98        void inc(int bits, const char *arg);
 99        void inc(int bits, int arg);
100        void marker(int bits);
101        void marker(int bits, const char *arg);
102        void marker(int bits, int arg);
103        void markAsCopyToDeviceAndInc(int argn);
104        void markAsCopyFromDeviceAndInc(int argn);
105        void markAsNDRangeAndInc();
106        void markAsStartComputeAndInc();
107        void markAsEndComputeAndInc();
108        void markAsEnterKernelDispatchAndInc();
109        void markAsLeaveKernelDispatchAndInc();
110        virtual ~OpenCLQueue();
111     };
112 
113     class OpenCLProgram : public Backend::Program {
114         class OpenCLKernel : public Backend::Program::Kernel {
115             class OpenCLBuffer : public Backend::Program::Kernel::Buffer {
116             public:
117                 cl_mem clMem;
118                 void copyToDevice();
119                 void copyFromDevice();
120                 OpenCLBuffer(Backend::Program::Kernel *kernel, Arg_s *arg);
121                 virtual ~OpenCLBuffer();
122             };
123         private:
124             const char *name;
125             cl_kernel kernel;
126         public:
127             OpenCLKernel(Backend::Program *program, char* name,cl_kernel kernel);
128             ~OpenCLKernel();
129             long ndrange( void *argArray);
130         };
131     private:
132         cl_program program;
133     public:
134         OpenCLProgram(Backend *backend, BuildInfo *buildInfo, cl_program program);
135         ~OpenCLProgram();
136         long getKernel(int nameLen, char *name);
137         bool programOK();
138     };
139 
140 public:
141 
142     cl_platform_id platform_id;
143     cl_context context;
144     cl_device_id device_id;
145     OpenCLConfig openclConfig;
146     OpenCLQueue openclQueue;
147     OpenCLBackend(int mode, int platform, int device);
148     ~OpenCLBackend();
149     int getMaxComputeUnits();
150     bool getBufferFromDeviceIfDirty(void *memorySegment, long memorySegmentLength);
151     void info();
152     void computeStart();
153     void computeEnd();
154     void dumpSled(std::ostream &out,void *argArray);
155     char *dumpSchema(std::ostream &out,int depth, char *ptr, void *data);
156     long compileProgram(int len, char *source);
157     char *strInfo(cl_device_info device_info);
158     cl_int cl_int_info( cl_device_info device_info);
159     cl_ulong cl_ulong_info( cl_device_info device_info);
160     size_t size_t_info( cl_device_info device_info);
161     char *strPlatformInfo(cl_platform_info platform_info);
162 public:
163     static const char *errorMsg(cl_int status);
164 };
165 extern "C" long getOpenCLBackend(int mode, int platform, int device, int unused);