LAMA
/home/brandes/workspace/LAMA/src/lama/LAMAArray.hpp
Go to the documentation of this file.
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_