/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%                   OOO   PPPP   EEEEE  N   N   CCCC  L                       %
%                  O   O  P   P  E      NN  N  C      L                       %
%                  O   O  PPPP   EEE    N N N  C      L                       %
%                  O   O  P      E      N  NN  C      L                       %
%                   OOO   P      EEEEE  N   N   CCCC  LLLLL                   %
%                                                                             %
%                                                                             %
%                         MagickCore OpenCL Methods                           %
%                                                                             %
%                              Software Design                                %
%                                John Cristy                                  %
%                                 March 2000                                  %
%                                                                             %
%                                                                             %
%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
%  dedicated to making software imaging solutions freely available.           %
%                                                                             %
%  You may not use this file except in compliance with the License.  You may  %
%  obtain a copy of the License at                                            %
%                                                                             %
%    http://www.imagemagick.org/script/license.php                            %
%                                                                             %
%  Unless required by applicable law or agreed to in writing, software        %
%  distributed under the License is distributed on an "AS IS" BASIS,          %
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
%  See the License for the specific language governing permissions and        %
%  limitations under the License.                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
%
*/
 
/*
Include declarations.
*/
#include "MagickCore/studio.h"
#include "MagickCore/artifact.h"
#include "MagickCore/cache.h"
#include "MagickCore/color.h"
#include "MagickCore/compare.h"
#include "MagickCore/constitute.h"
#include "MagickCore/distort.h"
#include "MagickCore/draw.h"
#include "MagickCore/effect.h"
#include "MagickCore/exception.h"
#include "MagickCore/exception-private.h"
#include "MagickCore/fx.h"
#include "MagickCore/gem.h"
#include "MagickCore/geometry.h"
#include "MagickCore/image.h"
#include "MagickCore/image-private.h"
#include "MagickCore/layer.h"
#include "MagickCore/mime-private.h"
#include "MagickCore/memory_.h"
#include "MagickCore/monitor.h"
#include "MagickCore/montage.h"
#include "MagickCore/morphology.h"
#include "MagickCore/nt-base.h"
#include "MagickCore/opencl.h"
#include "MagickCore/opencl-private.h"
#include "MagickCore/option.h"
#include "MagickCore/policy.h"
#include "MagickCore/property.h"
#include "MagickCore/quantize.h"
#include "MagickCore/quantum.h"
#include "MagickCore/resample.h"
#include "MagickCore/resource_.h"
#include "MagickCore/splay-tree.h"
#include "MagickCore/semaphore.h"
#include "MagickCore/statistic.h"
#include "MagickCore/string_.h"
#include "MagickCore/token.h"
#include "MagickCore/utility.h"

#ifdef MAGICKCORE_CLPERFMARKER
#include "CLPerfMarker.h"
#endif


#if defined(MAGICKCORE_OPENCL_SUPPORT)

struct _MagickCLEnv {
  MagickBooleanType OpenCLInitialized;  /* whether OpenCL environment is initialized. */
  MagickBooleanType OpenCLDisabled;	/* whether if OpenCL has been explicitely disabled. */

  /*OpenCL objects */
  cl_platform_id platform;
  cl_device_type deviceType;
  cl_device_id device;
  cl_context context;

  cl_program programs[MAGICK_OPENCL_NUM_PROGRAMS]; /* one program object maps one kernel source file */

  SemaphoreInfo* lock;
};


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   A c q u i r e M a g i c k O p e n C L E n v                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% AcquireMagickOpenCLEnv() allocates the MagickCLEnv structure 
%
*/

MagickExport MagickCLEnv AcquireMagickOpenCLEnv()
{
  MagickCLEnv clEnv;
  clEnv = (MagickCLEnv) AcquireMagickMemory(sizeof(struct _MagickCLEnv));
  if (clEnv != NULL)
  {
    memset(clEnv, 0, sizeof(struct _MagickCLEnv));
    AcquireSemaphoreInfo(&clEnv->lock);
  }
  return clEnv;
}


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   R e l i n q u i s h M a g i c k O p e n C L E n v                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RelinquishMagickOpenCLEnv() destroy the MagickCLEnv structure
%
%  The format of the RelinquishMagickOpenCLEnv method is:
%
%      MagickBooleanType RelinquishMagickOpenCLEnv(MagickCLEnv clEnv)
%
%  A description of each parameter follows:
%
%    o clEnv: MagickCLEnv structure to destroy
%
*/

MagickExport MagickBooleanType RelinquishMagickOpenCLEnv(MagickCLEnv clEnv)
{
  if (clEnv != (MagickCLEnv)NULL)
  {
    RelinquishSemaphoreInfo(clEnv->lock);
    RelinquishMagickMemory(clEnv);
    return MagickTrue;
  }
  return MagickFalse;
}


/*
* Default OpenCL environment
*/
MagickCLEnv defaultCLEnv;
SemaphoreInfo* defaultCLEnvLock;


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   G e t D e f a u l t O p e n C L E n v                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GetDefaultOpenCLEnv() returns the default OpenCL env
%
%  The format of the GetDefaultOpenCLEnv method is:
%
%      MagickCLEnv GetDefaultOpenCLEnv()
%
%  A description of each parameter follows:
%
%    o exception: return any errors or warnings.
%
*/

MagickExport MagickCLEnv GetDefaultOpenCLEnv()
{ 
  if (defaultCLEnv == NULL)
  {
    if (defaultCLEnvLock == NULL)
    {
      AcquireSemaphoreInfo(&defaultCLEnvLock);
    }
    LockSemaphoreInfo(defaultCLEnvLock);
    defaultCLEnv = AcquireMagickOpenCLEnv();
    UnlockSemaphoreInfo(defaultCLEnvLock); 
  }
  return defaultCLEnv; 
}

static void LockDefaultOpenCLEnv() {
  if (defaultCLEnvLock == NULL)
  {
    AcquireSemaphoreInfo(&defaultCLEnvLock);
  }
  LockSemaphoreInfo(defaultCLEnvLock);
}

static void UnlockDefaultOpenCLEnv() {
  if (defaultCLEnvLock == NULL)
  {
    AcquireSemaphoreInfo(&defaultCLEnvLock);
  }
  else
    UnlockSemaphoreInfo(defaultCLEnvLock);
}


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   S e t D e f a u l t O p e n C L E n v                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  SetDefaultOpenCLEnv() sets the new OpenCL environment as default 
%  and returns the old OpenCL environment
%  
%  The format of the SetDefaultOpenCLEnv() method is:
%
%      MagickCLEnv SetDefaultOpenCLEnv(MagickCLEnv clEnv)
%
%  A description of each parameter follows:
%
%    o clEnv: the new default OpenCL environment.
%
*/
MagickExport MagickCLEnv SetDefaultOpenCLEnv(MagickCLEnv clEnv)     
{
  MagickCLEnv oldEnv;
  LockDefaultOpenCLEnv();
  oldEnv = defaultCLEnv;
  defaultCLEnv = clEnv;
  UnlockDefaultOpenCLEnv();
  return oldEnv;
} 



/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   S e t M a g i c k O p e n C L E n v P a r a m                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  SetMagickOpenCLEnvParam() sets the parameters in the OpenCL environment  
%  
%  The format of the SetMagickOpenCLEnvParam() method is:
%
%      MagickBooleanType SetMagickOpenCLEnvParam(MagickCLEnv clEnv, 
%        MagickOpenCLEnvParam param, size_t dataSize, void* data, 
%        ExceptionInfo* exception)
%
%  A description of each parameter follows:
%
%    o clEnv: the OpenCL environment.
%    
%    o param: the parameter to be set.
%
%    o dataSize: the data size of the parameter value.
%
%    o data:  the pointer to the new parameter value
%
%    o exception: return any errors or warnings
%
*/

static MagickBooleanType SetMagickOpenCLEnvParamInternal(MagickCLEnv clEnv, MagickOpenCLEnvParam param
                                          , size_t dataSize, void* data, ExceptionInfo* exception)
{
  MagickBooleanType status = MagickFalse;

  if (clEnv == NULL
    || data == NULL)
    goto cleanup;

  switch(param)
  {
  case MAGICK_OPENCL_ENV_PARAM_DEVICE:
    if (dataSize != sizeof(clEnv->device))
      goto cleanup;
    clEnv->device = *((cl_device_id*)data);
    clEnv->OpenCLInitialized = MagickFalse;
    status = MagickTrue;
    break;

  case MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED:
    if (dataSize != sizeof(clEnv->OpenCLDisabled))
      goto cleanup;
    clEnv->OpenCLDisabled =  *((MagickBooleanType*)data);
    clEnv->OpenCLInitialized = MagickFalse;
    status = MagickTrue;
    break;

  case MAGICK_OPENCL_ENV_PARAM_OPENCL_INITIALIZED:
    (void) ThrowMagickException(exception, GetMagickModule(), ModuleWarning, "SetMagickOpenCLEnvParm cannot modify the OpenCL initialization state.", "'%s'", ".");
    break;

  default:
    goto cleanup;
  };

cleanup:
  return status;
}

