ViennaCL - The Vienna Computing Library
1.5.1
|
00001 #ifndef VIENNACL_OCL_BACKEND_HPP_ 00002 #define VIENNACL_OCL_BACKEND_HPP_ 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2014, 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 #include <vector> 00026 #include "viennacl/ocl/context.hpp" 00027 #include "viennacl/ocl/enqueue.hpp" 00028 00029 namespace viennacl 00030 { 00031 namespace ocl 00032 { 00033 00035 template <bool dummy = false> //never use parameter other than default (introduced for linkage issues only) 00036 class backend 00037 { 00038 public: 00043 static void switch_context(long i) 00044 { 00045 current_context_id_ = i; 00046 } 00047 00049 static viennacl::ocl::context & context(long id) 00050 { 00051 if (!initialized_[id]) 00052 { 00053 //std::cout << "Initializing context no. " << current_context_id_ << std::endl; 00054 contexts_[id].init(); 00055 //create one queue per device: 00056 std::vector<viennacl::ocl::device> devices = contexts_[id].devices(); 00057 for (vcl_size_t j = 0; j<devices.size(); ++j) 00058 contexts_[id].add_queue(devices[j]); 00059 initialized_[id] = true; 00060 /* 00061 std::cout << "Context no. " << current_context_id_ << " initialized with " << devices.size() << " devices" << std::endl; 00062 std::cout << "Device id: " << devices[0].id() << std::endl; 00063 std::cout << "Current device id: " << contexts_[current_context_id_].current_device().id() << std::endl; */ 00064 } 00065 return contexts_[id]; 00066 } 00067 00069 static viennacl::ocl::context & current_context() 00070 { 00071 return backend<dummy>::context(current_context_id_); 00072 } 00073 00075 static viennacl::ocl::command_queue & get_queue() 00076 { 00077 return current_context().get_queue(); 00078 } 00079 00085 static void setup_context(long i, 00086 std::vector<cl_device_id> const & devices) 00087 { 00088 if (initialized_[i]) 00089 std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl; 00090 else 00091 { 00092 //set devices for context: 00093 for (vcl_size_t j = 0; j<devices.size(); ++j) 00094 contexts_[i].add_device(devices[j]); 00095 } 00096 } 00097 00105 static void setup_context(long i, 00106 cl_context c, 00107 std::vector<cl_device_id> const & devices, 00108 std::map< cl_device_id, std::vector< cl_command_queue > > const & queues) 00109 { 00110 assert(devices.size() == queues.size() && bool("ViennaCL expects one queue per device!")); 00111 00112 if (initialized_[i]) 00113 std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl; 00114 else 00115 { 00116 //set devices for context: 00117 for (vcl_size_t j = 0; j<devices.size(); ++j) 00118 contexts_[i].add_device(devices[j]); 00119 00120 //init context: 00121 contexts_[i].init(c); 00122 00123 //add queues: 00124 typedef typename std::map< cl_device_id, std::vector< cl_command_queue > >::const_iterator queue_iterator; 00125 for (queue_iterator qit = queues.begin(); 00126 qit != queues.end(); 00127 ++qit) 00128 { 00129 std::vector<cl_command_queue> const & queues_for_device = qit->second; 00130 for (vcl_size_t j=0; j<queues_for_device.size(); ++j) 00131 contexts_[i].add_queue(qit->first, queues_for_device[j]); 00132 } 00133 00134 initialized_[i] = true; 00135 } 00136 } 00137 00145 static void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queue) 00146 { 00147 assert(devices.size() == queue.size() && bool("ViennaCL expects one queue per device!")); 00148 00149 //wrap queue vector into map 00150 std::map< cl_device_id, std::vector<cl_command_queue> > queues_map; 00151 for (vcl_size_t j = 0; j<devices.size(); ++j) 00152 queues_map[devices[j]].push_back(queue[j]); 00153 00154 setup_context(i, c, devices, queues_map); 00155 } 00156 00158 static void set_context_device_type(long i, cl_device_type t) 00159 { 00160 contexts_[i].default_device_type(t); 00161 } 00162 00164 static void set_context_device_num(long i, vcl_size_t num) 00165 { 00166 contexts_[i].default_device_num(num); 00167 } 00168 00170 static void set_context_platform_index(long i, vcl_size_t pf_index) 00171 { 00172 contexts_[i].platform_index(pf_index); 00173 } 00174 00175 private: 00176 static long current_context_id_; 00177 static std::map<long, bool> initialized_; 00178 static std::map<long, viennacl::ocl::context> contexts_; 00179 }; 00180 00181 template <bool dummy> 00182 long backend<dummy>::current_context_id_ = 0; 00183 00184 template <bool dummy> 00185 std::map<long, bool> backend<dummy>::initialized_; 00186 00187 template <bool dummy> 00188 std::map<long, viennacl::ocl::context> backend<dummy>::contexts_; 00189 00191 00192 inline viennacl::ocl::context & current_context() 00193 { 00194 return viennacl::ocl::backend<>::current_context(); 00195 } 00196 00198 inline void switch_context(long i) 00199 { 00200 viennacl::ocl::backend<>::switch_context(i); 00201 } 00202 00204 inline viennacl::ocl::context & get_context(long i) 00205 { 00206 return viennacl::ocl::backend<>::context(i); 00207 } 00208 00210 inline void setup_context(long i, 00211 std::vector<cl_device_id> const & devices) 00212 { 00213 viennacl::ocl::backend<>::setup_context(i, devices); 00214 } 00215 00217 inline void setup_context(long i, 00218 viennacl::ocl::device const & device) 00219 { 00220 std::vector<cl_device_id> device_id_array(1); 00221 device_id_array[0] = device.id(); 00222 viennacl::ocl::backend<>::setup_context(i, device_id_array); 00223 } 00224 00226 inline void setup_context(long i, 00227 cl_context c, 00228 std::vector<cl_device_id> const & devices, 00229 std::map< cl_device_id, std::vector<cl_command_queue> > const & queues) 00230 { 00231 viennacl::ocl::backend<>::setup_context(i, c, devices, queues); 00232 } 00233 00235 inline void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queues) 00236 { 00237 viennacl::ocl::backend<>::setup_context(i, c, devices, queues); 00238 } 00239 00241 inline void setup_context(long i, cl_context c, cl_device_id d, cl_command_queue q) 00242 { 00243 std::vector<cl_device_id> devices(1); 00244 std::vector<cl_command_queue> queues(1); 00245 devices[0] = d; 00246 queues[0] = q; 00247 viennacl::ocl::backend<>::setup_context(i, c, devices, queues); 00248 } 00249 00251 inline void set_context_device_type(long i, cl_device_type dev_type) 00252 { 00253 viennacl::ocl::backend<>::set_context_device_type(i, dev_type); 00254 } 00255 00257 inline void set_context_device_type(long i, viennacl::ocl::gpu_tag) 00258 { 00259 set_context_device_type(i, CL_DEVICE_TYPE_GPU); 00260 } 00261 00263 inline void set_context_device_type(long i, viennacl::ocl::cpu_tag) 00264 { 00265 set_context_device_type(i, CL_DEVICE_TYPE_CPU); 00266 } 00267 00269 inline void set_context_device_type(long i, viennacl::ocl::default_tag) 00270 { 00271 set_context_device_type(i, CL_DEVICE_TYPE_DEFAULT); 00272 } 00273 00275 inline void set_context_device_type(long i, viennacl::ocl::accelerator_tag) 00276 { 00277 set_context_device_type(i, CL_DEVICE_TYPE_ACCELERATOR); 00278 } 00279 00281 inline void set_context_device_num(long i, vcl_size_t num) 00282 { 00283 viennacl::ocl::backend<>::set_context_device_num(i, num); 00284 } 00285 00286 00292 inline void set_context_platform_index(long i, vcl_size_t pf_index) 00293 { 00294 viennacl::ocl::backend<>::set_context_platform_index(i, pf_index); 00295 } 00296 00298 00299 inline viennacl::ocl::command_queue & get_queue() 00300 { 00301 return viennacl::ocl::current_context().get_queue(); 00302 } 00303 00305 inline viennacl::ocl::command_queue & get_queue(viennacl::ocl::device d, unsigned int queue_id = 0) 00306 { 00307 return viennacl::ocl::current_context().get_queue(d.id(), queue_id); 00308 } 00309 00311 inline viennacl::ocl::command_queue & get_queue(cl_device_id dev_id, unsigned int queue_id = 0) 00312 { 00313 return viennacl::ocl::current_context().get_queue(dev_id, queue_id); 00314 } 00315 00316 00318 inline viennacl::ocl::kernel & get_kernel(std::string const & prog_name, std::string const & kernel_name) 00319 { 00320 return viennacl::ocl::current_context().get_program(prog_name).get_kernel(kernel_name); 00321 } 00322 00324 inline void switch_device(viennacl::ocl::device & d) 00325 { 00326 viennacl::ocl::current_context().switch_device(d); 00327 } 00328 00330 inline viennacl::ocl::device const & current_device() 00331 { 00332 return viennacl::ocl::current_context().current_device(); 00333 } 00334 00335 } //ocl 00336 } //viennacl 00337 #endif