[libc][math] Add cbrtbf16 math function (#180327)
Add a bfloat16 implementation of cbrt along with corresponding smoke tests and an MPFR-based exhaustive unit test. Fixes #179729
This commit is contained in:
parent
b0d9d4d240
commit
cd7e200e42
@ -355,6 +355,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -361,6 +361,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -356,6 +356,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -171,6 +171,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -277,6 +277,7 @@ list(APPEND TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.llrintbf16
|
||||
libc.src.math.llroundbf16
|
||||
libc.src.math.log_bf16
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.logbbf16
|
||||
libc.src.math.lrintbf16
|
||||
libc.src.math.lroundbf16
|
||||
|
||||
@ -299,6 +299,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -299,6 +299,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -441,6 +441,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -268,6 +268,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.atanhf
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -445,6 +445,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -490,6 +490,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.canonicalizel
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.ceill
|
||||
|
||||
@ -147,6 +147,7 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.atanhf
|
||||
libc.src.math.cbrt
|
||||
libc.src.math.cbrtf
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.math.copysign
|
||||
libc.src.math.copysignf
|
||||
libc.src.math.copysignl
|
||||
|
||||
@ -281,7 +281,7 @@ Higher Math Functions
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| atanpi | | | | |check| | | | 7.12.4.10 | F.10.1.10 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| cbrt | |check| | |check| | | | | | 7.12.7.1 | F.10.4.1 |
|
||||
| cbrt | |check| | |check| | | | | |check| | 7.12.7.1 | F.10.4.1 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
| compoundn | | | | | | | 7.12.7.2 | F.10.4.2 |
|
||||
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
|
||||
|
||||
@ -93,6 +93,7 @@ add_math_entrypoint_object(iscanonicalbf16)
|
||||
|
||||
add_math_entrypoint_object(cbrt)
|
||||
add_math_entrypoint_object(cbrtf)
|
||||
add_math_entrypoint_object(cbrtbf16)
|
||||
|
||||
add_math_entrypoint_object(ceil)
|
||||
add_math_entrypoint_object(ceilf)
|
||||
|
||||
21
libc/src/math/cbrtbf16.h
Normal file
21
libc/src/math/cbrtbf16.h
Normal file
@ -0,0 +1,21 @@
|
||||
//===-- Implementation header for cbrtbf16 ----------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_CBRTBF16_H
|
||||
#define LLVM_LIBC_SRC_MATH_CBRTBF16_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/macros/properties/types.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
bfloat16 cbrtbf16(bfloat16 x);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_CBRTBF16_H
|
||||
@ -4937,6 +4937,20 @@ add_entrypoint_object(
|
||||
libc.src.__support.math.cbrt
|
||||
)
|
||||
|
||||
add_entrypoint_object (
|
||||
cbrtbf16
|
||||
SRCS
|
||||
cbrtbf16.cpp
|
||||
HDRS
|
||||
../cbrtbf16.h
|
||||
DEPENDS
|
||||
libc.src.__support.common
|
||||
libc.src.__support.FPUtil.bfloat16
|
||||
libc.src.math.generic.cbrt
|
||||
libc.src.__support.macros.config
|
||||
libc.src.__support.macros.properties.types
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
dmull
|
||||
SRCS
|
||||
|
||||
18
libc/src/math/generic/cbrtbf16.cpp
Normal file
18
libc/src/math/generic/cbrtbf16.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation of cbrtbf16 function -------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/math/cbrtbf16.h"
|
||||
#include "src/__support/FPUtil/bfloat16.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include "src/__support/math/cbrtf.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
LLVM_LIBC_FUNCTION(bfloat16, cbrtbf16, (bfloat16 x)) {
|
||||
return static_cast<bfloat16>(math::cbrtf(static_cast<float>(x)));
|
||||
}
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
@ -3011,6 +3011,18 @@ add_fp_unittest(
|
||||
libc.src.__support.FPUtil.fp_bits
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
cbrtbf16_test
|
||||
NEED_MPFR
|
||||
SUITE
|
||||
libc-math-unittests
|
||||
SRCS
|
||||
cbrtbf16_test.cpp
|
||||
DEPENDS
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.__support.FPUtil.bfloat16
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
dmull_test
|
||||
NEED_MPFR
|
||||
|
||||
35
libc/test/src/math/cbrtbf16_test.cpp
Normal file
35
libc/test/src/math/cbrtbf16_test.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
//===-- Exhaustive test for cbrtbf16 --------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/FPUtil/bfloat16.h"
|
||||
#include "src/math/cbrtbf16.h"
|
||||
#include "test/UnitTest/FPMatcher.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
#include "utils/MPFRWrapper/MPFRUtils.h"
|
||||
|
||||
using LlvmLibcCbrtbf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
|
||||
|
||||
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
|
||||
|
||||
// for the exhaustive test, we test with every 16-bit combination
|
||||
// and skip NaN cases. v is uint32_t to prevent integer overflow and
|
||||
// wraparound to 0.
|
||||
TEST_F(LlvmLibcCbrtbf16Test, Exhaustive) {
|
||||
for (uint32_t v = 0x00000; v < 0x10000; ++v) {
|
||||
bfloat16 x =
|
||||
LIBC_NAMESPACE::fputil::FPBits<bfloat16>(static_cast<uint16_t>(v))
|
||||
.get_val();
|
||||
|
||||
LIBC_NAMESPACE::fputil::FPBits<bfloat16> bits(x); // NaN checking
|
||||
if (bits.is_nan())
|
||||
continue;
|
||||
|
||||
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cbrt, x,
|
||||
LIBC_NAMESPACE::cbrtbf16(x), 0.5);
|
||||
}
|
||||
}
|
||||
@ -6018,6 +6018,17 @@ add_fp_unittest(
|
||||
libc.src.math.cbrt
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
cbrtbf16_test
|
||||
SUITE
|
||||
libc-math-smoke-tests
|
||||
SRCS
|
||||
cbrtbf16_test.cpp
|
||||
DEPENDS
|
||||
libc.src.math.cbrtbf16
|
||||
libc.src.__support.FPUtil.bfloat16
|
||||
)
|
||||
|
||||
add_fp_unittest(
|
||||
dmull_test
|
||||
SUITE
|
||||
|
||||
75
libc/test/src/math/smoke/cbrtbf16_test.cpp
Normal file
75
libc/test/src/math/smoke/cbrtbf16_test.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Unittests for cbrtbf16
|
||||
|
||||
#include "src/__support/FPUtil/bfloat16.h"
|
||||
#include "src/math/cbrtbf16.h"
|
||||
#include "test/UnitTest/FPMatcher.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
using LlvmLibcCbrtbf16Test = LIBC_NAMESPACE::testing::FPTest<bfloat16>;
|
||||
|
||||
using LIBC_NAMESPACE::testing::tlog;
|
||||
|
||||
TEST_F(LlvmLibcCbrtbf16Test, SpecialNumbers) {
|
||||
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::cbrtbf16(sNaN), FE_INVALID);
|
||||
EXPECT_MATH_ERRNO(0);
|
||||
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::cbrtbf16(aNaN));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::cbrtbf16(inf));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, LIBC_NAMESPACE::cbrtbf16(neg_inf));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::cbrtbf16(zero));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(neg_zero, LIBC_NAMESPACE::cbrtbf16(neg_zero));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(1.0f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(1.0f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-1.0f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(-1.0f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(2.0f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(8.0f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-2.0f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(-8.0f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(3.0f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(27.0f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-3.0f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(-27.0f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(5.0f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(125.0f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-5.0f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(-125.0f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(0x1.0p42f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(0x1.0p126f)));
|
||||
EXPECT_FP_EQ_ALL_ROUNDING(bfloat16(-0x1.0p42f),
|
||||
LIBC_NAMESPACE::cbrtbf16(bfloat16(-0x1.0p126f)));
|
||||
}
|
||||
|
||||
#ifdef LIBC_TEST_FTZ_DAZ
|
||||
|
||||
using namespace LIBC_NAMESPACE::testing;
|
||||
|
||||
// the float version includes explicit FTZ-mode checks for subnormal
|
||||
// outputs using hex expectations. for bfloat16, this is unnecessary.
|
||||
// if x=2^e then cbrt(x)=2^(e/3). to produce a subnormal result, we would
|
||||
// need e/3 < -126, i.e e<-378. Since the smallest representable exponent
|
||||
// in bfloat16 is -133, no finite bfloat16 input can produce a subnormal
|
||||
// cube root. therefore, explicit subnormal output checks are omitted here.
|
||||
|
||||
TEST_F(LlvmLibcCbrtbf16Test, DAZMode) {
|
||||
ModifyMXCSR mxcsr(DAZ);
|
||||
|
||||
EXPECT_FP_EQ(bfloat16(0.0f), LIBC_NAMESPACE::cbrtbf16(min_denormal));
|
||||
EXPECT_FP_EQ(bfloat16(0.0f), LIBC_NAMESPACE::cbrtbf16(max_denormal));
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcCbrtbf16Test, FTZDAZMode) {
|
||||
ModifyMXCSR mxcsr(FTZ | DAZ);
|
||||
|
||||
EXPECT_FP_EQ(bfloat16(0.0f), LIBC_NAMESPACE::cbrtbf16(min_denormal));
|
||||
EXPECT_FP_EQ(bfloat16(0.0f), LIBC_NAMESPACE::cbrtbf16(max_denormal));
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user