MagickExport
  MagickBooleanType SetMagickOpenCLEnvParam(MagickCLEnv clEnv, MagickOpenCLEnvParam param
                                          , size_t dataSize, void* data, ExceptionInfo* exception) {
  MagickBooleanType status = MagickFalse;
  if (clEnv!=NULL) {
    LockSemaphoreInfo(clEnv->lock);
    status = SetMagickOpenCLEnvParamInternal(clEnv,param,dataSize,data,exception);
    UnlockSemaphoreInfo(clEnv->lock);
  }
  return status;
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   G e t M a g i c k O p e n C L E n v P a r a m                             %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GetMagickOpenCLEnvParam() gets the parameters in the OpenCL environment  
%  
%  The format of the GetMagickOpenCLEnvParam() method is:
%
%      MagickBooleanType GetMagickOpenCLEnvParam(MagickCLEnv clEnv, 
%        MagickOpenCLEnvParam param, size_t dataSize, void* data, 
%        ExceptionInfo* exception)
%
%  A description of each parameter follows:
%
%    o clEnv: the OpenCL environment.
%    
%    o param: the parameter to be returned.
%
%    o dataSize: the data size of the parameter value.
%
%    o data:  the location where the returned parameter value will be stored 
%
%    o exception: return any errors or warnings
%
*/

MagickExport
  MagickBooleanType GetMagickOpenCLEnvParam(MagickCLEnv clEnv, MagickOpenCLEnvParam param
                                          , size_t dataSize, void* data, ExceptionInfo* exception)
{
  MagickBooleanType status;
  status = MagickFalse;

  if (clEnv == NULL
    || data == NULL)
    goto cleanup;

  switch(param)
  {
  case MAGICK_OPENCL_ENV_PARAM_DEVICE:
    if (dataSize != sizeof(cl_device_id))
      goto cleanup;
    *((cl_device_id*)data) = clEnv->device;
    status = MagickTrue;
    break;

  case MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED:
    if (dataSize != sizeof(clEnv->OpenCLDisabled))
      goto cleanup;
    *((MagickBooleanType*)data) = clEnv->OpenCLDisabled;
    status = MagickTrue;
    break;

  case MAGICK_OPENCL_ENV_PARAM_OPENCL_INITIALIZED:
    if (dataSize != sizeof(clEnv->OpenCLDisabled))
      goto cleanup;
    *((MagickBooleanType*)data) = clEnv->OpenCLInitialized;
    status = MagickTrue;
    break;

  default:
    goto cleanup;
  };

cleanup:
  return status;
}


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   G e t O p e n C L C o n t e x t                                           %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GetOpenCLContext() returns the OpenCL context  
%  
%  The format of the GetOpenCLContext() method is:
%
%      cl_context GetOpenCLContext(MagickCLEnv clEnv) 
%
%  A description of each parameter follows:
%
%    o clEnv: OpenCL environment
%
*/

MagickExport
cl_context GetOpenCLContext(MagickCLEnv clEnv) {
  if (clEnv == NULL)
    return NULL;
  else
    return clEnv->context;
}

static char* getBinaryCLProgramName(MagickCLEnv clEnv, MagickOpenCLProgram prog, unsigned int signature)
{
  char* name;
  char* ptr;
  char path[MaxTextExtent];
  char deviceName[MaxTextExtent];
  const char* prefix = "magick_opencl";
  clGetDeviceInfo(clEnv->device, CL_DEVICE_NAME, MaxTextExtent, deviceName, NULL);
  ptr=deviceName;
  /* strip out illegal characters for file names */
  while (*ptr != '\0')
  {
    if ( *ptr == ' ' || *ptr == '\\' || *ptr == '/' || *ptr == ':' || *ptr == '*' 
        || *ptr == '?' || *ptr == '"' || *ptr == '<' || *ptr == '>' || *ptr == '|')
    {
      *ptr = '_';
    }
    ptr++;
  }
  (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s_%s_%02d_%08x.bin"
         ,GetOpenCLCachedFilesDirectory()
         ,DirectorySeparator,prefix,deviceName, (unsigned int)prog, signature);
  name = (char*)AcquireMagickMemory(strlen(path)+1);
  CopyMagickString(name,path,strlen(path)+1);
  return name;
}

static MagickBooleanType saveBinaryCLProgram(MagickCLEnv clEnv, MagickOpenCLProgram prog, unsigned int signature, ExceptionInfo* exception)
{
  MagickBooleanType saveSuccessful;
  cl_int clStatus;
  size_t binaryProgramSize;
  unsigned char* binaryProgram;
  char* binaryFileName;
  FILE* fileHandle;

#ifdef MAGICKCORE_CLPERFMARKER
  clBeginPerfMarkerAMD(__FUNCTION__,"");
#endif

  binaryProgram = NULL;
  binaryFileName = NULL;
  fileHandle = NULL;
  saveSuccessful = MagickFalse;

  clStatus = clGetProgramInfo(clEnv->programs[prog], CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binaryProgramSize, NULL);
  if (clStatus != CL_SUCCESS)
  {
    (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError, "clGetProgramInfo failed.", "'%s'", ".");
    goto cleanup;
  }

  binaryProgram = (unsigned char*) AcquireMagickMemory(binaryProgramSize);
  clStatus = clGetProgramInfo(clEnv->programs[prog], CL_PROGRAM_BINARIES, sizeof(char*), &binaryProgram, NULL);
  if (clStatus != CL_SUCCESS)
  {
    (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError, "clGetProgramInfo failed.", "'%s'", ".");
    goto cleanup;
  }

  binaryFileName = getBinaryCLProgramName(clEnv, prog, signature);
  fileHandle = fopen(binaryFileName, "wb");
  if (fileHandle != NULL)
  {
    fwrite(binaryProgram, sizeof(char), binaryProgramSize, fileHandle);
    saveSuccessful = MagickTrue;
  }
  else
  {
    (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning,
      "Saving binary kernel failed.", "'%s'", ".");
  }

cleanup:
  if (fileHandle != NULL)
    fclose(fileHandle);
  if (binaryProgram != NULL)
    RelinquishMagickMemory(binaryProgram);
  if (binaryFileName != NULL)
    free(binaryFileName);

#ifdef MAGICKCORE_CLPERFMARKER
  clEndPerfMarkerAMD();
#endif

  return saveSuccessful;
}

static MagickBooleanType loadBinaryCLProgram(MagickCLEnv clEnv, MagickOpenCLProgram prog, unsigned int signature, ExceptionInfo* exception)
{
  MagickBooleanType loadSuccessful;
  unsigned char* binaryProgram;
  char* binaryFileName;
  FILE* fileHandle;

#ifdef MAGICKCORE_CLPERFMARKER
  clBeginPerfMarkerAMD(__FUNCTION__,"");
#endif

  binaryProgram = NULL;
  binaryFileName = NULL;
  fileHandle = NULL;
  loadSuccessful = MagickFalse;

  binaryFileName = getBinaryCLProgramName(clEnv, prog, signature);
  fileHandle = fopen(binaryFileName, "rb");
  if (fileHandle != NULL)
  {
    int b_error;
    size_t length;
    cl_int clStatus;
    cl_int clBinaryStatus;

    b_error = 0 ;
    length = 0;
    b_error |= fseek( fileHandle, 0, SEEK_END ) < 0;
    b_error |= ( length = ftell( fileHandle ) ) <= 0;
    b_error |= fseek( fileHandle, 0, SEEK_SET ) < 0;
    if( b_error )
      goto cleanup;

    binaryProgram = (unsigned char*)AcquireMagickMemory(length);
    if (binaryProgram == NULL)
      goto cleanup;

    memset(binaryProgram, 0, length);
    b_error |= fread(binaryProgram, 1, length, fileHandle) != length;

    clEnv->programs[prog] = clCreateProgramWithBinary(clEnv->context, 1, &clEnv->device, &length, (const unsigned char**)&binaryProgram, &clBinaryStatus, &clStatus);
    if (clStatus != CL_SUCCESS
        || clBinaryStatus != CL_SUCCESS)
      goto cleanup;

    loadSuccessful = MagickTrue;
  }

cleanup:
  if (fileHandle != NULL)
    fclose(fileHandle);
  if (binaryFileName != NULL)
    free(binaryFileName);
  if (binaryProgram != NULL)
    RelinquishMagickMemory(binaryProgram);

#ifdef MAGICKCORE_CLPERFMARKER
  clEndPerfMarkerAMD();
#endif

  return loadSuccessful;
}

static unsigned int stringSignature(const char* string)
{
  unsigned int stringLength;
  unsigned int n,i,j;
  unsigned int signature;
  union
  {
    const char* s;
    const unsigned int* u;
  }p;

#ifdef MAGICKCORE_CLPERFMARKER
  clBeginPerfMarkerAMD(__FUNCTION__,"");
#endif

  stringLength = strlen(string);
  signature = stringLength;
  n = stringLength/sizeof(unsigned int);
  p.s = string;
  for (i = 0; i < n; i++)
  {
    signature^=p.u[i];
  }
  if (n * sizeof(unsigned int) != stringLength)
  {
    char padded[4];
    j = n * sizeof(unsigned int);
    for (i = 0; i < 4; i++,j++)
    {
      if (j < stringLength)
        padded[i] = p.s[j];
      else
        padded[i] = 0;
    }
    p.s = padded;
    signature^=p.u[0];
  }

#ifdef MAGICKCORE_CLPERFMARKER
  clEndPerfMarkerAMD();
#endif

  return signature;
}

/* OpenCL kernels for accelerate.c */
extern const char *accelerateKernels, *accelerateKernels2;

static MagickBooleanType CompileOpenCLKernels(MagickCLEnv clEnv, ExceptionInfo* exception) 
{
  MagickBooleanType status = MagickFalse;
  cl_int clStatus;
  unsigned int i;
  char* accelerateKernelsBuffer = NULL;

  /* The index of the program strings in this array has to match the value of the enum MagickOpenCLProgram */
  const char* MagickOpenCLProgramStrings[MAGICK_OPENCL_NUM_PROGRAMS]; 

  char options[MaxTextExtent];
  unsigned int optionsSignature;

#ifdef MAGICKCORE_CLPERFMARKER
  clBeginPerfMarkerAMD(__FUNCTION__,"");
#endif

  /* Get additional options */
  (void) FormatLocaleString(options, MaxTextExtent, CLOptions, (float)QuantumRange,
    (float)QuantumScale, (float)CLCharQuantumScale, (float)MagickEpsilon, (float)MagickPI, (unsigned int)MaxMap, (unsigned int)MAGICKCORE_QUANTUM_DEPTH);

  /*
  if (getenv("MAGICK_OCL_DEF"))
  {
    strcat(options," ");
    strcat(options,getenv("MAGICK_OCL_DEF"));
  }
  */

  /*
  if (getenv("MAGICK_OCL_BUILD"))
    printf("options: %s\n", options);
  */

  optionsSignature = stringSignature(options);

  /* get all the OpenCL program strings here */
  accelerateKernelsBuffer = (char*) AcquireMagickMemory(strlen(accelerateKernels)+strlen(accelerateKernels2)+1);
  sprintf(accelerateKernelsBuffer,"%s%s",accelerateKernels,accelerateKernels2);
  MagickOpenCLProgramStrings[MAGICK_OPENCL_ACCELERATE] = accelerateKernelsBuffer;

  for (i = 0; i < MAGICK_OPENCL_NUM_PROGRAMS; i++) 
  {
    MagickBooleanType loadSuccessful = MagickFalse;
    unsigned int programSignature = stringSignature(MagickOpenCLProgramStrings[i]) ^ optionsSignature;

    /* try to load the binary first */
    if (!getenv("MAGICK_OCL_REC"))
      loadSuccessful = loadBinaryCLProgram(clEnv, (MagickOpenCLProgram)i, programSignature, exception);

    if (loadSuccessful == MagickFalse)
    {
      /* Binary CL program unavailable, compile the program from source */
      size_t programLength = strlen(MagickOpenCLProgramStrings[i]);
      clEnv->programs[i] = clCreateProgramWithSource(clEnv->context, 1, &(MagickOpenCLProgramStrings[i]), &programLength, &clStatus);
      if (clStatus!=CL_SUCCESS)
      {
        (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning,
          "clCreateProgramWithSource failed.", "(%d)", (int)clStatus);

        goto cleanup;
      }
    }

    clStatus = clBuildProgram(clEnv->programs[i], 1, &clEnv->device, options, NULL, NULL);
    if (clStatus!=CL_SUCCESS)
    {
      (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning,
        "clBuildProgram failed.", "(%d)", (int)clStatus);

      if (loadSuccessful == MagickFalse)
      {
        char path[MaxTextExtent];
        FILE* fileHandle;

        /*  dump the source into a file */
        (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s"
         ,GetOpenCLCachedFilesDirectory()
         ,DirectorySeparator,"magick_badcl.cl");
        fileHandle = fopen(path, "wb");	
        if (fileHandle != NULL)
        {
          fwrite(MagickOpenCLProgramStrings[i], sizeof(char), strlen(MagickOpenCLProgramStrings[i]), fileHandle);
          fclose(fileHandle);
        }

        /* dump the build log */
        {
          char* log;
          size_t logSize;
          clGetProgramBuildInfo(clEnv->programs[i], clEnv->device, CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize);
          log = (char*)AcquireMagickMemory(logSize);
          clGetProgramBuildInfo(clEnv->programs[i], clEnv->device, CL_PROGRAM_BUILD_LOG, logSize, log, &logSize);

          (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s"
           ,GetOpenCLCachedFilesDirectory()
           ,DirectorySeparator,"magick_badcl_build.log");
          fileHandle = fopen(path, "wb");	
          if (fileHandle != NULL)
          {
            const char* buildOptionsTitle = "build options: ";
            fwrite(buildOptionsTitle, sizeof(char), strlen(buildOptionsTitle), fileHandle);
            fwrite(options, sizeof(char), strlen(options), fileHandle);
            fwrite("\n",sizeof(char), 1, fileHandle);
            fwrite(log, sizeof(char), logSize, fileHandle);
            fclose(fileHandle);
          }
          RelinquishMagickMemory(log);
        }
      }
      goto cleanup;
    }

    if (loadSuccessful == MagickFalse)
    {
      /* Save the binary to a file to avoid re-compilation of the kernels in the future */
      saveBinaryCLProgram(clEnv, (MagickOpenCLProgram)i, programSignature, exception);
    }

  }
  status = MagickTrue;

cleanup:

  if (accelerateKernelsBuffer!=NULL) RelinquishMagickMemory(accelerateKernelsBuffer);

#ifdef MAGICKCORE_CLPERFMARKER
  clEndPerfMarkerAMD();
#endif

  return status;
}

static MagickBooleanType InitOpenCLPlatformDevice(MagickCLEnv clEnv, ExceptionInfo* exception) {
  int i,j;
  cl_int status;
  cl_uint numPlatforms = 0;
  cl_platform_id *platforms = NULL;
  char* MAGICK_OCL_DEVICE = NULL;
  MagickBooleanType OpenCLAvailable = MagickFalse;

#ifdef MAGICKCORE_CLPERFMARKER
  clBeginPerfMarkerAMD(__FUNCTION__,"");
#endif

  /* check if there's an environment variable overriding the device selection */
  MAGICK_OCL_DEVICE = getenv("MAGICK_OCL_DEVICE");
  if (MAGICK_OCL_DEVICE != NULL)
  {
    if (strcmp(MAGICK_OCL_DEVICE, "CPU") == 0)
    {
      clEnv->deviceType = CL_DEVICE_TYPE_CPU;
    }
    else if (strcmp(MAGICK_OCL_DEVICE, "GPU") == 0)
    {
      clEnv->deviceType = CL_DEVICE_TYPE_GPU;
    }
    else if (strcmp(MAGICK_OCL_DEVICE, "OFF") == 0)
    {
      /* OpenCL disabled */
      goto cleanup;
    }
  }
  else if (clEnv->deviceType == 0) {
    clEnv->deviceType = CL_DEVICE_TYPE_ALL;
  }

  if (clEnv->device != NULL)
  {
    status = clGetDeviceInfo(clEnv->device, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), &clEnv->platform, NULL);
    if (status != CL_SUCCESS) {
      (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning,
          "Failed to get OpenCL platform from the selected device.", "(%d)", status);
    }
    goto cleanup;
  }
  else if (clEnv->platform != NULL)
  {
    numPlatforms = 1;
    platforms = (cl_platform_id *) AcquireMagickMemory(numPlatforms * sizeof(cl_platform_id));
    if (platforms == (cl_platform_id *) NULL)
    {
      (void) ThrowMagickException(exception, GetMagickModule(), ResourceLimitError,
        "AcquireMagickMemory failed.",".");
      goto cleanup;
    }
    platforms[0] = clEnv->platform;
  }
  else
  {
    clEnv->device = NULL;

    /* Get the number of OpenCL platforms available */
    status = clGetPlatformIDs(0, NULL, &numPlatforms);
    if (status != CL_SUCCESS)
    {
      (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning, 
        "clGetplatformIDs failed.", "(%d)", status);
      goto cleanup;
    }

    /* No OpenCL available, just leave */
    if (numPlatforms == 0) {
      goto cleanup;
    }

    platforms = (cl_platform_id *) AcquireMagickMemory(numPlatforms * sizeof(cl_platform_id));
    if (platforms == (cl_platform_id *) NULL)
    {
      (void) ThrowMagickException(exception, GetMagickModule(), ResourceLimitError,
        "AcquireMagickMemory failed.",".");
      goto cleanup;
    }

    status = clGetPlatformIDs(numPlatforms, platforms, NULL);
    if (status != CL_SUCCESS)
    {
      (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning,
        "clGetPlatformIDs failed.", "(%d)", status);
      goto cleanup;
    }
  }

  /* Device selection */
  clEnv->device = NULL;
  for (j = 0; j < 2; j++) 
  {

    cl_device_type deviceType;
    if (clEnv->deviceType == CL_DEVICE_TYPE_ALL)
    {
      if (j == 0)
        deviceType = CL_DEVICE_TYPE_GPU;
      else
        deviceType = CL_DEVICE_TYPE_CPU;
    }
    else if (j == 1)
    {
      break;
    }
    else
      deviceType = clEnv->deviceType;

    for (i = 0; i < numPlatforms; i++)
    {
      cl_uint numDevices;
      status = clGetDeviceIDs(platforms[i], deviceType, 1, &(clEnv->device), &numDevices);
      if (status != CL_SUCCESS)
      {
        (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning,
          "clGetPlatformIDs failed.", "(%d)", status);
        goto cleanup;
      }
      if (clEnv->device != NULL)
      {
        clEnv->platform = platforms[i];
  goto cleanup;
      }
    }
  }

cleanup:
  if (platforms!=NULL)
    RelinquishMagickMemory(platforms);

  OpenCLAvailable = (clEnv->platform!=NULL
          && clEnv->device!=NULL)?MagickTrue:MagickFalse;

#ifdef MAGICKCORE_CLPERFMARKER
  clEndPerfMarkerAMD();
#endif

  return OpenCLAvailable;
}

