| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 | /** * \file vector.txx * \author Dhairya Malhotra, dhairya.malhotra@gmail.com * \date 2-11-2011 * \brief This file contains implementation of the class Vector. */#include <cstdlib>#include <cstring>#include <cassert>#include <iomanip>#include <profile.hpp>#include <mem_utils.hpp>#include <device_wrapper.hpp>namespace pvfmm{template <class T>std::ostream& operator<<(std::ostream& output, const Vector<T>& V){  output<<std::fixed<<std::setprecision(4)<<std::setiosflags(std::ios::left);  for(size_t i=0;i<V.Dim();i++)    output<<std::setw(10)<<V[i]<<' ';  output<<";\n";  return output;}template <class T>Vector<T>::Vector(){  dim=0;  capacity=0;  own_data=true;  data_ptr=NULL;  dev.dev_ptr=(uintptr_t)NULL;}template <class T>Vector<T>::Vector(size_t dim_, T* data_, bool own_data_){  dim=dim_;  capacity=dim;  own_data=own_data_;  if(own_data){    if(dim>0){      data_ptr=mem::aligned_malloc<T>(capacity);#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)      Profile::Add_MEM(capacity*sizeof(T));#endif      if(data_!=NULL) mem::memcopy(data_ptr,data_,dim*sizeof(T));    }else data_ptr=NULL;  }else    data_ptr=data_;  dev.dev_ptr=(uintptr_t)NULL;}template <class T>Vector<T>::Vector(const Vector<T>& V){  dim=V.dim;  capacity=dim;  own_data=true;  if(dim>0){    data_ptr=mem::aligned_malloc<T>(capacity);#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)    Profile::Add_MEM(capacity*sizeof(T));#endif    mem::memcopy(data_ptr,V.data_ptr,dim*sizeof(T));  }else    data_ptr=NULL;  dev.dev_ptr=(uintptr_t)NULL;}template <class T>Vector<T>::Vector(const std::vector<T>& V){  dim=V.size();  capacity=dim;  own_data=true;  if(dim>0){    data_ptr=mem::aligned_malloc<T>(capacity);#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)    Profile::Add_MEM(capacity*sizeof(T));#endif    mem::memcopy(data_ptr,&V[0],dim*sizeof(T));  }else    data_ptr=NULL;  dev.dev_ptr=(uintptr_t)NULL;}template <class T>Vector<T>::~Vector(){  FreeDevice(false);  if(own_data){    if(data_ptr!=NULL){      mem::aligned_free(data_ptr);#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)      Profile::Add_MEM(-capacity*sizeof(T));#endif    }  }  data_ptr=NULL;  capacity=0;  dim=0;}template <class T>void Vector<T>::Swap(Vector<T>& v1){  size_t dim_=dim;  size_t capacity_=capacity;  T* data_ptr_=data_ptr;  bool own_data_=own_data;  Device dev_=dev;  dim=v1.dim;  capacity=v1.capacity;  data_ptr=v1.data_ptr;  own_data=v1.own_data;  dev=v1.dev;  v1.dim=dim_;  v1.capacity=capacity_;  v1.data_ptr=data_ptr_;  v1.own_data=own_data_;  v1.dev=dev_;}template <class T>void Vector<T>::ReInit(size_t dim_, T* data_, bool own_data_){  Vector<T> tmp(dim_,data_,own_data_);  this->Swap(tmp);}template <class T>typename Vector<T>::Device& Vector<T>::AllocDevice(bool copy){  if(dev.dev_ptr==(uintptr_t)NULL && dim>0) // Allocate data on device.    dev.dev_ptr=DeviceWrapper::alloc_device((char*)data_ptr, dim*sizeof(T));  if(dev.dev_ptr!=(uintptr_t)NULL && copy) // Copy data to device    DeviceWrapper::host2device((char*)data_ptr,(char*)data_ptr,dev.dev_ptr,dim*sizeof(T));  dev.dim=dim;  return dev;}template <class T>void Vector<T>::Device2Host(){  if(dev.dev_ptr==(uintptr_t)NULL) return;  DeviceWrapper::device2host((char*)data_ptr,dev.dev_ptr,(char*)data_ptr,dim*sizeof(T));}template <class T>void Vector<T>::FreeDevice(bool copy){  if(dev.dev_ptr==(uintptr_t)NULL) return;  if(copy) DeviceWrapper::device2host((char*)data_ptr,dev.dev_ptr,(char*)data_ptr,dim*sizeof(T));  DeviceWrapper::free_device((char*)data_ptr,dev.dev_ptr);  dev.dev_ptr=(uintptr_t)NULL;  dev.dim=0;}template <class T>void Vector<T>::Write(const char* fname){  FILE* f1=fopen(fname,"wb+");  if(f1==NULL){    std::cout<<"Unable to open file for writing:"<<fname<<'\n';    return;  }  int dim_=dim;  fwrite(&dim_,sizeof(int),2,f1);  fwrite(data_ptr,sizeof(T),dim,f1);  fclose(f1);}template <class T>inline size_t Vector<T>::Dim() const{  return dim;}template <class T>inline size_t Vector<T>::Capacity() const{  return capacity;}template <class T>void Vector<T>::Resize(size_t dim_,bool fit_size){  ASSERT_WITH_MSG(own_data || capacity>=dim_, "Resizing array beyond capacity when own_data=false.");  if(dim!=dim_) FreeDevice(false);  if((capacity>dim_ && !fit_size) || capacity==dim_ || !own_data){    dim=dim_;    return;  }  {    if(data_ptr!=NULL){      mem::aligned_free(data_ptr); data_ptr=NULL;#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)      Profile::Add_MEM(-capacity*sizeof(T));#endif    }    capacity=dim_;    if(capacity>0){      data_ptr=mem::aligned_malloc<T>(capacity);#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)      Profile::Add_MEM(capacity*sizeof(T));#endif    }  }  dim=dim_;}template <class T>void Vector<T>::SetZero(){  if(dim>0)    memset(data_ptr,0,dim*sizeof(T));}template <class T>Vector<T>& Vector<T>::operator=(const Vector<T>& V){  ASSERT_WITH_MSG(own_data || capacity>=V.dim, "Resizing array beyond capacity when own_data=false.");  if(this!=&V){    FreeDevice(false);    if(own_data && capacity<V.dim){      if(data_ptr!=NULL){        mem::aligned_free(data_ptr); data_ptr=NULL;#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)        Profile::Add_MEM(-capacity*sizeof(T));#endif      }      capacity=V.dim;      if(capacity>0){        data_ptr=mem::aligned_malloc<T>(capacity);#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)        Profile::Add_MEM(capacity*sizeof(T));#endif      }    }    dim=V.dim;    mem::memcopy(data_ptr,V.data_ptr,dim*sizeof(T));  }  return *this;}template <class T>Vector<T>& Vector<T>::operator=(const std::vector<T>& V){  ASSERT_WITH_MSG(own_data || capacity>=V.size(), "Resizing array beyond capacity when own_data=false.");  {    FreeDevice(false);    if(own_data && capacity<V.size()){      if(data_ptr!=NULL){        mem::aligned_free(data_ptr); data_ptr=NULL;#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)        Profile::Add_MEM(-capacity*sizeof(T));#endif      }      capacity=V.size();      if(capacity>0){        data_ptr=mem::aligned_malloc<T>(capacity);#if !defined(__MIC__) || !defined(__INTEL_OFFLOAD)        Profile::Add_MEM(capacity*sizeof(T));#endif      }    }    dim=V.size();    mem::memcopy(data_ptr,&V[0],dim*sizeof(T));  }  return *this;}template <class T>inline T& Vector<T>::operator[](size_t j) const{  assert(dim>0?j<dim:j==0); //TODO Change to (j<dim)  return data_ptr[j];}}//end namespace
 |