Commit 65df15aa authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Implementing tnlLongVector as template with device as a parameter.

parent 8dbe1eb4
Loading
Loading
Loading
Loading
+288 −128
Original line number Diff line number Diff line
@@ -23,54 +23,126 @@
#include <core/tnlObject.h>
#include <core/param-types.h>

template< class T > class tnlLongVectorCUDA;
#ifdef HAVE_CUDA
#include <cuda_runtime.h>
void tnlLongVectorCUDASetValue( int* data,
                                const int size,
                                const int& v );

void tnlLongVectorCUDASetValue( float* data,
                                const int size,
                                const float& v );

void tnlLongVectorCUDASetValue( double* data,
                                const int size,
                                const double& v );

#else
#include <iostream>
using namespace std;
#endif


template< class T > class tnlLongVector : public tnlObject
enum tnlDevice { tnlHost, tnlCuda };

template< class T, tnlDevice device > class tnlLongVectorCUDA;


template< class T, tnlDevice device = tnlHost > class tnlLongVector : public tnlObject
{

   public:

	bool setNewSize( int _size );

    bool setNewSize( const tnlLongVector< T, device >& v )
    {
    	return setNewSize( v. GetSize() );
    };

   //! Constructor with given size
   tnlLongVector( const char* name = 0, int _size = 0 )
   : size( _size ), shared_data( false )
   : size( _size ), shared_data( false ), data( 0 )
   {
      if( name )
         SetName( name );
      data = new T[ size + 1 ];
      if( ! data )
      {
         cerr << "Unable to allocate new long vector with size " << size << "." << endl;
         abort();
      }
      data ++;
      setNewSize( _size );
   };

   //! Constructor with another long vector as template
   tnlLongVector( const tnlLongVector& v )
   : tnlObject( v ), size( v. size ), shared_data( false )
   : tnlObject( v ), size( v. size ), shared_data( false ), data( 0 )
   {
      data = new T[ size + 1 ];
      if( ! data )
	  setNewSize( v );
   };
   
   tnlLongVector( const tnlLongVectorCUDA< T, device >& v );

   tnlString getType() const;

   void setSharedData( T* _data, const int _size );

   int getSize() const
   {
         cerr << "Unable to allocate new long vector with size " << size << "." << endl;
         abort();
      }
      data ++;
      return size;
   };

   tnlLongVector( const tnlLongVectorCUDA< T >& v );
   //! Returns pointer to data
   /*! This is not clear from the OOP point of view however it is necessary for keeping 
       good performance of derived numerical structure like solvers.
    */
   // TODO: return zero pointer if size == 0
   const T* Data() const
   {
      return data;
   };

   tnlString GetType() const
   //! Returns pointer to data
   T* Data()
   {
      T t;
      return tnlString( "tnlLongVector< " ) + tnlString( GetParameterType( t ) ) + tnlString( " >" );
      return data;
   }
  
   operator bool() const
   {
      return ( GetSize() != 0 );
   };
   
   T& operator[] ( int i );
   
   const T& operator[] ( int i ) const;

   void Zeros(); // TODO: replace by setValue

   void setValue( const T& v );

   bool copyFrom( const tnlLongVector< T >& long_vector );

   bool copyFrom( const tnlLongVectorCUDA< T, device >& cuda_vector );

   virtual ~tnlLongVector();

   //! Method for saving the object to a file as a binary data
   bool Save( ostream& file ) const;

   //! Method for restoring the object from a file
   bool Load( istream& file );

   protected:

   int size;

   T* data;

   bool shared_data;
};

   bool SetNewSize( int _size )