static MagickBooleanType EnableOpenCLInternal(MagickCLEnv clEnv) {
  if (clEnv->OpenCLInitialized == MagickTrue
    && clEnv->platform != NULL
    && clEnv->device != NULL) {
      clEnv->OpenCLDisabled = MagickFalse;
      return MagickTrue;
  }
  clEnv->OpenCLDisabled = MagickTrue;
  return MagickFalse;
}


static MagickBooleanType autoSelectDevice(MagickCLEnv clEnv, ExceptionInfo* exception);
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   I n i t O p e n C L E n v                                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  InitOpenCLEnv() initialize the OpenCL environment
%
%  The format of the RelinquishMagickOpenCLEnv method is:
%
%      MagickBooleanType InitOpenCLEnv(MagickCLEnv clEnv, ExceptionInfo* exception)
%
%  A description of each parameter follows:
%
%    o clEnv: OpenCL environment structure
%
%    o exception: return any errors or warnings.
%
*/

MagickExport
MagickBooleanType InitOpenCLEnvInternal(MagickCLEnv clEnv, ExceptionInfo* exception) {
  MagickBooleanType status = MagickTrue;
  cl_int clStatus;
  cl_context_properties cps[3];


  clEnv->OpenCLInitialized = MagickTrue;
  if (clEnv->OpenCLDisabled == MagickTrue)
    goto cleanup;

  clEnv->OpenCLDisabled = MagickTrue;
  /* setup the OpenCL platform and device */
  status = InitOpenCLPlatformDevice(clEnv, exception);
  if (status == MagickFalse) {
    /* No OpenCL device available */
    goto cleanup;
  }

  /* create an OpenCL context */
  cps[0] = CL_CONTEXT_PLATFORM;
  cps[1] = (cl_context_properties)clEnv->platform;
  cps[2] = 0;
  clEnv->context = clCreateContext(cps, 1, &(clEnv->device), NULL, NULL, &clStatus);
  if (clStatus != CL_SUCCESS)
  {
    (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning,
        "clCreateContext failed.", "(%d)", clStatus);
    status = MagickFalse;
    goto cleanup;
  }

  status = CompileOpenCLKernels(clEnv, exception);
  if (status == MagickFalse) {
   (void) ThrowMagickException(exception, GetMagickModule(), DelegateWarning,
        "clCreateCommandQueue failed.", "(%d)", status);

    status = MagickFalse;
    goto cleanup;
  }

  status = EnableOpenCLInternal(clEnv);
cleanup:
  return status;
}


