00001 #ifndef VIENNACL_OCL_BACKEND_HPP_
00002 #define VIENNACL_OCL_BACKEND_HPP_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024 #include <vector>
00025 #include "viennacl/ocl/context.hpp"
00026 #include "viennacl/ocl/enqueue.hpp"
00027
00028 namespace viennacl
00029 {
00030 namespace ocl
00031 {
00032
00034 template <bool dummy = false>
00035 class backend
00036 {
00037 public:
00042 static void switch_context(long i)
00043 {
00044 current_context_id_ = i;
00045 }
00046
00048 static viennacl::ocl::context & current_context()
00049 {
00050 if (!initialized_[current_context_id_])
00051 {
00052
00053 contexts_[current_context_id_].init();
00054
00055 std::vector<viennacl::ocl::device> devices = contexts_[current_context_id_].devices();
00056 for (size_t j = 0; j<devices.size(); ++j)
00057 contexts_[current_context_id_].add_queue(devices[j]);
00058 initialized_[current_context_id_] = true;
00059
00060
00061
00062
00063 }
00064 return contexts_[current_context_id_];
00065 }
00066
00068 static viennacl::ocl::command_queue & get_queue()
00069 {
00070 return current_context().get_queue();
00071 }
00072
00078 static void setup_context(long i,
00079 std::vector<cl_device_id> const & devices)
00080 {
00081 if (initialized_[i])
00082 std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl;
00083 else
00084 {
00085
00086 for (size_t j = 0; j<devices.size(); ++j)
00087 contexts_[i].add_device(devices[j]);
00088 }
00089 }
00090
00098 static void setup_context(long i,
00099 cl_context c,
00100 std::vector<cl_device_id> const & devices,
00101 std::map< cl_device_id, std::vector< cl_command_queue > > const & queues)
00102 {
00103 assert(devices.size() == queues.size() && "ViennaCL expects one queue per device!");
00104
00105 if (initialized_[i])
00106 std::cerr << "ViennaCL: Warning in init_context(): Providing a list of devices has no effect, because context for ViennaCL is already created!" << std::endl;
00107 else
00108 {
00109
00110 for (size_t j = 0; j<devices.size(); ++j)
00111 contexts_[i].add_device(devices[j]);
00112
00113
00114 contexts_[i].init(c);
00115
00116
00117 typedef typename std::map< cl_device_id, std::vector< cl_command_queue > >::const_iterator queue_iterator;
00118 for (queue_iterator qit = queues.begin();
00119 qit != queues.end();
00120 ++qit)
00121 {
00122 std::vector<cl_command_queue> const & queues_for_device = qit->second;
00123 for (size_t j=0; j<queues_for_device.size(); ++j)
00124 contexts_[i].add_queue(qit->first, queues_for_device[j]);
00125 }
00126
00127 initialized_[i] = true;
00128 }
00129 }
00130
00138 static void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queue)
00139 {
00140 assert(devices.size() == queue.size() && "ViennaCL expects one queue per device!");
00141
00142
00143 std::map< cl_device_id, std::vector<cl_command_queue> > queues_map;
00144 for (size_t j = 0; j<devices.size(); ++j)
00145 queues_map[devices[j]].push_back(queue[j]);
00146
00147 setup_context(i, c, devices, queues_map);
00148 }
00149
00151 static void set_context_device_type(long i, cl_device_type t)
00152 {
00153 contexts_[i].default_device_type(t);
00154 }
00155
00156 private:
00157 static long current_context_id_;
00158 static std::map<long, bool> initialized_;
00159 static std::map<long, viennacl::ocl::context> contexts_;
00160 };
00161
00162 template <bool dummy>
00163 long backend<dummy>::current_context_id_ = 0;
00164
00165 template <bool dummy>
00166 std::map<long, bool> backend<dummy>::initialized_;
00167
00168 template <bool dummy>
00169 std::map<long, viennacl::ocl::context> backend<dummy>::contexts_;
00170
00172
00173 inline viennacl::ocl::context & current_context()
00174 {
00175 return viennacl::ocl::backend<>::current_context();
00176 }
00177
00179 inline void switch_context(long i)
00180 {
00181 viennacl::ocl::backend<>::switch_context(i);
00182 }
00183
00184
00186 inline void setup_context(long i,
00187 std::vector<cl_device_id> const & devices)
00188 {
00189 viennacl::ocl::backend<>::setup_context(i, devices);
00190 }
00191
00193 inline void setup_context(long i,
00194 cl_context c,
00195 std::vector<cl_device_id> const & devices,
00196 std::map< cl_device_id, std::vector<cl_command_queue> > const & queues)
00197 {
00198 viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
00199 }
00200
00202 inline void setup_context(long i, cl_context c, std::vector<cl_device_id> const & devices, std::vector<cl_command_queue> const & queues)
00203 {
00204 viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
00205 }
00206
00208 inline void setup_context(long i, cl_context c, cl_device_id d, cl_command_queue q)
00209 {
00210 std::vector<cl_device_id> devices(1);
00211 std::vector<cl_command_queue> queues(1);
00212 devices[0] = d;
00213 queues[0] = q;
00214 viennacl::ocl::backend<>::setup_context(i, c, devices, queues);
00215 }
00216
00218 inline void set_context_device_type(long i, cl_device_type dev_type)
00219 {
00220 viennacl::ocl::backend<>::set_context_device_type(i, dev_type);
00221 }
00222
00224 inline void set_context_device_type(long i, viennacl::ocl::gpu_tag)
00225 {
00226 set_context_device_type(i, CL_DEVICE_TYPE_GPU);
00227 }
00228
00230 inline void set_context_device_type(long i, viennacl::ocl::cpu_tag)
00231 {
00232 set_context_device_type(i, CL_DEVICE_TYPE_CPU);
00233 }
00234
00236 inline void set_context_device_type(long i, viennacl::ocl::default_tag)
00237 {
00238 set_context_device_type(i, CL_DEVICE_TYPE_DEFAULT);
00239 }
00240
00242 inline void set_context_device_type(long i, viennacl::ocl::accelerator_tag)
00243 {
00244 set_context_device_type(i, CL_DEVICE_TYPE_ACCELERATOR);
00245 }
00246
00248
00249 inline viennacl::ocl::command_queue & get_queue()
00250 {
00251 return viennacl::ocl::current_context().get_queue();
00252 }
00253
00255 inline viennacl::ocl::command_queue & get_queue(viennacl::ocl::device d, unsigned int queue_id = 0)
00256 {
00257 return viennacl::ocl::current_context().get_queue(d.id(), queue_id);
00258 }
00259
00261 inline viennacl::ocl::command_queue & get_queue(cl_device_id dev_id, unsigned int queue_id = 0)
00262 {
00263 return viennacl::ocl::current_context().get_queue(dev_id, queue_id);
00264 }
00265
00266
00268 inline viennacl::ocl::kernel & get_kernel(std::string const & prog_name, std::string const & kernel_name)
00269 {
00270 return viennacl::ocl::current_context().get_program(prog_name).get_kernel(kernel_name);
00271 }
00272
00274 inline void switch_device(viennacl::ocl::device & d)
00275 {
00276 viennacl::ocl::current_context().switch_device(d);
00277 }
00278
00280 inline viennacl::ocl::device const & current_device()
00281 {
00282 return viennacl::ocl::current_context().current_device();
00283 }
00284
00285 }
00286 }
00287 #endif