cuda::isclose#
Defined in <cuda/numeric> header.
namespace cuda {
template <class T>
[[nodiscard]] __host__ __device__
bool isclose(T lhs, T rhs) noexcept;
template <class T>
[[nodiscard]] __host__ __device__
bool isclose(T lhs, T rhs, float relative_tol) noexcept;
template <class T>
[[nodiscard]] __host__ __device__
bool isclose(T lhs, T rhs, float relative_tol, T absolute_tol) noexcept;
template <class Complex>
[[nodiscard]] __host__ __device__
bool isclose(const Complex& lhs, const Complex& rhs) noexcept;
template <class Complex>
[[nodiscard]] __host__ __device__
bool isclose(const Complex& lhs, const Complex& rhs, float relative_tol) noexcept;
template <class Complex, class AbsTol>
[[nodiscard]] __host__ __device__
bool isclose(const Complex& lhs,
const Complex& rhs,
float relative_tol,
AbsTol absolute_tol) noexcept;
} // namespace cuda
cuda::isclose checks whether two values are approximately equal using the weak symmetric comparison in a similar manner to PEP 485:
abs(lhs - rhs) <= max(absolute_tol, relative_tol * max(abs(lhs), abs(rhs)))
For integral operands,
relative_tolis interpreted as its exact binary floating-point value. Comparing it to the integral difference is equivalent to rounding the relative threshold down to the nearest integer.The overloads without
relative_toluse a default relative tolerance based on half of available digits of accuracy. The default relative tolerance for integer types is 0.The overloads without
absolute_toluseabsolute_tol == 0.
Parameters
lhs: The first value to compare.rhs: The second value to compare.relative_tol: The relative tolerance. Passing0performs a purely absolute tolerance check whenabsolute_tolis non-zero.absolute_tol: The absolute tolerance. This is useful for comparisons near zero.
Return value
Returns
trueiflhsandrhsare close to each other, otherwise returnsfalse.
Preconditions
relative_tol: Must be in the range[0.0, 1.0].absolute_tol: Must be finite and non-negative.
Constraints
Scalar overloads require
lhs,rhs,absolute_tolto have the same arithmetic type (integer or floating point).Complex overloads accept
cuda::std::complex<T>andstd::complex<T>operands.AbsTolmust be the same type as the complex value type.
Special values
NaNis never close to any value, including anotherNaN.Infinity and negative infinity are only close to themselves.
Example#
#include <cuda/numeric>
#include <cuda/std/cassert>
#include <cuda/std/complex>
__global__ void kernel()
{
assert(cuda::isclose( 1.0f, 1.0f + 5e-6f));
assert(!cuda::isclose(1.0f, 1.0f + 2e-5f));
assert(cuda::isclose( 0.0f, 1e-12f, 0.0f, 1e-12f));
cuda::std::complex<float> z1{1.0f, 1.0f};
cuda::std::complex<float> z2{2.0f, 0.0f};
assert(cuda::isclose(z1, z2, 0.75f));
}
int main()
{
kernel<<<1, 1>>>();
cudaDeviceSynchronize();
}