MagickExport
MagickBooleanType InitOpenCLEnv(MagickCLEnv clEnv, ExceptionInfo* exception) {
  MagickBooleanType status = MagickFalse;

  if (clEnv == NULL)
    return MagickFalse;

#ifdef MAGICKCORE_CLPERFMARKER
  clBeginPerfMarkerAMD(__FUNCTION__,"");
#endif

  LockSemaphoreInfo(clEnv->lock);
  if (clEnv->OpenCLInitialized == MagickFalse) {
    if (clEnv->device==NULL
        && clEnv->OpenCLDisabled == MagickFalse)
      status = autoSelectDevice(clEnv, exception);
    else
      status = InitOpenCLEnvInternal(clEnv, exception);
  }
  UnlockSemaphoreInfo(clEnv->lock);

#ifdef MAGICKCORE_CLPERFMARKER
  clEndPerfMarkerAMD();
#endif
  return status;
}


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   A c q u i r e O p e n C L C o m m a n d Q u e u e                         %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  AcquireOpenCLCommandQueue() acquires an OpenCL command queue
%
%  The format of the AcquireOpenCLCommandQueue method is:
%
%      cl_command_queue AcquireOpenCLCommandQueue(MagickCLEnv clEnv)
%
%  A description of each parameter follows:
%
%    o clEnv: the OpenCL environment.
%
*/

MagickExport
cl_command_queue AcquireOpenCLCommandQueue(MagickCLEnv clEnv)
{
  if (clEnv != NULL)
    return clCreateCommandQueue(clEnv->context, clEnv->device, 0, NULL);
  else
    return NULL;
}


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   R e l i n q u i s h O p e n C L C o m m a n d Q u e u e                   %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RelinquishOpenCLCommandQueue() releases the OpenCL command queue
%
%  The format of the RelinquishOpenCLCommandQueue method is:
%
%      MagickBooleanType RelinquishOpenCLCommandQueue(MagickCLEnv clEnv,
%        cl_command_queue queue)
%
%  A description of each parameter follows:
%
%    o clEnv: the OpenCL environment.
%
%    o queue: the OpenCL queue to be released.
%
%
*/
MagickExport
MagickBooleanType RelinquishOpenCLCommandQueue(MagickCLEnv clEnv, cl_command_queue queue)
{
  if (clEnv != NULL)
  {
    return ((clReleaseCommandQueue(queue) == CL_SUCCESS) ? MagickTrue:MagickFalse);
  }
  else
    return MagickFalse;
}



/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   A c q u i r e O p e n C L K e r n e l                                     %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  AcquireOpenCLKernel() acquires an OpenCL kernel
%
%  The format of the AcquireOpenCLKernel method is:
%
%      cl_kernel AcquireOpenCLKernel(MagickCLEnv clEnv, 
%        MagickOpenCLProgram program, const char* kernelName)
%
%  A description of each parameter follows:
%
%    o clEnv: the OpenCL environment.
%
%    o program: the OpenCL program module that the kernel belongs to.
%
%    o kernelName:  the name of the kernel
%
*/

MagickExport
  cl_kernel AcquireOpenCLKernel(MagickCLEnv clEnv, MagickOpenCLProgram program, const char* kernelName)
{
  cl_int clStatus;
  cl_kernel kernel = NULL;
  if (clEnv != NULL && kernelName!=NULL)
  {
    kernel = clCreateKernel(clEnv->programs[program], kernelName, &clStatus);
  }
  return kernel;
}


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   R e l i n q u i s h O p e n C L K e r n e l                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  RelinquishOpenCLKernel() releases an OpenCL kernel
%
%  The format of the RelinquishOpenCLKernel method is:
%
%    MagickBooleanType RelinquishOpenCLKernel(MagickCLEnv clEnv,
%      cl_kernel kernel)
%
%  A description of each parameter follows:
%
%    o clEnv: the OpenCL environment.
%
%    o kernel: the OpenCL kernel object to be released.
%
%
*/

MagickExport
  MagickBooleanType RelinquishOpenCLKernel(MagickCLEnv clEnv, cl_kernel kernel)
{
  MagickBooleanType status = MagickFalse;
  if (clEnv != NULL && kernel != NULL)
  {
    status = ((clReleaseKernel(kernel) == CL_SUCCESS)?MagickTrue:MagickFalse);
  }
  return status;
}

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   G e t O p e n C L D e v i c e L o c a l M e m o r y S i z e               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  GetOpenCLDeviceLocalMemorySize() returns local memory size of the device
%
%  The format of the GetOpenCLDeviceLocalMemorySize method is:
%
%    unsigned long GetOpenCLDeviceLocalMemorySize(MagickCLEnv clEnv)
%
%  A description of each parameter follows:
%
%    o clEnv: the OpenCL environment.
%
%
*/

MagickExport
 unsigned long GetOpenCLDeviceLocalMemorySize(MagickCLEnv clEnv)
{
  cl_ulong localMemorySize;
  clGetDeviceInfo(clEnv->device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(cl_ulong), &localMemorySize, NULL);
  return (unsigned long)localMemorySize;
}

MagickExport
  unsigned long GetOpenCLDeviceMaxMemAllocSize(MagickCLEnv clEnv)
{
  cl_ulong maxMemAllocSize;
  clGetDeviceInfo(clEnv->device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &maxMemAllocSize, NULL);
  return (unsigned long)maxMemAllocSize;
}


/*
 Beginning of the OpenCL device selection infrastructure
*/


#define DS_DEVICE_NAME_LENGTH 256

typedef enum {
  DS_SUCCESS = 0
 ,DS_INVALID_PROFILE = 1000
 ,DS_MEMORY_ERROR
 ,DS_INVALID_PERF_EVALUATOR_TYPE
 ,DS_INVALID_PERF_EVALUATOR
 ,DS_PERF_EVALUATOR_ERROR
 ,DS_FILE_ERROR
 ,DS_UNKNOWN_DEVICE_TYPE
 ,DS_PROFILE_FILE_ERROR
 ,DS_SCORE_SERIALIZER_ERROR
 ,DS_SCORE_DESERIALIZER_ERROR
} ds_status;

/* device type */
typedef enum {
  DS_DEVICE_NATIVE_CPU = 0
 ,DS_DEVICE_OPENCL_DEVICE 
} ds_device_type;


typedef struct {
  ds_device_type  type;
  cl_device_id    oclDeviceID;
  char*           oclDeviceName;
  char*           oclDriverVersion;
  cl_uint         oclMaxClockFrequency;
  cl_uint         oclMaxComputeUnits;
  void*           score;            /* a pointer to the score data, the content/format is application defined */
} ds_device;

typedef struct {
  unsigned int  numDevices;
  ds_device*    devices;
  const char*   version;
} ds_profile;

/* deallocate memory used by score */
typedef ds_status (*ds_score_release)(void* score);

static ds_status releaseDeviceResource(ds_device* device, ds_score_release sr) {
  ds_status status = DS_SUCCESS;
  if (device) {
    if (device->oclDeviceName)      free(device->oclDeviceName);
    if (device->oclDriverVersion)   free(device->oclDriverVersion);
    if (device->score)              status = sr(device->score);
  }
  return status;
}

static ds_status releaseDSProfile(ds_profile* profile, ds_score_release sr) {
  ds_status status = DS_SUCCESS;
  if (profile!=NULL) {
    if (profile->devices!=NULL && sr!=NULL) {
      unsigned int i;
      for (i = 0; i < profile->numDevices; i++) {
        status = releaseDeviceResource(profile->devices+i,sr);
        if (status != DS_SUCCESS)
          break;
      }
      free(profile->devices);
    }
    free(profile);
  }
  return status;
}