template< class T, tnlDevice device > class tnlLongVector< T, tnlHost >
{
      if( size == _size ) return true;
      if( ! shared_data )
    bool setNewSize( int _size )
	{
    	if( tnlLongVector< T, device > :: size == _size ) return true;
    	if( data && ! shared_data )
    	{
    		delete[] -- data;
    		data = 0;
@@ -88,12 +160,13 @@ template< class T > class tnlLongVector : public tnlObject
    	return true;
	};

   bool SetNewSize( const tnlLongVector< T >& v )
    tnlString getType() const
    {
      return SetNewSize( v. GetSize() );
       T t;
       return tnlString( "tnlLongVector< " ) + tnlString( GetParameterType( t ) ) + tnlString( ", tnlHost >" );
    };

   void SetSharedData( T* _data, const int _size )
    void setSharedData( T* _data, const int _size )
    {
       if( data && ! shared_data ) delete -- data;
       data = _data;
@@ -101,32 +174,6 @@ template< class T > class tnlLongVector : public tnlObject
       size = _size;
    };

   int GetSize() const
   {
      return size;
   };

   //! Returns pointer to data
   /*! This is not clear from the OOP point of view however it is necessary for keeping 
       good performance of derived numerical structure like solvers.
    */
   // TODO: return zero pointer if size == 0
   const T* Data() const
   {
      return data;
   };

   //! Returns pointer to data
   T* Data()
   {
      return data;
   }
  
   operator bool() const
   {
      return ( GetSize() != 0 );
   };
   
    T& operator[] ( int i )
    {
       assert( i < size );
@@ -158,7 +205,7 @@ template< class T > class tnlLongVector : public tnlObject
       return true;
    };

   bool copyFrom( const tnlLongVectorCUDA< T >& cuda_vector );
    bool copyFrom( const tnlLongVectorCUDA< T, device >& cuda_vector );

    virtual ~tnlLongVector()
    {
@@ -204,19 +251,132 @@ template< class T > class tnlLongVector : public tnlObject
       if( file. bad() ) return false;
       return true;
    };
};

   protected:
template< class T, tnlDevice device > class tnlLongVector< T, tnlCuda >
{
    bool setNewSize( int _size )
	#ifdef HAVE_CUDA
	   {
	      dbgFunctionName( "tnlLongVectorCUDA", "setNewSize" );
	      dbgCout( "Setting new size to " << _size << " for " << GetName() );
	      if( size == _size ) return true;
	      if( data && ! shared_data )
	      {
	    	 dbgCout( "Freeing allocated memory on CUDA device of " << GetName() );
	         cudaFree( data );
	         data = NULL;
	      }
	      size = _size;
	      shared_data = false;
	      if( cudaMalloc( ( void** ) &data, size * sizeof( T ) ) != cudaSuccess )
	      {
	         cerr << "Unable to allocate new long vector with size "
	              << size * sizeof( T ) << " on CUDA device for "
	              << GetName() << "." << endl;
	         data = NULL;
	         size = 0;
	         return false;
	      }
	      return true;
	   };
	#else
	   {
	      cerr << "CUDA support is missing on this system." << endl;
	      return false;
	   };
	#endif

   int size;
    tnlString getType() const
    {
       T t;
       return tnlString( "tnlLongVector< " ) + tnlString( GetParameterType( t ) ) + tnlString( ", tnlCuda >" );
    };

   T* data;
    void setSharedData( T* _data, const int _size )
 #ifdef HAVE_CUDA
    {
       if( data && ! shared_data ) cudaFree( data );
       data = _data;
       shared_data = true;
       size = _size;
    };
 #else
    {
       cerr << "CUDA support is missing on this system." << endl;
    };
 #endif

    bool copyFrom( const tnlLongVector< T, tnlHost >& long_vector )
    {
 #ifdef HAVE_CUDA
       assert( long_vector. GetSize() == GetSize() );
       if( cudaMemcpy( data, long_vector. Data(), GetSize() * sizeof( T ), cudaMemcpyHostToDevice ) != cudaSuccess )
       {
          cerr << "Transfer of data from CUDA host ( " << long_vector. GetName()
               << " ) to CUDA device ( " << GetName() << " ) failed." << endl;
          return false;
       }
       return true;
 #else
       cerr << "CUDA support is missing on this system." << endl;
       return false;
 #endif
    };

    bool copyFrom( const tnlLongVectorCUDA< T >& long_vector, bool safe_mod = true )
    {
 #ifdef HAVE_CUDA
       assert( long_vector. GetSize() == GetSize() );
       if( cudaMemcpy( data, long_vector. Data(), GetSize() * sizeof( T ), cudaMemcpyDeviceToDevice ) != cudaSuccess )
       {
          cerr << "Transfer of data from CUDA host ( " << long_vector. GetName()
               << " ) to CUDA device ( " << GetName() << " ) failed." << endl;
          return false;
       }
       if( safe_mod )
          cudaThreadSynchronize();
       return true;
 #else
       cerr << "CUDA support is missing on this system." << endl;
       return false;
 #endif
    };

    void setValue( const T& c )
    {
 #ifdef HAVE_CUDA
       :: tnlLongVectorCUDASetValue( this -> Data(), this -> GetSize(), c );
 #else
       cerr << "CUDA support is missing on this system " << __FILE__ << " line " << __LINE__ << "." << endl;
 #endif
    };

    virtual
    ~tnlLongVectorCUDA()
    {
 	   dbgFunctionName( "tnlLongVectorCUDA", "~tnlLOngVectorCUDA" );
 #ifdef HAVE_CUDA
       if( data && ! shared_data )
       {
          dbgCout( "Freeing allocated memory of " << GetName() << " on CUDA device." );
          if( cudaFree( data ) != cudaSuccess )
          {
             cerr << "Unable to free alocated memory on CUDA device of " << GetName() << "." << endl;
          }
       }
 #else
       cerr << "CUDA support is missing on this system." << endl;
 #endif
    };

   bool shared_data;
};



#include <core/tnlLongVectorCUDA.h>

template< typename T > tnlLongVector< T > :: tnlLongVector( const tnlLongVectorCUDA< T >& v )
template< typename T, tnlDevice device > tnlLongVector< T, device > :: tnlLongVector( const tnlLongVectorCUDA< T, device >& v )
#ifdef HAVE_CUDA
         : tnlObject( v ), size( v. GetSize() ), shared_data( false )
{
@@ -234,7 +394,7 @@ template< typename T > tnlLongVector< T > :: tnlLongVector( const tnlLongVectorC
}
#endif

template< typename T > ostream& operator << ( ostream& o, const tnlLongVector< T >& v )
template< typename T, tnlDevice device > ostream& operator << ( ostream& o, const tnlLongVector< T, device >& v )
{
   int size = v. GetSize();
   int i;
@@ -244,7 +404,7 @@ template< typename T > ostream& operator << ( ostream& o, const tnlLongVector< T
   return o;
};

template< typename T > void Copy( const tnlLongVector< T >& v1,
template< typename T, tnlDevice device > void Copy( const tnlLongVector< T, device >& v1,
                                  tnlLongVector< T >& v2 )
{
   assert( v1. GetSize() == v2. GetSize() );
+2 −2
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ using namespace std;
#include <core/tnlLongVector.h>
#include <debug/tnlDebug.h>

template< class T > class tnlLongVectorCUDA : public tnlObject
template< class T, tnlDevice device = tnlHost > class tnlLongVectorCUDA : public tnlObject
{
   public:
   //! Constructor with given size
@@ -254,7 +254,7 @@ template< class T > class tnlLongVectorCUDA : public tnlObject
   //friend class tnlLongVectorCUDATester< T >;
};

template< class T > bool tnlLongVector< T > :: copyFrom( const tnlLongVectorCUDA< T >& cuda_vector )
template< class T, tnlDevice device > bool tnlLongVector< T, device > :: copyFrom( const tnlLongVectorCUDA< T, device >& cuda_vector )
{
#ifdef HAVE_CUDA
   assert( cuda_vector. GetSize() == GetSize() );
+1 −1
Original line number Diff line number Diff line
// Generated by Bisonc++ V2.4.7 on Thu, 27 May 2010 13:23:09 +0200
// Generated by Bisonc++ V2.4.7 on Fri, 04 Jun 2010 14:28:08 +0200

// $insert class.ih
#include "tnlDebugParser.ih"
+1 −1
Original line number Diff line number Diff line
// Generated by Bisonc++ V2.4.7 on Thu, 27 May 2010 13:23:09 +0200
// Generated by Bisonc++ V2.4.7 on Fri, 04 Jun 2010 14:28:08 +0200

#ifndef tnlDebugParserBase_h_included
#define tnlDebugParserBase_h_included
+2 −2
Original line number Diff line number Diff line
@@ -1944,10 +1944,10 @@ void tnlDebugfree (void * ptr )



/*int tnlDebugFlexLexer::yywrap()
int tnlDebugFlexLexer::yywrap()
{
   return 1;
}*/
}

extern int yywrap();
/*{
Loading