Files
TheRock/rocm-systems/projects/hip-tests/catch/unit/math/single_precision_intrinsics.cc
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

515 lines
18 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#include <hip_test_common.hh>
#include "unary_common.hh"
#include "binary_common.hh"
#include "ternary_common.hh"
/********** Unary Functions **********/
#define MATH_UNARY_SP_KERNEL_DEF(func_name) \
__global__ void func_name##_kernel(float* const ys, const size_t num_xs, float* const xs) { \
const auto tid = cg::this_grid().thread_rank(); \
const auto stride = cg::this_grid().size(); \
\
for (size_t i = tid; i < num_xs; i += stride) { \
ys[i] = func_name(xs[i]); \
} \
}
#define MATH_UNARY_SP_TEST_DEF_IMPL(func_name, ref_func, validator_builder) \
HIP_TEST_CASE(Unit_Device_##func_name##_Accuracy_Positive) { \
UnarySinglePrecisionTest(func_name##_kernel, ref_func, validator_builder); \
}
#define MATH_UNARY_SP_TEST_DEF(func_name, ref_func) \
MATH_UNARY_SP_TEST_DEF_IMPL(func_name, ref_func, func_name##_validator_builder)
#define MATH_UNARY_SP_VALIDATOR_BUILDER_DEF(func_name) \
static std::unique_ptr<MatcherBase<float>> func_name##_validator_builder(float target, float x)
static float __frcp_rn_ref(float x) { return 1.0f / x; }
MATH_UNARY_SP_KERNEL_DEF(__frcp_rn);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__frcp_rn(x)` for all possible inputs. The error bounds are
* IEEE-compliant.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF_IMPL(__frcp_rn, __frcp_rn_ref, EqValidatorBuilderFactory<float>());
MATH_UNARY_SP_KERNEL_DEF(__fsqrt_rn);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__fsqrt_rn(x)` for all possible inputs. The results are
* compared against reference function `float std::sqrt(float)`. The error bounds are
* IEEE-compliant.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF_IMPL(__fsqrt_rn, static_cast<float (*)(float)>(std::sqrt),
EqValidatorBuilderFactory<float>());
static float __frsqrt_rn_ref(float x) { return 1.0f / std::sqrt(x); }
MATH_UNARY_SP_KERNEL_DEF(__frsqrt_rn);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__frsqrt_rn(x)` for all possible inputs. The results are
* compared against reference function `float std::sqrt(float)`. The error bounds are
* IEEE-compliant.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF_IMPL(__frsqrt_rn, __frsqrt_rn_ref, EqValidatorBuilderFactory<float>());
MATH_UNARY_SP_VALIDATOR_BUILDER_DEF(__expf) {
const int64_t ulp_err = 2 + static_cast<int64_t>(std::floor(std::abs(1.16f * x)));
return ULPValidatorBuilderFactory<float>(ulp_err)(target);
}
MATH_UNARY_SP_KERNEL_DEF(__expf);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__expf(x)` for all possible inputs. The results are
* compared against reference function `double std::exp(double)`. The maximum ulp error is `2 +
* floor(abs(1.16 * x))`.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF(__expf, static_cast<double (*)(double)>(std::exp));
MATH_UNARY_SP_VALIDATOR_BUILDER_DEF(__exp10f) {
const int64_t ulp_err = 2 + static_cast<int64_t>(std::floor(std::abs(2.95f * x)));
return ULPValidatorBuilderFactory<float>(ulp_err)(target);
}
MATH_UNARY_SP_KERNEL_DEF(__exp10f);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__exp10f(x)` for all possible inputs. The results are
* compared against reference function `double exp10(double)`. The maximum ulp error is `2 +
* floor(abs(2.95 * x))`.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF(__exp10f, static_cast<double (*)(double)>(exp10));
MATH_UNARY_SP_VALIDATOR_BUILDER_DEF(__logf) {
if (0.5f <= x && x <= 2.0f) {
const auto abs_err = std::pow(2.0, -21.41);
return AbsValidatorBuilderFactory<float>(abs_err)(target);
} else {
return ULPValidatorBuilderFactory<float>(3)(target);
}
}
MATH_UNARY_SP_KERNEL_DEF(__logf);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__logf(x)` for all possible inputs. The results are
* compared against reference function `double std::log(double)`. For `x` in [0.5, 2], the maximum
* absolute error is 2^-21.41, otherwise, the maximum ulp error is 3.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF(__logf, static_cast<double (*)(double)>(std::log));
MATH_UNARY_SP_VALIDATOR_BUILDER_DEF(__log2f) {
if (0.5f <= x && x <= 2.0f) {
const auto abs_err = std::pow(2.0, -22.0);
return AbsValidatorBuilderFactory<float>(abs_err)(target);
} else {
return ULPValidatorBuilderFactory<float>(2)(target);
}
}
MATH_UNARY_SP_KERNEL_DEF(__log2f);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__log2f(x)` for all possible inputs. The results are
* compared against reference function `double std::log2(double)`. For `x` in [0.5, 2], the maximum
* absolute error is 2^-22, otherwise, the maximum ulp error is 2.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF(__log2f, static_cast<double (*)(double)>(std::log2));
MATH_UNARY_SP_VALIDATOR_BUILDER_DEF(__log10f) {
if (0.5f <= x && x <= 2.0f) {
const auto abs_err = std::pow(2.0, -24.0);
return AbsValidatorBuilderFactory<float>(abs_err)(target);
} else {
return ULPValidatorBuilderFactory<float>(3)(target);
}
}
MATH_UNARY_SP_KERNEL_DEF(__log10f);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__log10f(x)` for all possible inputs. The results are
* compared against reference function `double std::log10(double)`. For `x` in [0.5, 2], the maximum
* absolute error is 2^-24, otherwise, the maximum ulp error is 3.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF(__log10f, static_cast<double (*)(double)>(std::log10));
MATH_UNARY_SP_VALIDATOR_BUILDER_DEF(__sinf) {
if (-M_PI <= x && x <= M_PI) {
const auto abs_err = std::pow(2.0, -21.41);
return AbsValidatorBuilderFactory<float>(abs_err)(target);
} else {
return NopValidatorBuilderFactory<float>()();
}
}
MATH_UNARY_SP_KERNEL_DEF(__sinf);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__sinf(x)` for all possible inputs. The results are
* compared against reference function `double std::sin(double)`. For `x` in [-PI, PI], the maximum
* absolute error is 2^-21.41, and larger otherwise.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF(__sinf, static_cast<double (*)(double)>(std::sin));
__device__ float __sincosf_sin(float x) {
float sin, cos;
__sincosf(x, &sin, &cos);
return sin;
}
MATH_UNARY_SP_KERNEL_DEF(__sincosf_sin);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__sincosf(x, sptr, cptr)` for all possible inputs. The
* results in `sptr` are compared against reference function `double std::sin(double)`. For `x` in
* [-PI, PI], the maximum absolute error is 2^-21.41, and larger otherwise.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF_IMPL(__sincosf_sin, static_cast<double (*)(double)>(std::sin),
__sinf_validator_builder);
MATH_UNARY_SP_VALIDATOR_BUILDER_DEF(__cosf) {
if (-M_PI <= x && x <= M_PI) {
const auto abs_err = std::pow(2.0, -21.19);
return AbsValidatorBuilderFactory<float>(abs_err)(target);
} else {
return NopValidatorBuilderFactory<float>()();
}
}
MATH_UNARY_SP_KERNEL_DEF(__cosf);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__cosf(x)` for all possible inputs. The results are
* compared against reference function `double std::cos(double)`. For `x` in [-PI, PI], the maximum
* absolute error is 2^-21.19, and larger otherwise.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF(__cosf, static_cast<double (*)(double)>(std::cos));
__device__ float __sincosf_cos(float x) {
float sin, cos;
__sincosf(x, &sin, &cos);
return cos;
}
MATH_UNARY_SP_KERNEL_DEF(__sincosf_cos);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__sincosf(x, sptr, cptr)` for all possible inputs. The
* results in `cptr` are compared against reference function `double std::cos(double)`. For `x` in
* [-PI, PI], the maximum absolute error is 2^-21.19, and larger otherwise.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_UNARY_SP_TEST_DEF_IMPL(__sincosf_cos, static_cast<double (*)(double)>(std::cos),
__cosf_validator_builder);
/********** Binary Functions **********/
#define MATH_BINARY_SP_KERNEL_DEF(func_name) \
__global__ void func_name##_kernel(float* const ys, const size_t num_xs, float* const x1s, \
float* const x2s) { \
const auto tid = cg::this_grid().thread_rank(); \
const auto stride = cg::this_grid().size(); \
\
for (size_t i = tid; i < num_xs; i += stride) { \
ys[i] = func_name(x1s[i], x2s[i]); \
} \
}
#define MATH_BINARY_SP_TEST_DEF_IMPL(func_name, ref_func, validator_builder) \
HIP_TEST_CASE(Unit_Device_##func_name##_Accuracy_Positive) { \
BinaryFloatingPointTest(func_name##_kernel, ref_func, validator_builder); \
}
#define MATH_BINARY_SP_TEST_DEF(func_name, ref_func) \
MATH_BINARY_SP_TEST_DEF_IMPL(func_name, ref_func, func_name##_validator_builder)
#define MATH_BINARY_SP_VALIDATOR_BUILDER_DEF(func_name) \
static std::unique_ptr<MatcherBase<float>> func_name##_validator_builder(float target, float x1, \
float x2)
static float __fadd_rn_ref(float x1, float x2) { return x1 + x2; }
MATH_BINARY_SP_KERNEL_DEF(__fadd_rn);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__fadd_rn(x,y)` against a table of difficult values,
* followed by a large number of randomly generated values. The error bounds are IEEE-compliant.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_BINARY_SP_TEST_DEF_IMPL(__fadd_rn, __fadd_rn_ref, EqValidatorBuilderFactory<float>());
static float __fsub_rn_ref(float x1, float x2) { return x1 - x2; }
MATH_BINARY_SP_KERNEL_DEF(__fsub_rn);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__fsub_rn(x,y)` against a table of difficult values,
* followed by a large number of randomly generated values. The error bounds are IEEE-compliant.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_BINARY_SP_TEST_DEF_IMPL(__fsub_rn, __fsub_rn_ref, EqValidatorBuilderFactory<float>());
static float __fmul_rn_ref(float x1, float x2) { return x1 * x2; }
MATH_BINARY_SP_KERNEL_DEF(__fmul_rn);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__fmul_rn(x,y)` against a table of difficult values,
* followed by a large number of randomly generated values. The error bounds are IEEE-compliant.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_BINARY_SP_TEST_DEF_IMPL(__fmul_rn, __fmul_rn_ref, EqValidatorBuilderFactory<float>());
static float __fdiv_rn_ref(float x1, float x2) { return x1 / x2; }
MATH_BINARY_SP_KERNEL_DEF(__fdiv_rn);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__fdiv_rn(x,y)` against a table of difficult values,
* followed by a large number of randomly generated values. The error bounds are IEEE-compliant.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_BINARY_SP_TEST_DEF_IMPL(__fdiv_rn, __fdiv_rn_ref, EqValidatorBuilderFactory<float>());
MATH_BINARY_SP_VALIDATOR_BUILDER_DEF(__fdividef) {
x1 = 2.0f;
const auto abs_x2 = std::abs(x2);
if (std::pow(x1, -126.0f) <= abs_x2 && abs_x2 <= std::pow(x1, 126.0f)) {
return ULPValidatorBuilderFactory<float>(2)(target);
} else {
return NopValidatorBuilderFactory<float>()();
}
}
MATH_BINARY_SP_KERNEL_DEF(__fdividef);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__fdividef(x,y)` against a table of difficult values,
* followed by a large number of randomly generated values. For `|y|` in [2^-126, 2^126], the
* maximum ulp error is 2.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_BINARY_SP_TEST_DEF(__fdividef, __fdiv_rn_ref);
/********** Ternary Functions **********/
#define MATH_TERNARY_SP_KERNEL_DEF(func_name) \
__global__ void func_name##_kernel(float* const ys, const size_t num_xs, float* const x1s, \
float* const x2s, float* const x3s) { \
const auto tid = cg::this_grid().thread_rank(); \
const auto stride = cg::this_grid().size(); \
\
for (size_t i = tid; i < num_xs; i += stride) { \
ys[i] = func_name(x1s[i], x2s[i], x3s[i]); \
} \
}
#define MATH_TERNARY_SP_TEST_DEF_IMPL(func_name, ref_func, validator_builder) \
HIP_TEST_CASE(Unit_Device_##func_name##_Accuracy_Positive) { \
TernaryFloatingPointTest(func_name##_kernel, ref_func, validator_builder); \
}
#define MATH_TERNARY_SP_TEST_DEF(func_name, ref_func, validator_builder) \
MATH_TERNARY_SP_TEST_DEF_IMPL(func_name, ref_func, func_name##_validator_builder)
#define MATH_TERNARY_SP_VALIDATOR_BUILDER_DEF(func_name) \
static std::unique_ptr<MatcherBase<float>> func_name##_validator_builder(float target, float x1, \
float x2, float x3)
MATH_TERNARY_SP_KERNEL_DEF(__fmaf_rn);
/**
* Test Description
* ------------------------
* - Tests the numerical accuracy of `__fmaf(x,y,z)` against a table of difficult values,
* followed by a large number of randomly generated values. The error bounds are IEEE-compliant.
*
* Test source
* ------------------------
* - unit/math/single_precision_intrinsics.cc
* Test requirements
* ------------------------
* - HIP_VERSION >= 5.2
*/
MATH_TERNARY_SP_TEST_DEF_IMPL(__fmaf_rn, static_cast<float (*)(float, float, float)>(std::fma),
EqValidatorBuilderFactory<float>());