diff --git a/src/TNL/Math.h b/src/TNL/Math.h index 67e9f5e082af0b238e1d045bc516bf578efe82a0..2d81bea6678a41508ea8a1bdfa19d93b0c831c01 100644 --- a/src/TNL/Math.h +++ b/src/TNL/Math.h @@ -168,6 +168,24 @@ T sign( const T& a ) return ( T ) 1; } +template< class T > +__cuda_callable__ +bool isNan( const T& v ) +{ +#if defined HAVE_CUDA + #if defined(__CUDA_ARCH__) + return isnan( v ); + #else + #if defined (__GNUC__) && ( __GNUC__ < 5 ) + return false; + #else + return std::isnan( v ); + #endif + #endif +#else + return std::isnan( v ); +#endif +} template< typename Real > __cuda_callable__ bool isSmall( const Real& v, diff --git a/src/TNL/Pointers/SharedPointerCuda.h b/src/TNL/Pointers/SharedPointerCuda.h index f2a8c40ea42c7f32ebf647a77654c0b1c098c9ba..810d85e99125bea191cd112e88771b8ef2488322 100644 --- a/src/TNL/Pointers/SharedPointerCuda.h +++ b/src/TNL/Pointers/SharedPointerCuda.h @@ -17,8 +17,9 @@ #include <TNL/Devices/Cuda.h> #include <TNL/Pointers/SmartPointer.h> -#include <cstring> // std::memcpy, std::memcmp -#include <cstddef> // std::nullptr_t +#include <cstring> // std::memcpy, std::memcmp +#include <cstddef> // std::nullptr_t +#include <algorithm> // swap //#define TNL_DEBUG_SHARED_POINTERS @@ -67,7 +68,7 @@ class SharedPointer< Object, Devices::Cuda > : public SmartPointer using ObjectType = Object; using DeviceType = Devices::Cuda; - using ThisType = SharedPointer< Object, Devices::Host >; + using ThisType = SharedPointer< Object, Devices::Cuda >; SharedPointer( std::nullptr_t ) : pd( nullptr ) @@ -321,7 +322,7 @@ class SharedPointer< Object, Devices::Cuda > : public SmartPointer using ObjectType = Object; using DeviceType = Devices::Cuda; - using ThisType = SharedPointer< Object, Devices::Host >; + using ThisType = SharedPointer< Object, Devices::Cuda >; SharedPointer( std::nullptr_t ) : pd( nullptr ), diff --git a/src/TNL/Pointers/SharedPointerHost.h b/src/TNL/Pointers/SharedPointerHost.h index 6f1d05d3df459789a3feb58f31cb8d560d5f6ac0..f6c45cf710e6901c9a5f23ec4b02de295d48d62f 100644 --- a/src/TNL/Pointers/SharedPointerHost.h +++ b/src/TNL/Pointers/SharedPointerHost.h @@ -18,7 +18,8 @@ #include <TNL/Devices/CudaCallable.h> #include <TNL/Pointers/SmartPointer.h> -#include <cstddef> // std::nullptr_t +#include <cstddef> // std::nullptr_t +#include <algorithm> // swap namespace TNL { namespace Pointers { diff --git a/src/TNL/Pointers/SharedPointerMic.h b/src/TNL/Pointers/SharedPointerMic.h index b572a9859721a8ba1c37fdb09d407d36f780e5a0..3acea10bc8eb14a8753fce3a598e62011a06edb7 100644 --- a/src/TNL/Pointers/SharedPointerMic.h +++ b/src/TNL/Pointers/SharedPointerMic.h @@ -17,8 +17,9 @@ #include <TNL/Devices/MIC.h> #include <TNL/Pointers/SmartPointer.h> -#include <cstring> // std::memcpy, std::memcmp -#include <cstddef> // std::nullptr_t +#include <cstring> // std::memcpy, std::memcmp +#include <cstddef> // std::nullptr_t +#include <algorithm> // swap namespace TNL { namespace Pointers { @@ -44,7 +45,7 @@ class SharedPointer< Object, Devices::MIC > : public SmartPointer using ObjectType = Object; using DeviceType = Devices::MIC; - using ThisType = SharedPointer< Object, Devices::Host >; + using ThisType = SharedPointer< Object, Devices::MIC >; SharedPointer( std::nullptr_t ) : pd( nullptr ), diff --git a/src/TNL/Solvers/IterativeSolver_impl.h b/src/TNL/Solvers/IterativeSolver_impl.h index 333c38cd44a54478d01b439dbc27780711b44ac1..e65b3cdd412c899b6803b2129f193c9846c05766 100644 --- a/src/TNL/Solvers/IterativeSolver_impl.h +++ b/src/TNL/Solvers/IterativeSolver_impl.h @@ -107,7 +107,7 @@ bool IterativeSolver< Real, Index> :: checkNextIteration() { this->refreshSolverMonitor(); - if( std::isnan( this->getResidue() ) || + if( isNan( this->getResidue() ) || this->getIterations() > this->getMaxIterations() || ( this->getResidue() > this->getDivergenceResidue() && this->getIterations() >= this->getMinIterations() ) || ( this->getResidue() < this->getConvergenceResidue() && this->getIterations() >= this->getMinIterations() ) ) @@ -120,7 +120,7 @@ bool IterativeSolver< Real, Index>:: checkConvergence() { - if( std::isnan( this->getResidue() ) ) + if( isNan( this->getResidue() ) ) { std::cerr << std::endl << "The residue is NaN." << std::endl; return false; diff --git a/src/TNL/Solvers/Linear/BICGStabL_impl.h b/src/TNL/Solvers/Linear/BICGStabL_impl.h index 6606bddd561fa8a8d5b3ce5e8855b6e41541b546..467f1a91a04c018377863b27ac85985759eb988d 100644 --- a/src/TNL/Solvers/Linear/BICGStabL_impl.h +++ b/src/TNL/Solvers/Linear/BICGStabL_impl.h @@ -87,7 +87,7 @@ BICGStabL< Matrix >::solve( ConstVectorViewType b, VectorViewType x ) } sigma[ 0 ] = r_0.lpNorm( 2.0 ); - if( std::isnan( sigma[ 0 ] ) ) + if( isNan( sigma[ 0 ] ) ) throw std::runtime_error( "BiCGstab(ell): initial residue is NAN" ); r_ast = r_0; diff --git a/src/UnitTests/Pointers/SharedPointerCudaTest.cu b/src/UnitTests/Pointers/SharedPointerCudaTest.cu index 76241e28fc5889aec8fa92c251f29190c18509c4..813054c140fc9ec7aa07784adf596670d5d17c40 100644 --- a/src/UnitTests/Pointers/SharedPointerCudaTest.cu +++ b/src/UnitTests/Pointers/SharedPointerCudaTest.cu @@ -121,6 +121,19 @@ TEST( SharedPointerCudaTest, nullptrAssignement ) #endif } +TEST( SharedPointerCudaTest, swap ) +{ +#ifdef HAVE_CUDA + using TestType = Pointers::SharedPointer< double, Devices::Cuda >; + TestType p1( 1 ), p2( 2 ); + + p1.swap( p2 ); + + ASSERT_EQ( *p1, 2 ); + ASSERT_EQ( *p2, 1 ); +#endif +} + #endif diff --git a/src/UnitTests/Pointers/SharedPointerHostTest.cpp b/src/UnitTests/Pointers/SharedPointerHostTest.cpp index 49fe6531df026697fa0babe9d14bd2237945c9ec..b7d441f70e8e714cd911ae27d8e3a6a92204277e 100644 --- a/src/UnitTests/Pointers/SharedPointerHostTest.cpp +++ b/src/UnitTests/Pointers/SharedPointerHostTest.cpp @@ -51,6 +51,17 @@ TEST( SharedPointerCudaTest, nullptrAssignement ) ASSERT_FALSE( p2 ); } +TEST( SharedPointerCudaTest, swap ) +{ + using TestType = Pointers::SharedPointer< double, Devices::Host >; + TestType p1( 1 ), p2( 2 ); + + p1.swap( p2 ); + + ASSERT_EQ( *p1, 2 ); + ASSERT_EQ( *p2, 1 ); +} + #endif #include "../GtestMissingError.h"