• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/data/development/ViennaCL/ViennaCL-1.1.2/viennacl/ocl/enqueue.hpp

Go to the documentation of this file.
00001 /* =======================================================================
00002    Copyright (c) 2010, Institute for Microelectronics, TU Vienna.
00003    http://www.iue.tuwien.ac.at
00004                              -----------------
00005                      ViennaCL - The Vienna Computing Library
00006                              -----------------
00007                             
00008    authors:    Karl Rupp                          rupp@iue.tuwien.ac.at
00009                Florian Rudolf                     flo.rudy+viennacl@gmail.com
00010                Josef Weinbub                      weinbub@iue.tuwien.ac.at
00011 
00012    license:    MIT (X11), see file LICENSE in the ViennaCL base directory
00013 ======================================================================= */
00014 
00015 #ifndef _VIENNACL_ENQUEUE_HPP_
00016 #define _VIENNACL_ENQUEUE_HPP_
00017 
00022 #ifdef __APPLE__
00023 #include <OpenCL/cl.h>
00024 #else
00025 #include <CL/cl.h>
00026 #endif
00027 
00028 #include "viennacl/ocl/kernel.hpp"
00029 #include "viennacl/ocl/command_queue.hpp"
00030 
00031 namespace viennacl
00032 {
00033   namespace ocl
00034   {
00035 
00037     template <typename KernelType>
00038     void enqueue(KernelType & k, viennacl::ocl::command_queue const & queue)
00039     {
00040       // 1D kernel:
00041       if (k.local_work_size(1) == 0)
00042       {
00043         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
00044         std::cout << "ViennaCL: Starting 1D-kernel '" << k.name() << "'..." << std::endl;
00045         std::cout << "ViennaCL: Global work size: '"  << k.global_work_size() << "'..." << std::endl;
00046         std::cout << "ViennaCL: Local work size: '"   << k.local_work_size() << "'..." << std::endl;
00047         #endif
00048       
00049         size_t tmp_global = k.global_work_size();
00050         size_t tmp_local = k.local_work_size();
00051         
00052         cl_int err;
00053         if (tmp_global == 1 && tmp_local == 1)
00054           err = clEnqueueTask(queue.handle(), k.handle(), 0, NULL, NULL);
00055         else
00056           err = clEnqueueNDRangeKernel(queue.handle(), k.handle(), 1, NULL, &tmp_global, &tmp_local, 0, NULL, NULL);
00057 
00058         if (err != CL_SUCCESS)  //if not successful, try to start with smaller work size
00059         {
00060           //std::cout << "FAIL: " << std::endl; exit(0);
00061           while (err != CL_SUCCESS && tmp_local > 1)
00062           {
00063             //std::cout << "Flushing queue, then enqueuing again with half the size..." << std::endl;
00064             //std::cout << "Error code: " << err << std::endl;
00065             
00066             tmp_global /= 2;
00067             tmp_local /= 2;
00068 
00069             #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
00070             std::cout << "ViennaCL: Kernel start failed for '" << k.name() << "'." << std::endl;
00071             std::cout << "ViennaCL: Global work size: '"  << tmp_global << "'..." << std::endl;
00072             std::cout << "ViennaCL: Local work size: '"   << tmp_local << "'..." << std::endl;
00073             #endif
00074             
00075             queue.finish();
00076             err = clEnqueueNDRangeKernel(queue.handle(), k.handle(), 1, NULL, &tmp_global, &tmp_local, 0, NULL, NULL);
00077           }
00078           
00079           if (err != CL_SUCCESS)
00080           {
00081             //could not start kernel with any parameters
00082             std::cerr << "ViennaCL: FATAL ERROR: Kernel start failed for '" << k.name() << "'." << std::endl;
00083             std::cerr << "ViennaCL: Smaller work sizes could not solve the problem. " << std::endl;
00084             VIENNACL_ERR_CHECK(err);
00085           }
00086           else
00087           {
00088             //remember parameters:
00089             k.local_work_size(0, tmp_local);
00090             k.global_work_size(0, tmp_global);
00091             #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
00092             std::cout << "ViennaCL: Kernel '" << k.name() << "' now uses global work size " << tmp_global << " and local work size " << tmp_local << "."  << std::endl;
00093             #endif
00094           }          
00095         }
00096       }
00097       else //2D kernel
00098       {
00099         #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
00100         std::cout << "ViennaCL: Starting 2D-kernel '" << k.name() << "'..." << std::endl;
00101         std::cout << "ViennaCL: Global work size: '"  << k.global_work_size(0) << ", " << k.global_work_size(1) << "'..." << std::endl;
00102         std::cout << "ViennaCL: Local work size: '"   << k.local_work_size(0) << ", " << k.local_work_size(1) << "'..." << std::endl;
00103         #endif
00104 
00105         size_t tmp_global[2]; 
00106         tmp_global[0] = k.global_work_size(0);
00107         tmp_global[1] = k.global_work_size(1);
00108         
00109         size_t tmp_local[2];
00110         tmp_local[0] = k.local_work_size(0);
00111         tmp_local[1] = k.local_work_size(1);
00112         
00113         cl_int err = clEnqueueNDRangeKernel(queue.handle(), k.handle(), 2, NULL, tmp_global, tmp_local, 0, NULL, NULL);
00114 
00115         if (err != CL_SUCCESS)
00116         {
00117           //could not start kernel with any parameters
00118           std::cerr << "ViennaCL: FATAL ERROR: Kernel start failed for '" << k.name() << "'." << std::endl;
00119           VIENNACL_ERR_CHECK(err);
00120         }
00121         
00122       }
00123             
00124       #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL)
00125       queue.finish();
00126       std::cout << "ViennaCL: Kernel " << k.name() << " finished!" << std::endl;
00127       #endif
00128     } //enqueue()
00129     
00130     
00132     template <typename KernelType>
00133     void enqueue(KernelType & k)
00134     {
00135       enqueue(k, viennacl::ocl::current_context().get_queue());
00136     }
00137   } // namespace ocl
00138 } // namespace viennacl
00139 #endif

Generated on Sat May 21 2011 20:36:50 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1