tesseract
3.03
|
00001 #include <stdio.h> 00002 #include "allheaders.h" 00003 #include "pix.h" 00004 #ifdef USE_OPENCL 00005 #include "tiff.h" 00006 #include "tiffio.h" 00007 #endif 00008 #include "tprintf.h" 00009 00010 // including CL/cl.h doesn't occur until USE_OPENCL defined below 00011 00012 // platform preprocessor commands 00013 #if defined( WIN32 ) || defined( __WIN32__ ) || defined( _WIN32 ) || defined( __CYGWIN32__ ) || defined( __MINGW32__ ) 00014 #define ON_WINDOWS 1 00015 #define ON_LINUX 0 00016 #define ON_APPLE 0 00017 #define ON_OTHER 0 00018 #define IF_WINDOWS(X) X 00019 #define IF_LINUX(X) 00020 #define IF_APPLE(X) 00021 #define IF_OTHER(X) 00022 #define NOT_WINDOWS(X) 00023 #elif defined( __linux__ ) 00024 #define ON_WINDOWS 0 00025 #define ON_LINUX 1 00026 #define ON_APPLE 0 00027 #define ON_OTHER 0 00028 #define IF_WINDOWS(X) 00029 #define IF_LINUX(X) X 00030 #define IF_APPLE(X) 00031 #define IF_OTHER(X) 00032 #define NOT_WINDOWS(X) X 00033 #elif defined( __APPLE__ ) 00034 #define ON_WINDOWS 0 00035 #define ON_LINUX 0 00036 #define ON_APPLE 1 00037 #define ON_OTHER 0 00038 #define IF_WINDOWS(X) 00039 #define IF_LINUX(X) 00040 #define IF_APPLE(X) X 00041 #define IF_OTHER(X) 00042 #define NOT_WINDOWS(X) X 00043 #else 00044 #define ON_WINDOWS 0 00045 #define ON_LINUX 0 00046 #define ON_APPLE 0 00047 #define ON_OTHER 1 00048 #define IF_WINDOWS(X) 00049 #define IF_LINUX(X) 00050 #define IF_APPLE(X) 00051 #define IF_OTHER(X) X 00052 #define NOT_WINDOWS(X) X 00053 #endif 00054 00055 #if ON_LINUX 00056 #include <time.h> 00057 #endif 00058 00059 /************************************************************************************ 00060 * enable/disable reporting of performance 00061 * PERF_REPORT_LEVEL 00062 * 0 - no reporting 00063 * 1 - no reporting 00064 * 2 - report total function call time for functions we're tracking 00065 * 3 - optionally report breakdown of function calls (kernel launch, kernel time, data copies) 00066 ************************************************************************************/ 00067 #define PERF_COUNT_VERBOSE 1 00068 #define PERF_COUNT_REPORT_STR "[%36s], %24s, %11.6f\n" 00069 00070 00071 #if ON_WINDOWS 00072 00073 #if PERF_COUNT_VERBOSE >= 2 00074 #define PERF_COUNT_START(FUNCT_NAME) \ 00075 char *funct_name = FUNCT_NAME; \ 00076 double elapsed_time_sec; \ 00077 LARGE_INTEGER freq, time_funct_start, time_funct_end, time_sub_start, time_sub_end; \ 00078 QueryPerformanceFrequency(&freq); \ 00079 QueryPerformanceCounter(&time_funct_start); \ 00080 time_sub_start = time_funct_start; \ 00081 time_sub_end = time_funct_start; 00082 00083 #define PERF_COUNT_END \ 00084 QueryPerformanceCounter(&time_funct_end); \ 00085 elapsed_time_sec = (time_funct_end.QuadPart-time_funct_start.QuadPart)/(double)(freq.QuadPart); \ 00086 tprintf(PERF_COUNT_REPORT_STR, funct_name, "total", elapsed_time_sec); 00087 #else 00088 #define PERF_COUNT_START(FUNCT_NAME) 00089 #define PERF_COUNT_END 00090 #endif 00091 00092 #if PERF_COUNT_VERBOSE >= 3 00093 #define PERF_COUNT_SUB(SUB) \ 00094 QueryPerformanceCounter(&time_sub_end); \ 00095 elapsed_time_sec = (time_sub_end.QuadPart-time_sub_start.QuadPart)/(double)(freq.QuadPart); \ 00096 tprintf(PERF_COUNT_REPORT_STR, funct_name, SUB, elapsed_time_sec); \ 00097 time_sub_start = time_sub_end; 00098 #else 00099 #define PERF_COUNT_SUB(SUB) 00100 #endif 00101 00102 00103 // not on windows 00104 #else 00105 00106 #if PERF_COUNT_VERBOSE >= 2 00107 #define PERF_COUNT_START(FUNCT_NAME) \ 00108 char *funct_name = FUNCT_NAME; \ 00109 double elapsed_time_sec; \ 00110 timespec time_funct_start, time_funct_end, time_sub_start, time_sub_end; \ 00111 clock_gettime( CLOCK_MONOTONIC, &time_funct_start ); \ 00112 time_sub_start = time_funct_start; \ 00113 time_sub_end = time_funct_start; 00114 00115 #define PERF_COUNT_END \ 00116 clock_gettime( CLOCK_MONOTONIC, &time_funct_end ); \ 00117 elapsed_time_sec = (time_funct_end.tv_sec - time_funct_start.tv_sec)*1.0 + (time_funct_end.tv_nsec - time_funct_start.tv_nsec)/1000000000.0; \ 00118 tprintf(PERF_COUNT_REPORT_STR, funct_name, "total", elapsed_time_sec); 00119 #else 00120 #define PERF_COUNT_START(FUNCT_NAME) 00121 #define PERF_COUNT_END 00122 #endif 00123 00124 #if PERF_COUNT_VERBOSE >= 3 00125 #define PERF_COUNT_SUB(SUB) \ 00126 clock_gettime( CLOCK_MONOTONIC, &time_sub_end ); \ 00127 elapsed_time_sec = (time_sub_end.tv_sec - time_sub_start.tv_sec)*1.0 + (time_sub_end.tv_nsec - time_sub_start.tv_nsec)/1000000000.0; \ 00128 tprintf(PERF_COUNT_REPORT_STR, funct_name, SUB, elapsed_time_sec); \ 00129 time_sub_start = time_sub_end; 00130 #else 00131 #define PERF_COUNT_SUB(SUB) 00132 #endif 00133 00134 #endif 00135 /************************************************************************** 00136 * enable/disable use of OpenCL 00137 **************************************************************************/ 00138 00139 #ifdef USE_OPENCL 00140 00141 #define USE_DEVICE_SELECTION 1 00142 00143 #include "opencl_device_selection.h" 00144 00145 #ifndef strcasecmp 00146 #define strcasecmp strcmp 00147 #endif 00148 00149 #define MAX_KERNEL_STRING_LEN 64 00150 #define MAX_CLFILE_NUM 50 00151 #define MAX_CLKERNEL_NUM 200 00152 #define MAX_KERNEL_NAME_LEN 64 00153 #define CL_QUEUE_THREAD_HANDLE_AMD 0x403E 00154 #define GROUPSIZE_X 16 00155 #define GROUPSIZE_Y 16 00156 #define GROUPSIZE_HMORX 256 00157 #define GROUPSIZE_HMORY 1 00158 00159 typedef struct _KernelEnv 00160 { 00161 cl_context mpkContext; 00162 cl_command_queue mpkCmdQueue; 00163 cl_program mpkProgram; 00164 cl_kernel mpkKernel; 00165 char mckKernelName[150]; 00166 } KernelEnv; 00167 00168 typedef struct _OpenCLEnv 00169 { 00170 cl_platform_id mpOclPlatformID; 00171 cl_context mpOclContext; 00172 cl_device_id mpOclDevsID; 00173 cl_command_queue mpOclCmdQueue; 00174 } OpenCLEnv; 00175 typedef int ( *cl_kernel_function )( void **userdata, KernelEnv *kenv ); 00176 00177 00178 static l_int32 MORPH_BC = ASYMMETRIC_MORPH_BC; 00179 00180 static const l_uint32 lmask32[] = {0x0, 00181 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 00182 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, 00183 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, 00184 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 00185 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, 00186 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, 00187 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 00188 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff}; 00189 00190 static const l_uint32 rmask32[] = {0x0, 00191 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 00192 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 00193 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 00194 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 00195 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 00196 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 00197 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 00198 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff}; 00199 00200 #define CHECK_OPENCL(status,name) \ 00201 if( status != CL_SUCCESS ) \ 00202 { \ 00203 printf ("OpenCL error code is %d at when %s .\n", status, name); \ 00204 } 00205 00206 00207 typedef struct _GPUEnv 00208 { 00209 //share vb in all modules in hb library 00210 cl_platform_id mpPlatformID; 00211 cl_device_type mDevType; 00212 cl_context mpContext; 00213 cl_device_id *mpArryDevsID; 00214 cl_device_id mpDevID; 00215 cl_command_queue mpCmdQueue; 00216 cl_kernel mpArryKernels[MAX_CLFILE_NUM]; 00217 cl_program mpArryPrograms[MAX_CLFILE_NUM]; //one program object maps one kernel source file 00218 char mArryKnelSrcFile[MAX_CLFILE_NUM][256], //the max len of kernel file name is 256 00219 mArrykernelNames[MAX_CLKERNEL_NUM][MAX_KERNEL_STRING_LEN + 1]; 00220 cl_kernel_function mpArryKnelFuncs[MAX_CLKERNEL_NUM]; 00221 int mnKernelCount, mnFileCount, // only one kernel file 00222 mnIsUserCreated; // 1: created , 0:no create and needed to create by opencl wrapper 00223 int mnKhrFp64Flag; 00224 int mnAmdFp64Flag; 00225 00226 } GPUEnv; 00227 00228 00229 class OpenclDevice 00230 { 00231 00232 public: 00233 static GPUEnv gpuEnv; 00234 static int isInited; 00235 OpenclDevice(); 00236 ~OpenclDevice(); 00237 static int InitEnv(); // load dll, call InitOpenclRunEnv(0) 00238 static int InitOpenclRunEnv( int argc ); // RegistOpenclKernel, double flags, compile kernels 00239 static int InitOpenclRunEnv_DeviceSelection( int argc ); // RegistOpenclKernel, double flags, compile kernels 00240 static int InitOpenclRunEnv( GPUEnv *gpu ); // select device by env_CPU or selector 00241 static int RegistOpenclKernel(); 00242 static int ReleaseOpenclRunEnv(); 00243 static int ReleaseOpenclEnv( GPUEnv *gpuInfo ); 00244 static int CompileKernelFile( GPUEnv *gpuInfo, const char *buildOption ); 00245 static int CachedOfKernerPrg( const GPUEnv *gpuEnvCached, const char * clFileName ); 00246 static int GeneratBinFromKernelSource( cl_program program, const char * clFileName ); 00247 static int WriteBinaryToFile( const char* fileName, const char* birary, size_t numBytes ); 00248 static int BinaryGenerated( const char * clFileName, FILE ** fhandle ); 00249 //static int CompileKernelFile( const char *filename, GPUEnv *gpuInfo, const char *buildOption ); 00250 static l_uint32* pixReadFromTiffKernel(l_uint32 *tiffdata,l_int32 w,l_int32 h,l_int32 wpl, l_uint32 *line); 00251 static Pix* pixReadTiffCl( const char *filename, l_int32 n ); 00252 static PIX * pixReadStreamTiffCl ( FILE *fp, l_int32 n ); 00253 static PIX* pixReadFromTiffStreamCl(TIFF *tif); 00254 static int composeRGBPixelCl(int *tiffdata,int *line,int h,int w); 00255 static l_int32 getTiffStreamResolutionCl(TIFF *tif,l_int32 *pxres,l_int32 *pyres); 00256 static TIFF* fopenTiffCl(FILE *fp,const char *modestring); 00257 00258 /* OpenCL implementations of Morphological operations*/ 00259 00260 //Initialiation of OCL buffers used in Morph operations 00261 static int initMorphCLAllocations(l_int32 wpl, l_int32 h, PIX* pixs); 00262 static void releaseMorphCLBuffers(); 00263 00264 // OpenCL implementation of Morphology Dilate 00265 static PIX* pixDilateBrickCL(PIX *pixd, PIX *pixs, l_int32 hsize, l_int32 vsize, bool reqDataCopy); 00266 00267 // OpenCL implementation of Morphology Erode 00268 static PIX* pixErodeBrickCL(PIX *pixd, PIX *pixs, l_int32 hsize, l_int32 vsize, bool reqDataCopy); 00269 00270 // OpenCL implementation of Morphology Close 00271 static PIX* pixCloseBrickCL(PIX *pixd, PIX *pixs, l_int32 hsize, l_int32 vsize, bool reqDataCopy); 00272 00273 // OpenCL implementation of Morphology Open 00274 static PIX* pixOpenBrickCL(PIX *pixd, PIX *pixs, l_int32 hsize, l_int32 vsize, bool reqDataCopy); 00275 00276 // OpenCL implementation of Morphology Open 00277 static PIX* pixSubtractCL(PIX *pixd, PIX *pixs1, PIX *pixs2, bool reqDataCopy); 00278 00279 // OpenCL implementation of Morphology (Hollow = Closed - Open) 00280 static PIX* pixHollowCL(PIX *pixd, PIX *pixs, l_int32 close_hsize, l_int32 close_vsize, l_int32 open_hsize, l_int32 open_vsize, bool reqDataCopy); 00281 00282 static void pixGetLinesCL(PIX *pixd, PIX *pixs, 00283 PIX** pix_vline, PIX** pix_hline, 00284 PIX** pixClosed, bool getpixClosed, 00285 l_int32 close_hsize, l_int32 close_vsize, 00286 l_int32 open_hsize, l_int32 open_vsize, 00287 l_int32 line_hsize, l_int32 line_vsize); 00288 00289 //int InitOpenclAttr( OpenCLEnv * env ); 00290 //int ReleaseKernel( KernelEnv * env ); 00291 static int SetKernelEnv( KernelEnv *envInfo ); 00292 //int CreateKernel( char * kernelname, KernelEnv * env ); 00293 //int RunKernel( const char *kernelName, void **userdata ); 00294 //int ConvertToString( const char *filename, char **source ); 00295 //int CheckKernelName( KernelEnv *envInfo, const char *kernelName ); 00296 //int RegisterKernelWrapper( const char *kernelName, cl_kernel_function function ); 00297 //int RunKernelWrapper( cl_kernel_function function, const char * kernelName, void **usrdata ); 00298 //int GetKernelEnvAndFunc( const char *kernelName, KernelEnv *env, cl_kernel_function *function ); 00299 // static cl_device_id performDeviceSelection( ); 00300 //static bool thresholdRectToPixMicroBench( TessScoreEvaluationInputData input, ds_device_type type); 00301 00302 static int LoadOpencl(); 00303 #ifdef WIN32 00304 //static int OpenclInite(); 00305 static void FreeOpenclDll(); 00306 #endif 00307 00308 //int GetOpenclState(); 00309 //void SetOpenclState( int state ); 00310 inline static int AddKernelConfig( int kCount, const char *kName ); 00311 00312 /* for binarization */ 00313 static void HistogramRectOCL( 00314 const unsigned char *imagedata, 00315 int bytes_per_pixel, 00316 int bytes_per_line, 00317 int left, 00318 int top, 00319 int width, 00320 int height, 00321 int kHistogramSize, 00322 int *histogramAllChannels); 00323 static void ThresholdRectToPixOCL( 00324 const unsigned char* imagedata, 00325 int bytes_per_pixel, 00326 int bytes_per_line, 00327 const int* thresholds, 00328 const int* hi_values, 00329 Pix** pix, 00330 int rect_height, 00331 int rect_width, 00332 int rect_top, 00333 int rect_left); 00334 #if USE_DEVICE_SELECTION 00335 static ds_device getDeviceSelection(); 00336 static ds_device selectedDevice; 00337 static bool deviceIsSelected; 00338 #endif 00339 static bool selectedDeviceIsOpenCL(); 00340 static bool selectedDeviceIsNativeCPU(); 00341 00342 }; 00343 00344 00345 #endif