]> granicus.if.org Git - imagemagick/commitdiff
Added option to OpenCL to disable cache/regenerate profile.
authordirk <dirk@git.imagemagick.org>
Thu, 12 Dec 2013 06:16:19 +0000 (06:16 +0000)
committerdirk <dirk@git.imagemagick.org>
Thu, 12 Dec 2013 06:16:19 +0000 (06:16 +0000)
MagickCore/opencl.c
MagickCore/opencl.h

index c028801475f55c727e542d2362fead563cd7d830..66d6a12afd5627fb39f4e460b24419128f9c57e5 100644 (file)
@@ -96,8 +96,10 @@ struct _MagickCLEnv {
   cl_device_id device;
   cl_context context;
 
+  MagickBooleanType disableProgramCache; /* disable the OpenCL program cache */
   cl_program programs[MAGICK_OPENCL_NUM_PROGRAMS]; /* one program object maps one kernel source file */
 
+  MagickBooleanType regenerateProfile;   /* re-run the microbenchmark in auto device selection mode */ 
   SemaphoreInfo* lock;
 };
 
@@ -327,6 +329,22 @@ static MagickBooleanType SetMagickOpenCLEnvParamInternal(MagickCLEnv clEnv, Magi
     (void) ThrowMagickException(exception, GetMagickModule(), ModuleWarning, "SetMagickOpenCLEnvParm cannot modify the OpenCL initialization state.", "'%s'", ".");
     break;
 
+  case MAGICK_OPENCL_ENV_PARAM_PROGRAM_CACHE_DISABLED:
+    if (dataSize != sizeof(clEnv->disableProgramCache))
+      goto cleanup;
+    clEnv->disableProgramCache =  *((MagickBooleanType*)data);
+    clEnv->OpenCLInitialized = MagickFalse;
+    status = MagickTrue;
+    break;
+
+  case MAGICK_OPENCL_ENV_PARAM_REGENERATE_PROFILE:
+    if (dataSize != sizeof(clEnv->regenerateProfile))
+      goto cleanup;
+    clEnv->regenerateProfile =  *((MagickBooleanType*)data);
+    clEnv->OpenCLInitialized = MagickFalse;
+    status = MagickTrue;
+    break;
+
   default:
     goto cleanup;
   };
@@ -418,6 +436,20 @@ MagickExport
     status = MagickTrue;
     break;
 
+  case MAGICK_OPENCL_ENV_PARAM_PROGRAM_CACHE_DISABLED:
+    if (dataSize != sizeof(clEnv->disableProgramCache))
+      goto cleanup;
+    *((MagickBooleanType*)data) = clEnv->disableProgramCache;
+    status = MagickTrue;
+    break;
+
+  case MAGICK_OPENCL_ENV_PARAM_REGENERATE_PROFILE:
+    if (dataSize != sizeof(clEnv->regenerateProfile))
+      goto cleanup;
+    *((MagickBooleanType*)data) = clEnv->regenerateProfile;
+    status = MagickTrue;
+    break;
+
   default:
     goto cleanup;
   };
@@ -477,7 +509,7 @@ static char* getBinaryCLProgramName(MagickCLEnv clEnv, MagickOpenCLProgram prog,
     }
     ptr++;
   }
-  (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s_%s_%02d_%08x_%d.bin"
+  (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s_%s_%02d_%08x_%d.bin",
          GetOpenCLCachedFilesDirectory(),DirectorySeparator,prefix,deviceName,
          (unsigned int)prog,signature,sizeof(char*)*8);
   name = (char*)AcquireMagickMemory(strlen(path)+1);
@@ -704,7 +736,8 @@ static MagickBooleanType CompileOpenCLKernels(MagickCLEnv clEnv, ExceptionInfo*
     unsigned int programSignature = stringSignature(MagickOpenCLProgramStrings[i]) ^ optionsSignature;
 
     /* try to load the binary first */
-    if (!getenv("MAGICK_OCL_REC"))
+    if (clEnv->disableProgramCache != MagickTrue
+        && !getenv("MAGICK_OCL_REC"))
       loadSuccessful = loadBinaryCLProgram(clEnv, (MagickOpenCLProgram)i, programSignature);
 
     if (loadSuccessful == MagickFalse)
@@ -1339,8 +1372,8 @@ static ds_status initDSProfile(ds_profile** p, const char* version) {
     clGetPlatformIDs(numPlatforms, platforms, NULL);
     for (i = 0; i < (unsigned int)numPlatforms; i++) {
       cl_uint num;
-      clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_CPU | CL_DEVICE_TYPE_GPU, 0, NULL, &num);
-      numDevices+=num;
+      if (clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_CPU | CL_DEVICE_TYPE_GPU, 0, NULL, &num) == CL_SUCCESS)
+        numDevices+=num;
     }
   }
 
