LvArray
limits.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors.
3  * All rights reserved.
4  * See the LICENSE file for details.
5  * SPDX-License-Identifier: (BSD-3-Clause)
6  */
7 
14 #pragma once
15 
16 // Source includes
17 #include "Macros.hpp"
18 
19 // System includes
20 #include <limits>
21 
22 #if defined( LVARRAY_USE_CUDA )
23  #include <cuda_fp16.h>
24 #endif
25 
26 namespace LvArray
27 {
28 
35 template< typename T >
36 struct NumericLimits : public std::numeric_limits< T >
37 {
39  static constexpr T min = std::numeric_limits< T >::min();
41  static constexpr T lowest = std::numeric_limits< T >::lowest();
43  static constexpr T max = std::numeric_limits< T >::max();
45  static constexpr T epsilon = std::numeric_limits< T >::epsilon();
47  static constexpr T round_error = std::numeric_limits< T >::round_error();
49  static constexpr T infinity = std::numeric_limits< T >::infinity();
51  static constexpr T quiet_NaN = std::numeric_limits< T >::quiet_NaN();
53  static constexpr T signaling_NaN = std::numeric_limits< T >::signaling_NaN();
55  static constexpr T denorm_min = std::numeric_limits< T >::denorm_min();
56 };
57 
58 #if defined( LVARRAY_USE_CUDA )
59 
63 template<>
64 struct NumericLimits< __half >
65 {
67  static constexpr float min = 1.0 / 16384;
69  static constexpr float lowest = -65504;
71  static constexpr float max = 65504;
73  static constexpr float epsilon = 1.0 / 1024;
75  static constexpr float denorm_min = 1.0 / 16777216;
76 };
77 
78 template<>
79 struct NumericLimits< __half2 > : public NumericLimits< __half >
80 {};
81 
82 #endif
83 
90 template< typename T >
92 {
103 };
104 
105 namespace internal
106 {
107 
113 template< typename T, typename U >
114 constexpr bool sameSignedness = ( std::is_signed< T >::value && std::is_signed< U >::value ) ||
115  ( std::is_unsigned< T >::value && std::is_unsigned< U >::value );
116 
122 template< typename INPUT, typename OUTPUT >
123 constexpr bool canEasilyConvert = sizeof( INPUT ) < sizeof( OUTPUT ) ||
124  ( sizeof( INPUT ) == sizeof( OUTPUT ) && sameSignedness< INPUT, OUTPUT > );
125 
126 } // namespace internal
127 
134 template< typename OUTPUT, typename INPUT >
135 std::enable_if_t< internal::canEasilyConvert< INPUT, OUTPUT >, OUTPUT >
136 inline constexpr LVARRAY_HOST_DEVICE
137 integerConversion( INPUT input )
138 {
139  static_assert( std::is_integral< INPUT >::value, "INPUT must be an integral type." );
140  static_assert( std::is_integral< OUTPUT >::value, "OUTPUT must be an integral type." );
141 
142 // return OUTPUT{ input };
143  return static_cast< OUTPUT >(input);
144 }
145 
152 template< typename OUTPUT, typename INPUT >
153 std::enable_if_t< !internal::canEasilyConvert< INPUT, OUTPUT > &&
154  std::is_unsigned< INPUT >::value,
155  OUTPUT >
156 inline LVARRAY_HOST_DEVICE
157 integerConversion( INPUT input )
158 {
159  static_assert( std::is_integral< INPUT >::value, "INPUT must be an integral type." );
160  static_assert( std::is_integral< OUTPUT >::value, "OUTPUT must be an integral type." );
161 
163 
164  return static_cast< OUTPUT >( input );
165 }
166 
173 template< typename OUTPUT, typename INPUT >
174 std::enable_if_t< !internal::canEasilyConvert< INPUT, OUTPUT > &&
175  !std::is_unsigned< INPUT >::value,
176  OUTPUT >
177 inline LVARRAY_HOST_DEVICE
178 integerConversion( INPUT input )
179 {
180  static_assert( std::is_integral< INPUT >::value, "INPUT must be an integral type." );
181  static_assert( std::is_integral< OUTPUT >::value, "OUTPUT must be an integral type." );
182 
183  LVARRAY_ERROR_IF_LT( input, std::make_signed_t< OUTPUT >{ NumericLimits< OUTPUT >::min } );
184 
185  // If OUTPUT is unsigned we convert input to an unsigned type. This is safe because it must be
186  // positive due to the check above.
187  using ConditionallyUnsigned = std::conditional_t< std::is_unsigned< OUTPUT >::value, std::make_unsigned_t< INPUT >, INPUT >;
188  LVARRAY_ERROR_IF_GT( ConditionallyUnsigned( input ), NumericLimits< OUTPUT >::max );
189 
190  return static_cast< OUTPUT >( input );
191 }
192 
193 }
static constexpr T min
The smallest finite value T can hold.
Definition: limits.hpp:39
#define LVARRAY_ERROR_IF_LT(lhs, rhs)
Raise a hard error if one value compares less than the other.
Definition: Macros.hpp:417
static constexpr T signaling_NaN
A signaling NaN (if T is a floating point).
Definition: limits.hpp:53
LVARRAY_HOST_DEVICE constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > min(T const a, T const b)
Definition: math.hpp:358
static constexpr T infinity
A positive infinity value (if T is a floating point).
Definition: limits.hpp:49
#define LVARRAY_ERROR_IF_GT(lhs, rhs)
Raise a hard error if one value compares greater than the other.
Definition: Macros.hpp:353
static constexpr T denorm_min
The smallest positive subnormal value (if T is a floating point).
Definition: limits.hpp:55
constexpr bool sameSignedness
True iff.
Definition: limits.hpp:114
constexpr bool canEasilyConvert
True iff.
Definition: limits.hpp:123
static constexpr T round_error
The maximum rounding error (if T is a floating point).
Definition: limits.hpp:47
The same as NumericLimits except the entries are not static or constexpr.
Definition: limits.hpp:91
The top level namespace.
Definition: Array.hpp:24
A wrapper for the std::numeric_limits< T > member functions, this allows their values to be used on d...
Definition: limits.hpp:36
static constexpr T quiet_NaN
A quiet NaN (if T is a floating point).
Definition: limits.hpp:51
Contains a bunch of macro definitions.
LVARRAY_HOST_DEVICE constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > max(T const a, T const b)
Definition: math.hpp:311
static constexpr T lowest
The lowest finite value T can hold.
Definition: limits.hpp:41
static constexpr T epsilon
The difference between 1.0 and the next representable value (if T is floating point).
Definition: limits.hpp:45
std::enable_if_t< internal::canEasilyConvert< INPUT, OUTPUT >, OUTPUT > constexpr LVARRAY_HOST_DEVICE integerConversion(INPUT input)
Definition: limits.hpp:137
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.
Definition: Macros.hpp:549
static constexpr T max
The largest finite value T can hold.
Definition: limits.hpp:43