LAMA
|
00001 00035 #ifndef LAMA_LAMA_ARRAY_HPP_ 00036 #define LAMA_LAMA_ARRAY_HPP_ 00037 00038 // for dll_import 00039 #include <lama/config.hpp> 00040 00041 // base classes 00042 #include <lama/Printable.hpp> 00043 00044 // others 00045 #include <lama/LAMATypes.hpp> 00046 #include <lama/Context.hpp> 00047 #include <lama/Scalar.hpp> 00048 00049 // boost 00050 #include <boost/thread/recursive_mutex.hpp> 00051 00052 #include <vector> 00053 00058 #define LAMA_MAX_CONTEXTS 4 00059 00060 namespace lama 00061 { 00062 00063 class SyncToken; 00064 00065 // Forward declaration of friend classes. 00066 00067 template<typename T> 00068 class LAMAArrayView; 00069 00070 template<typename T> 00071 class LAMAArrayConstView; 00072 00078 class LAMA_DLL_IMPORTEXPORT _LAMAArray : public Printable 00079 { 00080 00081 public: 00082 00083 virtual ~_LAMAArray() {} 00084 00088 virtual Scalar::ScalarType getValueType() const = 0; 00089 00090 static std::auto_ptr<_LAMAArray> create( const Scalar::ScalarType ); 00091 00097 inline IndexType size() const; 00098 00099 protected: 00100 00101 explicit _LAMAArray( const IndexType n ) : mSize( n ), constFlag( false ) {} 00102 00103 IndexType mSize; 00104 00105 bool constFlag; 00106 00107 static size_t nContextIndex; // stands for no valid index 00108 }; 00109 00117 template<typename T> 00118 class LAMA_DLL_IMPORTEXPORT LAMAArray : public _LAMAArray 00119 { 00120 friend class LAMAArrayView<T>; 00121 friend class LAMAArrayConstView<T>; 00122 00123 public: 00124 00128 typedef T ValueType; 00129 00133 LAMAArray( ); 00134 00142 explicit LAMAArray( const IndexType n ); 00143 00153 LAMAArray( const IndexType n, const ValueType& value ); 00154 00164 template<typename OtherValueType> 00165 LAMAArray( const IndexType n, const OtherValueType* const values ); 00166 00175 LAMAArray( const LAMAArray<ValueType>& other ); 00176 00180 virtual ~LAMAArray(); 00181 00191 LAMAArray<ValueType>& operator= ( const LAMAArray<ValueType>& other ); 00192 00203 void assign( const LAMAArray<ValueType>& other, ContextPtr context ); 00204 00210 void swap( LAMAArray<ValueType>& other ); 00211 00224 void prefetch( ContextPtr context ) const; 00225 00232 bool isAvailableAt( ContextPtr context ) const; 00233 00241 ContextPtr getValidContext( const Context::ContextType preferredType = Context::Host) const; 00242 00246 void wait() const; 00247 00255 void clear(); 00256 00260 void purge(); 00261 00267 virtual void writeAt( std::ostream& stream ) const; 00268 00272 virtual Scalar::ScalarType getValueType() const; 00273 00274 protected: 00275 00276 using _LAMAArray::mSize; 00277 using _LAMAArray::constFlag; 00278 00279 ValueType* get( size_t index ); 00280 00281 const ValueType* get( const size_t index ) const; 00282 00283 void clear( const size_t index ); 00284 00285 void resize( const size_t index, const IndexType newSize ); 00286 00287 void reserve( const size_t index, const IndexType capacity, const bool copy ) const; 00288 00289 IndexType capacity( const size_t index ) const; 00290 00295 int acquireReadAccess( ContextPtr context ) const; 00296 00297 void releaseReadAccess( const size_t index ) const; 00298 00303 int acquireWriteAccess( ContextPtr context, bool keepFlag ); 00304 00305 int acquireWriteAccess(); 00306 00307 void releaseWriteAccess( const size_t index ); 00308 00309 void copy( const int toIndex, const int fromIndex ) const; 00310 00317 void fetch( Context::ContextData& target, const Context::ContextData& source ) const; 00318 00321 std::auto_ptr<SyncToken> fetchAsync( Context::ContextData& target, const Context::ContextData& source ) const; 00322 00323 void getAccess( size_t& contextIndex, size_t& validIndex, 00324 ContextPtr context, Context::ContextData::AccessKind kind ) const; 00325 00326 void setHostContext(); 00327 00328 mutable std::vector<Context::ContextData*> mContextData; // available context, pointers are never NULL 00329 00330 mutable std::auto_ptr<SyncToken> mSyncToken; 00331 00332 LAMA_LOG_DECL_STATIC_LOGGER( logger ); 00333 00334 static size_t nContextIndex; // stands for no valid index 00335 00336 mutable boost::recursive_mutex access_mutex; // needed to make accesses thread-safe 00337 }; 00338 00342 template<typename T> 00343 class LAMA_DLL_IMPORTEXPORT LAMAArrayRef : public LAMAArray<T> 00344 { 00345 public: 00346 00349 LAMAArrayRef( T* pointer, IndexType size ); 00350 00355 LAMAArrayRef( const T* pointer, IndexType size ); 00356 00357 protected: 00358 00359 using LAMAArray<T>::mSize; 00360 00361 using LAMAArray<T>::mContextData; 00362 using LAMAArray<T>::constFlag; 00363 }; 00364 00365 /* ---------------------------------------------------------------------------------*/ 00366 00367 inline IndexType _LAMAArray::size() const 00368 { 00369 return mSize; 00370 } 00371 00372 /* ---------------------------------------------------------------------------------*/ 00373 00374 template<typename ValueType> 00375 template<typename OtherValueType> 00376 LAMAArray<ValueType>::LAMAArray( const IndexType n, const OtherValueType* const values ) 00377 : _LAMAArray( n ), 00378 mSyncToken( 0 ) 00379 { 00380 setHostContext(); 00381 00382 if ( n <= 0 ) 00383 { 00384 LAMA_LOG_DEBUG( logger, "Zero-sized array with value constructed: " << *this ); 00385 return; 00386 } 00387 00388 Context::ContextData& host = *mContextData[0]; 00389 host.allocate( mSize * sizeof(ValueType) ); 00390 LAMA_LOG_DEBUG( logger, "constructed: " << *this ); 00391 00392 ValueType* host_pointer = static_cast<ValueType*>( host.pointer ); 00393 00394 #pragma omp parallel for schedule(LAMA_OMP_SCHEDULE) 00395 for ( int i = 0; i < mSize; ++i ) 00396 { 00397 host_pointer[i] = static_cast<ValueType>( values[i] ); 00398 } 00399 00400 host.valid = true; 00401 LAMA_LOG_DEBUG( logger, "constructed: " << *this ); 00402 } 00403 00404 } 00405 00406 #endif // LAMA_LAMA_ARRAY_HPP_