title: Getting NVIDIA OpenCL to work on OpenCV 2.4.10
body: <p>I am trying to get a sample OpenCL code from OpenCV directories to work. The sample code is "squares.cpp":</p>
  
  <pre><code>// The "Square Detector" program.
  // It loads several images sequentially and tries to find squares in
  // each image
  
  #include "opencv2/core/core.hpp"
  #include "opencv2/imgproc/imgproc.hpp"
  #include "opencv2/highgui/highgui.hpp"
  #include "opencv2/ocl/ocl.hpp"
  #include &lt;iostream&gt;
  #include &lt;math.h&gt;
  #include &lt;string.h&gt;
  
  using namespace cv;
  using namespace std;
  
  #define ACCURACY_CHECK
  
  #ifdef ACCURACY_CHECK
  // check if two vectors of vector of points are near or not
  // prior assumption is that they are in correct order
  static bool checkPoints(
      vector&lt; vector&lt;Point&gt; &gt; set1,
      vector&lt; vector&lt;Point&gt; &gt; set2,
      int maxDiff = 5)
  {
      if(set1.size() != set2.size())
      {
          return false;
      }
  
      for(vector&lt; vector&lt;Point&gt; &gt;::iterator it1 = set1.begin(), it2 = set2.begin();
              it1 &lt; set1.end() &amp;&amp; it2 &lt; set2.end(); it1 ++, it2 ++)
      {
          vector&lt;Point&gt; pts1 = *it1;
          vector&lt;Point&gt; pts2 = *it2;
  
  
          if(pts1.size() != pts2.size())
          {
              return false;
          }
          for(size_t i = 0; i &lt; pts1.size(); i ++)
          {
              Point pt1 = pts1[i], pt2 = pts2[i];
              if(std::abs(pt1.x - pt2.x) &gt; maxDiff ||
                      std::abs(pt1.y - pt2.y) &gt; maxDiff)
              {
                  return false;
              }
          }
      }
      return true;
  }
  #endif
  
  int thresh = 50, N = 11;
  const char* wndname = "OpenCL Square Detection Demo";
  
  
  // helper function:
  // finds a cosine of angle between vectors
  // from pt0-&gt;pt1 and from pt0-&gt;pt2
  static double angle( Point pt1, Point pt2, Point pt0 )
  {
      double dx1 = pt1.x - pt0.x;
      double dy1 = pt1.y - pt0.y;
      double dx2 = pt2.x - pt0.x;
      double dy2 = pt2.y - pt0.y;
      return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
  }
  
  
  // returns sequence of squares detected on the image.
  // the sequence is stored in the specified memory storage
  static void findSquares( const Mat&amp; image, vector&lt;vector&lt;Point&gt; &gt;&amp; squares )
  {
      squares.clear();
      Mat pyr, timg, gray0(image.size(), CV_8U), gray;
  
      // down-scale and upscale the image to filter out the noise
      pyrDown(image, pyr, Size(image.cols/2, image.rows/2));
      pyrUp(pyr, timg, image.size());
      vector&lt;vector&lt;Point&gt; &gt; contours;
  
      // find squares in every color plane of the image
      for( int c = 0; c &lt; 3; c++ )
      {
          int ch[] = {c, 0};
          mixChannels(&amp;timg, 1, &amp;gray0, 1, ch, 1);
  
          // try several threshold levels
          for( int l = 0; l &lt; N; l++ )
          {
              // hack: use Canny instead of zero threshold level.
              // Canny helps to catch squares with gradient shading
              if( l == 0 )
              {
                  // apply Canny. Take the upper threshold from slider
                  // and set the lower to 0 (which forces edges merging)
                  Canny(gray0, gray, 0, thresh, 5);
                  // dilate canny output to remove potential
                  // holes between edge segments
                  dilate(gray, gray, Mat(), Point(-1,-1));
              }
              else
              {
                  // apply threshold if l!=0:
                  //     tgray(x,y) = gray(x,y) &lt; (l+1)*255/N ? 255 : 0
                  cv::threshold(gray0, gray, (l+1)*255/N, 255, THRESH_BINARY);
              }
  
              // find contours and store them all as a list
              findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
  
              vector&lt;Point&gt; approx;
  
              // test each contour
              for( size_t i = 0; i &lt; contours.size(); i++ )
              {
                  // approximate contour with accuracy proportional
                  // to the contour perimeter
                  approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
  
                  // square contours should have 4 vertices after approximation
                  // relatively large area (to filter out noisy contours)
                  // and be convex.
                  // Note: absolute value of an area is used because
                  // area may be positive or negative - in accordance with the
                  // contour orientation
                  if( approx.size() == 4 &amp;&amp;
                          fabs(contourArea(Mat(approx))) &gt; 1000 &amp;&amp;
                          isContourConvex(Mat(approx)) )
                  {
                      double maxCosine = 0;
  
                      for( int j = 2; j &lt; 5; j++ )
                      {
                          // find the maximum cosine of the angle between joint edges
                          double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                          maxCosine = MAX(maxCosine, cosine);
                      }
  
                      // if cosines of all angles are small
                      // (all angles are ~90 degree) then write quandrange
                      // vertices to resultant sequence
                      if( maxCosine &lt; 0.3 )
                          squares.push_back(approx);
                  }
              }
          }
      }
  }
  
  
  // returns sequence of squares detected on the image.
  // the sequence is stored in the specified memory storage
  static void findSquares_ocl( const Mat&amp; image, vector&lt;vector&lt;Point&gt; &gt;&amp; squares )
  {
      squares.clear();
  
      Mat gray;
      cv::ocl::oclMat pyr_ocl, timg_ocl, gray0_ocl, gray_ocl;
  
      // down-scale and upscale the image to filter out the noise
      ocl::pyrDown(ocl::oclMat(image), pyr_ocl);
      ocl::pyrUp(pyr_ocl, timg_ocl);
  
      vector&lt;vector&lt;Point&gt; &gt; contours;
      vector&lt;cv::ocl::oclMat&gt; gray0s;
      ocl::split(timg_ocl, gray0s); // split 3 channels into a vector of oclMat
      // find squares in every color plane of the image
      for( int c = 0; c &lt; 3; c++ )
      {
          gray0_ocl = gray0s[c];
          // try several threshold levels
          for( int l = 0; l &lt; N; l++ )
          {
              // hack: use Canny instead of zero threshold level.
              // Canny helps to catch squares with gradient shading
              if( l == 0 )
              {
                  // do canny on OpenCL device
                  // apply Canny. Take the upper threshold from slider
                  // and set the lower to 0 (which forces edges merging)
                  cv::ocl::Canny(gray0_ocl, gray_ocl, 0, thresh, 5);
                  // dilate canny output to remove potential
                  // holes between edge segments
                  ocl::dilate(gray_ocl, gray_ocl, Mat(), Point(-1,-1));
                  gray = Mat(gray_ocl);
              }
              else
              {
                  // apply threshold if l!=0:
                  //     tgray(x,y) = gray(x,y) &lt; (l+1)*255/N ? 255 : 0
                  cv::ocl::threshold(gray0_ocl, gray_ocl, (l+1)*255/N, 255, THRESH_BINARY);
                  gray = gray_ocl;
              }
  
              // find contours and store them all as a list
              findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
  
              vector&lt;Point&gt; approx;
              // test each contour
              for( size_t i = 0; i &lt; contours.size(); i++ )
              {
                  // approximate contour with accuracy proportional
                  // to the contour perimeter
                  approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);
  
                  // square contours should have 4 vertices after approximation
                  // relatively large area (to filter out noisy contours)
                  // and be convex.
                  // Note: absolute value of an area is used because
                  // area may be positive or negative - in accordance with the
                  // contour orientation
                  if( approx.size() == 4 &amp;&amp;
                          fabs(contourArea(Mat(approx))) &gt; 1000 &amp;&amp;
                          isContourConvex(Mat(approx)) )
                  {
                      double maxCosine = 0;
                      for( int j = 2; j &lt; 5; j++ )
                      {
                          // find the maximum cosine of the angle between joint edges
                          double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1]));
                          maxCosine = MAX(maxCosine, cosine);
                      }
  
                      // if cosines of all angles are small
                      // (all angles are ~90 degree) then write quandrange
                      // vertices to resultant sequence
                      if( maxCosine &lt; 0.3 )
                          squares.push_back(approx);
                  }
              }
          }
      }
  }
  
  
  // the function draws all the squares in the image
  static void drawSquares( Mat&amp; image, const vector&lt;vector&lt;Point&gt; &gt;&amp; squares )
  {
      for( size_t i = 0; i &lt; squares.size(); i++ )
      {
          const Point* p = &amp;squares[i][0];
          int n = (int)squares[i].size();
          polylines(image, &amp;p, &amp;n, 1, true, Scalar(0,255,0), 3, CV_AA);
      }
  }
  
  
  // draw both pure-C++ and ocl square results onto a single image
  static Mat drawSquaresBoth( const Mat&amp; image,
                              const vector&lt;vector&lt;Point&gt; &gt;&amp; sqsCPP,
                              const vector&lt;vector&lt;Point&gt; &gt;&amp; sqsOCL
  )
  {
      Mat imgToShow(Size(image.cols * 2, image.rows), image.type());
      Mat lImg = imgToShow(Rect(Point(0, 0), image.size()));
      Mat rImg = imgToShow(Rect(Point(image.cols, 0), image.size()));
      image.copyTo(lImg);
      image.copyTo(rImg);
      drawSquares(lImg, sqsCPP);
      drawSquares(rImg, sqsOCL);
      float fontScale = 0.8f;
      Scalar white = Scalar::all(255), black = Scalar::all(0);
  
      putText(lImg, "C++", Point(10, 20), FONT_HERSHEY_COMPLEX_SMALL, fontScale, black, 2);
      putText(rImg, "OCL", Point(10, 20), FONT_HERSHEY_COMPLEX_SMALL, fontScale, black, 2);
      putText(lImg, "C++", Point(10, 20), FONT_HERSHEY_COMPLEX_SMALL, fontScale, white, 1);
      putText(rImg, "OCL", Point(10, 20), FONT_HERSHEY_COMPLEX_SMALL, fontScale, white, 1);
  
      return imgToShow;
  }
  
  
  int main(int argc, char** argv)
  {
      const char* keys =
          "{ i | input   |                    | specify input image }"
          "{ o | output  | squares_output.jpg | specify output save path}"
          "{ h | help    | false              | print help message }";
      CommandLineParser cmd(argc, argv, keys);
      string inputName = cmd.get&lt;string&gt;("i");
      string outfile = cmd.get&lt;string&gt;("o");
  
      if(cmd.get&lt;bool&gt;("help"))
      {
          cout &lt;&lt; "Usage : squares [options]" &lt;&lt; endl;
          cout &lt;&lt; "Available options:" &lt;&lt; endl;
          cmd.printParams();
          return EXIT_SUCCESS;
      }
  
      int iterations = 10;
      namedWindow( wndname, CV_WINDOW_AUTOSIZE );
      vector&lt;vector&lt;Point&gt; &gt; squares_cpu, squares_ocl;
  
      Mat image = imread(inputName, 1);
      if( image.empty() )
      {
          cout &lt;&lt; "Couldn't load " &lt;&lt; inputName &lt;&lt; endl;
          return EXIT_FAILURE;
      }
  
      int j = iterations;
      int64 t_ocl = 0, t_cpp = 0;
      //warm-ups
      cout &lt;&lt; "warming up ..." &lt;&lt; endl;
      findSquares(image, squares_cpu);
      findSquares_ocl(image, squares_ocl);
  
  
  #ifdef ACCURACY_CHECK
      cout &lt;&lt; "Checking ocl accuracy ... " &lt;&lt; endl;
      cout &lt;&lt; (checkPoints(squares_cpu, squares_ocl) ? "Pass" : "Failed") &lt;&lt; endl;
  #endif
      do
      {
          int64 t_start = cv::getTickCount();
          findSquares(image, squares_cpu);
          t_cpp += cv::getTickCount() - t_start;
  
  
          t_start  = cv::getTickCount();
          findSquares_ocl(image, squares_ocl);
          t_ocl += cv::getTickCount() - t_start;
          cout &lt;&lt; "run loop: " &lt;&lt; j &lt;&lt; endl;
      }
      while(--j);
      cout &lt;&lt; "cpp average time: " &lt;&lt; 1000.0f * (double)t_cpp / getTickFrequency() / iterations &lt;&lt; "ms" &lt;&lt; endl;
      cout &lt;&lt; "ocl average time: " &lt;&lt; 1000.0f * (double)t_ocl / getTickFrequency() / iterations &lt;&lt; "ms" &lt;&lt; endl;
  
      Mat result = drawSquaresBoth(image, squares_cpu, squares_ocl);
      imshow(wndname, result);
      imwrite(outfile, result);
      cvWaitKey(0);
  
      return EXIT_SUCCESS;
  }
  </code></pre>
  
  <p>I have installed the cuda framework; but I get the following error when I try to run the code in visual studio 2013:</p>
  
  <pre><code>warming up ...
  OpenCV Error: Gpu API call (CL_INVALID_VALUE) in cv::ocl::ContextImpl::ContextIm
  pl, file C:\builds\2_4_PackSlave-win64-vc12-shared\opencv\modules\ocl\src\cl_con
  text.cpp, line 578
  ERROR: Can't select OpenCL device: GeForce GTX 650 Ti BOOST(NVIDIA CUDA)
  ERROR: Required OpenCL device not found, check configuration:
      Platform: any
      Device types: GPU CPU
      Device name: any
  OpenCV Error: Unknown error code -221 (Can't select OpenCL device) in cv::ocl::C
  ontextImpl::getContext, file C:\builds\2_4_PackSlave-win64-vc12-shared\opencv\mo
  dules\ocl\src\cl_context.cpp, line 684
  </code></pre>
  
  <p><strong>UPDATE:</strong>
  this is the output of CLinfo:</p>
  
  <pre><code>Number of platforms:    1
          CL_PLATFORM_PROFILE:    FULL_PROFILE
          CL_PLATFORM_VERSION:    OpenCL 1.2 CUDA 7.0.0
          CL_PLATFORM_VENDOR:     NVIDIA Corporation
          CL_PLATFORM_EXTENSIONS: cl_khr_byte_addressable_store cl_khr_icd cl_khr_
  gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unro
  ll cl_nv_d3d9_sharing cl_nv_d3d10_sharing cl_khr_d3d10_sharing cl_nv_d3d11_shari
  ng cl_nv_copy_opts
          Number of devices:      1
                  CL_DEVICE_TYPE: CL_DEVICE_TYPE_GPU
                  CL_DEVICE_VENDOR_ID:    4318
                  CL_DEVICE_MAX_COMPUTE_UNITS:    4
                  CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:     3
          CL_DEVICE_MAX_WORK_ITEM_SIZES:  1024 1024 64
                  CL_DEVICE_MAX_WORK_GROUP_SIZE:  1024
                  CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:  1
                  CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: 1
                  CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:   1
                  CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:  1
                  CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: 1
                  CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:        1
                  CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:  0
                  CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:     1
                  CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:    1
                  CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:      1
                  CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:     1
                  CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:    1
                  CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:   1
                  CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:     0
                  CL_DEVICE_MAX_CLOCK_FREQUENCY:  1097
                  CL_DEVICE_ADDRESS_BITS: 64
                  CL_DEVICE_MAX_MEM_ALLOC_SIZE:   536870912
                  CL_DEVICE_IMAGE_SUPPORT:        1
                  CL_DEVICE_MAX_READ_IMAGE_ARGS:  256
                  CL_DEVICE_MAX_WRITE_IMAGE_ARGS: 16
                  CL_DEVICE_IMAGE2D_MAX_WIDTH:    16384
                  CL_DEVICE_IMAGE2D_MAX_WIDTH:    16384
                  CL_DEVICE_IMAGE2D_MAX_HEIGHT:   16384
                  CL_DEVICE_IMAGE3D_MAX_WIDTH:    4096
                  CL_DEVICE_IMAGE3D_MAX_HEIGHT:   4096
                  CL_DEVICE_IMAGE3D_MAX_DEPTH:    4096
                  CL_DEVICE_MAX_SAMPLERS: 32
                  CL_DEVICE_MAX_PARAMETER_SIZE:   4352
                  CL_DEVICE_MEM_BASE_ADDR_ALIGN:  4096
                  CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:     128
                  CL_DEVICE_SINGLE_FP_CONFIG:     CL_FP_DENORM | CL_FP_INF_NAN | C
  L_FP_ROUND_TO_NEAREST | CL_FP_ROUND_TO_ZERO | CL_FP_ROUND_TO_INF | CL_FP_FMA
                  CL_DEVICE_SINGLE_FP_CONFIG:     CL_READ_ONLY_CACHE | CL_READ_WRI
  TE_CACHE
                  CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:        CL_READ_WRITE_CACHE
                  CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:    128
                  CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:        65536
                  CL_DEVICE_GLOBAL_MEM_SIZE:      2147483648
                  CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:     65536
                  CL_DEVICE_MAX_CONSTANT_ARGS:    9
                  CL_DEVICE_LOCAL_MEM_TYPE:
                  CL_DEVICE_LOCAL_MEM_SIZE:       49151
                  CL_DEVICE_ERROR_CORRECTION_SUPPORT:     0
                  CL_DEVICE_HOST_UNIFIED_MEMORY:  0
                  CL_DEVICE_PROFILING_TIMER_RESOLUTION:   1000
                  CL_DEVICE_ENDIAN_LITTLE:        1
                  CL_DEVICE_AVAILABLE:    1
                  CL_DEVICE_COMPILER_AVAILABLE:   1
                  CL_DEVICE_EXECUTION_CAPABILITIES:       CL_EXEC_KERNEL
                  CL_DEVICE_QUEUE_PROPERTIES:     CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_
  ENABLE | CL_QUEUE_PROFILING_ENABLE
                  CL_DEVICE_PLATFORM:     000000DA609B27F0
          CL_DEVICE_NAME: GeForce GTX 650 Ti BOOST
          CL_DEVICE_VENDOR:       NVIDIA Corporation
          CL_DRIVER_VERSION:      350.12
          CL_DEVICE_PROFILE:      FULL_PROFILE
          CL_DEVICE_VERSION:      OpenCL 1.2 CUDA
          CL_DEVICE_OPENCL_C_VERSION:     OpenCL C 1.2
          CL_DEVICE_EXTENSIONS:   cl_khr_byte_addressable_store cl_khr_icd cl_khr_
  gl_sharing cl_nv_compiler_options cl_nv_device_attribute_query cl_nv_pragma_unro
  ll cl_nv_d3d9_sharing cl_nv_d3d10_sharing cl_khr_d3d10_sharing cl_nv_d3d11_shari
  ng cl_nv_copy_opts  cl_khr_global_int32_base_atomics cl_khr_global_int32_extende
  d_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl
  _khr_fp64
  </code></pre>
  
  <p>what should be the setting for <code>OPENCV_OPENCL_DEVICE</code> ? I have tried <code>:GPU:NVIDIA</code>, <code>:GPU:GeForce GTX 650 Ti BOOST</code>, <code>:GPU:GeForce GTX 650 Ti BOOST&lt;NVIDIA CUDA&gt;</code> and the error persists !</p>
  
  <p><strong>UPDATE2:</strong>
  with settings <code>:GPU:0</code> and <code>:GPU:1</code> I get the following errors respectively:</p>
  
  <pre><code>warming up ...
  OpenCV Error: Gpu API call (CL_INVALID_VALUE) in cv::ocl::ContextImpl::ContextIm
  pl, file C:\builds\2_4_PackSlave-win64-vc12-shared\opencv\modules\ocl\src\cl_con
  text.cpp, line 578
  ERROR: Can't select OpenCL device: GeForce GTX 650 Ti BOOST(NVIDIA CUDA)
  ERROR: Required OpenCL device not found, check configuration: :GPU:0
      Platform: any
      Device types: GPU
      Device name: 0
  OpenCV Error: Unknown error code -221 (Can't select OpenCL device) in cv::ocl::C
  ontextImpl::getContext, file C:\builds\2_4_PackSlave-win64-vc12-shared\opencv\mo
  dules\ocl\src\cl_context.cpp, line 684
  </code></pre>
  
  <p>and with <code>:GPU:1</code>(which is a little different error, length-wise):</p>
  
  <pre><code>warming up ...
  ERROR: Required OpenCL device not found, check configuration: :GPU:1
      Platform: any
      Device types: GPU
      Device name: 1
  OpenCV Error: Unknown error code -221 (Can't select OpenCL device) in cv::ocl::C
  ontextImpl::getContext, file C:\builds\2_4_PackSlave-win64-vc12-shared\opencv\mo
  dules\ocl\src\cl_context.cpp, line 684
  </code></pre>
  
  <p>I also took a screenshot of the environment settings to double check that I set these values correctly:</p>
  
  <p><img src="https://i.stack.imgur.com/10Ife.jpg" alt="enter image description here"></p>