static ds_status initDSProfile(ds_profile** p, const char* version) {
  int numDevices = 0;
  cl_uint numPlatforms = 0;
  cl_platform_id* platforms = NULL;
  cl_device_id*   devices = NULL;
  ds_status status = DS_SUCCESS;
  ds_profile* profile = NULL;
  unsigned int next = 0;
  unsigned int i;

  if (p == NULL)
    return DS_INVALID_PROFILE;

  profile = (ds_profile*)malloc(sizeof(ds_profile));
  if (profile == NULL)
    return DS_MEMORY_ERROR;
  
  memset(profile, 0, sizeof(ds_profile));

  clGetPlatformIDs(0, NULL, &numPlatforms);
  if (numPlatforms > 0) {
    platforms = (cl_platform_id*)malloc(numPlatforms*sizeof(cl_platform_id));
    if (platforms == NULL) {
      status = DS_MEMORY_ERROR;
      goto cleanup;
    }
    clGetPlatformIDs(numPlatforms, platforms, NULL);
    for (i = 0; i < (unsigned int)numPlatforms; i++) {
      cl_uint num;
      clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &num);
      numDevices+=num;
    }
  }

  profile->numDevices = numDevices+1;     /* +1 to numDevices to include the native CPU */

  profile->devices = (ds_device*)malloc(profile->numDevices*sizeof(ds_device));    
  if (profile->devices == NULL) {
    profile->numDevices = 0;
    status = DS_MEMORY_ERROR;
    goto cleanup;    
  }
  memset(profile->devices, 0, profile->numDevices*sizeof(ds_device));

  if (numDevices > 0) {
    devices = (cl_device_id*)malloc(numDevices*sizeof(cl_device_id));
    if (devices == NULL) {
      status = DS_MEMORY_ERROR;
      goto cleanup;
    }
    for (i = 0; i < (unsigned int)numPlatforms; i++) {
      cl_uint num;

      int d;
      for (d = 0; d < 2; d++) { 
        unsigned int j;
        cl_device_type deviceType;
        switch(d) {
        case 0:
          deviceType = CL_DEVICE_TYPE_GPU;
          break;
        case 1:
          deviceType = CL_DEVICE_TYPE_CPU;
          break;
        default:
          continue;
          break;
        }
        clGetDeviceIDs(platforms[i], deviceType, numDevices, devices, &num);
        for (j = 0; j < num; j++, next++) {
          char buffer[DS_DEVICE_NAME_LENGTH];
          size_t length;

          profile->devices[next].type = DS_DEVICE_OPENCL_DEVICE;
          profile->devices[next].oclDeviceID = devices[j];

          clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DEVICE_NAME
            , DS_DEVICE_NAME_LENGTH, &buffer, NULL);
          length = strlen(buffer);
          profile->devices[next].oclDeviceName = (char*)malloc(length+1);
          memcpy(profile->devices[next].oclDeviceName, buffer, length+1);

          clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DRIVER_VERSION
            , DS_DEVICE_NAME_LENGTH, &buffer, NULL);
          length = strlen(buffer);
          profile->devices[next].oclDriverVersion = (char*)malloc(length+1);
          memcpy(profile->devices[next].oclDriverVersion, buffer, length+1);

          clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DEVICE_MAX_CLOCK_FREQUENCY
            , sizeof(cl_uint), &profile->devices[next].oclMaxClockFrequency, NULL);

          clGetDeviceInfo(profile->devices[next].oclDeviceID, CL_DEVICE_MAX_COMPUTE_UNITS
            , sizeof(cl_uint), &profile->devices[next].oclMaxComputeUnits, NULL);
        }
      }
    }
  }

  profile->devices[next].type = DS_DEVICE_NATIVE_CPU;
  profile->version = version;

cleanup:
  if (platforms)  free(platforms);
  if (devices)    free(devices);
  if (status == DS_SUCCESS) {
    *p = profile;
  }
  else {
    if (profile) {
      if (profile->devices)
        free(profile->devices);
      free(profile);
    }
  }
  return status;
}

/* Pointer to a function that calculates the score of a device (ex: device->score) 
 update the data size of score. The encoding and the format of the score data 
 is implementation defined. The function should return DS_SUCCESS if there's no error to be reported.
 */
typedef ds_status (*ds_perf_evaluator)(ds_device* device, void* data);

typedef enum {
  DS_EVALUATE_ALL
  ,DS_EVALUATE_NEW_ONLY
} ds_evaluation_type;

static ds_status profileDevices(ds_profile* profile, const ds_evaluation_type type
                         ,ds_perf_evaluator evaluator, void* evaluatorData, unsigned int* numUpdates) {
  ds_status status = DS_SUCCESS;
  unsigned int i;
  unsigned int updates = 0;

  if (profile == NULL) {
    return DS_INVALID_PROFILE;
  }
  if (evaluator == NULL) {
    return DS_INVALID_PERF_EVALUATOR;
  }

  for (i = 0; i < profile->numDevices; i++) {
    ds_status evaluatorStatus;
    
    switch (type) {
    case DS_EVALUATE_NEW_ONLY:
      if (profile->devices[i].score != NULL)
        break;
      /*  else fall through */
    case DS_EVALUATE_ALL:
      evaluatorStatus = evaluator(profile->devices+i, evaluatorData);
      if (evaluatorStatus != DS_SUCCESS) {
        status = evaluatorStatus;
        return status;
      }
      updates++;
      break;
    default:
      return DS_INVALID_PERF_EVALUATOR_TYPE;
      break;
    };
  }
  if (numUpdates)
    *numUpdates = updates;
  return status;
}


#define DS_TAG_VERSION                      "<version>"
#define DS_TAG_VERSION_END                  "</version>"
#define DS_TAG_DEVICE                       "<device>"
#define DS_TAG_DEVICE_END                   "</device>"
#define DS_TAG_SCORE                        "<score>"
#define DS_TAG_SCORE_END                    "</score>"
#define DS_TAG_DEVICE_TYPE                  "<type>"
#define DS_TAG_DEVICE_TYPE_END              "</type>"
#define DS_TAG_DEVICE_NAME                  "<name>"
#define DS_TAG_DEVICE_NAME_END              "</name>"
#define DS_TAG_DEVICE_DRIVER_VERSION        "<driver>"
#define DS_TAG_DEVICE_DRIVER_VERSION_END    "</driver>"
#define DS_TAG_DEVICE_MAX_COMPUTE_UNITS     "<max cu>"
#define DS_TAG_DEVICE_MAX_COMPUTE_UNITS_END "</max cu>"
#define DS_TAG_DEVICE_MAX_CLOCK_FREQ        "<max clock>"
#define DS_TAG_DEVICE_MAX_CLOCK_FREQ_END    "</max clock>"

#define DS_DEVICE_NATIVE_CPU_STRING  "native_cpu"



typedef ds_status (*ds_score_serializer)(ds_device* device, void** serializedScore, unsigned int* serializedScoreSize);
static ds_status writeProfileToFile(ds_profile* profile, ds_score_serializer serializer, const char* file) {
  ds_status status = DS_SUCCESS;
  FILE* profileFile = NULL;


  if (profile == NULL)
    return DS_INVALID_PROFILE;

  profileFile = fopen(file, "wb");
  if (profileFile==NULL) {
    status = DS_FILE_ERROR;
  }
  else {
    unsigned int i;

    /* write version string */
    fwrite(DS_TAG_VERSION, sizeof(char), strlen(DS_TAG_VERSION), profileFile);
    fwrite(profile->version, sizeof(char), strlen(profile->version), profileFile);
    fwrite(DS_TAG_VERSION_END, sizeof(char), strlen(DS_TAG_VERSION_END), profileFile);
    fwrite("\n", sizeof(char), 1, profileFile);

    for (i = 0; i < profile->numDevices && status == DS_SUCCESS; i++) {
      void* serializedScore;
      unsigned int serializedScoreSize;

      fwrite(DS_TAG_DEVICE, sizeof(char), strlen(DS_TAG_DEVICE), profileFile);

      fwrite(DS_TAG_DEVICE_TYPE, sizeof(char), strlen(DS_TAG_DEVICE_TYPE), profileFile);
      fwrite(&profile->devices[i].type,sizeof(ds_device_type),1, profileFile);
      fwrite(DS_TAG_DEVICE_TYPE_END, sizeof(char), strlen(DS_TAG_DEVICE_TYPE_END), profileFile);

      switch(profile->devices[i].type) {
      case DS_DEVICE_NATIVE_CPU:
        { 
          /* There's no need to emit a device name for the native CPU device. */
          /*
          fwrite(DS_TAG_DEVICE_NAME, sizeof(char), strlen(DS_TAG_DEVICE_NAME), profileFile);
          fwrite(DS_DEVICE_NATIVE_CPU_STRING,sizeof(char),strlen(DS_DEVICE_NATIVE_CPU_STRING), profileFile);
          fwrite(DS_TAG_DEVICE_NAME_END, sizeof(char), strlen(DS_TAG_DEVICE_NAME_END), profileFile);
          */
        }
        break;
      case DS_DEVICE_OPENCL_DEVICE: 
        {
          char tmp[16];

          fwrite(DS_TAG_DEVICE_NAME, sizeof(char), strlen(DS_TAG_DEVICE_NAME), profileFile);
          fwrite(profile->devices[i].oclDeviceName,sizeof(char),strlen(profile->devices[i].oclDeviceName), profileFile);
          fwrite(DS_TAG_DEVICE_NAME_END, sizeof(char), strlen(DS_TAG_DEVICE_NAME_END), profileFile);

          fwrite(DS_TAG_DEVICE_DRIVER_VERSION, sizeof(char), strlen(DS_TAG_DEVICE_DRIVER_VERSION), profileFile);
          fwrite(profile->devices[i].oclDriverVersion,sizeof(char),strlen(profile->devices[i].oclDriverVersion), profileFile);
          fwrite(DS_TAG_DEVICE_DRIVER_VERSION_END, sizeof(char), strlen(DS_TAG_DEVICE_DRIVER_VERSION_END), profileFile);

          fwrite(DS_TAG_DEVICE_MAX_COMPUTE_UNITS, sizeof(char), strlen(DS_TAG_DEVICE_MAX_COMPUTE_UNITS), profileFile);
          sprintf(tmp,"%d",profile->devices[i].oclMaxComputeUnits);
          fwrite(tmp,sizeof(char),strlen(tmp), profileFile);
          fwrite(DS_TAG_DEVICE_MAX_COMPUTE_UNITS_END, sizeof(char), strlen(DS_TAG_DEVICE_MAX_COMPUTE_UNITS_END), profileFile);

          fwrite(DS_TAG_DEVICE_MAX_CLOCK_FREQ, sizeof(char), strlen(DS_TAG_DEVICE_MAX_CLOCK_FREQ), profileFile);
          sprintf(tmp,"%d",profile->devices[i].oclMaxClockFrequency);
          fwrite(tmp,sizeof(char),strlen(tmp), profileFile);
          fwrite(DS_TAG_DEVICE_MAX_CLOCK_FREQ_END, sizeof(char), strlen(DS_TAG_DEVICE_MAX_CLOCK_FREQ_END), profileFile);
        }
        break;
      default:
        status = DS_UNKNOWN_DEVICE_TYPE;
        break;
      };

      fwrite(DS_TAG_SCORE, sizeof(char), strlen(DS_TAG_SCORE), profileFile);
      status = serializer(profile->devices+i, &serializedScore, &serializedScoreSize);
      if (status == DS_SUCCESS && serializedScore!=NULL && serializedScoreSize > 0) {
        fwrite(serializedScore, sizeof(char), serializedScoreSize, profileFile);
        free(serializedScore);
      }
      fwrite(DS_TAG_SCORE_END, sizeof(char), strlen(DS_TAG_SCORE_END), profileFile);
      fwrite(DS_TAG_DEVICE_END, sizeof(char), strlen(DS_TAG_DEVICE_END), profileFile);
      fwrite("\n",sizeof(char),1,profileFile);
    }
    fclose(profileFile);
  }
  return status;
}


