00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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>
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
00051 contexts_[current_context_id_].init();
00052
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
00059
00060
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
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
00108 for (size_t j = 0; j<devices.size(); ++j)
00109 contexts_[i].add_device(devices[j]);
00110
00111
00112 contexts_[i].init(c);
00113
00114
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
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 }
00284 }
00285 #endif