vector.txx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /**
  2. * \file vector.txx
  3. * \author Dhairya Malhotra, dhairya.malhotra@gmail.com
  4. * \date 2-11-2011
  5. * \brief This file contains implementation of the class Vector.
  6. */
  7. #include <cassert>
  8. #include <iostream>
  9. #include <iomanip>
  10. #include <device_wrapper.hpp>
  11. #include <mem_mgr.hpp>
  12. #include <profile.hpp>
  13. namespace pvfmm{
  14. template <class T>
  15. std::ostream& operator<<(std::ostream& output, const Vector<T>& V){
  16. std::ios::fmtflags f(std::cout.flags());
  17. output<<std::fixed<<std::setprecision(4)<<std::setiosflags(std::ios::left);
  18. for(size_t i=0;i<V.Dim();i++)
  19. output<<std::setw(10)<<V[i]<<' ';
  20. output<<";\n";
  21. std::cout.flags(f);
  22. return output;
  23. }
  24. template <class T>
  25. Vector<T>::Vector(){
  26. dim=0;
  27. capacity=0;
  28. own_data=true;
  29. data_ptr=NULL;
  30. dev.dev_ptr=(uintptr_t)NULL;
  31. }
  32. template <class T>
  33. Vector<T>::Vector(size_t dim_, T* data_, bool own_data_){
  34. dim=dim_;
  35. capacity=dim;
  36. own_data=own_data_;
  37. if(own_data){
  38. if(dim>0){
  39. data_ptr=mem::aligned_new<T>(capacity);
  40. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  41. Profile::Add_MEM(capacity*sizeof(T));
  42. #endif
  43. if(data_!=NULL) mem::memcopy(data_ptr,data_,dim*sizeof(T));
  44. }else data_ptr=NULL;
  45. }else
  46. data_ptr=data_;
  47. dev.dev_ptr=(uintptr_t)NULL;
  48. }
  49. template <class T>
  50. Vector<T>::Vector(const Vector<T>& V){
  51. dim=V.dim;
  52. capacity=dim;
  53. own_data=true;
  54. if(dim>0){
  55. data_ptr=mem::aligned_new<T>(capacity);
  56. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  57. Profile::Add_MEM(capacity*sizeof(T));
  58. #endif
  59. mem::memcopy(data_ptr,V.data_ptr,dim*sizeof(T));
  60. }else
  61. data_ptr=NULL;
  62. dev.dev_ptr=(uintptr_t)NULL;
  63. }
  64. template <class T>
  65. Vector<T>::Vector(const std::vector<T>& V){
  66. dim=V.size();
  67. capacity=dim;
  68. own_data=true;
  69. if(dim>0){
  70. data_ptr=mem::aligned_new<T>(capacity);
  71. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  72. Profile::Add_MEM(capacity*sizeof(T));
  73. #endif
  74. mem::memcopy(data_ptr,&V[0],dim*sizeof(T));
  75. }else
  76. data_ptr=NULL;
  77. dev.dev_ptr=(uintptr_t)NULL;
  78. }
  79. template <class T>
  80. Vector<T>::~Vector(){
  81. FreeDevice(false);
  82. if(own_data){
  83. if(data_ptr!=NULL){
  84. mem::aligned_delete(data_ptr);
  85. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  86. Profile::Add_MEM(-capacity*sizeof(T));
  87. #endif
  88. }
  89. }
  90. data_ptr=NULL;
  91. capacity=0;
  92. dim=0;
  93. }
  94. template <class T>
  95. void Vector<T>::Swap(Vector<T>& v1){
  96. size_t dim_=dim;
  97. size_t capacity_=capacity;
  98. T* data_ptr_=data_ptr;
  99. bool own_data_=own_data;
  100. Device dev_=dev;
  101. dim=v1.dim;
  102. capacity=v1.capacity;
  103. data_ptr=v1.data_ptr;
  104. own_data=v1.own_data;
  105. dev=v1.dev;
  106. v1.dim=dim_;
  107. v1.capacity=capacity_;
  108. v1.data_ptr=data_ptr_;
  109. v1.own_data=own_data_;
  110. v1.dev=dev_;
  111. }
  112. template <class T>
  113. void Vector<T>::ReInit(size_t dim_, T* data_, bool own_data_){
  114. if(own_data_ && own_data && dim_<=capacity){
  115. if(dim!=dim_) FreeDevice(false); dim=dim_;
  116. if(data_) mem::memcopy(data_ptr,data_,dim*sizeof(T));
  117. }else{
  118. Vector<T> tmp(dim_,data_,own_data_);
  119. this->Swap(tmp);
  120. }
  121. }
  122. template <class T>
  123. typename Vector<T>::Device& Vector<T>::AllocDevice(bool copy){
  124. if(dev.dev_ptr==(uintptr_t)NULL && dim>0) // Allocate data on device.
  125. dev.dev_ptr=DeviceWrapper::alloc_device((char*)data_ptr, dim*sizeof(T));
  126. if(dev.dev_ptr!=(uintptr_t)NULL && copy) // Copy data to device
  127. DeviceWrapper::host2device((char*)data_ptr,(char*)data_ptr,dev.dev_ptr,dim*sizeof(T));
  128. dev.dim=dim;
  129. return dev;
  130. }
  131. template <class T>
  132. void Vector<T>::Device2Host(){
  133. if(dev.dev_ptr==(uintptr_t)NULL) return;
  134. DeviceWrapper::device2host((char*)data_ptr,dev.dev_ptr,(char*)data_ptr,dim*sizeof(T));
  135. }
  136. template <class T>
  137. void Vector<T>::FreeDevice(bool copy){
  138. if(dev.dev_ptr==(uintptr_t)NULL) return;
  139. if(copy) DeviceWrapper::device2host((char*)data_ptr,dev.dev_ptr,(char*)data_ptr,dim*sizeof(T));
  140. DeviceWrapper::free_device((char*)data_ptr,dev.dev_ptr);
  141. dev.dev_ptr=(uintptr_t)NULL;
  142. dev.dim=0;
  143. }
  144. template <class T>
  145. void Vector<T>::Write(const char* fname){
  146. FILE* f1=fopen(fname,"wb+");
  147. if(f1==NULL){
  148. std::cout<<"Unable to open file for writing:"<<fname<<'\n';
  149. return;
  150. }
  151. int dim_=dim;
  152. fwrite(&dim_,sizeof(int),2,f1);
  153. fwrite(data_ptr,sizeof(T),dim,f1);
  154. fclose(f1);
  155. }
  156. template <class T>
  157. inline size_t Vector<T>::Dim() const{
  158. return dim;
  159. }
  160. template <class T>
  161. inline size_t Vector<T>::Capacity() const{
  162. return capacity;
  163. }
  164. template <class T>
  165. void Vector<T>::Resize(size_t dim_){
  166. if(dim!=dim_) FreeDevice(false);
  167. if(capacity>=dim_) dim=dim_;
  168. else ReInit(dim_);
  169. }
  170. template <class T>
  171. void Vector<T>::SetZero(){
  172. if(dim>0)
  173. memset(data_ptr,0,dim*sizeof(T));
  174. }
  175. template <class ValueType>
  176. ValueType* Vector<ValueType>::Begin(){
  177. return data_ptr;
  178. }
  179. template <class ValueType>
  180. const ValueType* Vector<ValueType>::Begin() const{
  181. return data_ptr;
  182. }
  183. template <class T>
  184. Vector<T>& Vector<T>::operator=(const Vector<T>& V){
  185. if(this!=&V){
  186. if(dim!=V.dim) FreeDevice(false);
  187. if(capacity<V.dim) ReInit(V.dim); dim=V.dim;
  188. mem::memcopy(data_ptr,V.data_ptr,dim*sizeof(T));
  189. }
  190. return *this;
  191. }
  192. template <class T>
  193. Vector<T>& Vector<T>::operator=(const std::vector<T>& V){
  194. {
  195. if(dim!=V.size()) FreeDevice(false);
  196. if(capacity<V.size()) ReInit(V.size()); dim=V.size();
  197. mem::memcopy(data_ptr,&V[0],dim*sizeof(T));
  198. }
  199. return *this;
  200. }
  201. template <class T>
  202. inline T& Vector<T>::operator[](size_t j){
  203. assert(dim>0?j<dim:j==0); //TODO Change to (j<dim)
  204. return data_ptr[j];
  205. }
  206. template <class T>
  207. inline const T& Vector<T>::operator[](size_t j) const{
  208. assert(dim>0?j<dim:j==0); //TODO Change to (j<dim)
  209. return data_ptr[j];
  210. }
  211. }//end namespace