@@ -1991,6 +2024,9 @@ static ds_status AcceleratePerfEvaluator(ds_device *device,
   else
     ReturnStatus(DS_PERF_EVALUATOR_ERROR);
 
+  /* recompile the OpenCL kernels if it needs to */
+  clEnv->disableProgramCache = defaultCLEnv->disableProgramCache;
+
   InitOpenCLEnvInternal(clEnv,exception);
   oldClEnv=defaultCLEnv;
   defaultCLEnv=clEnv;
@@ -2110,6 +2146,7 @@ static MagickBooleanType autoSelectDevice(MagickCLEnv clEnv, ExceptionInfo* exce
   AccelerateScoreType bestScore;
   char path[MaxTextExtent];
   MagickBooleanType flag;
+  ds_evaluation_type profileType;
 
   LockDefaultOpenCLEnv();
 
@@ -2128,8 +2165,15 @@ static MagickBooleanType autoSelectDevice(MagickCLEnv clEnv, ExceptionInfo* exce
          ,GetOpenCLCachedFilesDirectory()
          ,DirectorySeparator,IMAGEMAGICK_PROFILE_FILE);
 
-  readProfileFromFile(profile, AccelerateScoreDeserializer, path);
-  status = profileDevices(profile, DS_EVALUATE_NEW_ONLY, AcceleratePerfEvaluator, NULL, &numDeviceProfiled);
+  if (clEnv->regenerateProfile == MagickTrue) {
+    profileType = DS_EVALUATE_ALL;
+  }
+  else {
+    readProfileFromFile(profile, AccelerateScoreDeserializer, path);
+    profileType = DS_EVALUATE_NEW_ONLY;
+  }
+  status = profileDevices(profile, profileType, AcceleratePerfEvaluator, NULL, &numDeviceProfiled);
+
   if (status!=DS_SUCCESS) {
     (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError, "Error when initializing the profile", "'%s'", ".");
     goto cleanup;
@@ -2259,6 +2303,15 @@ MagickExport MagickBooleanType InitImageMagickOpenCL(
       }
       break;
 
+    case MAGICK_OPENCL_DEVICE_SELECT_AUTO_CLEAR_CACHE:
+        flag = MagickTrue;
+        SetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_PROGRAM_CACHE_DISABLED
+          , sizeof(MagickBooleanType), &flag, exception);
+        flag = MagickTrue;
+        SetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_REGENERATE_PROFILE
+          , sizeof(MagickBooleanType), &flag, exception);
+
+    /* fall through here!! */
     case MAGICK_OPENCL_DEVICE_SELECT_AUTO:
     default:
       {
@@ -2281,7 +2334,7 @@ MagickExport MagickBooleanType InitImageMagickOpenCL(
 }
 
 
-MagickExport
+MagickPrivate
 MagickBooleanType OpenCLThrowMagickException(ExceptionInfo *exception,
   const char *module,const char *function,const size_t line,
   const ExceptionType severity,const char *tag,const char *format,...) {
@@ -2466,7 +2519,7 @@ MagickExport MagickBooleanType InitImageMagickOpenCL(
 }
 
 
-MagickExport
+MagickPrivate
 MagickBooleanType OpenCLThrowMagickException(ExceptionInfo *exception,
   const char *module,const char *function,const size_t line,
   const ExceptionType severity,const char *tag,const char *format,...) 
index f3838d89df312fdd2a33cfe82b40694034616967..19ab40a17ff95e375441144812b869decf57eff9 100644 (file)
@@ -47,9 +47,13 @@ extern MagickExport
 
 /* Parameter type accepted by SetMagickOpenCLEnvParm and GetMagickOpenCLEnvParm */
 typedef enum {
-    MAGICK_OPENCL_ENV_PARAM_DEVICE                  /* cl_device_id (from OpenCL) */
-  , MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED         /* MagickBooleanType */
-  , MAGICK_OPENCL_ENV_PARAM_OPENCL_INITIALIZED      /* MagickBooleanType */
+    MAGICK_OPENCL_ENV_PARAM_DEVICE                 /* cl_device_id (from OpenCL) */
+  , MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED        /* MagickBooleanType */
+  , MAGICK_OPENCL_ENV_PARAM_OPENCL_INITIALIZED     /* MagickBooleanType */
+  , MAGICK_OPENCL_ENV_PARAM_PROGRAM_CACHE_DISABLED /* MagickBooleanType */
+                                                   /* if true, disable the kernel binary cache */
+  , MAGICK_OPENCL_ENV_PARAM_REGENERATE_PROFILE     /* MagickBooleanType */
+                                                   /* if true, rerun microbenchmark in auto device selection */
 } MagickOpenCLEnvParam;
 
 extern MagickExport
@@ -66,13 +70,12 @@ typedef enum {
   MAGICK_OPENCL_OFF = 0
 , MAGICK_OPENCL_DEVICE_SELECT_AUTO = 1
 , MAGICK_OPENCL_DEVICE_SELECT_USER = 2
+, MAGICK_OPENCL_DEVICE_SELECT_AUTO_CLEAR_CACHE = 3
 } ImageMagickOpenCLMode ;
 
 extern MagickExport
 MagickBooleanType InitImageMagickOpenCL(ImageMagickOpenCLMode, void*, void*, ExceptionInfo*);
 
-
-
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif