00001 #ifndef PARALLEL_ARRAY_H 00002 #define PARALLEL_ARRAY_H 00003 00004 #include <parallel_common.h> 00005 #include <parallel_memory.h> 00006 00007 #include <stdio.h> 00008 #include <cstring> 00009 00010 namespace parallel_utils 00011 { 00012 00013 namespace ArrayTypes 00014 { 00016 enum ArrayType { HOST_ARRAY, DEVICE_ARRAY }; 00017 } 00018 typedef ArrayTypes::ArrayType ArrayType; 00019 00020 00021 #define BUFFER_MULTIPLIER 1.5 00022 #define BUFFER_MAX_THRESHOLD_MULTIPLIER .9 00023 #define BUFFER_MIN_THRESHOLD_MULTIPLIER .2 00025 00026 template <typename Type, typename RType, ParallelType PType> 00027 class ParallelArray 00028 { 00029 typedef MemManager<Type,PType> PMemManager; 00030 typedef typename PMemManager::mem_flags MemFlags; 00031 00032 public: 00033 00041 ParallelArray( ArrayType type = ArrayTypes::DEVICE_ARRAY, ArraySize size = 0, MemFlags flags = 0 ) 00042 : type_(type), size_(size), internalSize_(0), flags_(flags), buffer_(NULL) 00043 { 00044 realloc( ); 00045 } 00046 virtual ~ParallelArray() 00050 { 00051 dealloc( ); 00052 } 00053 00059 void setSize( ArraySize size ) 00060 { 00061 if( size_ != size ) 00062 { 00063 size_ = size; 00064 realloc(); 00065 } 00066 } 00067 00073 void setFlags( MemFlags flags ) 00074 { 00075 if( flags_ != flags ) 00076 { 00077 flags_ = flags; 00078 realloc(); 00079 } 00080 } 00081 00088 void print( const char* s, int stride = 1 ) const 00089 { 00090 printf("\n %s { ", s); 00091 for(ArraySize i = 0; i < getSize(); i += stride) 00092 printVal(buffer_[i]); 00093 printf("}\n"); 00094 } 00095 00096 inline void printVal(const int &a) const{ printf("%d ", a); } 00097 inline void printVal(const int4 &a) const { printf("(%d,%d,%d,%d) ", a.x, a.y, a.z, a.w); } 00098 inline void printVal(const float &a) const{ printf("%f ", a); } 00099 inline void printVal(const float3 &a) const { printf("(%f,%f,%f) ", a.x, a.y, a.z); } 00100 inline void printVal(const float4 &a) const { printf("(%f,%f,%f,%f) ", a.x, a.y, a.z, a.w); } 00101 inline void printVal(const double &a) const { printf("%f ", a); } 00102 inline void printVal(const double3 &a) const { printf("(%f,%f,%f) ", a.x, a.y, a.z); } 00103 inline void printVal(const double4 &a) const { printf("(%f,%f,%f,%f) ", a.x, a.y, a.z, a.w); } 00104 00105 inline bool isHostArray( ) const { return type_ == ArrayTypes::HOST_ARRAY; } 00106 inline bool isDeviceArray( ) const { return type_ == ArrayTypes::DEVICE_ARRAY; } 00107 inline ArrayType getType( ) const { return type_; } 00108 inline ArraySize getByteSize( ) const { return getByteSize( size_ ); } 00109 inline ArraySize getByteSize( ArraySize arraySize ) const { return arraySize * sizeof(Type); } 00110 inline ArraySize getSize( ) const { return size_; } 00111 inline ArraySize getInternalSize( ) const { return internalSize_; } 00112 inline ArraySize getInternalByteSize( ) const { return getByteSize( internalSize_ ); } 00113 inline MemFlags getFlags( ) const { return flags_; } 00114 inline RType getBuffer( ) { return buffer_; } 00115 inline RType getBuffer( ArraySize offset ) { return offsetBuffer<RType>(buffer_, offset); } 00116 00117 protected: 00118 00119 virtual void realloc( ) 00120 { 00121 if( size_ < internalSize_ * BUFFER_MIN_THRESHOLD_MULTIPLIER || 00122 size_ > internalSize_ * BUFFER_MAX_THRESHOLD_MULTIPLIER ) { 00123 dealloc(); 00124 internalSize_ = size_ * BUFFER_MULTIPLIER; 00125 if( isHostArray() ) PMemManager::allocateHost((void**)&this->buffer_, getInternalByteSize(), flags_ ); 00126 else PMemManager::allocateDevice( (typename PMemManager::device_init_type)&this->buffer_, getInternalByteSize() ); 00127 } 00128 } 00129 00130 virtual void dealloc( ) 00131 { 00132 if( internalSize_ == 0 ) return; 00133 if( isHostArray() ) PMemManager::freeHost( this->buffer_ ); 00134 else PMemManager::freeDevice( this->buffer_ ); 00135 this->buffer_ = NULL; 00136 } 00137 00138 private: 00139 00140 ArrayType type_; 00141 ArraySize size_; 00142 ArraySize internalSize_; 00143 MemFlags flags_; 00145 RType buffer_; 00147 }; 00148 00150 template <class Type, ParallelType PType> 00151 class ParallelHDArray 00152 { 00153 typedef MemManager<Type,PType> PMemManager; 00154 typedef typename PMemManager::device_type DType; 00155 typedef typename PMemManager::host_type HType; 00156 typedef typename PMemManager::stream_type SType; 00157 typedef typename PMemManager::mem_flags MemFlags; 00158 00159 public: 00160 00168 ParallelHDArray( ArraySize size = 0, MemFlags flags = 0, SType stream = 0) 00169 : stream_(stream), hostArray_( ArrayTypes::HOST_ARRAY, size, flags ), deviceArray_( ArrayTypes::DEVICE_ARRAY, size, flags ) 00170 { 00171 } 00172 00176 virtual ~ParallelHDArray() 00177 { 00178 } 00179 00187 inline void syncToHost( ArraySize offset, ArraySize length, CopyType copyType = CopyTypes::COPY_DEFAULT ) 00188 { 00189 if( getSize( ) <= 0 ) return; 00190 PMemManager::copyToHost( getHostBuffer( offset ), getDeviceBuffer( offset ), getByteSize( length ), copyType, stream_); 00191 } 00192 00200 inline void syncToDevice( ArraySize offset, ArraySize length, CopyType copyType = CopyTypes::COPY_DEFAULT ) 00201 { 00202 if( getSize( ) <= 0 ) return; 00203 PMemManager::copyToDevice( getDeviceBuffer( offset ), getHostBuffer( offset ), getByteSize( length ), copyType, stream_); 00204 } 00205 00211 inline void syncToHost( CopyType copyType = CopyTypes::COPY_DEFAULT ) { syncToHost(0, getSize(), copyType ); } 00212 00218 inline void syncToDevice( CopyType copyType = CopyTypes::COPY_DEFAULT ) { syncToDevice(0, getSize(), copyType ); } 00219 00225 void setSize( ArraySize size ) 00226 { 00227 hostArray_.setSize( size ); 00228 deviceArray_.setSize( size ); 00229 } 00230 00236 void setFlags( MemFlags flags ) 00237 { 00238 hostArray_.setFlags( flags ); 00239 deviceArray_.setFlags( flags ); 00240 } 00241 00248 void print( const char * s, int stride = 1 ) const { hostArray_.print( s, stride ); } 00249 00250 inline ArraySize getByteSize( ) const { return hostArray_.getByteSize(); } 00251 inline ArraySize getByteSize( ArraySize arraySize ) const { return hostArray_.getByteSize( arraySize ); } 00252 inline ArraySize getSize( ) const { return hostArray_.getSize(); } 00253 inline MemFlags getFlags( ) const { return hostArray_.getFlags(); } 00254 inline HType getHostBuffer( ) { return getHostBuffer( 0 ); } 00255 inline DType getDeviceBuffer( ) { return getDeviceBuffer( 0 ); } 00256 inline HType getHostBuffer( ArraySize offset ) { return hostArray_.getBuffer( offset ); } 00257 inline DType getDeviceBuffer( ArraySize offset ) { return deviceArray_.getBuffer( offset ); } 00258 00259 protected: 00260 00261 private: 00262 00263 SType stream_; 00265 ParallelArray<Type,HType,PType> hostArray_; 00266 ParallelArray<Type,DType,PType> deviceArray_; 00268 }; 00269 00270 } 00271 00272 #endif