ViennaCL - The Vienna Computing Library
1.5.0
|
00001 #ifndef VIENNACL_OCL_ENQUEUE_HPP_ 00002 #define VIENNACL_OCL_ENQUEUE_HPP_ 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2013, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00025 #ifdef __APPLE__ 00026 #include <OpenCL/cl.h> 00027 #else 00028 #include <CL/cl.h> 00029 #endif 00030 00031 #include "viennacl/ocl/backend.hpp" 00032 #include "viennacl/ocl/kernel.hpp" 00033 #include "viennacl/ocl/command_queue.hpp" 00034 #include "viennacl/ocl/context.hpp" 00035 00036 namespace viennacl 00037 { 00038 namespace generator{ 00039 class custom_operation; 00040 void enqueue_custom_op(viennacl::generator::custom_operation & op, viennacl::ocl::command_queue const & queue); 00041 } 00042 00043 namespace ocl 00044 { 00045 00047 template <typename KernelType> 00048 void enqueue(KernelType & k, viennacl::ocl::command_queue const & queue) 00049 { 00050 // 1D kernel: 00051 if (k.local_work_size(1) == 0) 00052 { 00053 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL) 00054 std::cout << "ViennaCL: Starting 1D-kernel '" << k.name() << "'..." << std::endl; 00055 std::cout << "ViennaCL: Global work size: '" << k.global_work_size() << "'..." << std::endl; 00056 std::cout << "ViennaCL: Local work size: '" << k.local_work_size() << "'..." << std::endl; 00057 #endif 00058 00059 vcl_size_t tmp_global = k.global_work_size(); 00060 vcl_size_t tmp_local = k.local_work_size(); 00061 00062 cl_int err; 00063 if (tmp_global == 1 && tmp_local == 1) 00064 err = clEnqueueTask(queue.handle().get(), k.handle().get(), 0, NULL, NULL); 00065 else 00066 err = clEnqueueNDRangeKernel(queue.handle().get(), k.handle().get(), 1, NULL, &tmp_global, &tmp_local, 0, NULL, NULL); 00067 00068 if (err != CL_SUCCESS) 00069 { 00070 std::cerr << "ViennaCL: FATAL ERROR: Kernel start failed for '" << k.name() << "'." << std::endl; 00071 std::cerr << "ViennaCL: Smaller work sizes could not solve the problem. " << std::endl; 00072 VIENNACL_ERR_CHECK(err); 00073 } 00074 } 00075 else //2D or 3D kernel 00076 { 00077 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL) 00078 std::cout << "ViennaCL: Starting 2D/3D-kernel '" << k.name() << "'..." << std::endl; 00079 std::cout << "ViennaCL: Global work size: '" << k.global_work_size(0) << ", " << k.global_work_size(1) << ", " << k.global_work_size(2) << "'..." << std::endl; 00080 std::cout << "ViennaCL: Local work size: '" << k.local_work_size(0) << ", " << k.local_work_size(1) << ", " << k.local_work_size(2) << "'..." << std::endl; 00081 #endif 00082 00083 vcl_size_t tmp_global[3]; 00084 tmp_global[0] = k.global_work_size(0); 00085 tmp_global[1] = k.global_work_size(1); 00086 tmp_global[2] = k.global_work_size(2); 00087 00088 vcl_size_t tmp_local[3]; 00089 tmp_local[0] = k.local_work_size(0); 00090 tmp_local[1] = k.local_work_size(1); 00091 tmp_local[2] = k.local_work_size(2); 00092 00093 cl_int err = clEnqueueNDRangeKernel(queue.handle().get(), k.handle().get(), (tmp_global[2] == 0) ? 2 : 3, NULL, tmp_global, tmp_local, 0, NULL, NULL); 00094 00095 if (err != CL_SUCCESS) 00096 { 00097 //could not start kernel with any parameters 00098 std::cerr << "ViennaCL: FATAL ERROR: Kernel start failed for '" << k.name() << "'." << std::endl; 00099 VIENNACL_ERR_CHECK(err); 00100 } 00101 } 00102 00103 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_KERNEL) 00104 queue.finish(); 00105 std::cout << "ViennaCL: Kernel " << k.name() << " finished!" << std::endl; 00106 #endif 00107 } //enqueue() 00108 00109 00111 template <typename KernelType> 00112 void enqueue(KernelType & k) 00113 { 00114 enqueue(k, k.context().get_queue()); 00115 } 00116 00117 inline void enqueue(viennacl::generator::custom_operation & op, viennacl::ocl::command_queue const & queue) 00118 { 00119 generator::enqueue_custom_op(op,queue); 00120 } 00121 00122 inline void enqueue(viennacl::generator::custom_operation & op) 00123 { 00124 enqueue(op, viennacl::ocl::current_context().get_queue()); 00125 } 00126 00127 } // namespace ocl 00128 } // namespace viennacl 00129 #endif