static ds_status readProFile(const char* fileName, char** content, size_t* contentSize) {
  ds_status status = DS_SUCCESS;
  FILE * input = NULL;
  size_t size = 0;
  size_t rsize = 0;
  char* binary = NULL;

  *contentSize = 0;
  *content = NULL;

  input = fopen(fileName, "rb");
  if(input == NULL) {
    return DS_FILE_ERROR;
  }

  fseek(input, 0L, SEEK_END); 
  size = ftell(input);
  rewind(input);
  binary = (char*)malloc(size);
  if(binary == NULL) {
    status = DS_FILE_ERROR;
    goto cleanup;
  }
  rsize = fread(binary, sizeof(char), size, input);
  if (rsize!=size
      || ferror(input)) {
    status = DS_FILE_ERROR;
    goto cleanup;
  }
  *contentSize = size;
  *content = binary;

cleanup:
  if (input != NULL) fclose(input);
  if (status != DS_SUCCESS
      && binary != NULL) {
      free(binary);
      *content = NULL;
      *contentSize = 0;
  }
  return status;
}


static const char* findString(const char* contentStart, const char* contentEnd, const char* string) {
  size_t stringLength;
  const char* currentPosition;
  const char* found;
  found = NULL;
  stringLength = strlen(string);
  currentPosition = contentStart;
  for(currentPosition = contentStart; currentPosition < contentEnd; currentPosition++) {
    if (*currentPosition == string[0]) {
      if (currentPosition+stringLength < contentEnd) {
        if (strncmp(currentPosition, string, stringLength) == 0) {
          found = currentPosition;
          break;
        }
      }
    }
  }
  return found;
}


typedef ds_status (*ds_score_deserializer)(ds_device* device, const unsigned char* serializedScore, unsigned int serializedScoreSize); 
static ds_status readProfileFromFile(ds_profile* profile, ds_score_deserializer deserializer, const char* file) {

  ds_status status = DS_SUCCESS;
  char* contentStart = NULL;
  const char* contentEnd = NULL;
  size_t contentSize;

  if (profile==NULL)
    return DS_INVALID_PROFILE;

  status = readProFile(file, &contentStart, &contentSize);
  if (status == DS_SUCCESS) {
    const char* currentPosition;
    const char* dataStart;
    const char* dataEnd;
    size_t versionStringLength;

    contentEnd = contentStart + contentSize;
    currentPosition = contentStart;


    /* parse the version string */
    dataStart = findString(currentPosition, contentEnd, DS_TAG_VERSION);
    if (dataStart == NULL) {
      status = DS_PROFILE_FILE_ERROR;
      goto cleanup;
    }
    dataStart += strlen(DS_TAG_VERSION);

    dataEnd = findString(dataStart, contentEnd, DS_TAG_VERSION_END);
    if (dataEnd==NULL) {
      status = DS_PROFILE_FILE_ERROR;
      goto cleanup;
    }

    versionStringLength = strlen(profile->version);
    if (versionStringLength!=(dataEnd-dataStart)   
        || strncmp(profile->version, dataStart, versionStringLength)!=(int)0) {
      /* version mismatch */
      status = DS_PROFILE_FILE_ERROR;
      goto cleanup;
    }
    currentPosition = dataEnd+strlen(DS_TAG_VERSION_END);

    /* parse the device information */
    while (1) {
      unsigned int i;

      const char* deviceTypeStart;
      const char* deviceTypeEnd;
      ds_device_type deviceType;

      const char* deviceNameStart;
      const char* deviceNameEnd;

      const char* deviceScoreStart;
      const char* deviceScoreEnd;

      const char* deviceDriverStart;
      const char* deviceDriverEnd;

      const char* tmpStart;
      const char* tmpEnd;
      char tmp[16];

      cl_uint maxClockFrequency;
      cl_uint maxComputeUnits;

      dataStart = findString(currentPosition, contentEnd, DS_TAG_DEVICE);
      if (dataStart==NULL) {
        /* nothing useful remain, quit...*/
        break;
      }
      dataStart+=strlen(DS_TAG_DEVICE);
      dataEnd = findString(dataStart, contentEnd, DS_TAG_DEVICE_END);
      if (dataEnd==NULL) {
        status = DS_PROFILE_FILE_ERROR;
        goto cleanup;
      }

      /* parse the device type */
      deviceTypeStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_TYPE);
      if (deviceTypeStart==NULL) {
        status = DS_PROFILE_FILE_ERROR;
        goto cleanup;       
      }
      deviceTypeStart+=strlen(DS_TAG_DEVICE_TYPE);
      deviceTypeEnd = findString(deviceTypeStart, contentEnd, DS_TAG_DEVICE_TYPE_END);
      if (deviceTypeEnd==NULL) {
        status = DS_PROFILE_FILE_ERROR;
        goto cleanup;
      }
      memcpy(&deviceType, deviceTypeStart, sizeof(ds_device_type));


      /* parse the device name */
      if (deviceType == DS_DEVICE_OPENCL_DEVICE) {

        deviceNameStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_NAME);
        if (deviceNameStart==NULL) {
          status = DS_PROFILE_FILE_ERROR;
          goto cleanup;       
        }
        deviceNameStart+=strlen(DS_TAG_DEVICE_NAME);
        deviceNameEnd = findString(deviceNameStart, contentEnd, DS_TAG_DEVICE_NAME_END);
        if (deviceNameEnd==NULL) {
          status = DS_PROFILE_FILE_ERROR;
          goto cleanup;       
        }


        deviceDriverStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_DRIVER_VERSION);
        if (deviceDriverStart==NULL) {
          status = DS_PROFILE_FILE_ERROR;
          goto cleanup;       
        }
        deviceDriverStart+=strlen(DS_TAG_DEVICE_DRIVER_VERSION);
        deviceDriverEnd = findString(deviceDriverStart, contentEnd, DS_TAG_DEVICE_DRIVER_VERSION_END);
        if (deviceDriverEnd ==NULL) {
          status = DS_PROFILE_FILE_ERROR;
          goto cleanup;       
        }


        tmpStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_MAX_COMPUTE_UNITS);
        if (tmpStart==NULL) {
          status = DS_PROFILE_FILE_ERROR;
          goto cleanup;       
        }
        tmpStart+=strlen(DS_TAG_DEVICE_MAX_COMPUTE_UNITS);
        tmpEnd = findString(tmpStart, contentEnd, DS_TAG_DEVICE_MAX_COMPUTE_UNITS_END);
        if (tmpEnd ==NULL) {
          status = DS_PROFILE_FILE_ERROR;
          goto cleanup;       
        }
        memcpy(tmp,tmpStart,tmpEnd-tmpStart);
        tmp[tmpEnd-tmpStart] = '\0';
        maxComputeUnits = atoi(tmp);


        tmpStart = findString(dataStart, contentEnd, DS_TAG_DEVICE_MAX_CLOCK_FREQ);
        if (tmpStart==NULL) {
          status = DS_PROFILE_FILE_ERROR;
          goto cleanup;       
        }
        tmpStart+=strlen(DS_TAG_DEVICE_MAX_CLOCK_FREQ);
        tmpEnd = findString(tmpStart, contentEnd, DS_TAG_DEVICE_MAX_CLOCK_FREQ_END);
        if (tmpEnd ==NULL) {
          status = DS_PROFILE_FILE_ERROR;
          goto cleanup;       
        }
        memcpy(tmp,tmpStart,tmpEnd-tmpStart);
        tmp[tmpEnd-tmpStart] = '\0';
        maxClockFrequency = atoi(tmp);


        /* check if this device is on the system */
        for (i = 0; i < profile->numDevices; i++) {
          if (profile->devices[i].type == DS_DEVICE_OPENCL_DEVICE) {
            size_t actualDeviceNameLength;
            size_t driverVersionLength;
            
            actualDeviceNameLength = strlen(profile->devices[i].oclDeviceName);
            driverVersionLength = strlen(profile->devices[i].oclDriverVersion);
            if (actualDeviceNameLength == (deviceNameEnd - deviceNameStart)
               && driverVersionLength == (deviceDriverEnd - deviceDriverStart)
               && maxComputeUnits == profile->devices[i].oclMaxComputeUnits
               && maxClockFrequency == profile->devices[i].oclMaxClockFrequency
               && strncmp(profile->devices[i].oclDeviceName, deviceNameStart, actualDeviceNameLength)==(int)0
               && strncmp(profile->devices[i].oclDriverVersion, deviceDriverStart, driverVersionLength)==(int)0) {

              deviceScoreStart = findString(dataStart, contentEnd, DS_TAG_SCORE);
              if (deviceNameStart==NULL) {
                status = DS_PROFILE_FILE_ERROR;
                goto cleanup;       
              }
              deviceScoreStart+=strlen(DS_TAG_SCORE);
              deviceScoreEnd = findString(deviceScoreStart, contentEnd, DS_TAG_SCORE_END);
              status = deserializer(profile->devices+i, (const unsigned char*)deviceScoreStart, deviceScoreEnd-deviceScoreStart);
              if (status != DS_SUCCESS) {
                goto cleanup;
              }
            }
          }
        }

      }
      else if (deviceType == DS_DEVICE_NATIVE_CPU) {
        for (i = 0; i < profile->numDevices; i++) {
          if (profile->devices[i].type == DS_DEVICE_NATIVE_CPU) {
            deviceScoreStart = findString(dataStart, contentEnd, DS_TAG_SCORE);
            if (deviceScoreStart==NULL) {
              status = DS_PROFILE_FILE_ERROR;
              goto cleanup;       
            }
            deviceScoreStart+=strlen(DS_TAG_SCORE);
            deviceScoreEnd = findString(deviceScoreStart, contentEnd, DS_TAG_SCORE_END);
            status = deserializer(profile->devices+i, (const unsigned char*)deviceScoreStart, deviceScoreEnd-deviceScoreStart);
            if (status != DS_SUCCESS) {
              goto cleanup;
            }
          }
        }
      }

      /* skip over the current one to find the next device */
      currentPosition = dataEnd+strlen(DS_TAG_DEVICE_END);
    }
  }
