|
ViennaCL - The Vienna Computing Library
1.1.2
|
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_BACKEND_HPP_ 00016 #define _VIENNACL_BACKEND_HPP_ 00017 00022 #include <vector> 00023 #include "viennacl/ocl/context.hpp" 00024 #include "viennacl/ocl/enqueue.hpp" 00025 00026 namespace viennacl 00027 { 00028 namespace ocl 00029 { 00030 00032 template <bool dummy = false> //never use parameter other than default (introduced for linkage issues only) 00033 class backend 00034 { 00035 public: 00040 static void switch_context(long i) 00041 { 00042 current_context_id_ = i; 00043 } 00044 00046 static viennacl::ocl::context & current_context() 00047 { 00048 if (!initialized_[current_context_id_]) 00049 { 00050 //std::cout << "Initializing context no. " << current_context_id_ << std::endl; 00051 contexts_[current_context_id_].init(); 00052 //create one queue per device: 00053 std::vector<viennacl::ocl::device> devices = contexts_[current_context_id_].devices(); 00054 for (size_t j = 0; j<devices.size(); ++j) 00055 contexts_[current_context_id_].add_queue(devices[j]); 00056 initialized_[current_context_id_] = true; 00057 /* 00058 std::cout << "Context no. " << current_context_id_ << " initialized with " << devices.size() << " devices" << std::endl; 00059 std::cout << "Device id: " << devices[0].id() << std::endl; 00060 std::cout << "Current device id: " << contexts_[current_context_id_].current_device().id() << std::endl; */ 00061 } 00062 return contexts_[current_context_id_]; 00063 } 00064 00066 static viennacl::ocl::command_queue & get_queue() 00067 { 00068 return current_context().get_queue(); 00069 } 00070 00076 static void setup_context(long i, 00077 std::vector<cl_device_id> const & devices) 00078 { 00079 if (initialized_[i]) 00080 std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl; 00081 else 00082 { 00083 //set devices for context: 00084 for (size_t j = 0; j<devices.size(); ++j) 00085 contexts_[i].add_device(devices[j]); 00086 } 00087 } 00088 00096 static void setup_context(long i, 00097 cl_context c, 00098 std::vector<cl_device_id> const & devices, 00099 std::map< cl_device_id, std::vector< cl_command_queue > > const & queues) 00100 { 00101 assert(devices.size() == queues.size() && "ViennaCL expects one queue per device!"); 00102 00103 if (initialized_[i]) 00104 std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl; 00105 else 00106 { 00107 //set devices for context: 00108 for (size_t j = 0; j<devices.size(); ++j) 00109 contexts_[i].add_device(devices[j]); 00110 00111 //init context: 00112 contexts_[i].init(c); 00113 00114 //add queues: 00115 typedef typename std::map< cl_device_id, std::vector< cl_command_queue > >::const_iterator queue_iterator; 00116 for (queue_iterator qit = queues.begin(); 00117 qit != queues.end(); 00118 ++qit) 00119 { 00120 std::vector<cl_command_queue> const & queues_for_device = qit->second; 00121 for (size_t j=0; j<queues_for_device.size(); ++j) 00122 contexts_[i].add_queue(qit->first, queues_for_device[j]); 00123 } 00124 00125 initialized_[i] = true; 00126 } 00127 } 00128 00136 static void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queue) 00137 { 00138 assert(devices.size() == queue.size() && "ViennaCL expects one queue per device!"); 00139 00140 //wrap queue vector into map 00141 std::map< cl_device_id, std::vector<cl_command_queue> > queues_map; 00142 for (size_t j = 0; j<devices.size(); ++j) 00143 queues_map[devices[j]].push_back(queue[j]); 00144 00145 setup_context(i, c, devices, queues_map); 00146 } 00147 00149 static void set_context_device_type(long i, cl_device_type t) 00150 { 00151 contexts_[i].default_device_type(t); 00152 } 00153 00154 private: 00155 static long current_context_id_; 00156 static std::map<long, bool> initialized_; 00157 static std::map<long, viennacl::ocl::context> contexts_; 00158 }; 00159 00160 template <bool dummy> 00161 long backend<dummy>::current_context_id_ = 0; 00162 00163 template <bool dummy> 00164 std::map<long, bool> backend<dummy>::initialized_; 00165 00166 template <bool dummy> 00167 std::map<long, viennacl::ocl::context> backend<dummy>::contexts_; 00168 00170 00171 inline viennacl::ocl::context & current_context() 00172 { 00173 return viennacl::ocl::backend<>::current_context(); 00174 } 00175 00177 inline void switch_context(long i) 00178 { 00179 viennacl::ocl::backend<>::switch_context(i); 00180 } 00181 00182 00184 inline void setup_context(long i, 00185 std::vector<cl_device_id> const & devices) 00186 { 00187 viennacl::ocl::backend<>::setup_context(i, devices); 00188 } 00189 00191 inline void setup_context(long i, 00192 cl_context c, 00193 std::vector<cl_device_id> const & devices, 00194 std::map< cl_device_id, std::vector<cl_command_queue> > const & queues) 00195 { 00196 viennacl::ocl::backend<>::setup_context(i, c, devices, queues); 00197 } 00198 00200 inline void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queues) 00201 { 00202 viennacl::ocl::backend<>::setup_context(i, c, devices, queues); 00203 } 00204 00206 inline void setup_context(long i, cl_context c, cl_device_id d, cl_command_queue q) 00207 { 00208 std::vector<cl_device_id> devices(1); 00209 std::vector<cl_command_queue> queues(1); 00210 devices[0] = d; 00211 queues[0] = q; 00212 viennacl::ocl::backend<>::setup_context(i, c, devices, queues); 00213 } 00214 00216 inline void set_context_device_type(long i, cl_device_type dev_type) 00217 { 00218 viennacl::ocl::backend<>::set_context_device_type(i, dev_type); 00219 } 00220 00222 inline void set_context_device_type(long i, viennacl::ocl::gpu_tag) 00223 { 00224 set_context_device_type(i, CL_DEVICE_TYPE_GPU); 00225 } 00226 00228 inline void set_context_device_type(long i, viennacl::ocl::cpu_tag) 00229 { 00230 set_context_device_type(i, CL_DEVICE_TYPE_CPU); 00231 } 00232 00234 inline void set_context_device_type(long i, viennacl::ocl::default_tag) 00235 { 00236 set_context_device_type(i, CL_DEVICE_TYPE_DEFAULT); 00237 } 00238 00240 inline void set_context_device_type(long i, viennacl::ocl::accelerator_tag) 00241 { 00242 set_context_device_type(i, CL_DEVICE_TYPE_ACCELERATOR); 00243 } 00244 00246 00247 inline viennacl::ocl::command_queue & get_queue() 00248 { 00249 return viennacl::ocl::current_context().get_queue(); 00250 } 00251 00253 inline viennacl::ocl::command_queue & get_queue(viennacl::ocl::device d, unsigned int queue_id = 0) 00254 { 00255 return viennacl::ocl::current_context().get_queue(d.id(), queue_id); 00256 } 00257 00259 inline viennacl::ocl::command_queue & get_queue(cl_device_id dev_id, unsigned int queue_id = 0) 00260 { 00261 return viennacl::ocl::current_context().get_queue(dev_id, queue_id); 00262 } 00263 00264 00266 inline viennacl::ocl::kernel & get_kernel(std::string const & prog_name, std::string const & kernel_name) 00267 { 00268 return viennacl::ocl::current_context().get_program(prog_name).get_kernel(kernel_name); 00269 } 00270 00272 inline void switch_device(viennacl::ocl::device & d) 00273 { 00274 viennacl::ocl::current_context().switch_device(d); 00275 } 00276 00278 inline viennacl::ocl::device const & current_device() 00279 { 00280 return viennacl::ocl::current_context().current_device(); 00281 } 00282 00283 } //ocl 00284 } //viennacl 00285 #endif
1.7.6.1