Skip to content

[libc][math] Add performance tests for fmul and fmull. #106262

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 28 additions & 22 deletions libc/test/src/math/performance_testing/BinaryOpSingleOutputPerf.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@

namespace LIBC_NAMESPACE_DECL {
namespace testing {

template <typename T> class BinaryOpSingleOutputPerf {
using FPBits = fputil::FPBits<T>;
template <typename OutputType, typename InputType>
class BinaryOpSingleOutputPerf {
using FPBits = fputil::FPBits<OutputType>;
using StorageType = typename FPBits::StorageType;
static constexpr StorageType UIntMax =
cpp::numeric_limits<StorageType>::max();

public:
typedef T Func(T, T);
typedef OutputType Func(InputType, InputType);

static void run_perf_in_range(Func myFunc, Func otherFunc,
StorageType startingBit, StorageType endingBit,
Expand All @@ -33,7 +33,7 @@ template <typename T> class BinaryOpSingleOutputPerf {
N = cpp::min(N, static_cast<size_t>(endingBit - startingBit));

auto runner = [=](Func func) {
[[maybe_unused]] volatile T result;
[[maybe_unused]] volatile OutputType result;
if (endingBit < startingBit) {
return;
}
Expand All @@ -42,8 +42,8 @@ template <typename T> class BinaryOpSingleOutputPerf {
for (size_t i = 0; i < rounds; i++) {
for (StorageType bitsX = startingBit, bitsY = endingBit;;
bitsX += step, bitsY -= step) {
T x = FPBits(bitsX).get_val();
T y = FPBits(bitsY).get_val();
InputType x = FPBits(bitsX).get_val();
InputType y = FPBits(bitsY).get_val();
result = func(x, y);
if (endingBit - bitsX < step) {
break;
Expand Down Expand Up @@ -94,10 +94,11 @@ template <typename T> class BinaryOpSingleOutputPerf {
1'000'001, rounds, log);
log << "\n Performance tests with inputs in normal range with exponents "
"close to each other:\n";
run_perf_in_range(myFunc, otherFunc,
/* startingBit= */ FPBits(T(0x1.0p-10)).uintval(),
/* endingBit= */ FPBits(T(0x1.0p+10)).uintval(),
1'000'001, rounds, log);
run_perf_in_range(
myFunc, otherFunc,
/* startingBit= */ FPBits(OutputType(0x1.0p-10)).uintval(),
/* endingBit= */ FPBits(OutputType(0x1.0p+10)).uintval(), 1'000'001,
rounds, log);
}

static void run_diff(Func myFunc, Func otherFunc, const char *logFile) {
Expand All @@ -115,8 +116,10 @@ template <typename T> class BinaryOpSingleOutputPerf {
log << "\n Diff tests with inputs in normal range with exponents "
"close to each other:\n";
diffCount += run_diff_in_range(
myFunc, otherFunc, /* startingBit= */ FPBits(T(0x1.0p-10)).uintval(),
/* endingBit= */ FPBits(T(0x1.0p+10)).uintval(), 10'000'001, log);
myFunc, otherFunc,
/* startingBit= */ FPBits(OutputType(0x1.0p-10)).uintval(),
/* endingBit= */ FPBits(OutputType(0x1.0p+10)).uintval(), 10'000'001,
log);

log << "Total number of differing results: " << diffCount << '\n';
}
Expand All @@ -125,18 +128,21 @@ template <typename T> class BinaryOpSingleOutputPerf {
} // namespace testing
} // namespace LIBC_NAMESPACE_DECL

#define BINARY_OP_SINGLE_OUTPUT_PERF(T, myFunc, otherFunc, filename) \
#define BINARY_OP_SINGLE_OUTPUT_PERF(OutputType, InputType, myFunc, otherFunc, \
filename) \
int main() { \
LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<T>::run_perf( \
&myFunc, &otherFunc, 1, filename); \
LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf< \
OutputType, InputType>::run_perf(&myFunc, &otherFunc, 1, filename); \
return 0; \
}

#define BINARY_OP_SINGLE_OUTPUT_PERF_EX(T, myFunc, otherFunc, rounds, \
filename) \
#define BINARY_OP_SINGLE_OUTPUT_PERF_EX(OutputType, InputType, myFunc, \
otherFunc, rounds, filename) \
{ \
LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<T>::run_perf( \
&myFunc, &otherFunc, rounds, filename); \
LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf<T>::run_perf( \
&myFunc, &otherFunc, rounds, filename); \
LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf< \
OutputType, InputType>::run_perf(&myFunc, &otherFunc, rounds, \
filename); \
LIBC_NAMESPACE::testing::BinaryOpSingleOutputPerf< \
OutputType, InputType>::run_perf(&myFunc, &otherFunc, rounds, \
filename); \
}
22 changes: 22 additions & 0 deletions libc/test/src/math/performance_testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -476,3 +476,25 @@ add_perf_binary(
COMPILE_OPTIONS
-fno-builtin
)

add_perf_binary(
fmul_perf
SRCS
fmul_perf.cpp
DEPENDS
.binary_op_single_output_diff
libc.src.math.fmul
COMPILE_OPTIONS
-fno-builtin
)

add_perf_binary(
fmull_perf
SRCS
fmull_perf.cpp
DEPENDS
.binary_op_single_output_diff
libc.src.math.fmull
COMPILE_OPTIONS
-fno-builtin
)
2 changes: 1 addition & 1 deletion libc/test/src/math/performance_testing/fmod_perf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@

#include <math.h>

BINARY_OP_SINGLE_OUTPUT_PERF(double, LIBC_NAMESPACE::fmod, ::fmod,
BINARY_OP_SINGLE_OUTPUT_PERF(double, double, LIBC_NAMESPACE::fmod, ::fmod,
"fmod_perf.log")
4 changes: 2 additions & 2 deletions libc/test/src/math/performance_testing/fmodf16_perf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
#define FMOD_FUNC(U) (LIBC_NAMESPACE::fputil::generic::FMod<float16, U>::eval)

int main() {
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, FMOD_FUNC(uint16_t),
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, float16, FMOD_FUNC(uint16_t),
FMOD_FUNC(uint32_t), 5000,
"fmodf16_u16_vs_u32_perf.log")

BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, FMOD_FUNC(uint16_t),
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, float16, FMOD_FUNC(uint16_t),
FMOD_FUNC(uint64_t), 5000,
"fmodf16_u16_vs_u64_perf.log")
return 0;
Expand Down
2 changes: 1 addition & 1 deletion libc/test/src/math/performance_testing/fmodf_perf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@

#include <math.h>

BINARY_OP_SINGLE_OUTPUT_PERF(float, LIBC_NAMESPACE::fmodf, ::fmodf,
BINARY_OP_SINGLE_OUTPUT_PERF(float, float, LIBC_NAMESPACE::fmodf, ::fmodf,
"fmodf_perf.log")
23 changes: 23 additions & 0 deletions libc/test/src/math/performance_testing/fmul_perf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- Performance test for the fmul 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 "BinaryOpSingleOutputPerf.h"
#include "src/math/fmul.h"

static constexpr size_t DOUBLE_ROUNDS = 40;

float fmul_placeholder_binary(double x, double y) {
return static_cast<float>(x * y);
}

int main() {
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, double, LIBC_NAMESPACE::fmul,
fmul_placeholder_binary, DOUBLE_ROUNDS,
"fmul_perf.log")
return 0;
}
23 changes: 23 additions & 0 deletions libc/test/src/math/performance_testing/fmull_perf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- Performance test for the fmull 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 "BinaryOpSingleOutputPerf.h"
#include "src/math/fmull.h"

static constexpr size_t LONG_DOUBLE_ROUNDS = 40;

float fmull_placeholder_binary(long double x, long double y) {
return static_cast<float>(x * y);
}

int main() {
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, long double, LIBC_NAMESPACE::fmull,
fmull_placeholder_binary, LONG_DOUBLE_ROUNDS,
"fmull_perf.log")
return 0;
}
2 changes: 1 addition & 1 deletion libc/test/src/math/performance_testing/hypot_perf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@

#include <math.h>

BINARY_OP_SINGLE_OUTPUT_PERF(double, LIBC_NAMESPACE::hypot, ::hypot,
BINARY_OP_SINGLE_OUTPUT_PERF(double, double, LIBC_NAMESPACE::hypot, ::hypot,
"hypot_perf.log")
2 changes: 1 addition & 1 deletion libc/test/src/math/performance_testing/hypotf_perf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@

#include <math.h>

BINARY_OP_SINGLE_OUTPUT_PERF(float, LIBC_NAMESPACE::hypotf, ::hypotf,
BINARY_OP_SINGLE_OUTPUT_PERF(float, float, LIBC_NAMESPACE::hypotf, ::hypotf,
"hypotf_perf.log")
32 changes: 16 additions & 16 deletions libc/test/src/math/performance_testing/max_min_funcs_perf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,39 +35,39 @@ float16 placeholder_binaryf16(float16 x, float16 y) { return x; }
float placeholder_binaryf(float x, float y) { return x; }

int main() {
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::fmaxf16,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, float16, LIBC_NAMESPACE::fmaxf16,
placeholder_binaryf16, FLOAT16_ROUNDS,
"fmaxf16_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::fminf16,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, float16, LIBC_NAMESPACE::fminf16,
placeholder_binaryf16, FLOAT16_ROUNDS,
"fminf16_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::fmaximumf16,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, float16, LIBC_NAMESPACE::fmaximumf16,
placeholder_binaryf16, FLOAT16_ROUNDS,
"fmaximumf16_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::fminimumf16,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, float16, LIBC_NAMESPACE::fminimumf16,
placeholder_binaryf16, FLOAT16_ROUNDS,
"fminimumf16_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::fmaximum_numf16,
placeholder_binaryf16, FLOAT16_ROUNDS,
"fmaximum_numf16_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::fminimum_numf16,
placeholder_binaryf16, FLOAT16_ROUNDS,
"fminimum_numf16_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(
float16, float16, LIBC_NAMESPACE::fmaximum_numf16, placeholder_binaryf16,
FLOAT16_ROUNDS, "fmaximum_numf16_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(
float16, float16, LIBC_NAMESPACE::fminimum_numf16, placeholder_binaryf16,
FLOAT16_ROUNDS, "fminimum_numf16_perf.log")

BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, LIBC_NAMESPACE::fmaxf, ::fmaxf,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, float, LIBC_NAMESPACE::fmaxf, ::fmaxf,
FLOAT_ROUNDS, "fmaxf_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, LIBC_NAMESPACE::fminf, ::fminf,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, float, LIBC_NAMESPACE::fminf, ::fminf,
FLOAT_ROUNDS, "fminf_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, LIBC_NAMESPACE::fmaximumf,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, float, LIBC_NAMESPACE::fmaximumf,
placeholder_binaryf, FLOAT_ROUNDS,
"fmaximumf_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, LIBC_NAMESPACE::fminimumf,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, float, LIBC_NAMESPACE::fminimumf,
placeholder_binaryf, FLOAT_ROUNDS,
"fminimumf_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, LIBC_NAMESPACE::fmaximum_numf,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, float, LIBC_NAMESPACE::fmaximum_numf,
placeholder_binaryf, FLOAT_ROUNDS,
"fmaximum_numf_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, LIBC_NAMESPACE::fminimum_numf,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, float, LIBC_NAMESPACE::fminimum_numf,
placeholder_binaryf, FLOAT_ROUNDS,
"fminimum_numf_perf.log")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ int main() {
SINGLE_INPUT_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::fabsf16,
placeholder_unaryf16, FLOAT16_ROUNDS,
"fabsf16_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, LIBC_NAMESPACE::copysignf16,
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float16, float16, LIBC_NAMESPACE::copysignf16,
placeholder_binaryf16, FLOAT16_ROUNDS,
"copysignf16_perf.log")

SINGLE_INPUT_SINGLE_OUTPUT_PERF_EX(float, LIBC_NAMESPACE::fabsf, fabsf,
FLOAT_ROUNDS, "fabsf_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, LIBC_NAMESPACE::copysignf, copysignf,
FLOAT_ROUNDS, "copysignf_perf.log")
BINARY_OP_SINGLE_OUTPUT_PERF_EX(float, float, LIBC_NAMESPACE::copysignf,
copysignf, FLOAT_ROUNDS, "copysignf_perf.log")

return 0;
}
Loading