cleanup:
  if (contentStart!=NULL) free(contentStart);
  return status;
}

static ds_status getNumDeviceWithEmptyScore(ds_profile* profile, unsigned int* num) {
  unsigned int i;
  if (profile == NULL || num==NULL)
    return DS_MEMORY_ERROR;
  *num=0;
  for (i = 0; i < profile->numDevices; i++) {
    if (profile->devices[i].score == NULL) {
      *num++;
    }
  }
  return DS_SUCCESS;
}

/*
 End of the OpenCL device selection infrastructure
*/



typedef struct _AccelerateTimer {
  long long _freq;	
  long long _clocks;
  long long _start;
} AccelerateTimer;

static void startAccelerateTimer(AccelerateTimer* timer) {
#ifdef _WIN32
      QueryPerformanceCounter((LARGE_INTEGER*)&timer->_start);	


#else
      struct timeval s;
      gettimeofday(&s, 0);
      timer->_start = (long long)s.tv_sec * (long long)1.0E3 + (long long)s.tv_usec / (long long)1.0E3;
#endif  
}

static void stopAccelerateTimer(AccelerateTimer* timer) {
      long long n=0;
#ifdef _WIN32
      QueryPerformanceCounter((LARGE_INTEGER*)&(n));	
#else
      struct timeval s;
      gettimeofday(&s, 0);
      n = (long long)s.tv_sec * (long long)1.0E3+ (long long)s.tv_usec / (long long)1.0E3;
#endif
      n -= timer->_start;
      timer->_start = 0;
      timer->_clocks += n;
}

static void resetAccelerateTimer(AccelerateTimer* timer) {
   timer->_clocks = 0; 
   timer->_start = 0;
}


static void initAccelerateTimer(AccelerateTimer* timer) {
#ifdef _WIN32
    QueryPerformanceFrequency((LARGE_INTEGER*)&timer->_freq);
#else
    timer->_freq = (long long)1.0E3;
#endif
   resetAccelerateTimer(timer);
}

double readAccelerateTimer(AccelerateTimer* timer) { return (double)timer->_clocks/(double)timer->_freq; };


typedef double AccelerateScoreType;

static ds_status AcceleratePerfEvaluator(ds_device* device, void* data) {

  ds_status status = DS_SUCCESS;
  MagickCLEnv clEnv = NULL;
  MagickCLEnv oldClEnv = NULL;
  ExceptionInfo* exception = NULL;
  AccelerateTimer timer;

  if (device == NULL) {
    status = DS_PERF_EVALUATOR_ERROR;
    goto cleanup;
  }

  clEnv = AcquireMagickOpenCLEnv();
  exception = AcquireExceptionInfo();

  if (device->type == DS_DEVICE_NATIVE_CPU) {
    /* CPU device */
    MagickBooleanType flag = MagickTrue;
    SetMagickOpenCLEnvParamInternal(clEnv, MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED
                                  , sizeof(MagickBooleanType), &flag, exception);
  }
  else if (device->type == DS_DEVICE_OPENCL_DEVICE) {
    /* OpenCL device */
    SetMagickOpenCLEnvParamInternal(clEnv, MAGICK_OPENCL_ENV_PARAM_DEVICE
      , sizeof(cl_device_id), &device->oclDeviceID,exception);
  }
  else {
    status = DS_PERF_EVALUATOR_ERROR;
    goto cleanup;
  }
  InitOpenCLEnvInternal(clEnv, exception);
  oldClEnv = defaultCLEnv;
  defaultCLEnv = clEnv;

  /* microbenchmark */
  {
#define ACCELERATE_PERF_DIMEN       "2048x1536"
#define NUM_ITER                      2

    Image* inputImage;
    ImageInfo* imageInfo;
    int i;

    imageInfo = AcquireImageInfo();
    CloneString(&imageInfo->size,ACCELERATE_PERF_DIMEN);
    CopyMagickString(imageInfo->filename,"xc:none",MaxTextExtent);
    inputImage = ReadImage(imageInfo,exception);

    initAccelerateTimer(&timer);

    for (i = 0; i <=NUM_ITER; i++) {

      Image* bluredImage;
      Image* unsharpedImage;
      Image* resizedImage;

      if (i > 0)
        startAccelerateTimer(&timer);

#ifdef MAGICKCORE_CLPERFMARKER
  clBeginPerfMarkerAMD("PerfEvaluatorRegion","");
#endif

      bluredImage = BlurImage(inputImage, 10.0f, 3.5f, exception);
      unsharpedImage = UnsharpMaskImage(bluredImage, 2.0f,2.0f,50.0f,10.0f,exception);
      resizedImage = ResizeImage(unsharpedImage,640,480,LanczosFilter,1.0,exception);

#ifdef MAGICKCORE_CLPERFMARKER
  clEndPerfMarkerAMD();
#endif

      if (i > 0)
        stopAccelerateTimer(&timer);

      if (bluredImage) DestroyImage(bluredImage);
      if (unsharpedImage) DestroyImage(unsharpedImage);
      if (resizedImage) DestroyImage(resizedImage);
    }
    DestroyImage(inputImage);
  }
  /* end of microbenchmark */
  
  if (device->score == NULL) {
    device->score = malloc(sizeof(AccelerateScoreType));
  }
  *(AccelerateScoreType*)device->score = readAccelerateTimer(&timer);

cleanup:
  if (clEnv!=NULL)
    RelinquishMagickOpenCLEnv(clEnv);
  if (oldClEnv!=NULL)
    defaultCLEnv = oldClEnv;
  return status;
}



ds_status AccelerateScoreSerializer(ds_device* device, void** serializedScore, unsigned int* serializedScoreSize) {
  if (device
     && device->score) {
    /* generate a string from the score */
    char* s = (char*)malloc(sizeof(char)*256);
    sprintf(s,"%.4f",*((AccelerateScoreType*)device->score));
    *serializedScore = (void*)s;
    *serializedScoreSize = strlen(s);
    return DS_SUCCESS;
  }
  else {
    return DS_SCORE_SERIALIZER_ERROR;
  }
}

ds_status AccelerateScoreDeserializer(ds_device* device, const unsigned char* serializedScore, unsigned int serializedScoreSize) {
  if (device) {
    /* convert the string back to an int */
    char* s = (char*)malloc(serializedScoreSize+1);
    memcpy(s, serializedScore, serializedScoreSize);
    s[serializedScoreSize] = (char)'\0';
    device->score = malloc(sizeof(AccelerateScoreType));
    *((AccelerateScoreType*)device->score) = (AccelerateScoreType)atof(s);
    free(s);
    return DS_SUCCESS;
  }
  else {
    return DS_SCORE_DESERIALIZER_ERROR;
  }
}

ds_status AccelerateScoreRelease(void* score) {
  if (score!=NULL) {
    free(score);
  }
  return DS_SUCCESS;
}


#define IMAGEMAGICK_PROFILE_VERSION "ImageMagick Device Selection v0.9"
#define IMAGEMAGICK_PROFILE_FILE    "ImagemagickOpenCLDeviceProfile"
static MagickBooleanType autoSelectDevice(MagickCLEnv clEnv, ExceptionInfo* exception) {

  MagickBooleanType mStatus = MagickFalse;
  ds_status status;
  ds_profile* profile;
  unsigned int numDeviceProfiled = 0;
  unsigned int i;
  unsigned int bestDeviceIndex;
  AccelerateScoreType bestScore;
  char path[MaxTextExtent];


  LockDefaultOpenCLEnv();

  status = initDSProfile(&profile, IMAGEMAGICK_PROFILE_VERSION);
  if (status!=DS_SUCCESS) {
    (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError, "Error when initializing the profile", "'%s'", ".");
    goto cleanup;
  }

  (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s"
         ,GetOpenCLCachedFilesDirectory()
         ,DirectorySeparator,IMAGEMAGICK_PROFILE_FILE);

  readProfileFromFile(profile, AccelerateScoreDeserializer, path);
  status = profileDevices(profile, DS_EVALUATE_NEW_ONLY, AcceleratePerfEvaluator, NULL, &numDeviceProfiled);
  if (status!=DS_SUCCESS) {
    (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError, "Error when initializing the profile", "'%s'", ".");
    goto cleanup;
  }
  if (numDeviceProfiled > 0) {
    status = writeProfileToFile(profile, AccelerateScoreSerializer, path);
    if (status!=DS_SUCCESS) {
      (void) ThrowMagickException(exception, GetMagickModule(), ModuleWarning, "Error when saving the profile into a file", "'%s'", ".");
    }
  }

  /* pick the best device */
  bestDeviceIndex = 0;
  bestScore = *(AccelerateScoreType*)profile->devices[bestDeviceIndex].score;
  for (i = 1; i < profile->numDevices; i++) {
    AccelerateScoreType score = *(AccelerateScoreType*)profile->devices[i].score;
    if (score < bestScore) {
      bestDeviceIndex = i;
      bestScore = score;
    }
  }

  /* set up clEnv with the best device */
  if (profile->devices[bestDeviceIndex].type == DS_DEVICE_NATIVE_CPU) {
    /* CPU device */
    MagickBooleanType flag = MagickTrue;
    SetMagickOpenCLEnvParamInternal(clEnv, MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED
                                  , sizeof(MagickBooleanType), &flag, exception);
  }
  else if (profile->devices[bestDeviceIndex].type == DS_DEVICE_OPENCL_DEVICE) {
    /* OpenCL device */
    SetMagickOpenCLEnvParamInternal(clEnv, MAGICK_OPENCL_ENV_PARAM_DEVICE
      , sizeof(cl_device_id), &profile->devices[bestDeviceIndex].oclDeviceID,exception);
  }
  else {
    status = DS_PERF_EVALUATOR_ERROR;
    goto cleanup;
  }
  InitOpenCLEnvInternal(clEnv, exception);

  status = releaseDSProfile(profile, AccelerateScoreRelease);
  if (status!=DS_SUCCESS) {
    (void) ThrowMagickException(exception, GetMagickModule(), ModuleWarning, "Error when releasing the profile", "'%s'", ".");
  }
  mStatus = MagickTrue;

cleanup:

  UnlockDefaultOpenCLEnv();
  return mStatus;
}


