Newer
Older
/***************************************************************************
-------------------
begin : 2005/07/05
copyright : (C) 2005 by Tomas Oberhuber
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
/* See Copyright Notice in tnl/Copyright */
#include <algorithm>
#include <TNL/Devices/CudaCallable.h>
template< typename T1, typename T2 >
using enable_if_same_base = std::enable_if< std::is_same< typename std::decay< T1 >::type, T2 >::value, T2 >;
template< typename T1, typename T2 >
using both_integral_or_floating = typename std::conditional<
( std::is_integral< T1 >::value && std::is_integral< T2 >::value ) ||
( std::is_floating_point< T1 >::value && std::is_floating_point< T2 >::value ),
std::true_type,
std::false_type >::type;
// 1. If both types are integral or floating-point, the larger type is selected.
// 2. If one type is integral and the other floating-point, the floating-point type is selected.
// Casting both arguments to the same type is necessary because std::min and std::max
// are implemented as a single-type template.
template< typename T1, typename T2 >
using larger_type = typename std::conditional<
( both_integral_or_floating< T1, T2 >::value && sizeof(T1) >= sizeof(T2) ) ||
std::is_floating_point<T1>::value,
T1, T2 >::type;
/***
* This function returns minimum of two numbers.
* GPU device code uses the functions defined in the CUDA's math_functions.h,
* MIC uses trivial override and host uses the STL functions.
template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
__cuda_callable__ inline
#if defined(__CUDA_ARCH__)
return ::min( (ResultType) a, (ResultType) b );
#elif defined(__MIC__)
return a < b ? a : b;
#endif
}
/***
* This function returns maximum of two numbers.
* GPU device code uses the functions defined in the CUDA's math_functions.h,
* MIC uses trivial override and host uses the STL functions.
template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
#if defined(__CUDA_ARCH__)
return ::max( (ResultType) a, (ResultType) b );
#elif defined(__MIC__)
return a > b ? a : b;
#endif
}
/***
* This function returns absolute value of given number.
*/
template< class T >
__cuda_callable__ inline
Tomáš Oberhuber
committed
{
Tomáš Oberhuber
committed
if( n < ( T ) 0 )
return -n;
return n;
Tomáš Oberhuber
committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/***
* This function returns argument of minimum of two numbers.
*/
template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
__cuda_callable__ inline
ResultType argMin( const T1& a, const T2& b )
{
return ( a < b ) ? a : b;
}
/***
* This function returns argument of maximum of two numbers.
*/
template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
__cuda_callable__
ResultType argMax( const T1& a, const T2& b )
{
return ( a > b ) ? a : b;
}
/***
* This function returns argument of minimum of absolute values of two numbers.
*/
template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
__cuda_callable__ inline
ResultType argAbsMin( const T1& a, const T2& b )
{
return ( TNL::abs( a ) < TNL::abs( b ) ) ? a : b;
}
/***
* This function returns argument of maximum of absolute values of two numbers.
*/
template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
__cuda_callable__
ResultType argAbsMax( const T1& a, const T2& b )
{
return ( TNL::abs( a ) > TNL::abs( b ) ) ? a : b;
}
template< typename T1, typename T2, typename ResultType = larger_type< T1, T2 > >
__cuda_callable__ inline
Tomáš Oberhuber
committed
{
#if defined(__CUDA_ARCH__) || defined(__MIC__)
return ::pow( (ResultType) base, (ResultType) exp );
return std::pow( (ResultType) base, (ResultType) exp );
Tomáš Oberhuber
committed
__cuda_callable__ inline
#if defined(__CUDA_ARCH__) || defined(__MIC__)
return ::sqrt( value );
#endif
}
template< typename Type >
void swap( Type& a, Type& b )
Tomáš Oberhuber
committed
{
Type tmp( a );
a = b;
b = tmp;
Tomáš Oberhuber
committed
Tomáš Oberhuber
committed
{
if( a < ( T ) 0 ) return ( T ) -1;
if( a == ( T ) 0 ) return ( T ) 0;
return ( T ) 1;
bool isSmall( const Real& v,
const Real& tolerance = 1.0e-5 )
{
return ( -tolerance <= v && v <= tolerance );
}
inline int roundUpDivision( const int num, const int div )
{
return num / div + ( num % div != 0 );
}
inline int roundToMultiple( int number, int multiple )
{
return multiple*( number/ multiple + ( number % multiple != 0 ) );
}
__cuda_callable__
inline bool isPow2( int x )
{
}
__cuda_callable__
inline bool isPow2( long int x )
{