vector.txx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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. Vector<T> tmp(dim_,data_,own_data_);
  115. this->Swap(tmp);
  116. }
  117. template <class T>
  118. typename Vector<T>::Device& Vector<T>::AllocDevice(bool copy){
  119. if(dev.dev_ptr==(uintptr_t)NULL && dim>0) // Allocate data on device.
  120. dev.dev_ptr=DeviceWrapper::alloc_device((char*)data_ptr, dim*sizeof(T));
  121. if(dev.dev_ptr!=(uintptr_t)NULL && copy) // Copy data to device
  122. DeviceWrapper::host2device((char*)data_ptr,(char*)data_ptr,dev.dev_ptr,dim*sizeof(T));
  123. dev.dim=dim;
  124. return dev;
  125. }
  126. template <class T>
  127. void Vector<T>::Device2Host(){
  128. if(dev.dev_ptr==(uintptr_t)NULL) return;
  129. DeviceWrapper::device2host((char*)data_ptr,dev.dev_ptr,(char*)data_ptr,dim*sizeof(T));
  130. }
  131. template <class T>
  132. void Vector<T>::FreeDevice(bool copy){
  133. if(dev.dev_ptr==(uintptr_t)NULL) return;
  134. if(copy) DeviceWrapper::device2host((char*)data_ptr,dev.dev_ptr,(char*)data_ptr,dim*sizeof(T));
  135. DeviceWrapper::free_device((char*)data_ptr,dev.dev_ptr);
  136. dev.dev_ptr=(uintptr_t)NULL;
  137. dev.dim=0;
  138. }
  139. template <class T>
  140. void Vector<T>::Write(const char* fname){
  141. FILE* f1=fopen(fname,"wb+");
  142. if(f1==NULL){
  143. std::cout<<"Unable to open file for writing:"<<fname<<'\n';
  144. return;
  145. }
  146. int dim_=dim;
  147. fwrite(&dim_,sizeof(int),2,f1);
  148. fwrite(data_ptr,sizeof(T),dim,f1);
  149. fclose(f1);
  150. }
  151. template <class T>
  152. inline size_t Vector<T>::Dim() const{
  153. return dim;
  154. }
  155. template <class T>
  156. inline size_t Vector<T>::Capacity() const{
  157. return capacity;
  158. }
  159. template <class T>
  160. void Vector<T>::Resize(size_t dim_,bool fit_size){
  161. ASSERT_WITH_MSG(own_data || capacity>=dim_, "Resizing array beyond capacity when own_data=false.");
  162. if(dim!=dim_) FreeDevice(false);
  163. if((capacity>dim_ && !fit_size) || capacity==dim_ || !own_data){
  164. dim=dim_;
  165. return;
  166. }
  167. {
  168. if(data_ptr!=NULL){
  169. mem::aligned_delete(data_ptr); data_ptr=NULL;
  170. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  171. Profile::Add_MEM(-capacity*sizeof(T));
  172. #endif
  173. }
  174. capacity=dim_;
  175. if(capacity>0){
  176. data_ptr=mem::aligned_new<T>(capacity);
  177. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  178. Profile::Add_MEM(capacity*sizeof(T));
  179. #endif
  180. }
  181. }
  182. dim=dim_;
  183. }
  184. template <class T>
  185. void Vector<T>::SetZero(){
  186. if(dim>0)
  187. memset(data_ptr,0,dim*sizeof(T));
  188. }
  189. template <class T>
  190. Vector<T>& Vector<T>::operator=(const Vector<T>& V){
  191. ASSERT_WITH_MSG(own_data || capacity>=V.dim, "Resizing array beyond capacity when own_data=false.");
  192. if(this!=&V){
  193. FreeDevice(false);
  194. if(own_data && capacity<V.dim){
  195. if(data_ptr!=NULL){
  196. mem::aligned_delete(data_ptr); data_ptr=NULL;
  197. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  198. Profile::Add_MEM(-capacity*sizeof(T));
  199. #endif
  200. }
  201. capacity=V.dim;
  202. if(capacity>0){
  203. data_ptr=mem::aligned_new<T>(capacity);
  204. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  205. Profile::Add_MEM(capacity*sizeof(T));
  206. #endif
  207. }
  208. }
  209. dim=V.dim;
  210. mem::memcopy(data_ptr,V.data_ptr,dim*sizeof(T));
  211. }
  212. return *this;
  213. }
  214. template <class T>
  215. Vector<T>& Vector<T>::operator=(const std::vector<T>& V){
  216. ASSERT_WITH_MSG(own_data || capacity>=V.size(), "Resizing array beyond capacity when own_data=false.");
  217. {
  218. FreeDevice(false);
  219. if(own_data && capacity<V.size()){
  220. if(data_ptr!=NULL){
  221. mem::aligned_delete(data_ptr); data_ptr=NULL;
  222. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  223. Profile::Add_MEM(-capacity*sizeof(T));
  224. #endif
  225. }
  226. capacity=V.size();
  227. if(capacity>0){
  228. data_ptr=mem::aligned_new<T>(capacity);
  229. #if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)
  230. Profile::Add_MEM(capacity*sizeof(T));
  231. #endif
  232. }
  233. }
  234. dim=V.size();
  235. mem::memcopy(data_ptr,&V[0],dim*sizeof(T));
  236. }
  237. return *this;
  238. }
  239. template <class T>
  240. inline T& Vector<T>::operator[](size_t j) const{
  241. assert(dim>0?j<dim:j==0); //TODO Change to (j<dim)
  242. return data_ptr[j];
  243. }
  244. }//end namespace