1dbba8217e1fb271747333c5b6ec528d03706eae7cristy/*
2dbba8217e1fb271747333c5b6ec528d03706eae7cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
4dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
5dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
6dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                   OOO   PPPP   EEEEE  N   N   CCCC  L                       %
7dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                  O   O  P   P  E      NN  N  C      L                       %
8dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                  O   O  PPPP   EEE    N N N  C      L                       %
9dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                  O   O  P      E      N  NN  C      L                       %
10dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                   OOO   P      EEEEE  N   N   CCCC  LLLLL                   %
11dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
12dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
13dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                         MagickCore OpenCL Methods                           %
14dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
15dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                              Software Design                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
17dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                 March 2000                                  %
18dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
19dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
21dbba8217e1fb271747333c5b6ec528d03706eae7cristy%  dedicated to making software imaging solutions freely available.           %
22dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
23dbba8217e1fb271747333c5b6ec528d03706eae7cristy%  You may not use this file except in compliance with the License.  You may  %
24dbba8217e1fb271747333c5b6ec528d03706eae7cristy%  obtain a copy of the License at                                            %
25dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
26dbba8217e1fb271747333c5b6ec528d03706eae7cristy%    http://www.imagemagick.org/script/license.php                            %
27dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
28dbba8217e1fb271747333c5b6ec528d03706eae7cristy%  Unless required by applicable law or agreed to in writing, software        %
29dbba8217e1fb271747333c5b6ec528d03706eae7cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
30dbba8217e1fb271747333c5b6ec528d03706eae7cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31dbba8217e1fb271747333c5b6ec528d03706eae7cristy%  See the License for the specific language governing permissions and        %
32dbba8217e1fb271747333c5b6ec528d03706eae7cristy%  limitations under the License.                                             %
33dbba8217e1fb271747333c5b6ec528d03706eae7cristy%                                                                             %
34dbba8217e1fb271747333c5b6ec528d03706eae7cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35dbba8217e1fb271747333c5b6ec528d03706eae7cristy%
36dbba8217e1fb271747333c5b6ec528d03706eae7cristy%
37dbba8217e1fb271747333c5b6ec528d03706eae7cristy%
38dbba8217e1fb271747333c5b6ec528d03706eae7cristy*/
391dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy
40dbba8217e1fb271747333c5b6ec528d03706eae7cristy/*
411dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy  Include declarations.
42dbba8217e1fb271747333c5b6ec528d03706eae7cristy*/
43dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/studio.h"
44dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/artifact.h"
45dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/cache.h"
4621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk#include "MagickCore/cache-private.h"
47dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/color.h"
48dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/compare.h"
49dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/constitute.h"
505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#include "MagickCore/configure.h"
51dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/distort.h"
52dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/draw.h"
53dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/effect.h"
54dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/exception.h"
55dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/exception-private.h"
56dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/fx.h"
57dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/gem.h"
58dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/geometry.h"
59dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/image.h"
60dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/image-private.h"
61dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/layer.h"
62dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/mime-private.h"
63dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/memory_.h"
64dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/monitor.h"
65dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/montage.h"
66dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/morphology.h"
67d116555b2b405226922658d88f7b1af833323274cristy#include "MagickCore/nt-base.h"
681e37e8f8f760d955432ae54298cb460098a4c21ecristy#include "MagickCore/nt-base-private.h"
69f034abbcb705540b0d42ade64679775e7a34e582cristy#include "MagickCore/opencl.h"
70f034abbcb705540b0d42ade64679775e7a34e582cristy#include "MagickCore/opencl-private.h"
71dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/option.h"
72dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/policy.h"
73dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/property.h"
74dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/quantize.h"
75dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/quantum.h"
760c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy#include "MagickCore/random_.h"
770c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy#include "MagickCore/random-private.h"
78dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/resample.h"
79dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/resource_.h"
80dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/splay-tree.h"
81f034abbcb705540b0d42ade64679775e7a34e582cristy#include "MagickCore/semaphore.h"
82dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/statistic.h"
83dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/string_.h"
845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#include "MagickCore/string-private.h"
85dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/token.h"
86dbba8217e1fb271747333c5b6ec528d03706eae7cristy#include "MagickCore/utility.h"
875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#include "MagickCore/utility-private.h"
88f034abbcb705540b0d42ade64679775e7a34e582cristy
89f034abbcb705540b0d42ade64679775e7a34e582cristy#if defined(MAGICKCORE_OPENCL_SUPPORT)
90f034abbcb705540b0d42ade64679775e7a34e582cristy
915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#ifndef MAGICKCORE_WINDOWS_SUPPORT
925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#include <dlfcn.h>
935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#endif
945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
950c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy#ifdef MAGICKCORE_HAVE_OPENCL_CL_H
960c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy#define MAGICKCORE_OPENCL_MACOSX  1
970c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy#endif
98f034abbcb705540b0d42ade64679775e7a34e582cristy
995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
1005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  Define declarations.
1015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
1028f012e53de440db26b36e690e61d480e78249ab8dirk#define IMAGEMAGICK_PROFILE_FILE "ImagemagickOpenCLDeviceProfile.xml"
1035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
1055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  Typedef declarations.
1065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
1075a2575faca105cecbf44bc70f7f8a177f6c4f674dirktypedef struct
1085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
1095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  long long freq;
1105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  long long clocks;
1115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  long long start;
1125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk} AccelerateTimer;
1139973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
1149973174de229bd4c4a8b947ea7acb19f4447dc5ddirktypedef struct
1159973174de229bd4c4a8b947ea7acb19f4447dc5ddirk{
1165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
1175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *name,
1188f012e53de440db26b36e690e61d480e78249ab8dirk    *platform_name,
1195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *version;
1205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_uint
1225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    max_clock_frequency,
1235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    max_compute_units;
1245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  double
1265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    score;
1275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk} MagickCLDeviceBenchmark;
1289973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
1295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
1305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  Forward declarations.
1315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
1325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1335a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickBooleanType
1345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  HasOpenCLDevices(MagickCLEnv,ExceptionInfo *),
1355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  LoadOpenCLLibrary(void);
1365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1375a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickCLDevice
1385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  RelinquishMagickCLDevice(MagickCLDevice);
1395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1405a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickCLEnv
1415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  RelinquishMagickCLEnv(MagickCLEnv);
1425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1435a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void
1445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BenchmarkOpenCLDevices(MagickCLEnv);
1455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1465a2575faca105cecbf44bc70f7f8a177f6c4f674dirkextern const char
1475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  *accelerateKernels, *accelerateKernels2;
1485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/* OpenCL library */
1505a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickLibrary
1515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  *openCL_library;
1525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/* Default OpenCL environment */
1545a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickCLEnv
1555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  default_CLEnv;
1565a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickThreadType
1575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  test_thread_id=0;
1585a2575faca105cecbf44bc70f7f8a177f6c4f674dirkSemaphoreInfo
15921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  *openCL_lock;
1605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/* Cached location of the OpenCL cache files */
1625a2575faca105cecbf44bc70f7f8a177f6c4f674dirkchar
1635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  *cache_directory;
1645a2575faca105cecbf44bc70f7f8a177f6c4f674dirkSemaphoreInfo
1655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  *cache_directory_lock;
1665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1675a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic inline MagickBooleanType IsSameOpenCLDevice(MagickCLDevice a,
1685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDevice b)
1695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
1708f012e53de440db26b36e690e61d480e78249ab8dirk  if ((LocaleCompare(a->platform_name,b->platform_name) == 0) &&
1718f012e53de440db26b36e690e61d480e78249ab8dirk      (LocaleCompare(a->name,b->name) == 0) &&
1725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      (LocaleCompare(a->version,b->version) == 0) &&
1735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      (a->max_clock_frequency == b->max_clock_frequency) &&
1745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      (a->max_compute_units == b->max_compute_units))
1755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickTrue);
1769973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
1775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickFalse);
1785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
1799973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
1805a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic inline MagickBooleanType IsBenchmarkedOpenCLDevice(MagickCLDevice a,
1815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDeviceBenchmark *b)
1825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
1838f012e53de440db26b36e690e61d480e78249ab8dirk  if ((LocaleCompare(a->platform_name,b->platform_name) == 0) &&
1848f012e53de440db26b36e690e61d480e78249ab8dirk      (LocaleCompare(a->name,b->name) == 0) &&
1855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      (LocaleCompare(a->version,b->version) == 0) &&
1865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      (a->max_clock_frequency == b->max_clock_frequency) &&
1875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      (a->max_compute_units == b->max_compute_units))
1885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickTrue);
1895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1905a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickFalse);
1915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
1925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1935a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic inline void RelinquishMagickCLDevices(MagickCLEnv clEnv)
1945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
1955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
1965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i;
1975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
1985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv->devices != (MagickCLDevice *) NULL)
1995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
2005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      for (i = 0; i < clEnv->number_devices; i++)
2015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        clEnv->devices[i]=RelinquishMagickCLDevice(clEnv->devices[i]);
2025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      clEnv->devices=(MagickCLDevice *) RelinquishMagickMemory(clEnv->devices);
2035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
2045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  clEnv->number_devices=0;
2055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
2069973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
2075a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic inline MagickBooleanType MagickCreateDirectory(const char *path)
2085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
2095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  int
2105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status;
2119973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
2125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#ifdef MAGICKCORE_WINDOWS_SUPPORT
2135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  status=mkdir(path);
2149973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#else
2155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  status=mkdir(path, 0777);
2169973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#endif
2175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(status == 0 ? MagickTrue : MagickFalse);
2189973174de229bd4c4a8b947ea7acb19f4447dc5ddirk}
2199973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
2205a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic inline void InitAccelerateTimer(AccelerateTimer *timer)
2215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
2229973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#ifdef _WIN32
2235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  QueryPerformanceFrequency((LARGE_INTEGER*)&timer->freq);
2249973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#else
2255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  timer->freq=(long long)1.0E3;
2269973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#endif
2275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  timer->clocks=0;
2285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  timer->start=0;
2299973174de229bd4c4a8b947ea7acb19f4447dc5ddirk}
2309973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
2315a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic inline double ReadAccelerateTimer(AccelerateTimer *timer)
2325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
2335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return (double)timer->clocks/(double)timer->freq;
2349973174de229bd4c4a8b947ea7acb19f4447dc5ddirk}
2359973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
2365a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic inline void StartAccelerateTimer(AccelerateTimer* timer)
2375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
2389973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#ifdef _WIN32
2395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  QueryPerformanceCounter((LARGE_INTEGER*)&timer->start);
2409973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#else
2415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  struct timeval
2425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    s;
2435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  gettimeofday(&s,0);
2445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  timer->start=(long long)s.tv_sec*(long long)1.0E3+(long long)s.tv_usec/
2455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (long long)1.0E3;
2469973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#endif
2479973174de229bd4c4a8b947ea7acb19f4447dc5ddirk}
2489973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
2495a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic inline void StopAccelerateTimer(AccelerateTimer *timer)
2505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
2515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  long long
2525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    n;
2539973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
2545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  n=0;
2555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#ifdef _WIN32
2565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  QueryPerformanceCounter((LARGE_INTEGER*)&(n));
257d2a7a2d4a46c82a8679688ae763ef9d7bb53ccd7dirk#else
2585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  struct timeval
2595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    s;
2605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  gettimeofday(&s,0);
2615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  n=(long long)s.tv_sec*(long long)1.0E3+(long long)s.tv_usec/
2625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (long long)1.0E3;
2639973174de229bd4c4a8b947ea7acb19f4447dc5ddirk#endif
2645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  n-=timer->start;
2655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  timer->start=0;
2665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  timer->clocks+=n;
2679973174de229bd4c4a8b947ea7acb19f4447dc5ddirk}
2689973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
2695a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic const char *GetOpenCLCacheDirectory()
2709973174de229bd4c4a8b947ea7acb19f4447dc5ddirk{
2715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (cache_directory == (char *) NULL)
2725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
27301314608565b2c1cf1a9b73f562791b1c335aaa7dirk      if (cache_directory_lock == (SemaphoreInfo *) NULL)
27401314608565b2c1cf1a9b73f562791b1c335aaa7dirk        ActivateSemaphoreInfo(&cache_directory_lock);
27501314608565b2c1cf1a9b73f562791b1c335aaa7dirk      LockSemaphoreInfo(cache_directory_lock);
27601314608565b2c1cf1a9b73f562791b1c335aaa7dirk      if (cache_directory == (char *) NULL)
27701314608565b2c1cf1a9b73f562791b1c335aaa7dirk        {
27801314608565b2c1cf1a9b73f562791b1c335aaa7dirk          char
27901314608565b2c1cf1a9b73f562791b1c335aaa7dirk            *home,
28001314608565b2c1cf1a9b73f562791b1c335aaa7dirk            path[MagickPathExtent],
28101314608565b2c1cf1a9b73f562791b1c335aaa7dirk            *temp;
2829973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
28301314608565b2c1cf1a9b73f562791b1c335aaa7dirk          MagickBooleanType
28401314608565b2c1cf1a9b73f562791b1c335aaa7dirk            status;
2859973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
28601314608565b2c1cf1a9b73f562791b1c335aaa7dirk          struct stat
28701314608565b2c1cf1a9b73f562791b1c335aaa7dirk            attributes;
2889973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
28901314608565b2c1cf1a9b73f562791b1c335aaa7dirk          temp=(char *) NULL;
29001314608565b2c1cf1a9b73f562791b1c335aaa7dirk          home=GetEnvironmentValue("MAGICK_OPENCL_CACHE_DIR");
2915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          if (home == (char *) NULL)
2925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            {
29301314608565b2c1cf1a9b73f562791b1c335aaa7dirk              home=GetEnvironmentValue("XDG_CACHE_HOME");
29401314608565b2c1cf1a9b73f562791b1c335aaa7dirk              if (home == (char *) NULL)
29501314608565b2c1cf1a9b73f562791b1c335aaa7dirk                home=GetEnvironmentValue("LOCALAPPDATA");
29601314608565b2c1cf1a9b73f562791b1c335aaa7dirk              if (home == (char *) NULL)
29701314608565b2c1cf1a9b73f562791b1c335aaa7dirk                home=GetEnvironmentValue("APPDATA");
29801314608565b2c1cf1a9b73f562791b1c335aaa7dirk              if (home == (char *) NULL)
29901314608565b2c1cf1a9b73f562791b1c335aaa7dirk                home=GetEnvironmentValue("USERPROFILE");
3005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            }
3010c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
3025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          if (home != (char *) NULL)
3035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            {
30401314608565b2c1cf1a9b73f562791b1c335aaa7dirk              /* first check if $HOME exists */
30501314608565b2c1cf1a9b73f562791b1c335aaa7dirk              (void) FormatLocaleString(path,MagickPathExtent,"%s",home);
3065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk              status=GetPathAttributes(path,&attributes);
3075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk              if (status == MagickFalse)
3085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                status=MagickCreateDirectory(path);
3095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
31001314608565b2c1cf1a9b73f562791b1c335aaa7dirk              /* first check if $HOME/ImageMagick exists */
3115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk              if (status != MagickFalse)
3125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                {
3135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                  (void) FormatLocaleString(path,MagickPathExtent,
31401314608565b2c1cf1a9b73f562791b1c335aaa7dirk                    "%s%sImageMagick",home,DirectorySeparator);
31501314608565b2c1cf1a9b73f562791b1c335aaa7dirk
3165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                  status=GetPathAttributes(path,&attributes);
3175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                  if (status == MagickFalse)
3185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                    status=MagickCreateDirectory(path);
3195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                }
3205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
3215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk              if (status != MagickFalse)
3225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                {
32301314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  temp=(char*) AcquireMagickMemory(strlen(path)+1);
3245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                  CopyMagickString(temp,path,strlen(path)+1);
3255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                }
3265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk              home=DestroyString(home);
3275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            }
32801314608565b2c1cf1a9b73f562791b1c335aaa7dirk          else
32901314608565b2c1cf1a9b73f562791b1c335aaa7dirk            {
33001314608565b2c1cf1a9b73f562791b1c335aaa7dirk              home=GetEnvironmentValue("HOME");
33101314608565b2c1cf1a9b73f562791b1c335aaa7dirk              if (home != (char *) NULL)
33201314608565b2c1cf1a9b73f562791b1c335aaa7dirk                {
33301314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  /* first check if $HOME/.cache exists */
33401314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  (void) FormatLocaleString(path,MagickPathExtent,"%s%s.cache",
33501314608565b2c1cf1a9b73f562791b1c335aaa7dirk                    home,DirectorySeparator);
33601314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  status=GetPathAttributes(path,&attributes);
33701314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  if (status == MagickFalse)
33801314608565b2c1cf1a9b73f562791b1c335aaa7dirk                    status=MagickCreateDirectory(path);
33901314608565b2c1cf1a9b73f562791b1c335aaa7dirk
34001314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  /* first check if $HOME/.cache/ImageMagick exists */
34101314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  if (status != MagickFalse)
34201314608565b2c1cf1a9b73f562791b1c335aaa7dirk                    {
34301314608565b2c1cf1a9b73f562791b1c335aaa7dirk                      (void) FormatLocaleString(path,MagickPathExtent,
34401314608565b2c1cf1a9b73f562791b1c335aaa7dirk                        "%s%s.cache%sImageMagick",home,DirectorySeparator,
34501314608565b2c1cf1a9b73f562791b1c335aaa7dirk                        DirectorySeparator);
34601314608565b2c1cf1a9b73f562791b1c335aaa7dirk                      status=GetPathAttributes(path,&attributes);
34701314608565b2c1cf1a9b73f562791b1c335aaa7dirk                      if (status == MagickFalse)
34801314608565b2c1cf1a9b73f562791b1c335aaa7dirk                        status=MagickCreateDirectory(path);
34901314608565b2c1cf1a9b73f562791b1c335aaa7dirk                    }
35001314608565b2c1cf1a9b73f562791b1c335aaa7dirk
35101314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  if (status != MagickFalse)
35201314608565b2c1cf1a9b73f562791b1c335aaa7dirk                    {
35301314608565b2c1cf1a9b73f562791b1c335aaa7dirk                      temp=(char*) AcquireMagickMemory(strlen(path)+1);
35401314608565b2c1cf1a9b73f562791b1c335aaa7dirk                      CopyMagickString(temp,path,strlen(path)+1);
35501314608565b2c1cf1a9b73f562791b1c335aaa7dirk                    }
35601314608565b2c1cf1a9b73f562791b1c335aaa7dirk                  home=DestroyString(home);
35701314608565b2c1cf1a9b73f562791b1c335aaa7dirk                }
35801314608565b2c1cf1a9b73f562791b1c335aaa7dirk            }
35901314608565b2c1cf1a9b73f562791b1c335aaa7dirk          if (temp == (char *) NULL)
36001314608565b2c1cf1a9b73f562791b1c335aaa7dirk            temp=AcquireString("?");
36101314608565b2c1cf1a9b73f562791b1c335aaa7dirk          cache_directory=temp;
3625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        }
36301314608565b2c1cf1a9b73f562791b1c335aaa7dirk      UnlockSemaphoreInfo(cache_directory_lock);
3645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
36501314608565b2c1cf1a9b73f562791b1c335aaa7dirk  if (*cache_directory == '?')
36601314608565b2c1cf1a9b73f562791b1c335aaa7dirk    return((const char *) NULL);
3675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(cache_directory);
3680c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy}
3690c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
3705a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void SelectOpenCLDevice(MagickCLEnv clEnv,cl_device_type type)
3710c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
3725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDevice
3735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device;
3745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
3755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
3765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i,
3775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    j;
3785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
3795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
3805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv->devices[i]->enabled=MagickFalse;
3815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
3825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
3835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
3845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device=clEnv->devices[i];
3855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (device->type != type)
3865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      continue;
3875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
3885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device->enabled=MagickTrue;
3895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    for (j = i+1; j < clEnv->number_devices; j++)
3900c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy    {
3915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      MagickCLDevice
3925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        other_device;
3935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
3945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      other_device=clEnv->devices[j];
3955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      if (IsSameOpenCLDevice(device,other_device))
3965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        other_device->enabled=MagickTrue;
3970c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy    }
3985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  }
3990c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy}
4000c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
4018f012e53de440db26b36e690e61d480e78249ab8dirkstatic size_t StringSignature(const char* string)
4020c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
4038f012e53de440db26b36e690e61d480e78249ab8dirk  size_t
4045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    n,
4055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i,
4065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    j,
4075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    signature,
4085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    stringLength;
4095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
4105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  union
4115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
4125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    const char* s;
4138f012e53de440db26b36e690e61d480e78249ab8dirk    const size_t* u;
4145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  } p;
4155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
4168f012e53de440db26b36e690e61d480e78249ab8dirk  stringLength=(size_t) strlen(string);
4175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  signature=stringLength;
4188f012e53de440db26b36e690e61d480e78249ab8dirk  n=stringLength/sizeof(size_t);
4195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  p.s=string;
4205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < n; i++)
4215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    signature^=p.u[i];
4228f012e53de440db26b36e690e61d480e78249ab8dirk  if (n * sizeof(size_t) != stringLength)
4235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
4245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      char
4255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        padded[4];
426f034abbcb705540b0d42ade64679775e7a34e582cristy
4278f012e53de440db26b36e690e61d480e78249ab8dirk      j=n*sizeof(size_t);
4285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      for (i = 0; i < 4; i++, j++)
4295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
4305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (j < stringLength)
4315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          padded[i]=p.s[j];
4325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        else
4335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          padded[i]=0;
4345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
4355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      p.s=padded;
4365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      signature^=p.u[0];
4375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
4385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(signature);
4395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
440f034abbcb705540b0d42ade64679775e7a34e582cristy
44121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk/*
44221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  Provide call to OpenCL library methods
44321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk*/
44421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
44521dc0310cdaa5cc6034a1e100746706f5ec089ebdirkMagickPrivate cl_mem CreateOpenCLBuffer(MagickCLDevice device,
44666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  cl_mem_flags flags,size_t size,void *host_ptr)
44721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
448e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk  return(openCL_library->clCreateBuffer(device->context,flags,size,host_ptr,
44921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    (cl_int *) NULL));
45021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
45121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
45221dc0310cdaa5cc6034a1e100746706f5ec089ebdirkMagickPrivate void ReleaseOpenCLKernel(cl_kernel kernel)
45321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
45421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  (void) openCL_library->clReleaseKernel(kernel);
45521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
45621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
45721dc0310cdaa5cc6034a1e100746706f5ec089ebdirkMagickPrivate void ReleaseOpenCLMemObject(cl_mem memobj)
45821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
45921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  (void) openCL_library->clReleaseMemObject(memobj);
46021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
46121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
46221dc0310cdaa5cc6034a1e100746706f5ec089ebdirkMagickPrivate cl_int SetOpenCLKernelArg(cl_kernel kernel,cl_uint arg_index,
46321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  size_t arg_size,const void *arg_value)
46421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
46521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  return(openCL_library->clSetKernelArg(kernel,arg_index,arg_size,arg_value));
46621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
46721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
46821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk/*
46921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
47121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
47221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
47321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   A c q u i r e M a g i c k C L C a c h e I n f o                           %
47421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
47521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
47621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
47721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
47921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  AcquireMagickCLCacheInfo() acquires an OpenCL cache info structure.
48021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
48121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  The format of the AcquireMagickCLCacheInfo method is:
48221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
48321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%      MagickCLCacheInfo AcquireMagickCLCacheInfo(MagickCLDevice device,
48421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%        Quantum *pixels,const MagickSizeType length)
48521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
48621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  A description of each parameter follows:
48721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
48821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o device: the OpenCL device.
48921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
49021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o pixels: the pixel buffer of the image.
49121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
49221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o length: the length of the pixel buffer.
49321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
49421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk*/
49521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
49621dc0310cdaa5cc6034a1e100746706f5ec089ebdirkMagickPrivate MagickCLCacheInfo AcquireMagickCLCacheInfo(MagickCLDevice device,
49721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  Quantum *pixels,const MagickSizeType length)
49821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
499e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk  cl_int
500e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk    status;
501e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk
50221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  MagickCLCacheInfo
50321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    info;
50421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
50521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  info=(MagickCLCacheInfo) AcquireMagickMemory(sizeof(*info));
50621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if (info == (MagickCLCacheInfo) NULL)
50721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
50821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  (void) ResetMagickMemory(info,0,sizeof(*info));
50921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  LockSemaphoreInfo(openCL_lock);
51021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  device->requested++;
51121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  UnlockSemaphoreInfo(openCL_lock);
51221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  info->device=device;
51321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  info->length=length;
51421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  info->pixels=pixels;
51521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  info->buffer=openCL_library->clCreateBuffer(device->context,
51666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR,(size_t) length,(void *) pixels,
51766acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    &status);
518e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk  if (status == CL_SUCCESS)
519e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk    return(info);
520e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk  LockSemaphoreInfo(openCL_lock);
521e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk  device->requested--;
522e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk  UnlockSemaphoreInfo(openCL_lock);
523e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk  return((MagickCLCacheInfo) RelinquishMagickMemory(info));
52421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
52521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
526f034abbcb705540b0d42ade64679775e7a34e582cristy/*
527f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
528f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
529f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
530f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
5315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   A c q u i r e M a g i c k C L D e v i c e                                 %
532f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
533f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
534f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
535f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
536f034abbcb705540b0d42ade64679775e7a34e582cristy%
5375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  AcquireMagickCLDevice() acquires an OpenCL device
5385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
5395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the AcquireMagickCLDevice method is:
5405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
5415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickCLDevice AcquireMagickCLDevice()
542f034abbcb705540b0d42ade64679775e7a34e582cristy%
543f034abbcb705540b0d42ade64679775e7a34e582cristy*/
544f034abbcb705540b0d42ade64679775e7a34e582cristy
5455a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickCLDevice AcquireMagickCLDevice()
546f034abbcb705540b0d42ade64679775e7a34e582cristy{
5475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDevice
5485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device;
5495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
5505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  device=(MagickCLDevice) AcquireMagickMemory(sizeof(*device));
5515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device != NULL)
552f034abbcb705540b0d42ade64679775e7a34e582cristy  {
5535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (void) ResetMagickMemory(device,0,sizeof(*device));
5545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    ActivateSemaphoreInfo(&device->lock);
5555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device->score=MAGICKCORE_OPENCL_UNDEFINED_SCORE;
5565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device->command_queues_index=-1;
5575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device->enabled=MagickTrue;
558f034abbcb705540b0d42ade64679775e7a34e582cristy  }
5595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(device);
560f034abbcb705540b0d42ade64679775e7a34e582cristy}
561f034abbcb705540b0d42ade64679775e7a34e582cristy
562f034abbcb705540b0d42ade64679775e7a34e582cristy/*
563f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
565f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
566f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
5675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   A c q u i r e M a g i c k C L E n v                                       %
568f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
569f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
570f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
571f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572f034abbcb705540b0d42ade64679775e7a34e582cristy%
5735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk% AcquireMagickCLEnv() allocates the MagickCLEnv structure
574f034abbcb705540b0d42ade64679775e7a34e582cristy%
575f034abbcb705540b0d42ade64679775e7a34e582cristy*/
576f034abbcb705540b0d42ade64679775e7a34e582cristy
5775a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickCLEnv AcquireMagickCLEnv(void)
5780c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
5795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const char
5805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *option;
5819973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
5825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLEnv
5835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv;
5840c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
5855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  clEnv=(MagickCLEnv) AcquireMagickMemory(sizeof(*clEnv));
5865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv != (MagickCLEnv) NULL)
5870c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy  {
5885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (void) ResetMagickMemory(clEnv,0,sizeof(*clEnv));
5895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    ActivateSemaphoreInfo(&clEnv->lock);
5905a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv->cpu_score=MAGICKCORE_OPENCL_UNDEFINED_SCORE;
5915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv->enabled=MagickTrue;
5925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    option=getenv("MAGICK_OCL_DEVICE");
5935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if ((option != (const char *) NULL) && (strcmp(option,"OFF") == 0))
5945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      clEnv->enabled=MagickFalse;
5950c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy  }
5965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return clEnv;
5970c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy}
5980c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
599f034abbcb705540b0d42ade64679775e7a34e582cristy/*
600f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
602f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
603f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
60421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   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                         %
605f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
606f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
607f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
608f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
609f034abbcb705540b0d42ade64679775e7a34e582cristy%
6105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  AcquireOpenCLCommandQueue() acquires an OpenCL command queue
611f034abbcb705540b0d42ade64679775e7a34e582cristy%
6125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the AcquireOpenCLCommandQueue method is:
613f034abbcb705540b0d42ade64679775e7a34e582cristy%
6145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      cl_command_queue AcquireOpenCLCommandQueue(MagickCLDevice device)
615f034abbcb705540b0d42ade64679775e7a34e582cristy%
616f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
617f034abbcb705540b0d42ade64679775e7a34e582cristy%
6185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device.
619f034abbcb705540b0d42ade64679775e7a34e582cristy%
620f034abbcb705540b0d42ade64679775e7a34e582cristy*/
621f034abbcb705540b0d42ade64679775e7a34e582cristy
6225a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickPrivate cl_command_queue AcquireOpenCLCommandQueue(MagickCLDevice device)
6231dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy{
6245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_command_queue
6255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    queue;
626f034abbcb705540b0d42ade64679775e7a34e582cristy
6275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_command_queue_properties
6285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    properties;
629f034abbcb705540b0d42ade64679775e7a34e582cristy
6305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  assert(device != (MagickCLDevice) NULL);
6315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  LockSemaphoreInfo(device->lock);
632d55bcc38127ab9c5aab001ce46593e218f8ef8f9dirk  if ((device->profile_kernels == MagickFalse) &&
633d55bcc38127ab9c5aab001ce46593e218f8ef8f9dirk      (device->command_queues_index >= 0))
634f034abbcb705540b0d42ade64679775e7a34e582cristy  {
6355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    queue=device->command_queues[device->command_queues_index--];
6365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    UnlockSemaphoreInfo(device->lock);
637f034abbcb705540b0d42ade64679775e7a34e582cristy  }
638f034abbcb705540b0d42ade64679775e7a34e582cristy  else
6395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
6405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    UnlockSemaphoreInfo(device->lock);
6415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    properties=(cl_command_queue_properties) NULL;
6427d42b3c11794313e25ede648463812545161de2ddirk    if (device->profile_kernels != MagickFalse)
6437d42b3c11794313e25ede648463812545161de2ddirk      properties=CL_QUEUE_PROFILING_ENABLE;
6445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    queue=openCL_library->clCreateCommandQueue(device->context,
645e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk      device->deviceID,properties,(cl_int *) NULL);
6465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  }
6475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(queue);
648f034abbcb705540b0d42ade64679775e7a34e582cristy}
649f034abbcb705540b0d42ade64679775e7a34e582cristy
650f034abbcb705540b0d42ade64679775e7a34e582cristy/*
651f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
653f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
654f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
65521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   A c q u i r e O p e n C L K e r n e l                                     %
656f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
657f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
658f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
659f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660f034abbcb705540b0d42ade64679775e7a34e582cristy%
6615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  AcquireOpenCLKernel() acquires an OpenCL kernel
6621dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy%
6635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the AcquireOpenCLKernel method is:
664f034abbcb705540b0d42ade64679775e7a34e582cristy%
6655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      cl_kernel AcquireOpenCLKernel(MagickCLEnv clEnv,
6665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%        MagickOpenCLProgram program, const char* kernelName)
667f034abbcb705540b0d42ade64679775e7a34e582cristy%
668f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
669f034abbcb705540b0d42ade64679775e7a34e582cristy%
6705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o clEnv: the OpenCL environment.
6715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
6725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o program: the OpenCL program module that the kernel belongs to.
6735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
6745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o kernelName:  the name of the kernel
675f034abbcb705540b0d42ade64679775e7a34e582cristy%
676f034abbcb705540b0d42ade64679775e7a34e582cristy*/
677f034abbcb705540b0d42ade64679775e7a34e582cristy
6785a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickPrivate cl_kernel AcquireOpenCLKernel(MagickCLDevice device,
6795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const char *kernel_name)
6805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
6815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_kernel
6825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    kernel;
6835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
6845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  assert(device != (MagickCLDevice) NULL);
685e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk  kernel=openCL_library->clCreateKernel(device->program,kernel_name,
686e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk    (cl_int *) NULL);
6875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(kernel);
6885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
689f034abbcb705540b0d42ade64679775e7a34e582cristy
690f034abbcb705540b0d42ade64679775e7a34e582cristy/*
691f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
693f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
694f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
6955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   A u t o S e l e c t O p e n C L D e v i c e s                             %
696f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
697f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
698f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
699f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
700f034abbcb705540b0d42ade64679775e7a34e582cristy%
7015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  AutoSelectOpenCLDevices() determines the best device based on the
7025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  information from the micro-benchmark.
7031dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy%
7045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the AutoSelectOpenCLDevices method is:
705f034abbcb705540b0d42ade64679775e7a34e582cristy%
7065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      void AcquireOpenCLKernel(MagickCLEnv clEnv,ExceptionInfo *exception)
707f034abbcb705540b0d42ade64679775e7a34e582cristy%
708f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
709f034abbcb705540b0d42ade64679775e7a34e582cristy%
710f034abbcb705540b0d42ade64679775e7a34e582cristy%    o clEnv: the OpenCL environment.
7111dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy%
7125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o exception: return any errors or warnings in this structure.
713f034abbcb705540b0d42ade64679775e7a34e582cristy%
714f034abbcb705540b0d42ade64679775e7a34e582cristy*/
715f034abbcb705540b0d42ade64679775e7a34e582cristy
7165a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void LoadOpenCLDeviceBenchmark(MagickCLEnv clEnv,const char *xml)
7175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
7185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
7195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    keyword[MagickPathExtent],
7205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *token;
7215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
7225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const char
7235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *q;
7245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
7255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDeviceBenchmark
7265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *device_benchmark;
7275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
7285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickStatusType
7295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status;
7305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
7315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
7325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i,
7335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    extent;
7345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
7355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (xml == (char *) NULL)
7365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return;
7375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  status=MagickTrue;
7385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  device_benchmark=(MagickCLDeviceBenchmark *) NULL;
7395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  token=AcquireString(xml);
7405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  extent=strlen(token)+MagickPathExtent;
7415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (q=(char *) xml; *q != '\0'; )
7425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
7435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    /*
7445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      Interpret XML.
7455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    */
7465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetNextToken(q,&q,extent,token);
7475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (*token == '\0')
7485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      break;
7495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (void) CopyMagickString(keyword,token,MagickPathExtent);
7505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
7515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
7525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        /*
7535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          Doctype element.
7545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        */
7555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
7565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          GetNextToken(q,&q,extent,token);
7575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        continue;
7585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
7595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (LocaleNCompare(keyword,"<!--",4) == 0)
7605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
7615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        /*
7625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          Comment element.
7635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        */
7645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
7655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          GetNextToken(q,&q,extent,token);
7665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        continue;
7675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
7685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (LocaleCompare(keyword,"<device") == 0)
7695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
7705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        /*
7715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          Device element.
7725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        */
7735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        device_benchmark=(MagickCLDeviceBenchmark *) AcquireMagickMemory(
7745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          sizeof(*device_benchmark));
7755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (device_benchmark == (MagickCLDeviceBenchmark *) NULL)
7765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          break;
7775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        (void) ResetMagickMemory(device_benchmark,0,sizeof(*device_benchmark));
7785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        device_benchmark->score=MAGICKCORE_OPENCL_UNDEFINED_SCORE;
7795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        continue;
7805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
7815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (device_benchmark == (MagickCLDeviceBenchmark *) NULL)
7825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      continue;
7835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (LocaleCompare(keyword,"/>") == 0)
7845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
7855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (device_benchmark->score != MAGICKCORE_OPENCL_UNDEFINED_SCORE)
7865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          {
7875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            if (LocaleCompare(device_benchmark->name, "CPU") == 0)
7885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk              clEnv->cpu_score=device_benchmark->score;
7895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            else
7905a2575faca105cecbf44bc70f7f8a177f6c4f674dirk              {
7915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                MagickCLDevice
7925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                  device;
7935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
7945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                /*
7955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                  Set the score for all devices that match this device.
7965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                */
7975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                for (i = 0; i < clEnv->number_devices; i++)
7985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                {
7995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                  device=clEnv->devices[i];
8005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                  if (IsBenchmarkedOpenCLDevice(device,device_benchmark))
8015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                    device->score=device_benchmark->score;
8025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk                }
8035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk              }
8045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          }
8055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
80623fc990aa9fa0c4fcaa24c65a79564e943cff843dirk        device_benchmark->platform_name=RelinquishMagickMemory(
80723fc990aa9fa0c4fcaa24c65a79564e943cff843dirk          device_benchmark->platform_name);
80823fc990aa9fa0c4fcaa24c65a79564e943cff843dirk        device_benchmark->name=RelinquishMagickMemory(device_benchmark->name);
80923fc990aa9fa0c4fcaa24c65a79564e943cff843dirk        device_benchmark->version=RelinquishMagickMemory(
81023fc990aa9fa0c4fcaa24c65a79564e943cff843dirk          device_benchmark->version);
8115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        device_benchmark=(MagickCLDeviceBenchmark *) RelinquishMagickMemory(
8125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          device_benchmark);
8135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        continue;
8145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
8155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetNextToken(q,(const char **) NULL,extent,token);
8165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (*token != '=')
8175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      continue;
8185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetNextToken(q,&q,extent,token);
8195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetNextToken(q,&q,extent,token);
8205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    switch (*keyword)
8215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
8225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      case 'M':
8235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      case 'm':
8245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
8255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (LocaleCompare((char *) keyword,"maxClockFrequency") == 0)
8265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          {
8275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            device_benchmark->max_clock_frequency=StringToInteger(token);
8285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            break;
8295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          }
8305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (LocaleCompare((char *) keyword,"maxComputeUnits") == 0)
8315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          {
8325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            device_benchmark->max_compute_units=StringToInteger(token);
8335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            break;
8345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          }
8355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        break;
8365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
8375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      case 'N':
8385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      case 'n':
8395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
8405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (LocaleCompare((char *) keyword,"name") == 0)
8415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          device_benchmark->name=ConstantString(token);
8425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        break;
8435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
8448f012e53de440db26b36e690e61d480e78249ab8dirk      case 'P':
8458f012e53de440db26b36e690e61d480e78249ab8dirk      case 'p':
8468f012e53de440db26b36e690e61d480e78249ab8dirk      {
8478f012e53de440db26b36e690e61d480e78249ab8dirk        if (LocaleCompare((char *) keyword,"platform") == 0)
8488f012e53de440db26b36e690e61d480e78249ab8dirk          device_benchmark->platform_name=ConstantString(token);
8498f012e53de440db26b36e690e61d480e78249ab8dirk        break;
8508f012e53de440db26b36e690e61d480e78249ab8dirk      }
8515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      case 'S':
8525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      case 's':
8535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
8545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (LocaleCompare((char *) keyword,"score") == 0)
8555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          device_benchmark->score=StringToDouble(token,(char **) NULL);
8565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        break;
8575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
8585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      case 'V':
8595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      case 'v':
8605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
8615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (LocaleCompare((char *) keyword,"version") == 0)
8625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          device_benchmark->version=ConstantString(token);
8635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        break;
8645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
8655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      default:
8665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        break;
8675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
8685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  }
8695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  token=(char *) RelinquishMagickMemory(token);
8705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  device_benchmark=(MagickCLDeviceBenchmark *) RelinquishMagickMemory(
8715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device_benchmark);
8725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
8735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
8745a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickBooleanType CanWriteProfileToFile(const char *filename)
8755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
8765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  FILE
8775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *profileFile;
8785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
8795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  profileFile=fopen(filename,"ab");
8805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
8815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (profileFile == (FILE *)NULL)
8825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
8835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
8845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  fclose(profileFile);
8855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickTrue);
8865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
8875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
8885a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickBooleanType LoadOpenCLBenchmarks(MagickCLEnv clEnv,
8895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ExceptionInfo *exception)
890f034abbcb705540b0d42ade64679775e7a34e582cristy{
8915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
8925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    filename[MagickPathExtent];
8935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
8945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const StringInfo
8955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *option;
896f034abbcb705540b0d42ade64679775e7a34e582cristy
8975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  LinkedListInfo
8985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *options;
8995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
9015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i;
9025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) FormatLocaleString(filename,MagickPathExtent,"%s%s%s",
9045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetOpenCLCacheDirectory(),DirectorySeparator,
9055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    IMAGEMAGICK_PROFILE_FILE);
9065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  /*
908b35e60bc66f70afd600fffec27668978a0f5e997dirk    We don't run the benchmark when we can not write out a device profile. The
909b35e60bc66f70afd600fffec27668978a0f5e997dirk    first GPU device will be used.
9105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  */
911b18d864b3f06e9272582b7736230d934d715d542dirk#if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
9125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (CanWriteProfileToFile(filename) == MagickFalse)
913b18d864b3f06e9272582b7736230d934d715d542dirk#endif
9145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
9155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      for (i = 0; i < clEnv->number_devices; i++)
9165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        clEnv->devices[i]->score=1.0;
9175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      SelectOpenCLDevice(clEnv,CL_DEVICE_TYPE_GPU);
9195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      return(MagickFalse);
9205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
921f034abbcb705540b0d42ade64679775e7a34e582cristy
9225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  options=GetConfigureOptions(filename,exception);
9235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  option=(const StringInfo *) GetNextValueInLinkedList(options);
9245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  while (option != (const StringInfo *) NULL)
925f034abbcb705540b0d42ade64679775e7a34e582cristy  {
9265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    LoadOpenCLDeviceBenchmark(clEnv,(const char *) GetStringInfoDatum(
9275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      option));
9285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    option=(const StringInfo *) GetNextValueInLinkedList(options);
9295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  }
9305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  options=DestroyConfigureOptions(options);
9315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickTrue);
932f034abbcb705540b0d42ade64679775e7a34e582cristy}
933f034abbcb705540b0d42ade64679775e7a34e582cristy
9345a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void AutoSelectOpenCLDevices(MagickCLEnv clEnv,ExceptionInfo *exception)
9355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
9365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const char
9375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *option;
9385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  double
9405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    best_score;
9415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickBooleanType
9435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    benchmark;
9445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
9465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i;
9475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  option=getenv("MAGICK_OCL_DEVICE");
9495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (option != (const char *) NULL)
9505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
9515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      if (strcmp(option,"GPU") == 0)
9525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        SelectOpenCLDevice(clEnv,CL_DEVICE_TYPE_GPU);
9535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      else if (strcmp(option,"CPU") == 0)
9545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        SelectOpenCLDevice(clEnv,CL_DEVICE_TYPE_CPU);
9555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      else if (strcmp(option,"OFF") == 0)
9565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        {
9575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          for (i = 0; i < clEnv->number_devices; i++)
9585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk            clEnv->devices[i]->enabled=MagickFalse;
9595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          clEnv->enabled=MagickFalse;
9605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        }
9615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
9625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (LoadOpenCLBenchmarks(clEnv,exception) == MagickFalse)
9645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return;
9655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  benchmark=MagickFalse;
9675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv->cpu_score == MAGICKCORE_OPENCL_UNDEFINED_SCORE)
9685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    benchmark=MagickTrue;
9695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  else
9705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
9715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      for (i = 0; i < clEnv->number_devices; i++)
9725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
9735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        if (clEnv->devices[i]->score == MAGICKCORE_OPENCL_UNDEFINED_SCORE)
9745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        {
9755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          benchmark=MagickTrue;
9765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk          break;
9775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        }
9785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
9795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
9805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (benchmark != MagickFalse)
9825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    BenchmarkOpenCLDevices(clEnv);
9835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  best_score=clEnv->cpu_score;
9855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
9865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    best_score=MagickMin(clEnv->devices[i]->score,best_score);
9875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
9885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
9895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
9905a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (clEnv->devices[i]->score != best_score)
9915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      clEnv->devices[i]->enabled=MagickFalse;
992f034abbcb705540b0d42ade64679775e7a34e582cristy  }
993f034abbcb705540b0d42ade64679775e7a34e582cristy}
994f034abbcb705540b0d42ade64679775e7a34e582cristy
995f034abbcb705540b0d42ade64679775e7a34e582cristy/*
996f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
997f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
998f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
999f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
10005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   B e n c h m a r k O p e n C L D e v i c e s                               %
1001f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1002f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1003f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1004f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1005f034abbcb705540b0d42ade64679775e7a34e582cristy%
10065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  BenchmarkOpenCLDevices() benchmarks the OpenCL devices and the CPU to help
10075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  the automatic selection of the best device.
10081dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy%
10095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the BenchmarkOpenCLDevices method is:
1010f034abbcb705540b0d42ade64679775e7a34e582cristy%
10115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    void BenchmarkOpenCLDevices(MagickCLEnv clEnv,ExceptionInfo *exception)
1012f034abbcb705540b0d42ade64679775e7a34e582cristy%
1013f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
1014f034abbcb705540b0d42ade64679775e7a34e582cristy%
1015f034abbcb705540b0d42ade64679775e7a34e582cristy%    o clEnv: the OpenCL environment.
10161dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy%
1017f034abbcb705540b0d42ade64679775e7a34e582cristy%    o exception: return any errors or warnings
1018f034abbcb705540b0d42ade64679775e7a34e582cristy*/
1019f034abbcb705540b0d42ade64679775e7a34e582cristy
102021dc0310cdaa5cc6034a1e100746706f5ec089ebdirkstatic double RunOpenCLBenchmark(MagickBooleanType is_cpu)
1021f034abbcb705540b0d42ade64679775e7a34e582cristy{
10225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  AccelerateTimer
10235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    timer;
10245dcb762a097a37893d58dea56184068aeb06826edirk
10255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ExceptionInfo
10265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *exception;
10275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  Image
10295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *inputImage;
10305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ImageInfo
10325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *imageInfo;
10335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
10355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i;
10365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  exception=AcquireExceptionInfo();
10385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  imageInfo=AcquireImageInfo();
10395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  CloneString(&imageInfo->size,"2048x1536");
10405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  CopyMagickString(imageInfo->filename,"xc:none",MagickPathExtent);
10415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  inputImage=ReadImage(imageInfo,exception);
10425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  InitAccelerateTimer(&timer);
10445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i=0; i<=2; i++)
10465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
10475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    Image
10485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      *bluredImage,
10495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      *resizedImage,
10505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      *unsharpedImage;
10515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (i > 0)
10535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      StartAccelerateTimer(&timer);
10545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    bluredImage=BlurImage(inputImage,10.0f,3.5f,exception);
10565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    unsharpedImage=UnsharpMaskImage(bluredImage,2.0f,2.0f,50.0f,10.0f,
10575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      exception);
10585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    resizedImage=ResizeImage(unsharpedImage,640,480,LanczosFilter,
10595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      exception);
10605dcb762a097a37893d58dea56184068aeb06826edirk
106121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    /*
106221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      We need this to get a proper performance benchmark, the operations
106321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      are executed asynchronous.
106421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    */
106521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    if (is_cpu == MagickFalse)
106621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      {
106721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk        CacheInfo
106821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          *cache_info;
106921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
107021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk        cache_info=(CacheInfo *) resizedImage->cache;
107121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk        if (cache_info->opencl != (MagickCLCacheInfo) NULL)
107221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          openCL_library->clWaitForEvents(cache_info->opencl->event_count,
107321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk            cache_info->opencl->events);
107421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      }
107521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
10765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (i > 0)
10775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      StopAccelerateTimer(&timer);
1078f034abbcb705540b0d42ade64679775e7a34e582cristy
10795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (bluredImage != (Image *) NULL)
10805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      DestroyImage(bluredImage);
10815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (unsharpedImage != (Image *) NULL)
10825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      DestroyImage(unsharpedImage);
10835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (resizedImage != (Image *) NULL)
10845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      DestroyImage(resizedImage);
10855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  }
10865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  DestroyImage(inputImage);
10875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(ReadAccelerateTimer(&timer));
10885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
10895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
10905a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void RunDeviceBenckmark(MagickCLEnv clEnv,MagickCLEnv testEnv,
10915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDevice device)
10925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
10935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv->devices[0]=device;
10945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  default_CLEnv=testEnv;
109521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  device->score=RunOpenCLBenchmark(MagickFalse);
10965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  default_CLEnv=clEnv;
10975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv->devices[0]=(MagickCLDevice) NULL;
10985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
1099f034abbcb705540b0d42ade64679775e7a34e582cristy
11005a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void CacheOpenCLBenchmarks(MagickCLEnv clEnv)
11015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
11025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
11035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    filename[MagickPathExtent];
11045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  FILE
11065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *cache_file;
11075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDevice
11095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device;
11105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
11125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i,
11135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    j;
11145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) FormatLocaleString(filename,MagickPathExtent,"%s%s%s",
11165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetOpenCLCacheDirectory(),DirectorySeparator,
11175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    IMAGEMAGICK_PROFILE_FILE);
11185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cache_file=fopen_utf8(filename,"wb");
11205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (cache_file == (FILE *) NULL)
11215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return;
11225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  fwrite("<devices>\n",sizeof(char),10,cache_file);
11235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  fprintf(cache_file,"  <device name=\"CPU\" score=\"%.4g\"/>\n",
11245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv->cpu_score);
11255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
1126f034abbcb705540b0d42ade64679775e7a34e582cristy  {
11275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    MagickBooleanType
11285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      duplicate;
11295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device=clEnv->devices[i];
11315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    duplicate=MagickFalse;
11325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    for (j = 0; j < i; j++)
11335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
11345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      if (IsSameOpenCLDevice(clEnv->devices[j],device))
11355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      {
11365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        duplicate=MagickTrue;
11375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        break;
11385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      }
11395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
11405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (duplicate)
11425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      continue;
11435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (device->score != MAGICKCORE_OPENCL_UNDEFINED_SCORE)
11458f012e53de440db26b36e690e61d480e78249ab8dirk      fprintf(cache_file,"  <device platform=\"%s\" name=\"%s\" version=\"%s\"\
11468f012e53de440db26b36e690e61d480e78249ab8dirk maxClockFrequency=\"%d\" maxComputeUnits=\"%d\" score=\"%.4g\"/>\n",
11478f012e53de440db26b36e690e61d480e78249ab8dirk        device->platform_name,device->name,device->version,
11488f012e53de440db26b36e690e61d480e78249ab8dirk        (int)device->max_clock_frequency,(int)device->max_compute_units,
11498f012e53de440db26b36e690e61d480e78249ab8dirk        device->score);
11505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  }
11515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  fwrite("</devices>",sizeof(char),10,cache_file);
11525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  fclose(cache_file);
1154f034abbcb705540b0d42ade64679775e7a34e582cristy}
1155f034abbcb705540b0d42ade64679775e7a34e582cristy
11565a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void BenchmarkOpenCLDevices(MagickCLEnv clEnv)
11575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
11585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDevice
11595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device;
11605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLEnv
11625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    testEnv;
11635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
11655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i,
11665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    j;
11675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv=AcquireMagickCLEnv();
11695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv->library=openCL_library;
11705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv->devices=(MagickCLDevice *) AcquireMagickMemory(
11715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    sizeof(MagickCLDevice));
11725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv->number_devices=1;
11735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv->benchmark_thread_id=GetMagickThreadId();
11745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv->initialized=MagickTrue;
11755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
11775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv->devices[i]->score=MAGICKCORE_OPENCL_UNDEFINED_SCORE;
11785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
11805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
11815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device=clEnv->devices[i];
11825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (device->score == MAGICKCORE_OPENCL_UNDEFINED_SCORE)
11835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      RunDeviceBenckmark(clEnv,testEnv,device);
11845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    /* Set the score on all the other devices that are the same */
11865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    for (j = i+1; j < clEnv->number_devices; j++)
11875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
11885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      MagickCLDevice
11895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        other_device;
11905a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      other_device=clEnv->devices[j];
11925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      if (IsSameOpenCLDevice(device,other_device))
11935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        other_device->score=device->score;
11945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
11955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  }
11965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
11975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv->enabled=MagickFalse;
11985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  default_CLEnv=testEnv;
119921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  clEnv->cpu_score=RunOpenCLBenchmark(MagickTrue);
12005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  default_CLEnv=clEnv;
12015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
12025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  testEnv=RelinquishMagickCLEnv(testEnv);
12035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  CacheOpenCLBenchmarks(clEnv);
12045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
1205f034abbcb705540b0d42ade64679775e7a34e582cristy
1206f034abbcb705540b0d42ade64679775e7a34e582cristy/*
1207f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1208f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1209f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1210f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
12115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   C o m p i l e O p e n C L K e r n e l                                     %
1212f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1213f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1214f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1215f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1216f034abbcb705540b0d42ade64679775e7a34e582cristy%
12175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  CompileOpenCLKernel() compiles the kernel for the specified device. The
12185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  kernel will be cached on disk to reduce the compilation time.
12191dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy%
12205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the CompileOpenCLKernel method is:
1221f034abbcb705540b0d42ade64679775e7a34e582cristy%
12225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickBooleanType AcquireOpenCLKernel(MagickCLDevice clEnv,
12235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%        unsigned int signature,const char *kernel,const char *options,
12245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%        ExceptionInfo *exception)
1225f034abbcb705540b0d42ade64679775e7a34e582cristy%
1226f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
1227f034abbcb705540b0d42ade64679775e7a34e582cristy%
12285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device.
12295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
12305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o kernel: the source code of the kernel.
12315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
12325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o options: options for the compiler.
12335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
12345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o signature: a number to uniquely identify the kernel
12355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
12365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o exception: return any errors or warnings in this structure.
1237f034abbcb705540b0d42ade64679775e7a34e582cristy%
1238f034abbcb705540b0d42ade64679775e7a34e582cristy*/
1239f034abbcb705540b0d42ade64679775e7a34e582cristy
12405a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void CacheOpenCLKernel(MagickCLDevice device,char *filename,
12415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ExceptionInfo *exception)
1242f034abbcb705540b0d42ade64679775e7a34e582cristy{
12435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_uint
12445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status;
1245f034abbcb705540b0d42ade64679775e7a34e582cristy
12465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
12475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    binaryProgramSize;
1248f034abbcb705540b0d42ade64679775e7a34e582cristy
12495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  unsigned char
12505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *binaryProgram;
1251f034abbcb705540b0d42ade64679775e7a34e582cristy
12525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  status=openCL_library->clGetProgramInfo(device->program,
12535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    CL_PROGRAM_BINARY_SIZES,sizeof(size_t),&binaryProgramSize,NULL);
12545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (status != CL_SUCCESS)
12555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return;
1256f034abbcb705540b0d42ade64679775e7a34e582cristy
12575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  binaryProgram=(unsigned char*) AcquireMagickMemory(binaryProgramSize);
12585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  status=openCL_library->clGetProgramInfo(device->program,
12595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    CL_PROGRAM_BINARIES,sizeof(unsigned char*),&binaryProgram,NULL);
12605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (status == CL_SUCCESS)
12615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (void) BlobToFile(filename,binaryProgram,binaryProgramSize,exception);
12625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  binaryProgram=(unsigned char *) RelinquishMagickMemory(binaryProgram);
12635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
1264f034abbcb705540b0d42ade64679775e7a34e582cristy
12655a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickBooleanType LoadCachedOpenCLKernel(MagickCLDevice device,
12665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const char *filename)
12675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
12685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_int
12695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    binaryStatus,
12705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status;
1271f034abbcb705540b0d42ade64679775e7a34e582cristy
12725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ExceptionInfo
12735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *exception;
1274f034abbcb705540b0d42ade64679775e7a34e582cristy
12755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
12765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    length;
1277f034abbcb705540b0d42ade64679775e7a34e582cristy
12785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  unsigned char
12795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *binaryProgram;
1280f034abbcb705540b0d42ade64679775e7a34e582cristy
12815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  exception=AcquireExceptionInfo();
12825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  binaryProgram=(unsigned char *) FileToBlob(filename,~0UL,&length,exception);
12835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  exception=DestroyExceptionInfo(exception);
12845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (binaryProgram == (unsigned char *) NULL)
12855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
12865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  device->program=openCL_library->clCreateProgramWithBinary(device->context,1,
12875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    &device->deviceID,&length,(const unsigned char**)&binaryProgram,
12885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    &binaryStatus,&status);
12895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  binaryProgram=(unsigned char *) RelinquishMagickMemory(binaryProgram);
12905a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return((status != CL_SUCCESS) || (binaryStatus != CL_SUCCESS) ? MagickFalse :
12915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    MagickTrue);
1292f034abbcb705540b0d42ade64679775e7a34e582cristy}
1293f034abbcb705540b0d42ade64679775e7a34e582cristy
12944a8f72432afccff78ffef4db21b55139b7cb7803dirkstatic void LogOpenCLBuildFailure(MagickCLDevice device,const char *kernel,
12955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ExceptionInfo *exception)
1296f034abbcb705540b0d42ade64679775e7a34e582cristy{
12975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
12985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    filename[MagickPathExtent],
12995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *log;
1300f034abbcb705540b0d42ade64679775e7a34e582cristy
13015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
13025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    logSize;
1303f034abbcb705540b0d42ade64679775e7a34e582cristy
13045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) FormatLocaleString(filename,MagickPathExtent,"%s%s%s",
13055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetOpenCLCacheDirectory(),DirectorySeparator,"magick_badcl.cl");
1306f034abbcb705540b0d42ade64679775e7a34e582cristy
13074a8f72432afccff78ffef4db21b55139b7cb7803dirk  (void) remove_utf8(filename);
13085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) BlobToFile(filename,kernel,strlen(kernel),exception);
1309f034abbcb705540b0d42ade64679775e7a34e582cristy
13105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  openCL_library->clGetProgramBuildInfo(device->program,device->deviceID,
13115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    CL_PROGRAM_BUILD_LOG,0,NULL,&logSize);
13125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  log=(char*)AcquireMagickMemory(logSize);
13135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  openCL_library->clGetProgramBuildInfo(device->program,device->deviceID,
13145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    CL_PROGRAM_BUILD_LOG,logSize,log,&logSize);
1315f034abbcb705540b0d42ade64679775e7a34e582cristy
13165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) FormatLocaleString(filename,MagickPathExtent,"%s%s%s",
13175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetOpenCLCacheDirectory(),DirectorySeparator,"magick_badcl.log");
1318f034abbcb705540b0d42ade64679775e7a34e582cristy
13194a8f72432afccff78ffef4db21b55139b7cb7803dirk  (void) remove_utf8(filename);
13205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) BlobToFile(filename,log,logSize,exception);
1321f034abbcb705540b0d42ade64679775e7a34e582cristy}
1322f034abbcb705540b0d42ade64679775e7a34e582cristy
13235a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickBooleanType CompileOpenCLKernel(MagickCLDevice device,
13248f012e53de440db26b36e690e61d480e78249ab8dirk  const char *kernel,const char *options,size_t signature,
13255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ExceptionInfo *exception)
1326f034abbcb705540b0d42ade64679775e7a34e582cristy{
13275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
13285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    deviceName[MagickPathExtent],
13295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    filename[MagickPathExtent],
13305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *ptr;
1331f034abbcb705540b0d42ade64679775e7a34e582cristy
13325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_int
13335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status;
13345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
13355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickBooleanType
13365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    loaded;
13375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
13385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
13395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    length;
13405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
13415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) CopyMagickString(deviceName,device->name,MagickPathExtent);
13425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ptr=deviceName;
13435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  /* Strip out illegal characters for file names */
13445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  while (*ptr != '\0')
1345f034abbcb705540b0d42ade64679775e7a34e582cristy  {
13465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if ((*ptr == ' ') || (*ptr == '\\') || (*ptr == '/') || (*ptr == ':') ||
13475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        (*ptr == '*') || (*ptr == '?') || (*ptr == '"') || (*ptr == '<') ||
13485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        (*ptr == '>' || *ptr == '|'))
13495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      *ptr = '_';
13505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    ptr++;
1351f034abbcb705540b0d42ade64679775e7a34e582cristy  }
13525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) FormatLocaleString(filename,MagickPathExtent,
13535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    "%s%s%s_%s_%08x_%.20g.bin",GetOpenCLCacheDirectory(),
13545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    DirectorySeparator,"magick_opencl",deviceName,signature,
13555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (double) sizeof(char*)*8);
13565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  loaded=LoadCachedOpenCLKernel(device,filename);
13575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (loaded == MagickFalse)
1358f034abbcb705540b0d42ade64679775e7a34e582cristy    {
13595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      /* Binary CL program unavailable, compile the program from source */
13605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      length=strlen(kernel);
13615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      device->program=openCL_library->clCreateProgramWithSource(
13625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        device->context,1,&kernel,&length,&status);
13635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      if (status != CL_SUCCESS)
13645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        return(MagickFalse);
1365f034abbcb705540b0d42ade64679775e7a34e582cristy    }
13665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
13675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  status=openCL_library->clBuildProgram(device->program,1,&device->deviceID,
13685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    options,NULL,NULL);
13695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (status != CL_SUCCESS)
13705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
13715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (void) ThrowMagickException(exception,GetMagickModule(),DelegateWarning,
13725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      "clBuildProgram failed.","(%d)",(int)status);
13734a8f72432afccff78ffef4db21b55139b7cb7803dirk    LogOpenCLBuildFailure(device,kernel,exception);
13745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
1375f034abbcb705540b0d42ade64679775e7a34e582cristy  }
1376f034abbcb705540b0d42ade64679775e7a34e582cristy
13775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  /* Save the binary to a file to avoid re-compilation of the kernels */
13785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (loaded == MagickFalse)
13795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    CacheOpenCLKernel(device,filename,exception);
1380f034abbcb705540b0d42ade64679775e7a34e582cristy
13815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickTrue);
1382f034abbcb705540b0d42ade64679775e7a34e582cristy}
1383f034abbcb705540b0d42ade64679775e7a34e582cristy
13845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
13855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
13875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
13885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
138921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   C o p y M a g i c k C L C a c h e I n f o                                 %
139021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
139121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
139221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
139321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
139521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  CopyMagickCLCacheInfo() copies the memory from the device into host memory.
139621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
139721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  The format of the CopyMagickCLCacheInfo method is:
139821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
139921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%      void CopyMagickCLCacheInfo(MagickCLCacheInfo info)
140021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
140121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  A description of each parameter follows:
140221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
140321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o info: the OpenCL cache info.
140421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
140521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk*/
140621dc0310cdaa5cc6034a1e100746706f5ec089ebdirkMagickPrivate MagickCLCacheInfo CopyMagickCLCacheInfo(MagickCLCacheInfo info)
140721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
140821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  cl_command_queue
140921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    queue;
141021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
141121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  Quantum
141221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    *pixels;
141321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
1414a5135bab78e20f0313232559540039f45bad5ca9dirk  if (info == (MagickCLCacheInfo) NULL)
141521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    return((MagickCLCacheInfo) NULL);
1416a5135bab78e20f0313232559540039f45bad5ca9dirk  if (info->event_count > 0)
1417a5135bab78e20f0313232559540039f45bad5ca9dirk    {
1418a5135bab78e20f0313232559540039f45bad5ca9dirk      queue=AcquireOpenCLCommandQueue(info->device);
141966acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      pixels=openCL_library->clEnqueueMapBuffer(queue,info->buffer,CL_TRUE,
1420a5135bab78e20f0313232559540039f45bad5ca9dirk        CL_MAP_READ | CL_MAP_WRITE,0,info->length,info->event_count,
142166acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk        info->events,(cl_event *) NULL,(cl_int *) NULL);
1422a5135bab78e20f0313232559540039f45bad5ca9dirk      assert(pixels == info->pixels);
142366acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      ReleaseOpenCLCommandQueue(info->device,queue);
1424a5135bab78e20f0313232559540039f45bad5ca9dirk    }
142521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  return(RelinquishMagickCLCacheInfo(info,MagickFalse));
142621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
142721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
142821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk/*
142921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
143121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
143221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
143321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   D u m p O p e n C L P r o f i l e D a t a                                 %
14345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
14355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
14365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
14375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
14395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  DumpOpenCLProfileData() dumps the kernel profile data.
14405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
14415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the DumpProfileData method is:
14425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
14435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      void DumpProfileData()
14445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
14455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
1446f034abbcb705540b0d42ade64679775e7a34e582cristy
14475a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickPrivate void DumpOpenCLProfileData()
1448f034abbcb705540b0d42ade64679775e7a34e582cristy{
14495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#define OpenCLLog(message) \
14505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk   fwrite(message,sizeof(char),strlen(message),log); \
14515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk   fwrite("\n",sizeof(char),1,log);
1452f034abbcb705540b0d42ade64679775e7a34e582cristy
14535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
14545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    buf[4096],
14555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    filename[MagickPathExtent],
14565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    indent[160];
1457f034abbcb705540b0d42ade64679775e7a34e582cristy
14585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  FILE
14595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *log;
1460f034abbcb705540b0d42ade64679775e7a34e582cristy
14615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLEnv
14625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv;
1463f034abbcb705540b0d42ade64679775e7a34e582cristy
14645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
14655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i,
14665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    j;
1467f034abbcb705540b0d42ade64679775e7a34e582cristy
14685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  clEnv=GetCurrentOpenCLEnv();
146901314608565b2c1cf1a9b73f562791b1c335aaa7dirk  if (clEnv == (MagickCLEnv) NULL)
147001314608565b2c1cf1a9b73f562791b1c335aaa7dirk    return;
1471f034abbcb705540b0d42ade64679775e7a34e582cristy
14727d42b3c11794313e25ede648463812545161de2ddirk  for (i = 0; i < clEnv->number_devices; i++)
14737d42b3c11794313e25ede648463812545161de2ddirk    if (clEnv->devices[i]->profile_kernels != MagickFalse)
14747d42b3c11794313e25ede648463812545161de2ddirk      break;
14757d42b3c11794313e25ede648463812545161de2ddirk  if (i == clEnv->number_devices)
14767d42b3c11794313e25ede648463812545161de2ddirk    return;
14777d42b3c11794313e25ede648463812545161de2ddirk
14785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) FormatLocaleString(filename,MagickPathExtent,"%s%s%s",
14795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    GetOpenCLCacheDirectory(),DirectorySeparator,"ImageMagickOpenCL.log");
1480f034abbcb705540b0d42ade64679775e7a34e582cristy
14815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  log=fopen_utf8(filename,"wb");
1482f034abbcb705540b0d42ade64679775e7a34e582cristy
14835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
1484f034abbcb705540b0d42ade64679775e7a34e582cristy  {
14855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    MagickCLDevice
14865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      device;
14875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
14885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device=clEnv->devices[i];
14897d42b3c11794313e25ede648463812545161de2ddirk    if ((device->profile_kernels == MagickFalse) ||
14907d42b3c11794313e25ede648463812545161de2ddirk        (device->profile_records == (KernelProfileRecord *) NULL))
14917d42b3c11794313e25ede648463812545161de2ddirk      continue;
14927d42b3c11794313e25ede648463812545161de2ddirk
14935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    OpenCLLog("====================================================");
14945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    fprintf(log,"Device:  %s\n",device->name);
14955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    fprintf(log,"Version: %s\n",device->version);
14965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    OpenCLLog("====================================================");
14975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    OpenCLLog("                     average   calls     min     max");
14985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    OpenCLLog("                     -------   -----     ---     ---");
14997d42b3c11794313e25ede648463812545161de2ddirk    j=0;
15007d42b3c11794313e25ede648463812545161de2ddirk    while (device->profile_records[j] != (KernelProfileRecord) NULL)
1501f034abbcb705540b0d42ade64679775e7a34e582cristy    {
15025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      KernelProfileRecord
15035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        profile;
1504f034abbcb705540b0d42ade64679775e7a34e582cristy
15057d42b3c11794313e25ede648463812545161de2ddirk      profile=device->profile_records[j];
15065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      strcpy(indent,"                    ");
150721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      strncpy(indent,profile->kernel_name,MagickMin(strlen(
150821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk        profile->kernel_name),strlen(indent)-1));
15097d42b3c11794313e25ede648463812545161de2ddirk      sprintf(buf,"%s %7d %7d %7d %7d",indent,(int) (profile->total/
15107d42b3c11794313e25ede648463812545161de2ddirk        profile->count),(int) profile->count,(int) profile->min,
15117d42b3c11794313e25ede648463812545161de2ddirk        (int) profile->max);
15125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      OpenCLLog(buf);
15137d42b3c11794313e25ede648463812545161de2ddirk      j++;
1514f034abbcb705540b0d42ade64679775e7a34e582cristy    }
15155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    OpenCLLog("====================================================");
15165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    fwrite("\n\n",sizeof(char),2,log);
1517f034abbcb705540b0d42ade64679775e7a34e582cristy  }
15185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  fclose(log);
1519f034abbcb705540b0d42ade64679775e7a34e582cristy}
152021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk/*
152121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
152221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
152321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
152421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
152521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   E n q u e u e O p e n C L K e r n e l                                     %
152621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
152721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
152821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
152921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
153121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  EnqueueOpenCLKernel() enques the specified kernel and registers the OpenCL
153221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  events with the images.
153321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
153421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  The format of the EnqueueOpenCLKernel method is:
153521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
153621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%      MagickBooleanType EnqueueOpenCLKernel(cl_kernel kernel,cl_uint work_dim,
153721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%        const size_t *global_work_offset,const size_t *global_work_size,
153821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%        const size_t *local_work_size,const Image *input_image,
153921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%        const Image *output_image,ExceptionInfo *exception)
154021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
154121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  A description of each parameter follows:
154221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
154321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o kernel: the OpenCL kernel.
154421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
154521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o work_dim: the number of dimensions used to specify the global work-items
154621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                and work-items in the work-group.
154721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
154821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o offset: can be used to specify an array of work_dim unsigned values
154921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%              that describe the offset used to calculate the global ID of a
155021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%              work-item.
155121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
155221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o gsize: points to an array of work_dim unsigned values that describe the
155321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%             number of global work-items in work_dim dimensions that will
155421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%             execute the kernel function.
155521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
155621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o lsize: points to an array of work_dim unsigned values that describe the
155721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%             number of work-items that make up a work-group that will execute
155821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%             the kernel specified by kernel.
155921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
156021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o input_image: the input image of the operation.
156121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
156221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o output_image: the output or secondairy image of the operation.
156321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
156421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o exception: return any errors or warnings in this structure.
156521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
156621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk*/
156721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
1568d060d8001ebab6e0253ad62329b6f340f8d1feeadirkstatic void RegisterCacheEvent(MagickCLCacheInfo info,cl_event event)
156921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
157021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  assert(info != (MagickCLCacheInfo) NULL);
157121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  assert(event != (cl_event) NULL);
157221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if (info->events == (cl_event *) NULL)
157321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    {
157421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      info->events=AcquireMagickMemory(sizeof(*info->events));
157521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      info->event_count=1;
157621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    }
157721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  else
157821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    info->events=ResizeQuantumMemory(info->events,++info->event_count,
157921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      sizeof(*info->events));
158021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if (info->events == (cl_event *) NULL)
158121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
158221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  info->events[info->event_count-1]=event;
158321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  openCL_library->clRetainEvent(event);
158421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
158521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
158666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirkMagickPrivate MagickBooleanType EnqueueOpenCLKernel(cl_command_queue queue,
158766acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  cl_kernel kernel,cl_uint work_dim,const size_t *offset,const size_t *gsize,
158821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  const size_t *lsize,const Image *input_image,const Image *output_image,
158921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  ExceptionInfo *exception)
159021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
159121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  CacheInfo
159221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    *output_info,
159321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    *input_info;
159421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
159521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  cl_event
159621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    event,
159721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    *events;
159821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
159921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  cl_int
160021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    status;
160121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
160221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  cl_uint
160321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    event_count;
160421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
160521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  assert(input_image != (const Image *) NULL);
160621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  input_info=(CacheInfo *) input_image->cache;
160721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  assert(input_info != (CacheInfo *) NULL);
160821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  assert(input_info->opencl != (MagickCLCacheInfo) NULL);
160921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  event_count=input_info->opencl->event_count;
161021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  events=input_info->opencl->events;
161121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  output_info=(CacheInfo *) NULL;
161221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if (output_image != (const Image *) NULL)
161321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    {
161421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      output_info=(CacheInfo *) output_image->cache;
161521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      assert(output_info != (CacheInfo *) NULL);
161621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      assert(output_info->opencl != (MagickCLCacheInfo) NULL);
161721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      if (output_info->opencl->event_count > 0)
161821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk        {
161921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          ssize_t
162021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk            i;
162121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
162221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          event_count+=output_info->opencl->event_count;
162321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          events=AcquireQuantumMemory(event_count,sizeof(*events));
162421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          if (events == (cl_event *) NULL)
162566acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk            return(MagickFalse);
162621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          for (i=0; i < (ssize_t) event_count; i++)
162721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          {
162823fc990aa9fa0c4fcaa24c65a79564e943cff843dirk            if (i < (ssize_t) input_info->opencl->event_count)
162921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk              events[i]=input_info->opencl->events[i];
163021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk            else
163121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk              events[i]=output_info->opencl->events[i-
163221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk                input_info->opencl->event_count];
163321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk          }
163421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk        }
163521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    }
163621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  status=openCL_library->clEnqueueNDRangeKernel(queue,kernel,work_dim,offset,
163721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    gsize,lsize,event_count,events,&event);
163821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if ((output_info != (CacheInfo *) NULL) &&
163921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      (output_info->opencl->event_count > 0))
164021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    events=(cl_event *) RelinquishMagickMemory(events);
164121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if (status != CL_SUCCESS)
164221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    {
164321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      (void) OpenCLThrowMagickException(input_info->opencl->device,exception,
1644e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk        GetMagickModule(),ResourceLimitWarning,
1645e1200376cc2bb4bb1f3e71462df9d68f359e8b84dirk        "clEnqueueNDRangeKernel failed.","'%s'",".");
164621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk      return(MagickFalse);
164721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    }
1648f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk  if (RecordProfileData(input_info->opencl->device,kernel,event) == MagickFalse)
1649f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk    {
1650f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk      RegisterCacheEvent(input_info->opencl,event);
1651f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk      if (output_info != (CacheInfo *) NULL)
1652f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk        RegisterCacheEvent(output_info->opencl,event);
1653f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk    }
165421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  openCL_library->clReleaseEvent(event);
165521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  return(MagickTrue);
165621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
1657f034abbcb705540b0d42ade64679775e7a34e582cristy
16585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
16595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
16615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
16625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
166321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   G e t C u r r u n t O p e n C L E n v                                     %
16645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
16655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
16665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
16675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
16685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
16695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  GetCurrentOpenCLEnv() returns the current OpenCL env
16705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
16715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the GetCurrentOpenCLEnv method is:
16725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
16735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickCLEnv GetCurrentOpenCLEnv()
16745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
16755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
1676f034abbcb705540b0d42ade64679775e7a34e582cristy
16775a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickPrivate MagickCLEnv GetCurrentOpenCLEnv(void)
16785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
16795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (default_CLEnv != (MagickCLEnv) NULL)
1680f034abbcb705540b0d42ade64679775e7a34e582cristy  {
16815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if ((default_CLEnv->benchmark_thread_id != (MagickThreadType) 0) &&
16825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        (default_CLEnv->benchmark_thread_id != GetMagickThreadId()))
16835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      return((MagickCLEnv) NULL);
1684f034abbcb705540b0d42ade64679775e7a34e582cristy    else
16855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      return(default_CLEnv);
1686f034abbcb705540b0d42ade64679775e7a34e582cristy  }
1687f034abbcb705540b0d42ade64679775e7a34e582cristy
168801314608565b2c1cf1a9b73f562791b1c335aaa7dirk  if (GetOpenCLCacheDirectory() == (char *) NULL)
168901314608565b2c1cf1a9b73f562791b1c335aaa7dirk    return((MagickCLEnv) NULL);
169001314608565b2c1cf1a9b73f562791b1c335aaa7dirk
169121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if (openCL_lock == (SemaphoreInfo *) NULL)
169221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    ActivateSemaphoreInfo(&openCL_lock);
1693f034abbcb705540b0d42ade64679775e7a34e582cristy
169421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  LockSemaphoreInfo(openCL_lock);
16955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (default_CLEnv == (MagickCLEnv) NULL)
16965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    default_CLEnv=AcquireMagickCLEnv();
169721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  UnlockSemaphoreInfo(openCL_lock);
1698f034abbcb705540b0d42ade64679775e7a34e582cristy
16995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(default_CLEnv);
1700f034abbcb705540b0d42ade64679775e7a34e582cristy}
1701f034abbcb705540b0d42ade64679775e7a34e582cristy
1702f034abbcb705540b0d42ade64679775e7a34e582cristy/*
1703f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1704f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1705f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1706f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
17075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   G e t O p e n C L D e v i c e B e n c h m a r k D u r a t i o n           %
1708f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1709f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1710f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1711f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1712f034abbcb705540b0d42ade64679775e7a34e582cristy%
17135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  GetOpenCLDeviceBenchmarkScore() returns the score of the benchmark for the
17145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  device. The score is determined by the duration of the micro benchmark so
17155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  that means a lower score is better than a higher score.
1716f034abbcb705540b0d42ade64679775e7a34e582cristy%
17175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the GetOpenCLDeviceBenchmarkScore method is:
1718f034abbcb705540b0d42ade64679775e7a34e582cristy%
17195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      double GetOpenCLDeviceBenchmarkScore(const MagickCLDevice device)
1720f034abbcb705540b0d42ade64679775e7a34e582cristy%
1721f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
1722f034abbcb705540b0d42ade64679775e7a34e582cristy%
17235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device.
1724f034abbcb705540b0d42ade64679775e7a34e582cristy*/
1725f034abbcb705540b0d42ade64679775e7a34e582cristy
17265a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport double GetOpenCLDeviceBenchmarkScore(
17275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickCLDevice device)
1728f034abbcb705540b0d42ade64679775e7a34e582cristy{
17295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device == (MagickCLDevice) NULL)
17305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MAGICKCORE_OPENCL_UNDEFINED_SCORE);
17315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(device->score);
17329973174de229bd4c4a8b947ea7acb19f4447dc5ddirk}
1733f034abbcb705540b0d42ade64679775e7a34e582cristy
1734f034abbcb705540b0d42ade64679775e7a34e582cristy/*
1735f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1736f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1737f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1738f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
17395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   G e t O p e n C L D e v i c e E n a b l e d                               %
1740f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1741f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1742f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1743f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1744f034abbcb705540b0d42ade64679775e7a34e582cristy%
17455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  GetOpenCLDeviceEnabled() returns true if the device is enabled.
1746f034abbcb705540b0d42ade64679775e7a34e582cristy%
17475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the GetOpenCLDeviceEnabled method is:
1748f034abbcb705540b0d42ade64679775e7a34e582cristy%
17495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickBooleanType GetOpenCLDeviceEnabled(const MagickCLDevice device)
1750f034abbcb705540b0d42ade64679775e7a34e582cristy%
1751f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
1752f034abbcb705540b0d42ade64679775e7a34e582cristy%
17535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device.
1754f034abbcb705540b0d42ade64679775e7a34e582cristy*/
17559973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
17565a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport MagickBooleanType GetOpenCLDeviceEnabled(
17575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickCLDevice device)
1758f034abbcb705540b0d42ade64679775e7a34e582cristy{
17595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device == (MagickCLDevice) NULL)
17609973174de229bd4c4a8b947ea7acb19f4447dc5ddirk    return(MagickFalse);
17615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(device->enabled);
17629973174de229bd4c4a8b947ea7acb19f4447dc5ddirk}
1763f034abbcb705540b0d42ade64679775e7a34e582cristy
1764f034abbcb705540b0d42ade64679775e7a34e582cristy/*
1765f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1766f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1767f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1768f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
17695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   G e t O p e n C L D e v i c e N a m e                                     %
1770f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1771f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1772f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1773f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1774f034abbcb705540b0d42ade64679775e7a34e582cristy%
17755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  GetOpenCLDeviceName() returns the name of the device.
1776f034abbcb705540b0d42ade64679775e7a34e582cristy%
17775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the GetOpenCLDeviceName method is:
1778f034abbcb705540b0d42ade64679775e7a34e582cristy%
17795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      const char *GetOpenCLDeviceName(const MagickCLDevice device)
1780f034abbcb705540b0d42ade64679775e7a34e582cristy%
1781f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
1782f034abbcb705540b0d42ade64679775e7a34e582cristy%
17835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device.
17845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
17855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
17865a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport const char *GetOpenCLDeviceName(const MagickCLDevice device)
17875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
17885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device == (MagickCLDevice) NULL)
17895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return((const char *) NULL);
17905a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(device->name);
17915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
17925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
17935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
17945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
17965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
17975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
17985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   G e t O p e n C L D e v i c e s                                           %
17995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1803f034abbcb705540b0d42ade64679775e7a34e582cristy%
18045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  GetOpenCLDevices() returns the devices of the OpenCL environment at sets the
18055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  value of length to the number of devices that are available.
1806f034abbcb705540b0d42ade64679775e7a34e582cristy%
18075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the GetOpenCLDevices method is:
18085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
18097d42b3c11794313e25ede648463812545161de2ddirk%      const MagickCLDevice *GetOpenCLDevices(size_t *length,
18107d42b3c11794313e25ede648463812545161de2ddirk%        ExceptionInfo *exception)
1811f034abbcb705540b0d42ade64679775e7a34e582cristy%
18125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  A description of each parameter follows:
18135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
18147d42b3c11794313e25ede648463812545161de2ddirk%    o length: the number of device.
18157d42b3c11794313e25ede648463812545161de2ddirk%
18167d42b3c11794313e25ede648463812545161de2ddirk%    o exception: return any errors or warnings in this structure.
18177d42b3c11794313e25ede648463812545161de2ddirk%
1818f034abbcb705540b0d42ade64679775e7a34e582cristy*/
1819f034abbcb705540b0d42ade64679775e7a34e582cristy
18207d42b3c11794313e25ede648463812545161de2ddirkMagickExport MagickCLDevice *GetOpenCLDevices(size_t *length,
18217d42b3c11794313e25ede648463812545161de2ddirk  ExceptionInfo *exception)
1822f034abbcb705540b0d42ade64679775e7a34e582cristy{
18235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLEnv
18245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv;
18258d097d0dcf410b44eb1ce19aa5c3312384b3f8e7dirk
18265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  clEnv=GetCurrentOpenCLEnv();
18275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv == (MagickCLEnv) NULL)
18287d42b3c11794313e25ede648463812545161de2ddirk    {
18297d42b3c11794313e25ede648463812545161de2ddirk      if (length != (size_t *) NULL)
18307d42b3c11794313e25ede648463812545161de2ddirk        *length=0;
18317d42b3c11794313e25ede648463812545161de2ddirk      return((MagickCLDevice *) NULL);
18327d42b3c11794313e25ede648463812545161de2ddirk    }
18337d42b3c11794313e25ede648463812545161de2ddirk  InitializeOpenCL(clEnv,exception);
18345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (length != (size_t *) NULL)
18355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *length=clEnv->number_devices;
18365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(clEnv->devices);
1837f034abbcb705540b0d42ade64679775e7a34e582cristy}
1838f034abbcb705540b0d42ade64679775e7a34e582cristy
18395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
18405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   G e t O p e n C L D e v i c e T y p e                                     %
18455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
18485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
18505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  GetOpenCLDeviceType() returns the type of the device.
18515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
18525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the GetOpenCLDeviceType method is:
18535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
18545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickCLDeviceType GetOpenCLDeviceType(const MagickCLDevice device)
18555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
18565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  A description of each parameter follows:
18575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
18585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device.
18595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
18605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
18615a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport MagickCLDeviceType GetOpenCLDeviceType(
18625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickCLDevice device)
18635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
18645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device == (MagickCLDevice) NULL)
18655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(UndefinedCLDeviceType);
18665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device->type == CL_DEVICE_TYPE_GPU)
18675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(GpuCLDeviceType);
18685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device->type == CL_DEVICE_TYPE_CPU)
18695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(CpuCLDeviceType);
18705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(UndefinedCLDeviceType);
18715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
1872f034abbcb705540b0d42ade64679775e7a34e582cristy
1873f034abbcb705540b0d42ade64679775e7a34e582cristy/*
1874f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1875f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1876f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1877f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
18785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   G e t O p e n C L D e v i c e V e r s i o n                               %
1879f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1880f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1881f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1882f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1883f034abbcb705540b0d42ade64679775e7a34e582cristy%
18845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  GetOpenCLDeviceVersion() returns the version of the device.
1885f034abbcb705540b0d42ade64679775e7a34e582cristy%
18865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the GetOpenCLDeviceName method is:
1887f034abbcb705540b0d42ade64679775e7a34e582cristy%
18887d42b3c11794313e25ede648463812545161de2ddirk%      const char *GetOpenCLDeviceVersion(MagickCLDevice device)
1889f034abbcb705540b0d42ade64679775e7a34e582cristy%
1890f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
1891f034abbcb705540b0d42ade64679775e7a34e582cristy%
18925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device.
18935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
18945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
18955a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport const char *GetOpenCLDeviceVersion(const MagickCLDevice device)
18965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
18975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device == (MagickCLDevice) NULL)
18985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return((const char *) NULL);
18995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(device->version);
19005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk}
19015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
19025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
19035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
19055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
19065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
19075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   G e t O p e n C L E n a b l e d                                           %
19085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
19095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
19105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
19115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1912f034abbcb705540b0d42ade64679775e7a34e582cristy%
19135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  GetOpenCLEnabled() returns true if OpenCL acceleration is enabled.
1914f034abbcb705540b0d42ade64679775e7a34e582cristy%
19155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the GetOpenCLEnabled method is:
19165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
19175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickBooleanType GetOpenCLEnabled()
1918f034abbcb705540b0d42ade64679775e7a34e582cristy%
1919f034abbcb705540b0d42ade64679775e7a34e582cristy*/
1920f034abbcb705540b0d42ade64679775e7a34e582cristy
19215a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport MagickBooleanType GetOpenCLEnabled(void)
1922f034abbcb705540b0d42ade64679775e7a34e582cristy{
19235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLEnv
19245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv;
19255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
19265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  clEnv=GetCurrentOpenCLEnv();
19275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv == (MagickCLEnv) NULL)
19285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
19295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(clEnv->enabled);
1930f034abbcb705540b0d42ade64679775e7a34e582cristy}
1931f034abbcb705540b0d42ade64679775e7a34e582cristy
1932f034abbcb705540b0d42ade64679775e7a34e582cristy/*
1933f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1934f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1935f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1936f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
19377d42b3c11794313e25ede648463812545161de2ddirk%   G e t O p e n C L K e r n e l P r o f i l e R e c o r d s                 %
19387d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
19397d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
19407d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
19417d42b3c11794313e25ede648463812545161de2ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19427d42b3c11794313e25ede648463812545161de2ddirk%
19437d42b3c11794313e25ede648463812545161de2ddirk%  GetOpenCLKernelProfileRecords() returns the profile records for the
19447d42b3c11794313e25ede648463812545161de2ddirk%  specified device and sets length to the number of profile records.
19457d42b3c11794313e25ede648463812545161de2ddirk%
19467d42b3c11794313e25ede648463812545161de2ddirk%  The format of the GetOpenCLKernelProfileRecords method is:
19477d42b3c11794313e25ede648463812545161de2ddirk%
19487d42b3c11794313e25ede648463812545161de2ddirk%      const KernelProfileRecord *GetOpenCLKernelProfileRecords(size *length)
19497d42b3c11794313e25ede648463812545161de2ddirk%
19507d42b3c11794313e25ede648463812545161de2ddirk%  A description of each parameter follows:
19517d42b3c11794313e25ede648463812545161de2ddirk%
19527d42b3c11794313e25ede648463812545161de2ddirk%    o length: the number of profiles records.
19537d42b3c11794313e25ede648463812545161de2ddirk*/
19547d42b3c11794313e25ede648463812545161de2ddirk
19557d42b3c11794313e25ede648463812545161de2ddirkMagickExport const KernelProfileRecord *GetOpenCLKernelProfileRecords(
19567d42b3c11794313e25ede648463812545161de2ddirk  const MagickCLDevice device,size_t *length)
19577d42b3c11794313e25ede648463812545161de2ddirk{
19587d42b3c11794313e25ede648463812545161de2ddirk  if ((device == (const MagickCLDevice) NULL) || (device->profile_records ==
19597d42b3c11794313e25ede648463812545161de2ddirk      (KernelProfileRecord *) NULL))
19607d42b3c11794313e25ede648463812545161de2ddirk  {
19617d42b3c11794313e25ede648463812545161de2ddirk    if (length != (size_t *) NULL)
19627d42b3c11794313e25ede648463812545161de2ddirk      *length=0;
19637d42b3c11794313e25ede648463812545161de2ddirk    return((const KernelProfileRecord *) NULL);
19647d42b3c11794313e25ede648463812545161de2ddirk  }
19657d42b3c11794313e25ede648463812545161de2ddirk  if (length != (size_t *) NULL)
19667d42b3c11794313e25ede648463812545161de2ddirk    {
196783b804e8c3520d3092137d7da2250d175eb73c5cdirk      *length=0;
1968d55bcc38127ab9c5aab001ce46593e218f8ef8f9dirk      LockSemaphoreInfo(device->lock);
19697d42b3c11794313e25ede648463812545161de2ddirk      while (device->profile_records[*length] != (KernelProfileRecord) NULL)
19707d42b3c11794313e25ede648463812545161de2ddirk        *length=*length+1;
1971d55bcc38127ab9c5aab001ce46593e218f8ef8f9dirk      UnlockSemaphoreInfo(device->lock);
19727d42b3c11794313e25ede648463812545161de2ddirk    }
19737d42b3c11794313e25ede648463812545161de2ddirk  return(device->profile_records);
19747d42b3c11794313e25ede648463812545161de2ddirk}
19757d42b3c11794313e25ede648463812545161de2ddirk
19767d42b3c11794313e25ede648463812545161de2ddirk/*
19777d42b3c11794313e25ede648463812545161de2ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
19787d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
19797d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
19807d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
19815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   H a s O p e n C L D e v i c e s                                           %
1982f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1983f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1984f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
1985f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1986f034abbcb705540b0d42ade64679775e7a34e582cristy%
19875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  HasOpenCLDevices() checks if the OpenCL environment has devices that are
19885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  enabled and compiles the kernel for the device when necessary. False will be
19895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  returned if no enabled devices could be found
1990f034abbcb705540b0d42ade64679775e7a34e582cristy%
19915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the HasOpenCLDevices method is:
1992f034abbcb705540b0d42ade64679775e7a34e582cristy%
19935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    MagickBooleanType HasOpenCLDevices(MagickCLEnv clEnv,
19945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      ExceptionInfo exception)
1995f034abbcb705540b0d42ade64679775e7a34e582cristy%
1996f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
1997f034abbcb705540b0d42ade64679775e7a34e582cristy%
1998f034abbcb705540b0d42ade64679775e7a34e582cristy%    o clEnv: the OpenCL environment.
1999f034abbcb705540b0d42ade64679775e7a34e582cristy%
20005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o exception: return any errors or warnings in this structure.
2001f034abbcb705540b0d42ade64679775e7a34e582cristy%
2002f034abbcb705540b0d42ade64679775e7a34e582cristy*/
2003f034abbcb705540b0d42ade64679775e7a34e582cristy
20045a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickBooleanType HasOpenCLDevices(MagickCLEnv clEnv,
20055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ExceptionInfo *exception)
2006f034abbcb705540b0d42ade64679775e7a34e582cristy{
20075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
20085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *accelerateKernelsBuffer,
20095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    options[MagickPathExtent];
2010f034abbcb705540b0d42ade64679775e7a34e582cristy
20115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickStatusType
20125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status;
2013f034abbcb705540b0d42ade64679775e7a34e582cristy
20145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
20155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i;
2016f034abbcb705540b0d42ade64679775e7a34e582cristy
20178f012e53de440db26b36e690e61d480e78249ab8dirk  size_t
20185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    signature;
2019f034abbcb705540b0d42ade64679775e7a34e582cristy
20205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  /* Check if there are enabled devices */
20215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
20225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
20235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if ((clEnv->devices[i]->enabled != MagickFalse))
20245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      break;
2025f034abbcb705540b0d42ade64679775e7a34e582cristy  }
20265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (i == clEnv->number_devices)
20275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
20281dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy
20295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  /* Check if we need to compile a kernel for one of the devices */
2030c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  status=MagickTrue;
20315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
20325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
20335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if ((clEnv->devices[i]->enabled != MagickFalse) &&
20345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        (clEnv->devices[i]->program == (cl_program) NULL))
2035c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    {
2036c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk      status=MagickFalse;
2037f034abbcb705540b0d42ade64679775e7a34e582cristy      break;
2038c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    }
2039f034abbcb705540b0d42ade64679775e7a34e582cristy  }
2040c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  if (status != MagickFalse)
20415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickTrue);
2042f034abbcb705540b0d42ade64679775e7a34e582cristy
20435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  /* Get additional options */
20445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) FormatLocaleString(options,MaxTextExtent,CLOptions,
20455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (float)QuantumRange,(float)QuantumScale,(float)CLCharQuantumScale,
20465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (float)MagickEpsilon,(float)MagickPI,(unsigned int)MaxMap,
20475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (unsigned int)MAGICKCORE_QUANTUM_DEPTH);
20485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
20495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  signature=StringSignature(options);
20505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  accelerateKernelsBuffer=(char*) AcquireMagickMemory(
20515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    strlen(accelerateKernels)+strlen(accelerateKernels2)+1);
20525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (accelerateKernelsBuffer == (char*) NULL)
20535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
20545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  sprintf(accelerateKernelsBuffer,"%s%s",accelerateKernels,accelerateKernels2);
20555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  signature^=StringSignature(accelerateKernelsBuffer);
2056f034abbcb705540b0d42ade64679775e7a34e582cristy
20575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  status=MagickTrue;
20585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < clEnv->number_devices; i++)
20595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
20605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    MagickCLDevice
20615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      device;
2062f034abbcb705540b0d42ade64679775e7a34e582cristy
20638f012e53de440db26b36e690e61d480e78249ab8dirk    size_t
20648f012e53de440db26b36e690e61d480e78249ab8dirk      device_signature;
20658f012e53de440db26b36e690e61d480e78249ab8dirk
20665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    device=clEnv->devices[i];
20675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if ((device->enabled == MagickFalse) ||
20685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        (device->program != (cl_program) NULL))
20695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      continue;
2070f034abbcb705540b0d42ade64679775e7a34e582cristy
20715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    LockSemaphoreInfo(device->lock);
20725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (device->program != (cl_program) NULL)
20735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
20745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      UnlockSemaphoreInfo(device->lock);
20755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      continue;
2076f034abbcb705540b0d42ade64679775e7a34e582cristy    }
20778f012e53de440db26b36e690e61d480e78249ab8dirk    device_signature=signature;
207833f78c858bab404ea6957f350ae2b262e5aa685adirk    device_signature^=StringSignature(device->platform_name);
20795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status=CompileOpenCLKernel(device,accelerateKernelsBuffer,options,
20808f012e53de440db26b36e690e61d480e78249ab8dirk      device_signature,exception);
20815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    UnlockSemaphoreInfo(device->lock);
20825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (status == MagickFalse)
20835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      break;
2084f034abbcb705540b0d42ade64679775e7a34e582cristy  }
20855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  accelerateKernelsBuffer=RelinquishMagickMemory(accelerateKernelsBuffer);
20865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(status);
2087f034abbcb705540b0d42ade64679775e7a34e582cristy}
2088f034abbcb705540b0d42ade64679775e7a34e582cristy
20895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
20905a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
20925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
20935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
209421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   I n i t i a l i z e O p e n C L                                           %
20955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
20965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
20975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
20985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
21005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  InitializeOpenCL() is used to initialize the OpenCL environment. This method
21015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  makes sure the devices are propertly initialized and benchmarked.
21025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
21035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the InitializeOpenCL method is:
21045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
21055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    MagickBooleanType InitializeOpenCL(ExceptionInfo exception)
21065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
21075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  A description of each parameter follows:
21085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
21095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o exception: return any errors or warnings in this structure.
21105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
21115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
2112f034abbcb705540b0d42ade64679775e7a34e582cristy
21135a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic cl_uint GetOpenCLDeviceCount(MagickCLEnv clEnv,cl_platform_id platform)
21145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
21155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  char
21165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    version[MagickPathExtent];
2117f034abbcb705540b0d42ade64679775e7a34e582cristy
21185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_uint
21195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    num;
2120f034abbcb705540b0d42ade64679775e7a34e582cristy
21215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv->library->clGetPlatformInfo(platform,CL_PLATFORM_VERSION,
21225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        MagickPathExtent,version,NULL) != CL_SUCCESS)
21235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(0);
21245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (strncmp(version, "OpenCL 1.0 ", 11) == 0)
21255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(0);
21265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv->library->clGetDeviceIDs(platform,
21275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        CL_DEVICE_TYPE_CPU|CL_DEVICE_TYPE_GPU,0,NULL,&num) != CL_SUCCESS)
21285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(0);
21295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(num);
2130f034abbcb705540b0d42ade64679775e7a34e582cristy}
2131f034abbcb705540b0d42ade64679775e7a34e582cristy
21325a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic void LoadOpenCLDevices(MagickCLEnv clEnv)
21335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
21348f012e53de440db26b36e690e61d480e78249ab8dirk  cl_context_properties
21358f012e53de440db26b36e690e61d480e78249ab8dirk    properties[3];
21368f012e53de440db26b36e690e61d480e78249ab8dirk
21375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_device_id
21385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *devices;
21395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
21408f012e53de440db26b36e690e61d480e78249ab8dirk  cl_int
21418f012e53de440db26b36e690e61d480e78249ab8dirk    status;
21428f012e53de440db26b36e690e61d480e78249ab8dirk
21435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_platform_id
21445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *platforms;
21455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
21465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_uint
21475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    i,
21485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    j,
21495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    next,
21508f012e53de440db26b36e690e61d480e78249ab8dirk    number_devices,
21515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    number_platforms;
21525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
21535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  size_t
21545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    length;
21555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
21565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  number_platforms=0;
21575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (openCL_library->clGetPlatformIDs(0,NULL,&number_platforms) != CL_SUCCESS)
21585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return;
21595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (number_platforms == 0)
21605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return;
21615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  platforms=(cl_platform_id *) AcquireMagickMemory(number_platforms*
21625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    sizeof(cl_platform_id));
21635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (platforms == (cl_platform_id *) NULL)
21645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return;
21655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (openCL_library->clGetPlatformIDs(number_platforms,platforms,NULL) != CL_SUCCESS)
21665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
21675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk       platforms=(cl_platform_id *) RelinquishMagickMemory(platforms);
21685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk       return;
2169f034abbcb705540b0d42ade64679775e7a34e582cristy    }
21705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < number_platforms; i++)
21715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
21728f012e53de440db26b36e690e61d480e78249ab8dirk    number_devices=GetOpenCLDeviceCount(clEnv,platforms[i]);
21738f012e53de440db26b36e690e61d480e78249ab8dirk    if (number_devices == 0)
21745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      platforms[i]=(cl_platform_id) NULL;
21755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    else
21768f012e53de440db26b36e690e61d480e78249ab8dirk      clEnv->number_devices+=number_devices;
2177f034abbcb705540b0d42ade64679775e7a34e582cristy  }
21785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv->number_devices == 0)
21795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
21805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      platforms=(cl_platform_id *) RelinquishMagickMemory(platforms);
21815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      return;
2182f034abbcb705540b0d42ade64679775e7a34e582cristy    }
21838f012e53de440db26b36e690e61d480e78249ab8dirk  clEnv->devices=(MagickCLDevice *) AcquireQuantumMemory(clEnv->number_devices,
21845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    sizeof(MagickCLDevice));
21855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv->devices == (MagickCLDevice *) NULL)
21865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
21875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      RelinquishMagickCLDevices(clEnv);
21885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      platforms=(cl_platform_id *) RelinquishMagickMemory(platforms);
21895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      return;
2190f034abbcb705540b0d42ade64679775e7a34e582cristy    }
21915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) ResetMagickMemory(clEnv->devices,0,clEnv->number_devices*
21925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    sizeof(MagickCLDevice));
21938f012e53de440db26b36e690e61d480e78249ab8dirk  devices=(cl_device_id *) AcquireQuantumMemory(clEnv->number_devices,
21945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    sizeof(cl_device_id));
21955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (devices == (cl_device_id *) NULL)
21965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
21975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      platforms=(cl_platform_id *) RelinquishMagickMemory(platforms);
21985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      RelinquishMagickCLDevices(clEnv);
21995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      return;
2200f034abbcb705540b0d42ade64679775e7a34e582cristy    }
22018f012e53de440db26b36e690e61d480e78249ab8dirk  clEnv->number_contexts=(size_t) number_platforms;
22028f012e53de440db26b36e690e61d480e78249ab8dirk  clEnv->contexts=(cl_context *) AcquireQuantumMemory(clEnv->number_contexts,
22038f012e53de440db26b36e690e61d480e78249ab8dirk    sizeof(cl_context));
22048f012e53de440db26b36e690e61d480e78249ab8dirk  if (clEnv->contexts == (cl_context *) NULL)
22058f012e53de440db26b36e690e61d480e78249ab8dirk    {
22068f012e53de440db26b36e690e61d480e78249ab8dirk      devices=(cl_device_id *) RelinquishMagickMemory(devices);
22078f012e53de440db26b36e690e61d480e78249ab8dirk      platforms=(cl_platform_id *) RelinquishMagickMemory(platforms);
22088f012e53de440db26b36e690e61d480e78249ab8dirk      RelinquishMagickCLDevices(clEnv);
22098f012e53de440db26b36e690e61d480e78249ab8dirk      return;
22108f012e53de440db26b36e690e61d480e78249ab8dirk    }
22115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  next=0;
22125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  for (i = 0; i < number_platforms; i++)
22135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
22145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (platforms[i] == (cl_platform_id) NULL)
22155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      continue;
2216f034abbcb705540b0d42ade64679775e7a34e582cristy
22178f012e53de440db26b36e690e61d480e78249ab8dirk    status=clEnv->library->clGetDeviceIDs(platforms[i],CL_DEVICE_TYPE_CPU |
22188f012e53de440db26b36e690e61d480e78249ab8dirk      CL_DEVICE_TYPE_GPU,clEnv->number_devices,devices,&number_devices);
22198f012e53de440db26b36e690e61d480e78249ab8dirk    if (status != CL_SUCCESS)
22208f012e53de440db26b36e690e61d480e78249ab8dirk      continue;
22218f012e53de440db26b36e690e61d480e78249ab8dirk
22228f012e53de440db26b36e690e61d480e78249ab8dirk    properties[0]=CL_CONTEXT_PLATFORM;
22238f012e53de440db26b36e690e61d480e78249ab8dirk    properties[1]=(cl_context_properties) platforms[i];
22248f012e53de440db26b36e690e61d480e78249ab8dirk    properties[2]=0;
22258f012e53de440db26b36e690e61d480e78249ab8dirk    clEnv->contexts[i]=openCL_library->clCreateContext(properties,number_devices,
22268f012e53de440db26b36e690e61d480e78249ab8dirk      devices,NULL,NULL,&status);
22278f012e53de440db26b36e690e61d480e78249ab8dirk    if (status != CL_SUCCESS)
22285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      continue;
2229f034abbcb705540b0d42ade64679775e7a34e582cristy
22308f012e53de440db26b36e690e61d480e78249ab8dirk    for (j = 0; j < number_devices; j++,next++)
22315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
22325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      MagickCLDevice
22335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        device;
2234f034abbcb705540b0d42ade64679775e7a34e582cristy
22355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      device=AcquireMagickCLDevice();
22365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      if (device == (MagickCLDevice) NULL)
2237f034abbcb705540b0d42ade64679775e7a34e582cristy        break;
2238f034abbcb705540b0d42ade64679775e7a34e582cristy
22398f012e53de440db26b36e690e61d480e78249ab8dirk      device->context=clEnv->contexts[i];
22405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      device->deviceID=devices[j];
2241f034abbcb705540b0d42ade64679775e7a34e582cristy
22428f012e53de440db26b36e690e61d480e78249ab8dirk      openCL_library->clGetPlatformInfo(platforms[i],CL_PLATFORM_NAME,0,NULL,
22438f012e53de440db26b36e690e61d480e78249ab8dirk        &length);
22448f012e53de440db26b36e690e61d480e78249ab8dirk      device->platform_name=AcquireQuantumMemory(length,
22458f012e53de440db26b36e690e61d480e78249ab8dirk        sizeof(*device->platform_name));
22468f012e53de440db26b36e690e61d480e78249ab8dirk      openCL_library->clGetPlatformInfo(platforms[i],CL_PLATFORM_NAME,length,
22478f012e53de440db26b36e690e61d480e78249ab8dirk        device->platform_name,NULL);
22488f012e53de440db26b36e690e61d480e78249ab8dirk
22498f012e53de440db26b36e690e61d480e78249ab8dirk      openCL_library->clGetDeviceInfo(devices[j],CL_DEVICE_NAME,0,NULL,
22508f012e53de440db26b36e690e61d480e78249ab8dirk        &length);
22515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      device->name=AcquireQuantumMemory(length,sizeof(*device->name));
22525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      openCL_library->clGetDeviceInfo(devices[j],CL_DEVICE_NAME,length,
22535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        device->name,NULL);
2254f034abbcb705540b0d42ade64679775e7a34e582cristy
22555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      openCL_library->clGetDeviceInfo(devices[j],CL_DRIVER_VERSION,0,NULL,
22565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        &length);
22575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      device->version=AcquireQuantumMemory(length,sizeof(*device->version));
22585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      openCL_library->clGetDeviceInfo(devices[j],CL_DRIVER_VERSION,length,
22595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        device->version,NULL);
2260f034abbcb705540b0d42ade64679775e7a34e582cristy
22615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      openCL_library->clGetDeviceInfo(devices[j],CL_DEVICE_MAX_CLOCK_FREQUENCY,
22625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        sizeof(cl_uint),&device->max_clock_frequency,NULL);
2263f034abbcb705540b0d42ade64679775e7a34e582cristy
22645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      openCL_library->clGetDeviceInfo(devices[j],CL_DEVICE_MAX_COMPUTE_UNITS,
22655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        sizeof(cl_uint),&device->max_compute_units,NULL);
2266f034abbcb705540b0d42ade64679775e7a34e582cristy
22675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      openCL_library->clGetDeviceInfo(devices[j],CL_DEVICE_TYPE,
22685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        sizeof(cl_device_type),&device->type,NULL);
2269f034abbcb705540b0d42ade64679775e7a34e582cristy
22705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      openCL_library->clGetDeviceInfo(devices[j],CL_DEVICE_LOCAL_MEM_SIZE,
22715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        sizeof(cl_ulong),&device->local_memory_size,NULL);
2272f034abbcb705540b0d42ade64679775e7a34e582cristy
22735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      clEnv->devices[next]=device;
2274f034abbcb705540b0d42ade64679775e7a34e582cristy    }
2275f034abbcb705540b0d42ade64679775e7a34e582cristy  }
22765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (next != clEnv->number_devices)
22775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    RelinquishMagickCLDevices(clEnv);
22785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  platforms=(cl_platform_id *) RelinquishMagickMemory(platforms);
22795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  devices=(cl_device_id *) RelinquishMagickMemory(devices);
2280f034abbcb705540b0d42ade64679775e7a34e582cristy}
2281f034abbcb705540b0d42ade64679775e7a34e582cristy
22825a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickPrivate MagickBooleanType InitializeOpenCL(MagickCLEnv clEnv,
22835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  ExceptionInfo *exception)
22845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
22855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  LockSemaphoreInfo(clEnv->lock);
22865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv->initialized != MagickFalse)
22875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
22885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      UnlockSemaphoreInfo(clEnv->lock);
22895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      return(HasOpenCLDevices(clEnv,exception));
2290f034abbcb705540b0d42ade64679775e7a34e582cristy    }
22915a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (LoadOpenCLLibrary() != MagickFalse)
22925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
22935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      clEnv->library=openCL_library;
22945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      LoadOpenCLDevices(clEnv);
22955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      if (clEnv->number_devices > 0)
22965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        AutoSelectOpenCLDevices(clEnv,exception);
22975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
22985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  clEnv->initialized=MagickTrue;
22995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  UnlockSemaphoreInfo(clEnv->lock);
23005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(HasOpenCLDevices(clEnv,exception));
2301f034abbcb705540b0d42ade64679775e7a34e582cristy}
2302f034abbcb705540b0d42ade64679775e7a34e582cristy
2303f034abbcb705540b0d42ade64679775e7a34e582cristy/*
23045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
23065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
23075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
23085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   L o a d O p e n C L L i b r a r y                                         %
23095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
23105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
23115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
23125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
23135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
23145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  LoadOpenCLLibrary() load and binds the OpenCL library.
23155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
23165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the LoadOpenCLLibrary method is:
23175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
23185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    MagickBooleanType LoadOpenCLLibrary(void)
23195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
2320f034abbcb705540b0d42ade64679775e7a34e582cristy*/
2321f034abbcb705540b0d42ade64679775e7a34e582cristy
23225a2575faca105cecbf44bc70f7f8a177f6c4f674dirkvoid *OsLibraryGetFunctionAddress(void *library,const char *functionName)
232322624f1549ee59e742c72529c69401ef4289ff65dirk{
23245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if ((library == (void *) NULL) || (functionName == (const char *) NULL))
23255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return (void *) NULL;
23265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#ifdef MAGICKCORE_WINDOWS_SUPPORT
23275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return (void *) GetProcAddress((HMODULE)library,functionName);
23285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#else
23295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return (void *) dlsym(library,functionName);
23305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#endif
233122624f1549ee59e742c72529c69401ef4289ff65dirk}
2332f034abbcb705540b0d42ade64679775e7a34e582cristy
23338f012e53de440db26b36e690e61d480e78249ab8dirkstatic MagickBooleanType BindOpenCLFunctions()
23345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
23355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  void
23365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *library;
2337f034abbcb705540b0d42ade64679775e7a34e582cristy
23385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#ifdef MAGICKCORE_OPENCL_MACOSX
23395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#define BIND(X) openCL_library->X= &X;
23405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#else
23415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  (void) ResetMagickMemory(openCL_library,0,sizeof(MagickLibrary));
23425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#ifdef MAGICKCORE_WINDOWS_SUPPORT
23435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  library=(void *)LoadLibraryA("OpenCL.dll");
23445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#else
23455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  library=(void *)dlopen("libOpenCL.so", RTLD_NOW);
23465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#endif
2347f034abbcb705540b0d42ade64679775e7a34e582cristy
23485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#define BIND(X) \
23495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if ((openCL_library->X=(MAGICKpfn_##X)OsLibraryGetFunctionAddress(library,#X)) == NULL) \
23505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
23515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#endif
2352f034abbcb705540b0d42ade64679775e7a34e582cristy
23535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clGetPlatformIDs);
23545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clGetPlatformInfo);
2355f034abbcb705540b0d42ade64679775e7a34e582cristy
23565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clGetDeviceIDs);
23575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clGetDeviceInfo);
2358f034abbcb705540b0d42ade64679775e7a34e582cristy
23595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clCreateBuffer);
23605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clReleaseMemObject);
2361f034abbcb705540b0d42ade64679775e7a34e582cristy
23625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clCreateContext);
23635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clReleaseContext);
2364f034abbcb705540b0d42ade64679775e7a34e582cristy
23655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clCreateCommandQueue);
23665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clReleaseCommandQueue);
236766acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  BIND(clFlush);
236866acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  BIND(clFinish);
2369f034abbcb705540b0d42ade64679775e7a34e582cristy
23705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clCreateProgramWithSource);
23715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clCreateProgramWithBinary);
23725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clReleaseProgram);
23735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clBuildProgram);
23745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clGetProgramBuildInfo);
23755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clGetProgramInfo);
23761dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy
23775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clCreateKernel);
23785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clReleaseKernel);
23795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clSetKernelArg);
23807d42b3c11794313e25ede648463812545161de2ddirk  BIND(clGetKernelInfo);
2381f034abbcb705540b0d42ade64679775e7a34e582cristy
23825a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clEnqueueReadBuffer);
23835a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clEnqueueMapBuffer);
23845a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clEnqueueUnmapMemObject);
23855a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clEnqueueNDRangeKernel);
2386f034abbcb705540b0d42ade64679775e7a34e582cristy
23875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clWaitForEvents);
23885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  BIND(clReleaseEvent);
238921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  BIND(clRetainEvent);
239021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  BIND(clSetEventCallback);
239121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
239221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  BIND(clGetEventProfilingInfo);
2393f034abbcb705540b0d42ade64679775e7a34e582cristy
23945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickTrue);
2395f034abbcb705540b0d42ade64679775e7a34e582cristy}
2396f034abbcb705540b0d42ade64679775e7a34e582cristy
23975a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickBooleanType LoadOpenCLLibrary(void)
2398b05dcc98d31306c326538effc895c502fb0be0cadirk{
23995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  openCL_library=(MagickLibrary *) AcquireMagickMemory(sizeof(MagickLibrary));
24005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (openCL_library == (MagickLibrary *) NULL)
24015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
24021dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy
24038f012e53de440db26b36e690e61d480e78249ab8dirk  if (BindOpenCLFunctions() == MagickFalse)
24045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
24055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      openCL_library=(MagickLibrary *)RelinquishMagickMemory(openCL_library);
24065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      return(MagickFalse);
24075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    }
2408b05dcc98d31306c326538effc895c502fb0be0cadirk
24095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickTrue);
2410b05dcc98d31306c326538effc895c502fb0be0cadirk}
2411f034abbcb705540b0d42ade64679775e7a34e582cristy
24125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
24135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
24155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
24165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
241721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   O p e n C L T e r m i n u s                                               %
24185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
24195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
24205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
24215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
24225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
24235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  AnnotateComponentTerminus() destroys the annotate component.
24245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
24255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the AnnotateComponentTerminus method is:
24265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
24275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      AnnotateComponentTerminus(void)
24285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
24295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
2430f034abbcb705540b0d42ade64679775e7a34e582cristy
24315a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickPrivate void OpenCLTerminus()
24325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
24335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  DumpOpenCLProfileData();
24345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (cache_directory != (char *) NULL)
24355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    cache_directory=DestroyString(cache_directory);
24365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (cache_directory_lock != (SemaphoreInfo *) NULL)
24375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    RelinquishSemaphoreInfo(&cache_directory_lock);
24385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (default_CLEnv != (MagickCLEnv) NULL)
24395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    default_CLEnv=RelinquishMagickCLEnv(default_CLEnv);
244021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if (openCL_lock != (SemaphoreInfo *) NULL)
244121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    RelinquishSemaphoreInfo(&openCL_lock);
24425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (openCL_library != (MagickLibrary *) NULL)
24435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    openCL_library=(MagickLibrary *)RelinquishMagickMemory(openCL_library);
2444f034abbcb705540b0d42ade64679775e7a34e582cristy}
2445f034abbcb705540b0d42ade64679775e7a34e582cristy
2446f034abbcb705540b0d42ade64679775e7a34e582cristy/*
2447f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2448f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
2449f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
2450f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
245121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   O p e n C L T h r o w M a g i c k E x c e p t i o n                       %
2452f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
2453f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
2454f034abbcb705540b0d42ade64679775e7a34e582cristy%                                                                             %
2455f034abbcb705540b0d42ade64679775e7a34e582cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2456f034abbcb705540b0d42ade64679775e7a34e582cristy%
24575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  OpenCLThrowMagickException logs an OpenCL exception as determined by the log
24585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  configuration file.  If an error occurs, MagickFalse is returned
24595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  otherwise MagickTrue.
24601dd96dac75e0789ee5aae01960aa046d1a2412b4Cristy%
24615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the OpenCLThrowMagickException method is:
2462f034abbcb705540b0d42ade64679775e7a34e582cristy%
24635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickBooleanType ThrowFileException(ExceptionInfo *exception,
24645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%        const char *module,const char *function,const size_t line,
24655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%        const ExceptionType severity,const char *tag,const char *format,...)
2466f034abbcb705540b0d42ade64679775e7a34e582cristy%
2467f034abbcb705540b0d42ade64679775e7a34e582cristy%  A description of each parameter follows:
2468f034abbcb705540b0d42ade64679775e7a34e582cristy%
24695a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o exception: the exception info.
24705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
24715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o filename: the source module filename.
2472f034abbcb705540b0d42ade64679775e7a34e582cristy%
24735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o function: the function name.
2474f034abbcb705540b0d42ade64679775e7a34e582cristy%
24755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o line: the line number of the source module.
2476f034abbcb705540b0d42ade64679775e7a34e582cristy%
24775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o severity: Specifies the numeric error category.
24785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
24795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o tag: the locale tag.
24805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
24815a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o format: the output format.
2482f034abbcb705540b0d42ade64679775e7a34e582cristy%
2483f034abbcb705540b0d42ade64679775e7a34e582cristy*/
2484f034abbcb705540b0d42ade64679775e7a34e582cristy
24855a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickPrivate MagickBooleanType OpenCLThrowMagickException(
24865a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLDevice device,ExceptionInfo *exception,const char *module,
24875a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const char *function,const size_t line,const ExceptionType severity,
24885a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const char *tag,const char *format,...)
24895a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
2490a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  MagickBooleanType
2491a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy    status;
2492a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy
24935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  assert(device != (MagickCLDevice) NULL);
2494a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  assert(exception != (ExceptionInfo *) NULL);
2495e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
2496a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy
24975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  status=MagickTrue;
24985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (severity != 0)
24995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  {
25005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    if (device->type == CL_DEVICE_TYPE_CPU)
25015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    {
2502a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy      /* Workaround for Intel OpenCL CPU runtime bug */
2503a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy      /* Turn off OpenCL when a problem is detected! */
25048f012e53de440db26b36e690e61d480e78249ab8dirk      if (strncmp(device->platform_name, "Intel",5) == 0)
25055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk        default_CLEnv->enabled=MagickFalse;
2506a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy    }
2507a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  }
2508a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy
2509a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy#ifdef OPENCLLOG_ENABLED
2510a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  {
2511a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy    va_list
2512a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy      operands;
2513a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy    va_start(operands,format);
25145a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status=ThrowMagickExceptionList(exception,module,function,line,severity,tag,
25155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      format,operands);
2516a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy    va_end(operands);
2517a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  }
2518a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy#else
2519a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  magick_unreferenced(module);
2520a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  magick_unreferenced(function);
2521a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  magick_unreferenced(line);
2522a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  magick_unreferenced(tag);
2523a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  magick_unreferenced(format);
2524a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy#endif
2525a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy
2526a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy  return(status);
2527a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy}
2528a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy
25295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
25305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25315a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
25325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
25335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
253421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   R e c o r d P r o f i l e D a t a                                         %
25355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
25365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
25375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
25385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
25405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  RecordProfileData() records profile data.
25415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
25425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the RecordProfileData method is:
25435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
25445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      void RecordProfileData(MagickCLDevice device,ProfiledKernels kernel,
25455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%        cl_event event)
25465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
25475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  A description of each parameter follows:
25485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
25495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device that did the operation.
25505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
25515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o event: the event that contains the profiling data.
25525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
25535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
25540c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
2555f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirkMagickPrivate MagickBooleanType RecordProfileData(MagickCLDevice device,
25567d42b3c11794313e25ede648463812545161de2ddirk  cl_kernel kernel,cl_event event)
25575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk{
25587d42b3c11794313e25ede648463812545161de2ddirk  char
25597d42b3c11794313e25ede648463812545161de2ddirk    *name;
25607d42b3c11794313e25ede648463812545161de2ddirk
25615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_int
25625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    status;
25630c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
25645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  cl_ulong
25655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    elapsed,
25665a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    end,
25675a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    start;
25685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
25697d42b3c11794313e25ede648463812545161de2ddirk  KernelProfileRecord
25707d42b3c11794313e25ede648463812545161de2ddirk    profile_record;
25717d42b3c11794313e25ede648463812545161de2ddirk
25727d42b3c11794313e25ede648463812545161de2ddirk  size_t
25737d42b3c11794313e25ede648463812545161de2ddirk    i,
25747d42b3c11794313e25ede648463812545161de2ddirk    length;
25757d42b3c11794313e25ede648463812545161de2ddirk
25767d42b3c11794313e25ede648463812545161de2ddirk  if (device->profile_kernels == MagickFalse)
2577f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk    return(MagickFalse);
2578f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk  status=openCL_library->clWaitForEvents(1,&event);
2579f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk  if (status != CL_SUCCESS)
2580f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk    return(MagickFalse);
25817d42b3c11794313e25ede648463812545161de2ddirk  status=openCL_library->clGetKernelInfo(kernel,CL_KERNEL_FUNCTION_NAME,0,NULL,
25827d42b3c11794313e25ede648463812545161de2ddirk    &length);
25837d42b3c11794313e25ede648463812545161de2ddirk  if (status != CL_SUCCESS)
2584f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk    return(MagickTrue);
25857d42b3c11794313e25ede648463812545161de2ddirk  name=AcquireQuantumMemory(length,sizeof(*name));
2586f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk  if (name == (char *) NULL)
2587f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk    return(MagickTrue);
2588f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk  start=end=elapsed=0;
258966acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  status=openCL_library->clGetKernelInfo(kernel,CL_KERNEL_FUNCTION_NAME,length,
259066acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    name,(size_t *) NULL);
259166acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  status|=openCL_library->clGetEventProfilingInfo(event,
25925a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&start,NULL);
259366acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  status|=openCL_library->clGetEventProfilingInfo(event,
25945a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&end,NULL);
25955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (status != CL_SUCCESS)
25967d42b3c11794313e25ede648463812545161de2ddirk    {
25977d42b3c11794313e25ede648463812545161de2ddirk      name=DestroyString(name);
2598f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk      return(MagickTrue);
25997d42b3c11794313e25ede648463812545161de2ddirk    }
26005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  start/=1000; // usecs
26015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  end/=1000;   // usecs
26025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  elapsed=end-start;
26035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  LockSemaphoreInfo(device->lock);
26047d42b3c11794313e25ede648463812545161de2ddirk  i=0;
26057d42b3c11794313e25ede648463812545161de2ddirk  profile_record=(KernelProfileRecord) NULL;
26067d42b3c11794313e25ede648463812545161de2ddirk  if (device->profile_records != (KernelProfileRecord *) NULL)
26077d42b3c11794313e25ede648463812545161de2ddirk    {
2608f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk      while (device->profile_records[i] != (KernelProfileRecord) NULL)
26097d42b3c11794313e25ede648463812545161de2ddirk      {
261083b804e8c3520d3092137d7da2250d175eb73c5cdirk        if (LocaleCompare(device->profile_records[i]->kernel_name,name) == 0)
26117d42b3c11794313e25ede648463812545161de2ddirk          {
26127d42b3c11794313e25ede648463812545161de2ddirk            profile_record=device->profile_records[i];
26137d42b3c11794313e25ede648463812545161de2ddirk            break;
26147d42b3c11794313e25ede648463812545161de2ddirk          }
26157d42b3c11794313e25ede648463812545161de2ddirk        i++;
26167d42b3c11794313e25ede648463812545161de2ddirk      }
26177d42b3c11794313e25ede648463812545161de2ddirk    }
2618f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk  if (profile_record != (KernelProfileRecord) NULL)
2619f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk    name=DestroyString(name);
2620f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk  else
26217d42b3c11794313e25ede648463812545161de2ddirk    {
26227d42b3c11794313e25ede648463812545161de2ddirk      profile_record=AcquireMagickMemory(sizeof(*profile_record));
26237d42b3c11794313e25ede648463812545161de2ddirk      (void) ResetMagickMemory(profile_record,0,sizeof(*profile_record));
2624f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk      profile_record->kernel_name=name;
262583b804e8c3520d3092137d7da2250d175eb73c5cdirk      device->profile_records=ResizeMagickMemory(device->profile_records,(i+2)*
262666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk        sizeof(*device->profile_records));
26277d42b3c11794313e25ede648463812545161de2ddirk      device->profile_records[i]=profile_record;
26287d42b3c11794313e25ede648463812545161de2ddirk      device->profile_records[i+1]=(KernelProfileRecord) NULL;
26297d42b3c11794313e25ede648463812545161de2ddirk    }
26307d42b3c11794313e25ede648463812545161de2ddirk  if ((elapsed < profile_record->min) || (profile_record->count == 0))
26317d42b3c11794313e25ede648463812545161de2ddirk    profile_record->min=elapsed;
26327d42b3c11794313e25ede648463812545161de2ddirk  if (elapsed > profile_record->max)
26337d42b3c11794313e25ede648463812545161de2ddirk    profile_record->max=elapsed;
26347d42b3c11794313e25ede648463812545161de2ddirk  profile_record->total+=elapsed;
26357d42b3c11794313e25ede648463812545161de2ddirk  profile_record->count+=1;
26365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  UnlockSemaphoreInfo(device->lock);
2637f0ae4ef12c8f73b05afe55f79e1429717c1deb58dirk  return(MagickTrue);
26380c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy}
26390c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
26405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
26415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
26435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
26445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
264566acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk+  R e l e a s e O p e n C L C o m m a n d Q u e u e                          %
264666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%                                                                             %
264766acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%                                                                             %
264866acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%                                                                             %
264966acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265066acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%
265166acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%  ReleaseOpenCLCommandQueue() releases the OpenCL command queue
265266acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%
265366acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%  The format of the ReleaseOpenCLCommandQueue method is:
265466acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%
265566acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%      void ReleaseOpenCLCommandQueue(MagickCLDevice device,
265666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%        cl_command_queue queue)
265766acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%
265866acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%  A description of each parameter follows:
265966acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%
266066acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%    o device: the OpenCL device.
266166acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%
266266acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%    o queue: the OpenCL queue to be released.
266366acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk*/
266466acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk
266566acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirkMagickPrivate void ReleaseOpenCLCommandQueue(MagickCLDevice device,
266666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  cl_command_queue queue)
266766acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk{
266866acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  if (queue == (cl_command_queue) NULL)
266966acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    return;
267066acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk
267166acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  assert(device != (MagickCLDevice) NULL);
267266acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  LockSemaphoreInfo(device->lock);
267366acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  if ((device->profile_kernels != MagickFalse) ||
267466acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      (device->command_queues_index >= MAGICKCORE_OPENCL_COMMAND_QUEUES-1))
267566acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    {
267666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      UnlockSemaphoreInfo(device->lock);
267766acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      openCL_library->clFinish(queue);
267866acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      (void) openCL_library->clReleaseCommandQueue(queue);
267966acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    }
268066acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  else
268166acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    {
268266acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      openCL_library->clFlush(queue);
268366acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      device->command_queues[++device->command_queues_index]=queue;
268466acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk      UnlockSemaphoreInfo(device->lock);
268566acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    }
268666acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk}
268766acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk
268866acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk/*
268966acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269066acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%                                                                             %
269166acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%                                                                             %
269266acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk%                                                                             %
269321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   R e l e a s e  M a g i c k C L D e v i c e                                %
2694c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2695c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2696c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2697c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2698c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2699c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%  ReleaseOpenCLDevice() returns the OpenCL device to the environment
2700c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2701c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%  The format of the ReleaseOpenCLDevice method is:
2702c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
270321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%      void ReleaseOpenCLDevice(MagickCLDevice device)
2704c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2705c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%  A description of each parameter follows:
2706c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2707c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%    o device: the OpenCL device to be released.
2708c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2709c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk*/
2710c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
271121dc0310cdaa5cc6034a1e100746706f5ec089ebdirkMagickPrivate void ReleaseOpenCLDevice(MagickCLDevice device)
2712c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk{
271321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  assert(device != (MagickCLDevice) NULL);
271421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  LockSemaphoreInfo(openCL_lock);
2715c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  device->requested--;
271621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  UnlockSemaphoreInfo(openCL_lock);
271721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
271821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
271921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk/*
272021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
272221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
272321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
272421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   R e l i n q u i s h M a g i c k C L C a c h e I n f o                     %
272521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
272621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
272721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%                                                                             %
272821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
273021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  RelinquishMagickCLCacheInfo() frees memory acquired with
273121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  AcquireMagickCLCacheInfo()
273221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
273321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  The format of the RelinquishMagickCLCacheInfo method is:
273421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
273521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%      MagickCLCacheInfo RelinquishMagickCLCacheInfo(MagickCLCacheInfo info,
273621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%        const MagickBooleanType relinquish_pixels)
273721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
273821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%  A description of each parameter follows:
273921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
274021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o info: the OpenCL cache info.
274121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
274221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%    o relinquish_pixels: the pixels will be relinquish when set to true.
274321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk%
274421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk*/
27455fb2395d563883c0558115e7c1ae930d6ca5c942dirkstatic void DestroyMagickCLCacheInfo(MagickCLCacheInfo info)
27465fb2395d563883c0558115e7c1ae930d6ca5c942dirk{
27475fb2395d563883c0558115e7c1ae930d6ca5c942dirk  ssize_t
27485fb2395d563883c0558115e7c1ae930d6ca5c942dirk    i;
27495fb2395d563883c0558115e7c1ae930d6ca5c942dirk
27505fb2395d563883c0558115e7c1ae930d6ca5c942dirk  for (i=0; i < (ssize_t) info->event_count; i++)
27515fb2395d563883c0558115e7c1ae930d6ca5c942dirk    openCL_library->clReleaseEvent(info->events[i]);
275266acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk  info->events=(cl_event *) RelinquishMagickMemory(info->events);
27535fb2395d563883c0558115e7c1ae930d6ca5c942dirk  if (info->buffer != (cl_mem) NULL)
275466acef5cd2089f66bbdb7dc7b3b18e2eb6d792aedirk    openCL_library->clReleaseMemObject(info->buffer);
27555fb2395d563883c0558115e7c1ae930d6ca5c942dirk  ReleaseOpenCLDevice(info->device);
27565fb2395d563883c0558115e7c1ae930d6ca5c942dirk  RelinquishMagickMemory(info);
27575fb2395d563883c0558115e7c1ae930d6ca5c942dirk}
275821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
27595fb2395d563883c0558115e7c1ae930d6ca5c942dirkstatic void CL_API_CALL DestroyMagickCLCacheInfoAndPixels(
27605fb2395d563883c0558115e7c1ae930d6ca5c942dirk  cl_event magick_unused(event),
27615fb2395d563883c0558115e7c1ae930d6ca5c942dirk  cl_int magick_unused(event_command_exec_status),void *user_data)
276221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
276321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  MagickCLCacheInfo
276421dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    info;
276521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
276621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  magick_unreferenced(event);
276721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  magick_unreferenced(event_command_exec_status);
276821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  info=(MagickCLCacheInfo) user_data;
276921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  (void) RelinquishAlignedMemory(info->pixels);
277021dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  RelinquishMagickResource(MemoryResource,info->length);
277121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  DestroyMagickCLCacheInfo(info);
277221dc0310cdaa5cc6034a1e100746706f5ec089ebdirk}
277321dc0310cdaa5cc6034a1e100746706f5ec089ebdirk
277421dc0310cdaa5cc6034a1e100746706f5ec089ebdirkMagickPrivate MagickCLCacheInfo RelinquishMagickCLCacheInfo(
277521dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  MagickCLCacheInfo info,const MagickBooleanType relinquish_pixels)
277621dc0310cdaa5cc6034a1e100746706f5ec089ebdirk{
277721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  if (info == (MagickCLCacheInfo) NULL)
277821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    return((MagickCLCacheInfo) NULL);
27795fb2395d563883c0558115e7c1ae930d6ca5c942dirk  if (relinquish_pixels != MagickFalse)
27805fb2395d563883c0558115e7c1ae930d6ca5c942dirk    {
27815fb2395d563883c0558115e7c1ae930d6ca5c942dirk      if (info->event_count > 0)
27825fb2395d563883c0558115e7c1ae930d6ca5c942dirk        openCL_library->clSetEventCallback(info->events[info->event_count-1],
27835fb2395d563883c0558115e7c1ae930d6ca5c942dirk          CL_COMPLETE,&DestroyMagickCLCacheInfoAndPixels,info);
27845fb2395d563883c0558115e7c1ae930d6ca5c942dirk      else
27855fb2395d563883c0558115e7c1ae930d6ca5c942dirk        DestroyMagickCLCacheInfoAndPixels((cl_event) NULL,0,info);
27865fb2395d563883c0558115e7c1ae930d6ca5c942dirk    }
278721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  else
278821dc0310cdaa5cc6034a1e100746706f5ec089ebdirk    DestroyMagickCLCacheInfo(info);
278921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  return((MagickCLCacheInfo) NULL);
2790c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk}
2791c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2792c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk/*
2793c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2794c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2795c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2796c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
27975a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   R e l i n q u i s h M a g i c k C L D e v i c e                           %
27985a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
27995a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28005a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28025a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28035a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  RelinquishMagickCLDevice() releases the OpenCL device
28045a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28055a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the RelinquishMagickCLDevice method is:
28065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28075a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickCLDevice RelinquishMagickCLDevice(MagickCLDevice device)
28085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  A description of each parameter follows:
28105a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28115a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device to be released.
28125a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
28140c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
28155a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickCLDevice RelinquishMagickCLDevice(MagickCLDevice device)
28160c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
28175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device == (MagickCLDevice) NULL)
28185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return((MagickCLDevice) NULL);
28195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk
28208f012e53de440db26b36e690e61d480e78249ab8dirk  device->platform_name=RelinquishMagickMemory(device->platform_name);
28215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  device->name=RelinquishMagickMemory(device->name);
28225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  device->version=RelinquishMagickMemory(device->version);
28235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device->program != (cl_program) NULL)
28245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (void) openCL_library->clReleaseProgram(device->program);
28255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  while (device->command_queues_index >= 0)
28265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    (void) openCL_library->clReleaseCommandQueue(
28275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk      device->command_queues[device->command_queues_index--]);
28285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  RelinquishSemaphoreInfo(&device->lock);
28295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return((MagickCLDevice) RelinquishMagickMemory(device));
28300c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy}
28310c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
28325a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
28335a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28365a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   R e l i n q u i s h M a g i c k C L E n v                                 %
28385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28425a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28435a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  RelinquishMagickCLEnv() releases the OpenCL environment
28445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28455a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the RelinquishMagickCLEnv method is:
28465a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      MagickCLEnv RelinquishMagickCLEnv(MagickCLEnv device)
28485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  A description of each parameter follows:
28505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o clEnv: the OpenCL environment to be released.
28525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
28535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
28540c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
28555a2575faca105cecbf44bc70f7f8a177f6c4f674dirkstatic MagickCLEnv RelinquishMagickCLEnv(MagickCLEnv clEnv)
28560c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
28575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv == (MagickCLEnv) NULL)
28585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return((MagickCLEnv) NULL);
2859f034abbcb705540b0d42ade64679775e7a34e582cristy
28605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  RelinquishSemaphoreInfo(&clEnv->lock);
28615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  RelinquishMagickCLDevices(clEnv);
28628f012e53de440db26b36e690e61d480e78249ab8dirk  if (clEnv->contexts != (cl_context *) NULL)
28638f012e53de440db26b36e690e61d480e78249ab8dirk    {
28648f012e53de440db26b36e690e61d480e78249ab8dirk      ssize_t
28658f012e53de440db26b36e690e61d480e78249ab8dirk        i;
28668f012e53de440db26b36e690e61d480e78249ab8dirk
28678f012e53de440db26b36e690e61d480e78249ab8dirk      for (i=0; i < clEnv->number_contexts; i++)
28688f012e53de440db26b36e690e61d480e78249ab8dirk         (void) openCL_library->clReleaseContext(clEnv->contexts[i]);
28698f012e53de440db26b36e690e61d480e78249ab8dirk      clEnv->contexts=(cl_context *) RelinquishMagickMemory(clEnv->contexts);
28708f012e53de440db26b36e690e61d480e78249ab8dirk    }
28715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return((MagickCLEnv) RelinquishMagickMemory(clEnv));
2872f034abbcb705540b0d42ade64679775e7a34e582cristy}
2873f034abbcb705540b0d42ade64679775e7a34e582cristy
28745a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
28755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
28785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
287921dc0310cdaa5cc6034a1e100746706f5ec089ebdirk+   R e q u e s t O p e n C L D e v i c e                                     %
2880c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2881c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2882c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2883c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2884c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2885c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%  RequestOpenCLDevice() returns one of the enabled OpenCL devices.
2886c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2887c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%  The format of the RequestOpenCLDevice method is:
2888c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2889c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%      MagickCLDevice RequestOpenCLDevice(MagickCLEnv clEnv)
2890c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2891c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%  A description of each parameter follows:
2892c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%
2893c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%    o clEnv: the OpenCL environment.
2894c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk*/
2895c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2896c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirkMagickPrivate MagickCLDevice RequestOpenCLDevice(MagickCLEnv clEnv)
2897c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk{
2898c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  MagickCLDevice
2899c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    device;
2900c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2901c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  double
2902c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    score,
2903c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    best_score;
2904c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2905c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  size_t
2906c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    i;
2907c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2908c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  if (clEnv == (MagickCLEnv) NULL)
2909c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    return((MagickCLDevice) NULL);
2910c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2911c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  if (clEnv->number_devices == 1)
2912c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  {
2913c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    if (clEnv->devices[0]->enabled)
2914c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk      return(clEnv->devices[0]);
2915c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    else
2916c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk      return((MagickCLDevice) NULL);
2917c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  }
2918c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2919c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  device=(MagickCLDevice) NULL;
2920c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  best_score=0.0;
292121dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  LockSemaphoreInfo(openCL_lock);
2922c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  for (i = 0; i < clEnv->number_devices; i++)
2923c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  {
2924c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    if (clEnv->devices[i]->enabled == MagickFalse)
2925c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk      continue;
2926c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2927c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    score=clEnv->devices[i]->score+(clEnv->devices[i]->score*
2928c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk      clEnv->devices[i]->requested);
2929c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    if ((device == (MagickCLDevice) NULL) || (score < best_score))
2930c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    {
2931c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk      device=clEnv->devices[i];
2932c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk      best_score=score;
2933c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    }
2934c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  }
2935c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  if (device != (MagickCLDevice)NULL)
2936c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk    device->requested++;
293721dc0310cdaa5cc6034a1e100746706f5ec089ebdirk  UnlockSemaphoreInfo(openCL_lock);
2938c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2939c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk  return(device);
2940c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk}
2941c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk
2942c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk/*
2943c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2944c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2945c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
2946c5a1b3fdf708febd3b38129d6b00469f173b7bc3dirk%                                                                             %
29475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   S e t O p e n C L D e v i c e E n a b l e d                               %
29485a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
29495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
29505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
29515a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29525a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
29535a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  SetOpenCLDeviceEnabled() can be used to enable or disabled the device.
29545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
29555a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the SetOpenCLDeviceEnabled method is:
29565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
29577d42b3c11794313e25ede648463812545161de2ddirk%      void SetOpenCLDeviceEnabled(MagickCLDevice device,
29585a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%        MagickBooleanType value)
29595a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
29605a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  A description of each parameter follows:
29615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
29625a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o device: the OpenCL device.
29635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
29645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o value: determines if the device should be enabled or disabled.
29655a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
2966f034abbcb705540b0d42ade64679775e7a34e582cristy
29677d42b3c11794313e25ede648463812545161de2ddirkMagickExport void SetOpenCLDeviceEnabled(MagickCLDevice device,
29685a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickBooleanType value)
2969f034abbcb705540b0d42ade64679775e7a34e582cristy{
29705a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (device == (MagickCLDevice) NULL)
29715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return;
29725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  device->enabled=value;
2973f034abbcb705540b0d42ade64679775e7a34e582cristy}
2974f034abbcb705540b0d42ade64679775e7a34e582cristy
29755a2575faca105cecbf44bc70f7f8a177f6c4f674dirk/*
29765a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
29785a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
29795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
29807d42b3c11794313e25ede648463812545161de2ddirk%   S e t O p e n C L K e r n e l P r o f i l e E n a b l e d                 %
29817d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
29827d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
29837d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
29847d42b3c11794313e25ede648463812545161de2ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29857d42b3c11794313e25ede648463812545161de2ddirk%
29867d42b3c11794313e25ede648463812545161de2ddirk%  SetOpenCLKernelProfileEnabled() can be used to enable or disabled the
29877d42b3c11794313e25ede648463812545161de2ddirk%  kernel profiling of a device.
29887d42b3c11794313e25ede648463812545161de2ddirk%
29897d42b3c11794313e25ede648463812545161de2ddirk%  The format of the SetOpenCLKernelProfileEnabled method is:
29907d42b3c11794313e25ede648463812545161de2ddirk%
29917d42b3c11794313e25ede648463812545161de2ddirk%      void SetOpenCLKernelProfileEnabled(MagickCLDevice device,
29927d42b3c11794313e25ede648463812545161de2ddirk%        MagickBooleanType value)
29937d42b3c11794313e25ede648463812545161de2ddirk%
29947d42b3c11794313e25ede648463812545161de2ddirk%  A description of each parameter follows:
29957d42b3c11794313e25ede648463812545161de2ddirk%
29967d42b3c11794313e25ede648463812545161de2ddirk%    o device: the OpenCL device.
29977d42b3c11794313e25ede648463812545161de2ddirk%
29987d42b3c11794313e25ede648463812545161de2ddirk%    o value: determines if kernel profiling for the device should be enabled
29997d42b3c11794313e25ede648463812545161de2ddirk%             or disabled.
30007d42b3c11794313e25ede648463812545161de2ddirk*/
30017d42b3c11794313e25ede648463812545161de2ddirk
30027d42b3c11794313e25ede648463812545161de2ddirkMagickExport void SetOpenCLKernelProfileEnabled(MagickCLDevice device,
30037d42b3c11794313e25ede648463812545161de2ddirk  const MagickBooleanType value)
30047d42b3c11794313e25ede648463812545161de2ddirk{
30057d42b3c11794313e25ede648463812545161de2ddirk  if (device == (MagickCLDevice) NULL)
30067d42b3c11794313e25ede648463812545161de2ddirk    return;
30077d42b3c11794313e25ede648463812545161de2ddirk  device->profile_kernels=value;
30087d42b3c11794313e25ede648463812545161de2ddirk}
30097d42b3c11794313e25ede648463812545161de2ddirk
30107d42b3c11794313e25ede648463812545161de2ddirk/*
30117d42b3c11794313e25ede648463812545161de2ddirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30127d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
30137d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
30147d42b3c11794313e25ede648463812545161de2ddirk%                                                                             %
30155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%   S e t O p e n C L E n a b l e d                                           %
30165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
30175a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
30185a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%                                                                             %
30195a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30205a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
30215a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  SetOpenCLEnabled() can be used to enable or disable OpenCL acceleration.
30225a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
30235a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  The format of the SetOpenCLEnabled method is:
30245a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
30255a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%      void SetOpenCLEnabled(MagickBooleanType)
30265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
30275a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%  A description of each parameter follows:
30285a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%
30295a2575faca105cecbf44bc70f7f8a177f6c4f674dirk%    o value: specify true to enable OpenCL acceleration
30305a2575faca105cecbf44bc70f7f8a177f6c4f674dirk*/
3031f034abbcb705540b0d42ade64679775e7a34e582cristy
30325a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport MagickBooleanType SetOpenCLEnabled(const MagickBooleanType value)
3033f034abbcb705540b0d42ade64679775e7a34e582cristy{
30345a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  MagickCLEnv
30355a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    clEnv;
3036f034abbcb705540b0d42ade64679775e7a34e582cristy
30375a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  clEnv=GetCurrentOpenCLEnv();
30385a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (clEnv == (MagickCLEnv) NULL)
30395a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    return(MagickFalse);
30405a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  clEnv->enabled=value;
30415a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(clEnv->enabled);
3042f034abbcb705540b0d42ade64679775e7a34e582cristy}
3043f034abbcb705540b0d42ade64679775e7a34e582cristy
30445a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#else
3045f034abbcb705540b0d42ade64679775e7a34e582cristy
30465a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport double GetOpenCLDeviceBenchmarkScore(
30475a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickCLDevice magick_unused(device))
3048f034abbcb705540b0d42ade64679775e7a34e582cristy{
30495a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  magick_unreferenced(device);
30505a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(0.0);
3051f034abbcb705540b0d42ade64679775e7a34e582cristy}
3052f034abbcb705540b0d42ade64679775e7a34e582cristy
30535a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport MagickBooleanType GetOpenCLDeviceEnabled(
30545a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickCLDevice magick_unused(device))
3055f034abbcb705540b0d42ade64679775e7a34e582cristy{
30565a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  magick_unreferenced(device);
30575a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickFalse);
3058f034abbcb705540b0d42ade64679775e7a34e582cristy}
3059f034abbcb705540b0d42ade64679775e7a34e582cristy
30605a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport const char *GetOpenCLDeviceName(
30615a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickCLDevice magick_unused(device))
3062f034abbcb705540b0d42ade64679775e7a34e582cristy{
30635a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  magick_unreferenced(device);
30645a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return((const char *) NULL);
3065f034abbcb705540b0d42ade64679775e7a34e582cristy}
3066f034abbcb705540b0d42ade64679775e7a34e582cristy
30677d42b3c11794313e25ede648463812545161de2ddirkMagickExport MagickCLDevice *GetOpenCLDevices(size_t *length,
30687d42b3c11794313e25ede648463812545161de2ddirk  ExceptionInfo *magick_unused(exception))
3069f034abbcb705540b0d42ade64679775e7a34e582cristy{
30707d42b3c11794313e25ede648463812545161de2ddirk  magick_unreferenced(exception);
30715a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  if (length != (size_t *) NULL)
30725a2575faca105cecbf44bc70f7f8a177f6c4f674dirk    *length=0;
30735a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return((MagickCLDevice *) NULL);
3074f034abbcb705540b0d42ade64679775e7a34e582cristy}
3075f034abbcb705540b0d42ade64679775e7a34e582cristy
30765a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport MagickCLDeviceType GetOpenCLDeviceType(
30775a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickCLDevice magick_unused(device))
3078a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy{
30795a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  magick_unreferenced(device);
30805a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(UndefinedCLDeviceType);
3081a22457d1cb46b3681b0758006816ffc2a7fcf1f7cristy}
30820c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
30837d42b3c11794313e25ede648463812545161de2ddirkMagickExport const KernelProfileRecord *GetOpenCLKernelProfileRecords(
3084669ff2735bdccdd746b46faa1c7ac85113a30670dirk  const MagickCLDevice magick_unused(device),size_t *length)
30857d42b3c11794313e25ede648463812545161de2ddirk{
3086669ff2735bdccdd746b46faa1c7ac85113a30670dirk  magick_unreferenced(device);
30877d42b3c11794313e25ede648463812545161de2ddirk  if (length != (size_t *) NULL)
30887d42b3c11794313e25ede648463812545161de2ddirk    *length=0;
30893c60ad61643e0273f1b07599afd9fdc3238a638fdirk  return((const KernelProfileRecord *) NULL);
30907d42b3c11794313e25ede648463812545161de2ddirk}
30917d42b3c11794313e25ede648463812545161de2ddirk
30925a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport const char *GetOpenCLDeviceVersion(
30935a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickCLDevice magick_unused(device))
30940c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
30955a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  magick_unreferenced(device);
30965a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return((const char *) NULL);
30970c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy}
30980c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
30995a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport MagickBooleanType GetOpenCLEnabled(void)
31000c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
31015a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickFalse);
31020c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy}
31030c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
31045a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport void SetOpenCLDeviceEnabled(
31057d42b3c11794313e25ede648463812545161de2ddirk  MagickCLDevice magick_unused(device),
31065a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickBooleanType magick_unused(value))
31070c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
31085a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  magick_unreferenced(device);
31095a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  magick_unreferenced(value);
31100c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy}
31110c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy
31125a2575faca105cecbf44bc70f7f8a177f6c4f674dirkMagickExport MagickBooleanType SetOpenCLEnabled(
31135a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  const MagickBooleanType magick_unused(value))
31140c832c68ae950d35e8166671cdcb29ec46ef7b3fcristy{
31155a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  magick_unreferenced(value);
31165a2575faca105cecbf44bc70f7f8a177f6c4f674dirk  return(MagickFalse);
3117f034abbcb705540b0d42ade64679775e7a34e582cristy}
31189973174de229bd4c4a8b947ea7acb19f4447dc5ddirk
31193c60ad61643e0273f1b07599afd9fdc3238a638fdirkMagickExport void SetOpenCLKernelProfileEnabled(
31207d42b3c11794313e25ede648463812545161de2ddirk  MagickCLDevice magick_unused(device),
31217d42b3c11794313e25ede648463812545161de2ddirk  const MagickBooleanType magick_unused(value))
31227d42b3c11794313e25ede648463812545161de2ddirk{
31237d42b3c11794313e25ede648463812545161de2ddirk  magick_unreferenced(device);
31247d42b3c11794313e25ede648463812545161de2ddirk  magick_unreferenced(value);
31257d42b3c11794313e25ede648463812545161de2ddirk}
31265a2575faca105cecbf44bc70f7f8a177f6c4f674dirk#endif