Column-oriented GPU-accelerated Database Management System
CoGaDB
|
00001 #pragma once 00002 #ifndef __CUDACC__ 00003 #error "cannot compile header file __FILE__: you have to use nvcc!" 00004 #endif 00005 00006 #include <gpu/gpu_base_column.hpp> 00007 #include <gpu/gpu_positionlist.hpp> 00008 #include <thrust/device_vector.h> 00009 #include <thrust/gather.h> 00010 #include <thrust/functional.h> 00011 00012 namespace CoGaDB{ 00013 namespace gpu{ 00014 00015 template<typename T> 00016 class GPU_Typed_Base_Column : public GPU_Base_Column{ 00017 public: 00018 explicit GPU_Typed_Base_Column(const std::string& name, AttributeType db_type); 00019 00020 virtual ~GPU_Typed_Base_Column(); 00021 00022 bool insert_from_host_memory(const std::vector<T>& host_column); 00023 bool insert_from_device_memory_in_host_vector(std::vector<T>& host_column); //not const reference, because routine inserts directly in host vector 00024 virtual bool insert(const boost::any& new_Value); 00025 virtual bool update(TID tid, const boost::any& new_Value); 00026 virtual bool remove(TID tid); 00027 00028 virtual const boost::any get(TID tid); //not const, because operator [] does not provide const return type and the child classes rely on [] 00029 00030 virtual bool add(const boost::any& new_Value); 00031 //vector addition between columns 00032 virtual bool add(shared_pointer_namespace::shared_ptr<GPU_Base_Column> column); 00033 00034 virtual bool minus(const boost::any& new_Value); 00035 virtual bool minus(shared_pointer_namespace::shared_ptr<GPU_Base_Column> column); 00036 00037 virtual bool multiply(const boost::any& new_Value); 00038 virtual bool multiply(shared_pointer_namespace::shared_ptr<GPU_Base_Column> column); 00039 00040 virtual bool division(const boost::any& new_Value); 00041 virtual bool division(shared_pointer_namespace::shared_ptr<GPU_Base_Column> column); 00042 00043 virtual const shared_pointer_namespace::shared_ptr<GPU_Base_Column> copy() const; 00044 virtual const shared_pointer_namespace::shared_ptr<GPU_Base_Column> materialize(shared_pointer_namespace::shared_ptr<GPU_Positionlist> pos_list) const; 00045 00046 virtual void print() const throw(); 00047 virtual size_t size() const throw(); 00048 virtual const std::type_info& type() const throw(); 00050 // AttributeType getType() const throw(); 00051 // const std::string getName() const throw(); 00052 00053 thrust::device_vector<T>& getContent(); 00054 friend const ColumnPtr copy_column_device_to_host(GPU_Base_ColumnPtr device_column); 00055 00056 protected: 00057 thrust::device_vector<T> data_; 00058 }; 00059 00060 template<typename T> 00061 GPU_Typed_Base_Column<T>::GPU_Typed_Base_Column(const std::string& name, AttributeType db_type) : GPU_Base_Column(name,db_type), data_(){ 00062 00063 } 00064 00065 template<typename T> 00066 GPU_Typed_Base_Column<T>::~GPU_Typed_Base_Column(){ 00067 00068 } 00069 template<typename T> 00070 bool GPU_Typed_Base_Column<T>::insert_from_host_memory(const std::vector<T>& host_column){ 00071 //TODO: add time measurement 00072 data_=host_column; 00073 return true; 00074 } 00075 template<typename T> 00076 bool GPU_Typed_Base_Column<T>::insert_from_device_memory_in_host_vector(std::vector<T>& host_column){ 00077 //TODO: add time measurement 00078 host_column.clear(); 00079 thrust::host_vector<T> t(data_.begin(),data_.end()); 00080 host_column.insert(host_column.begin(),t.begin(),t.end()); 00081 //host_column.insert(host_column.begin(),data_.begin(),data_.end()); 00082 return true; 00083 } 00084 00085 template<typename T> 00086 bool GPU_Typed_Base_Column<T>::insert(const boost::any& new_Value){ 00087 return false; 00088 } 00089 00090 template<typename T> 00091 bool GPU_Typed_Base_Column<T>::update(TID tid, const boost::any& new_Value){ 00092 return false; 00093 } 00094 00095 template<typename T> 00096 bool GPU_Typed_Base_Column<T>::remove(TID tid){ 00097 return false; 00098 } 00099 00100 template<typename T> 00101 const boost::any GPU_Typed_Base_Column<T>::get(TID tid){ 00102 return boost::any(data_[tid]); 00103 } 00104 00105 00106 template<class Type> 00107 bool GPU_Typed_Base_Column<Type>::add(const boost::any& new_value){ 00108 if(new_value.empty()) return false; 00109 if(typeid(Type)!=new_value.type()){ 00110 return false; 00111 } 00112 Type value = boost::any_cast<Type>(new_value); 00113 //using thrust::placeholders; 00114 //the third agument is an unnamed functor!, see 00115 //http://stackoverflow.com/questions/9671104/how-to-decrement-each-element-of-a-device-vector-by-a-constant for details 00116 thrust::for_each(this->data_.begin(), this->data_.end(), thrust::placeholders::_1 += value); 00117 return true; 00118 } 00119 00120 00121 00122 template<class Type> 00123 bool GPU_Typed_Base_Column<Type>::add(shared_pointer_namespace::shared_ptr<GPU_Base_Column> column){ 00124 //std::transform ( first, first+5, second, results, std::plus<int>() ); 00125 shared_pointer_namespace::shared_ptr<GPU_Typed_Base_Column<Type> > typed_column = shared_pointer_namespace::static_pointer_cast<GPU_Typed_Base_Column<Type> >(column); 00126 if(!typed_column) return false; 00127 if(this->size()!=typed_column->size()) return false; 00128 00129 thrust::transform(this->data_.begin(), this->data_.end(), typed_column->data_.begin(), this->data_.begin(), thrust::plus<Type>()); 00130 00131 return true; 00132 } 00133 00134 00135 00136 template<class Type> 00137 bool GPU_Typed_Base_Column<Type>::minus(const boost::any& new_value){ 00138 //shared_pointer_namespace::shared_ptr<GPU_Typed_Base_Column<Type> > typed_column = shared_pointer_namespace::static_pointer_cast<GPU_Typed_Base_Column<Type> >(column); 00139 if(new_value.empty()) return false; 00140 if(typeid(Type)!=new_value.type()){ 00141 return false; 00142 } 00143 Type value = boost::any_cast<Type>(new_value); 00144 using namespace thrust::placeholders; 00145 thrust::for_each(this->data_.begin(), this->data_.end(), thrust::placeholders::_1 -= value); 00146 return true; 00147 } 00148 00149 template<class Type> 00150 bool GPU_Typed_Base_Column<Type>::minus(shared_pointer_namespace::shared_ptr<GPU_Base_Column> column){ 00151 //std::transform ( first, first+5, second, results, std::plus<int>() ); 00152 //std::transform ( first, first+5, second, results, std::plus<int>() ); 00153 shared_pointer_namespace::shared_ptr<GPU_Typed_Base_Column<Type> > typed_column = shared_pointer_namespace::static_pointer_cast<GPU_Typed_Base_Column<Type> >(column); 00154 if(!typed_column) return false; 00155 if(this->size()!=typed_column->size()) return false; 00156 00157 thrust::transform(this->data_.begin(), this->data_.end(), typed_column->data_.begin(), this->data_.begin(), thrust::minus<Type>()); 00158 00159 return true; 00160 } 00161 00162 00163 template<class Type> 00164 bool GPU_Typed_Base_Column<Type>::multiply(const boost::any& new_value){ 00165 if(new_value.empty()) return false; 00166 if(typeid(Type)!=new_value.type()){ 00167 return false; 00168 } 00169 Type value = boost::any_cast<Type>(new_value); 00170 //using thrust::placeholders; 00171 thrust::for_each(this->data_.begin(), this->data_.end(), thrust::placeholders::_1 *= value); 00172 return true; 00173 } 00174 00175 template<class Type> 00176 bool GPU_Typed_Base_Column<Type>::multiply(GPU_Base_ColumnPtr column){ 00177 //std::transform ( first, first+5, second, results, std::plus<int>() ); 00178 shared_pointer_namespace::shared_ptr<GPU_Typed_Base_Column<Type> > typed_column = shared_pointer_namespace::static_pointer_cast<GPU_Typed_Base_Column<Type> >(column); 00179 if(!typed_column) return false; 00180 if(this->size()!=typed_column->size()) return false; 00181 00182 thrust::transform(this->data_.begin(), this->data_.end(), typed_column->data_.begin(), this->data_.begin(), thrust::multiplies<Type>()); 00183 00184 return true; 00185 } 00186 00187 00188 00189 template<class Type> 00190 bool GPU_Typed_Base_Column<Type>::division(const boost::any& new_value){ 00191 if(new_value.empty()) return false; 00192 if(typeid(Type)!=new_value.type()){ 00193 return false; 00194 } 00195 Type value = boost::any_cast<Type>(new_value); 00196 //using thrust::placeholders; 00197 thrust::for_each(this->data_.begin(), this->data_.end(), thrust::placeholders::_1 /= value); 00198 return true; 00199 } 00200 00201 template<class Type> 00202 bool GPU_Typed_Base_Column<Type>::division(GPU_Base_ColumnPtr column){ 00203 //std::transform ( first, first+5, second, results, std::plus<int>() ); 00204 shared_pointer_namespace::shared_ptr<GPU_Typed_Base_Column<Type> > typed_column = shared_pointer_namespace::static_pointer_cast<GPU_Typed_Base_Column<Type> >(column); 00205 if(!typed_column) return false; 00206 if(this->size()!=typed_column->size()) return false; 00207 00208 thrust::transform(this->data_.begin(), this->data_.end(), typed_column->data_.begin(), this->data_.begin(), thrust::divides<Type>()); 00209 00210 return true; 00211 } 00212 00213 //total tempalte specializations, because numeric computations are undefined on strings 00214 template<> 00215 inline bool GPU_Typed_Base_Column<std::string>::add(const boost::any&){ return false; } 00216 template<> 00217 inline bool GPU_Typed_Base_Column<std::string>::add(GPU_Base_ColumnPtr){ return false; } 00218 00219 template<> 00220 inline bool GPU_Typed_Base_Column<std::string>::minus(const boost::any&){ return false; } 00221 template<> 00222 inline bool GPU_Typed_Base_Column<std::string>::minus(GPU_Base_ColumnPtr){ return false; } 00223 00224 00225 template<> 00226 inline bool GPU_Typed_Base_Column<std::string>::multiply(const boost::any&){ return false; } 00227 template<> 00228 inline bool GPU_Typed_Base_Column<std::string>::multiply(GPU_Base_ColumnPtr){ return false; } 00229 00230 template<> 00231 inline bool GPU_Typed_Base_Column<std::string>::division(const boost::any&){ return false; } 00232 template<> 00233 inline bool GPU_Typed_Base_Column<std::string>::division(GPU_Base_ColumnPtr){ return false; } 00234 00235 00236 template<typename T> 00237 const GPU_Base_ColumnPtr GPU_Typed_Base_Column<T>::copy() const{ 00238 return GPU_Base_ColumnPtr(new GPU_Typed_Base_Column<T>(*this)); 00239 } 00240 00241 template<typename T> 00242 const shared_pointer_namespace::shared_ptr<GPU_Base_Column> GPU_Typed_Base_Column<T>::materialize(shared_pointer_namespace::shared_ptr<GPU_Positionlist> pos_list) const{ 00243 GPU_Typed_Base_Column<T>* new_column = new GPU_Typed_Base_Column<T>(this->name_,this->db_type_); 00244 00245 shared_pointer_namespace::shared_ptr<Impl_GPU_Positionlist> dev_pos_list = shared_pointer_namespace::static_pointer_cast<Impl_GPU_Positionlist> (pos_list); 00246 00247 thrust::device_vector<T>& data = new_column->getContent(); //empty device vector 00248 thrust::device_vector<TID>& tids = dev_pos_list->getContent(); //map with indeces 00249 00250 data.resize(tids.size()); 00251 //std::cout << "Calling Gather..." << std::endl; 00252 00253 //std::cout << "TIDS:.." << std::endl; 00254 thrust::copy(tids.begin(), tids.end(), std::ostream_iterator<int>(std::cout, "\n")); 00255 //std::cout << "data_:.." << std::endl; 00256 thrust::copy(data_.begin(), data_.end(), std::ostream_iterator<int>(std::cout, "\n")); 00257 00258 thrust::gather(tids.begin(), tids.end(), 00259 this->data_.begin(), //from this object 00260 data.begin()); //from created column 00261 //std::cout << "new data:.." << std::endl; 00262 thrust::copy(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, "\n")); 00263 00264 return GPU_Base_ColumnPtr(new_column); 00265 } 00266 00267 template<typename T> 00268 void GPU_Typed_Base_Column<T>::print() const throw(){ 00269 thrust::host_vector<T> v(data_); 00270 std::cout << "GPU Column: " << name_ << " of Type: " << typeid(T).name() << std::endl; 00271 std::cout << "Values: (" << v.size() << ")" << std::endl; 00272 for(unsigned int i=0;i<v.size();i++){ 00273 std::cout << v[i] << std::endl; 00274 } 00275 } 00276 00277 template<typename T> 00278 size_t GPU_Typed_Base_Column<T>::size() const throw(){ 00279 return data_.size(); 00280 } 00281 00282 template<typename T> 00283 const std::type_info& GPU_Typed_Base_Column<T>::type() const throw(){ 00284 return typeid(T); 00285 } 00286 00287 template<typename T> 00288 thrust::device_vector<T>& GPU_Typed_Base_Column<T>::getContent(){ 00289 return this->data_; 00290 } 00291 00293 // template<typename T> 00294 // AttributeType GPU_Typed_Base_Column<T>::getType() const throw(){ 00295 // return this->db_type_; 00296 // } 00297 // 00298 // template<typename T> 00299 // const std::string GPU_Typed_Base_Column<T>::getName() const throw(){ 00300 // return this->name_; 00301 // } 00302 00303 00304 }; //end namespace gpu 00305 }; //end namespace CogaDB 00306