• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/data/development/ViennaCL/dev/viennacl/ocl/backend.hpp

Go to the documentation of this file.
00001 #ifndef VIENNACL_OCL_BACKEND_HPP_
00002 #define VIENNACL_OCL_BACKEND_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2011, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                   ViennaCL - The Vienna Computing Library
00011                             -----------------
00012 
00013    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00014                
00015    (A list of authors and contributors can be found in the PDF manual)
00016 
00017    License:         MIT (X11), see file LICENSE in the base directory
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>  //never use parameter other than default (introduced for linkage issues only)
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             //std::cout << "Initializing context no. " << current_context_id_ << std::endl;
00053             contexts_[current_context_id_].init();
00054             //create one queue per device:
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             std::cout << "Context no. " << current_context_id_ << " initialized with " << devices.size() << " devices" << std::endl;
00061             std::cout << "Device id: " << devices[0].id() << std::endl;
00062             std::cout << "Current device id: " << contexts_[current_context_id_].current_device().id() << std::endl; */
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             //set devices for context:
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             //set devices for context:
00110             for (size_t j = 0; j<devices.size(); ++j)
00111               contexts_[i].add_device(devices[j]);
00112             
00113             //init context:
00114             contexts_[i].init(c);
00115             
00116             //add queues:
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           //wrap queue vector into map
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   } //ocl
00286 } //viennacl
00287 #endif

Generated on Fri Dec 30 2011 23:20:43 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1