ViennaCL - The Vienna Computing Library  1.5.1
viennacl/backend/mem_handle.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_BACKEND_MEM_HANDLE_HPP
00002 #define VIENNACL_BACKEND_MEM_HANDLE_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 <cassert>
00027 #include "viennacl/forwards.h"
00028 #include "viennacl/tools/shared_ptr.hpp"
00029 #include "viennacl/backend/cpu_ram.hpp"
00030 
00031 #ifdef VIENNACL_WITH_OPENCL
00032   #include "viennacl/backend/opencl.hpp"
00033 #endif
00034 
00035 #ifdef VIENNACL_WITH_CUDA
00036   #include "viennacl/backend/cuda.hpp"
00037 #endif
00038 
00039 
00040 namespace viennacl
00041 {
00042   namespace backend
00043   {
00044 
00045 
00046 // if a user compiles with CUDA, it is reasonable to expect that CUDA should be the default
00047 #ifdef VIENNACL_WITH_CUDA
00048     inline memory_types default_memory_type() { return CUDA_MEMORY; }
00049 #elif defined(VIENNACL_WITH_OPENCL)
00050     inline memory_types default_memory_type() { return OPENCL_MEMORY; }
00051 #else
00052     inline memory_types default_memory_type() { return MAIN_MEMORY; }
00053 #endif
00054 
00055 
00062     class mem_handle
00063     {
00064       public:
00065         typedef viennacl::tools::shared_ptr<char>      ram_handle_type;
00066         typedef viennacl::tools::shared_ptr<char>      cuda_handle_type;
00067 
00069         mem_handle() : active_handle_(MEMORY_NOT_INITIALIZED), size_in_bytes_(0) {}
00070 
00072         ram_handle_type       & ram_handle()       { return ram_handle_; }
00074         ram_handle_type const & ram_handle() const { return ram_handle_; }
00075 
00076 #ifdef VIENNACL_WITH_OPENCL
00077 
00078         viennacl::ocl::handle<cl_mem>       & opencl_handle()       { return opencl_handle_; }
00080         viennacl::ocl::handle<cl_mem> const & opencl_handle() const { return opencl_handle_; }
00081 #endif
00082 
00083 #ifdef VIENNACL_WITH_CUDA
00084 
00085         cuda_handle_type       & cuda_handle()       { return cuda_handle_; }
00087         cuda_handle_type const & cuda_handle() const { return cuda_handle_; }
00088 #endif
00089 
00091         memory_types get_active_handle_id() const { return active_handle_; }
00092 
00094         void switch_active_handle_id(memory_types new_id)
00095         {
00096           if (new_id != active_handle_)
00097           {
00098             if (active_handle_ == MEMORY_NOT_INITIALIZED)
00099               active_handle_ = new_id;
00100             else if (active_handle_ == MAIN_MEMORY)
00101             {
00102               active_handle_ = new_id;
00103             }
00104             else if (active_handle_ == OPENCL_MEMORY)
00105             {
00106 #ifdef VIENNACL_WITH_OPENCL
00107               active_handle_ = new_id;
00108 #else
00109               throw "compiled without OpenCL suppport!";
00110 #endif
00111             }
00112             else if (active_handle_ == CUDA_MEMORY)
00113             {
00114 #ifdef VIENNACL_WITH_CUDA
00115               active_handle_ = new_id;
00116 #else
00117               throw "compiled without CUDA suppport!";
00118 #endif
00119             }
00120             else
00121               throw "invalid new memory region!";
00122           }
00123         }
00124 
00126         bool operator==(mem_handle const & other) const
00127         {
00128           if (active_handle_ != other.active_handle_)
00129             return false;
00130 
00131           switch (active_handle_)
00132           {
00133             case MAIN_MEMORY:
00134               return ram_handle_.get() == other.ram_handle_.get();
00135 #ifdef VIENNACL_WITH_OPENCL
00136             case OPENCL_MEMORY:
00137               return opencl_handle_.get() == other.opencl_handle_.get();
00138 #endif
00139 #ifdef VIENNACL_WITH_CUDA
00140             case CUDA_MEMORY:
00141               return cuda_handle_.get() == other.cuda_handle_.get();
00142 #endif
00143             default: break;
00144           }
00145 
00146           return false;
00147         }
00148 
00152         bool operator<(mem_handle const & other) const
00153         {
00154           if (active_handle_ != other.active_handle_)
00155             return false;
00156 
00157           switch (active_handle_)
00158           {
00159             case MAIN_MEMORY:
00160               return ram_handle_.get() < other.ram_handle_.get();
00161 #ifdef VIENNACL_WITH_OPENCL
00162             case OPENCL_MEMORY:
00163               return opencl_handle_.get() < other.opencl_handle_.get();
00164 #endif
00165 #ifdef VIENNACL_WITH_CUDA
00166             case CUDA_MEMORY:
00167               return cuda_handle_.get() < other.cuda_handle_.get();
00168 #endif
00169             default: break;
00170           }
00171 
00172           return false;
00173         }
00174 
00175 
00176         bool operator!=(mem_handle const & other) const { return !(*this == other); }
00177 
00179         void swap(mem_handle & other)
00180         {
00181           // swap handle type:
00182           memory_types active_handle_tmp = other.active_handle_;
00183           other.active_handle_ = active_handle_;
00184           active_handle_ = active_handle_tmp;
00185 
00186           // swap ram handle:
00187           ram_handle_type ram_handle_tmp = other.ram_handle_;
00188           other.ram_handle_ = ram_handle_;
00189           ram_handle_ = ram_handle_tmp;
00190 
00191           // swap OpenCL handle:
00192 #ifdef VIENNACL_WITH_OPENCL
00193           opencl_handle_.swap(other.opencl_handle_);
00194 #endif
00195 #ifdef VIENNACL_WITH_CUDA
00196           cuda_handle_type cuda_handle_tmp = other.cuda_handle_;
00197           other.cuda_handle_ = cuda_handle_;
00198           cuda_handle_ = cuda_handle_tmp;
00199 #endif
00200         }
00201 
00203         vcl_size_t raw_size() const               { return size_in_bytes_; }
00204 
00206         void        raw_size(vcl_size_t new_size) { size_in_bytes_ = new_size; }
00207 
00208       private:
00209         memory_types active_handle_;
00210         ram_handle_type ram_handle_;
00211 #ifdef VIENNACL_WITH_OPENCL
00212         viennacl::ocl::handle<cl_mem> opencl_handle_;
00213 #endif
00214 #ifdef VIENNACL_WITH_CUDA
00215         cuda_handle_type        cuda_handle_;
00216 #endif
00217         vcl_size_t size_in_bytes_;
00218     };
00219 
00220 
00221   } //backend
00222 
00223 
00224 } //viennacl
00225 #endif