Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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)
00059 {
00060
00061 while (err != CL_SUCCESS && tmp_local > 1)
00062 {
00063
00064
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
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
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
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
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 }
00129
00130
00132 template <typename KernelType>
00133 void enqueue(KernelType & k)
00134 {
00135 enqueue(k, viennacl::ocl::current_context().get_queue());
00136 }
00137 }
00138 }
00139 #endif