/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
+   I n i t I m a g e M a g i c k O p e n C L                                 %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  InitImageMagickOpenCL() provides a simplified interface to initialize
%  the OpenCL environtment in ImageMagick
%  
%  The format of the InitImageMagickOpenCL() method is:
%
%      MagickBooleanType InitImageMagickOpenCL(ImageMagickOpenCLMode mode, 
%                                        void* userSelectedDevice, 
%                                        void* selectedDevice) 
%
%  A description of each parameter follows:
%
%    o mode: OpenCL mode in ImageMagick, could be off,auto,user
%
%    o userSelectedDevice:  when in user mode, a pointer to the selected
%                           cl_device_id
%
%    o selectedDevice: a pointer to cl_device_id where the selected
%                      cl_device_id by ImageMagick could be returned
%
%    o exception: exception
%
*/
MagickBooleanType InitImageMagickOpenCL(ImageMagickOpenCLMode mode, 
                                        void* userSelectedDevice, 
                                        void* selectedDevice,
                                        ExceptionInfo* exception) {
 
  MagickBooleanType status = MagickTrue;
  MagickCLEnv clEnv = NULL;
  MagickBooleanType flag;

  exception = AcquireExceptionInfo();
  clEnv = GetDefaultOpenCLEnv();
  if (clEnv!=NULL) {
    switch(mode) {

    case MAGICK_OPENCL_OFF:
      flag = MagickTrue;
      SetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED
        , sizeof(MagickBooleanType), &flag, exception);
      status = InitOpenCLEnv(clEnv, exception);

      if (selectedDevice)
        *(cl_device_id*)selectedDevice = NULL;
      break;

    case MAGICK_OPENCL_DEVICE_SELECT_USER:

      if (userSelectedDevice == NULL)
        return MagickFalse;

      flag = MagickFalse;
      SetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED
        , sizeof(MagickBooleanType), &flag, exception);

      SetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_DEVICE
        , sizeof(cl_device_id), userSelectedDevice,exception);

      status = InitOpenCLEnv(clEnv, exception);
      if (selectedDevice) {
        GetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_DEVICE
          , sizeof(cl_device_id), selectedDevice, exception);
      }
      break;

    case MAGICK_OPENCL_DEVICE_SELECT_AUTO:
    default:
      {
        cl_device_id d = NULL;
        flag = MagickFalse;
        SetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_OPENCL_DISABLED
          , sizeof(MagickBooleanType), &flag, exception);
        SetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_DEVICE
          , sizeof(cl_device_id), &d,exception);
        status = InitOpenCLEnv(clEnv, exception);
        if (selectedDevice) {
          GetMagickOpenCLEnvParam(clEnv, MAGICK_OPENCL_ENV_PARAM_DEVICE
            , sizeof(cl_device_id),  selectedDevice, exception);
        }
      }
      break;
    };
  }
  return status;
}


#else

struct _MagickCLEnv {
  MagickBooleanType OpenCLInitialized;  /* whether OpenCL environment is initialized. */
};

extern MagickExport MagickCLEnv AcquireMagickOpenCLEnv()
{
  return NULL;
}

extern MagickExport MagickBooleanType RelinquishMagickOpenCLEnv(
  MagickCLEnv magick_unused(clEnv))
{
  magick_unreferenced(clEnv);

  return MagickFalse;
}

/*
* Return the OpenCL environment
*/ 
MagickExport MagickCLEnv GetDefaultOpenCLEnv(
  ExceptionInfo *magick_unused(exception))
{
  magick_unreferenced(exception);

  return (MagickCLEnv) NULL;
}

MagickExport MagickCLEnv SetDefaultOpenCLEnv(
  MagickCLEnv magick_unused(clEnv))
{
  magick_unreferenced(clEnv);

  return (MagickCLEnv) NULL;
} 

MagickExport MagickBooleanType SetMagickOpenCLEnvParam(
  MagickCLEnv magick_unused(clEnv),MagickOpenCLEnvParam magick_unused(param),
  size_t magick_unused(dataSize),void *magick_unused(data),
  ExceptionInfo *magick_unused(exception))
{
  magick_unreferenced(clEnv);
  magick_unreferenced(param);
  magick_unreferenced(dataSize);
  magick_unreferenced(data);
  magick_unreferenced(exception);

  return MagickFalse;
}

MagickExport MagickBooleanType GetMagickOpenCLEnvParam(
  MagickCLEnv magick_unused(clEnv),MagickOpenCLEnvParam magick_unused(param),
  size_t magick_unused(dataSize),void *magick_unused(data),
  ExceptionInfo *magick_unused(exception))
{
  magick_unreferenced(clEnv);
  magick_unreferenced(param);
  magick_unreferenced(dataSize);
  magick_unreferenced(data);
  magick_unreferenced(exception);

  return MagickFalse;
}

MagickExport MagickBooleanType InitOpenCLEnv(MagickCLEnv magick_unused(clEnv),
  ExceptionInfo *magick_unused(exception))
{
  magick_unreferenced(clEnv);
  magick_unreferenced(exception);

  return MagickFalse;
}

MagickExport cl_command_queue AcquireOpenCLCommandQueue(
  MagickCLEnv magick_unused(clEnv))
{
  magick_unreferenced(clEnv);

  return (cl_command_queue) NULL;
}

MagickExport MagickBooleanType RelinquishCommandQueue(
  MagickCLEnv magick_unused(clEnv),cl_command_queue magick_unused(queue))
{
  magick_unreferenced(clEnv);
  magick_unreferenced(queue);

  return MagickFalse;
}

MagickExport cl_kernel AcquireOpenCLKernel(
  MagickCLEnv magick_unused(clEnv),MagickOpenCLProgram magick_unused(program),
  const char *magick_unused(kernelName))
{
  magick_unreferenced(clEnv);
  magick_unreferenced(program);
  magick_unreferenced(kernelName);

  return (cl_kernel)NULL;
}

MagickExport MagickBooleanType RelinquishOpenCLKernel(
  MagickCLEnv magick_unused(clEnv),cl_kernel magick_unused(kernel))
{
  magick_unreferenced(clEnv);
  magick_unreferenced(kernel);

  return MagickFalse;
}

MagickExport unsigned long GetOpenCLDeviceLocalMemorySize(
  MagickCLEnv magick_unused(clEnv))
{
  magick_unreferenced(clEnv);

  return 0;
}

MagickBooleanType InitImageMagickOpenCL(ImageMagickOpenCLMode mode, 
                                        void* userSelectedDevice, 
                                        void* selectedDevice,
                                        ExceptionInfo* exception) 
{
  magick_unreferenced(mode);
  magick_unreferenced(userSelectedDevice);
  magick_unreferenced(selectedDevice);
  magick_unreferenced(exception);
  return MagickFalse;
}

#endif /* MAGICKCORE_OPENCL_SUPPORT */

char* openclCachedFilesDirectory;
SemaphoreInfo* openclCachedFilesDirectoryLock;

MagickExport
const char* GetOpenCLCachedFilesDirectory() {
  if (openclCachedFilesDirectory == NULL) {
    if (openclCachedFilesDirectoryLock == NULL)
    {
      AcquireSemaphoreInfo(&openclCachedFilesDirectoryLock);
    }
    LockSemaphoreInfo(openclCachedFilesDirectoryLock);
    if (openclCachedFilesDirectory == NULL) {
      char path[MaxTextExtent];
      char *home = NULL;
      char *temp = NULL;
      struct stat attributes;
      MagickBooleanType status;

#ifdef MAGICKCORE_WINDOWS_SUPPORT
      home=GetEnvironmentValue("LOCALAPPDATA");
      if (home == (char *) NULL)
        home=GetEnvironmentValue("APPDATA");
      if (home == (char *) NULL)
        home=GetEnvironmentValue("USERPROFILE");
#else
      home=GetEnvironmentValue("HOME");
#endif
      if (home != (char *) NULL)
      {
        /*
        Search $HOME/.magick.
        */
        (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick",home,
          DirectorySeparator);
        home=DestroyString(home);
        temp = (char*)AcquireMagickMemory(strlen(path)+1);
        CopyMagickString(temp,path,strlen(path)+1);
        status=GetPathAttributes(path,&attributes);
        if (status == MagickFalse) {
#ifdef MAGICKCORE_WINDOWS_SUPPORT
          mkdir(path);
#else
          mkdir(path, 0777);
#endif
        }
      }
      openclCachedFilesDirectory = temp;
    }
    UnlockSemaphoreInfo(openclCachedFilesDirectoryLock); 
  }
  return openclCachedFilesDirectory;
}

/* create a function for OpenCL log */
MagickExport
void OpenCLLog(const char* message) {

#ifdef OPENCLLOG_ENABLED
#define OPENCL_LOG_FILE "ImageMagickOpenCL.log"

  FILE* log;
  if (getenv("MAGICK_OCL_LOG"))
  {
    if (message) {
      char path[MaxTextExtent];

      /*  dump the source into a file */
      (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s"
        ,GetOpenCLCachedFilesDirectory()
        ,DirectorySeparator,OPENCL_LOG_FILE);


      log = fopen(path, "ab");
      fwrite(message, sizeof(char), strlen(message), log);
      fwrite("\n", sizeof(char), 1, log);
      fclose(log);
    }
  }
#else
  magick_unreferenced(message);
#endif
}

