1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 // http://www.apache.org/licenses/LICENSE-2.0
5 // Unless required by applicable law or agreed to in writing, software
6 // distributed under the License is distributed on an "AS IS" BASIS,
7 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8 // See the License for the specific language governing permissions and
9 // limitations under the License.
10 
11 #ifndef TESSERACT_OPENCL_OPENCLWRAPPER_H_
12 #define TESSERACT_OPENCL_OPENCLWRAPPER_H_
13 
14 #include <allheaders.h>
15 #include <cstdio>
16 #include "pix.h"
17 #include "tprintf.h"
18 
19 // including CL/cl.h doesn't occur until USE_OPENCL defined below
20 
21 /**************************************************************************
22  * enable/disable use of OpenCL
23  **************************************************************************/
24 
25 #ifdef USE_OPENCL
26 
27 #  ifdef __APPLE__
28 #    include <OpenCL/cl.h>
29 #  else
30 #    include <CL/cl.h>
31 #  endif
32 
33 namespace tesseract {
34 
35 class Image;
36 struct TessDeviceScore;
37 
38 // device type
39 enum ds_device_type { DS_DEVICE_NATIVE_CPU = 0, DS_DEVICE_OPENCL_DEVICE };
40 
41 struct ds_device {
42   ds_device_type type;
43   cl_device_id oclDeviceID;
44   char *oclDeviceName;
45   char *oclDriverVersion;
46   // a pointer to the score data, the content/format is application defined.
47   TessDeviceScore *score;
48 };
49 
50 #  ifndef strcasecmp
51 #    define strcasecmp strcmp
52 #  endif
53 
54 #  define MAX_KERNEL_STRING_LEN 64
55 #  define MAX_CLFILE_NUM 50
56 #  define MAX_CLKERNEL_NUM 200
57 #  define MAX_KERNEL_NAME_LEN 64
58 #  define CL_QUEUE_THREAD_HANDLE_AMD 0x403E
59 #  define GROUPSIZE_X 16
60 #  define GROUPSIZE_Y 16
61 #  define GROUPSIZE_HMORX 256
62 #  define GROUPSIZE_HMORY 1
63 
64 struct KernelEnv {
65   cl_context mpkContext;
66   cl_command_queue mpkCmdQueue;
67   cl_program mpkProgram;
68   cl_kernel mpkKernel;
69   char mckKernelName[150];
70 };
71 
72 struct OpenCLEnv {
73   cl_platform_id mpOclPlatformID;
74   cl_context mpOclContext;
75   cl_device_id mpOclDevsID;
76   cl_command_queue mpOclCmdQueue;
77 };
78 typedef int (*cl_kernel_function)(void **userdata, KernelEnv *kenv);
79 
80 #  define CHECK_OPENCL(status, name)                                     \
81     if (status != CL_SUCCESS) {                                          \
82       tprintf("OpenCL error code is %d at   when %s .\n", status, name); \
83     }
84 
85 struct GPUEnv {
86   // share vb in all modules in hb library
87   cl_platform_id mpPlatformID;
88   cl_device_type mDevType;
89   cl_context mpContext;
90   cl_device_id *mpArryDevsID;
91   cl_device_id mpDevID;
92   cl_command_queue mpCmdQueue;
93   cl_kernel mpArryKernels[MAX_CLFILE_NUM];
94   cl_program mpArryPrograms[MAX_CLFILE_NUM];  // one program object maps one
95                                               // kernel source file
96   char mArryKnelSrcFile[MAX_CLFILE_NUM][256], // the max len of kernel file name is 256
97       mArrykernelNames[MAX_CLKERNEL_NUM][MAX_KERNEL_STRING_LEN + 1];
98   cl_kernel_function mpArryKnelFuncs[MAX_CLKERNEL_NUM];
99   int mnKernelCount, mnFileCount, // only one kernel file
100       mnIsUserCreated;            // 1: created , 0:no create and needed to create by
101                                   // opencl wrapper
102   int mnKhrFp64Flag;
103   int mnAmdFp64Flag;
104 };
105 
106 class OpenclDevice {
107 public:
108   static GPUEnv gpuEnv;
109   static int isInited;
110   OpenclDevice();
111   ~OpenclDevice();
112   static int InitEnv();                  // load dll, call InitOpenclRunEnv(0)
113   static int InitOpenclRunEnv(int argc); // RegistOpenclKernel, double flags, compile kernels
114   static int InitOpenclRunEnv_DeviceSelection(
115       int argc); // RegistOpenclKernel, double flags, compile kernels
116   static int RegistOpenclKernel();
117   static int ReleaseOpenclRunEnv();
118   static int ReleaseOpenclEnv(GPUEnv *gpuInfo);
119   static int CompileKernelFile(GPUEnv *gpuInfo, const char *buildOption);
120   static int CachedOfKernerPrg(const GPUEnv *gpuEnvCached, const char *clFileName);
121   static int GeneratBinFromKernelSource(cl_program program, const char *clFileName);
122   static int WriteBinaryToFile(const char *fileName, const char *birary, size_t numBytes);
123   static int BinaryGenerated(const char *clFileName, FILE **fhandle);
124   // static int CompileKernelFile( const char *filename, GPUEnv *gpuInfo, const
125   // char *buildOption );
126   static l_uint32 *pixReadFromTiffKernel(l_uint32 *tiffdata, l_int32 w, l_int32 h, l_int32 wpl,
127                                          l_uint32 *line);
128   static int composeRGBPixelCl(int *tiffdata, int *line, int h, int w);
129 
130   /* OpenCL implementations of Morphological operations*/
131 
132   // Initialization of OCL buffers used in Morph operations
133   static int initMorphCLAllocations(l_int32 wpl, l_int32 h, Image pixs);
134   static void releaseMorphCLBuffers();
135 
136   static void pixGetLinesCL(Image pixd, Image pixs, Image *pix_vline, Image *pix_hline, Image *pixClosed,
137                             bool getpixClosed, l_int32 close_hsize, l_int32 close_vsize,
138                             l_int32 open_hsize, l_int32 open_vsize, l_int32 line_hsize,
139                             l_int32 line_vsize);
140 
141   // int InitOpenclAttr( OpenCLEnv * env );
142   // int ReleaseKernel( KernelEnv * env );
143   static int SetKernelEnv(KernelEnv *envInfo);
144   // int CreateKernel( char * kernelname, KernelEnv * env );
145   // int RunKernel( const char *kernelName, void **userdata );
146   // int ConvertToString( const char *filename, char **source );
147   // int CheckKernelName( KernelEnv *envInfo, const char *kernelName );
148   // int RegisterKernelWrapper( const char *kernelName, cl_kernel_function
149   // function ); int RunKernelWrapper( cl_kernel_function function, const char *
150   // kernelName, void **usrdata ); int GetKernelEnvAndFunc( const char
151   // *kernelName, KernelEnv *env, cl_kernel_function *function );
152 
153   static int LoadOpencl();
154 #  ifdef WIN32
155   // static int OpenclInite();
156   static void FreeOpenclDll();
157 #  endif
158 
159   inline static int AddKernelConfig(int kCount, const char *kName);
160 
161   /* for binarization */
162   static int HistogramRectOCL(void *imagedata, int bytes_per_pixel, int bytes_per_line, int left,
163                               int top, int width, int height, int kHistogramSize,
164                               int *histogramAllChannels);
165 
166   static int ThresholdRectToPixOCL(unsigned char *imagedata, int bytes_per_pixel,
167                                    int bytes_per_line, int *thresholds, int *hi_values, Image *pix,
168                                    int rect_height, int rect_width, int rect_top, int rect_left);
169 
170   static ds_device getDeviceSelection();
171   static ds_device selectedDevice;
172   static bool deviceIsSelected;
173   static bool selectedDeviceIsOpenCL();
174 };
175 
176 }
177 
178 #endif // USE_OPENCL
179 #endif // TESSERACT_OPENCL_OPENCLWRAPPER_H_
180