Skip to content

Commit

Permalink
Remove benchmarks and tests against hardware implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
Maratyszcza committed May 28, 2024
1 parent beb60cc commit 9b81155
Show file tree
Hide file tree
Showing 7 changed files with 0 additions and 273 deletions.
4 changes: 0 additions & 4 deletions bench/from-alt-array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
#include <functional>
#include <algorithm>

#if defined(__ARM_NEON__) || defined(__aarch64__)
#include <arm_neon.h>
#endif


static void fp16_alt_to_fp32_bits(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
Expand Down
111 changes: 0 additions & 111 deletions bench/from-ieee-array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@
#include <functional>
#include <algorithm>

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
#include <immintrin.h>
#endif

#if defined(__ARM_NEON__) || defined(__aarch64__)
#include <arm_neon.h>
#endif

#ifdef FP16_COMPARATIVE_BENCHMARKS
#include <third-party/THHalf.h>
#include <third-party/npy-halffloat.h>
Expand Down Expand Up @@ -75,109 +67,6 @@ static void fp16_ieee_to_fp32_value(benchmark::State& state) {
}
BENCHMARK(fp16_ieee_to_fp32_value)->RangeMultiplier(2)->Range(1<<10, 64<<20);

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
static void hardware_mm_cvtph_ps(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
auto rng = std::bind(std::uniform_real_distribution<float>(-1.0f, 1.0f), std::mt19937(seed));

std::vector<uint16_t> fp16(state.range(0));
std::vector<float> fp32(state.range(0));
std::generate(fp16.begin(), fp16.end(),
[&rng]{ return fp16_ieee_from_fp32_value(rng()); });

while (state.KeepRunning()) {
uint16_t* input = fp16.data();
benchmark::DoNotOptimize(input);

float* output = fp32.data();
const size_t n = state.range(0);
for (size_t i = 0; i < n; i += 4) {
_mm_storeu_ps(&output[i],
_mm_cvtph_ps(
_mm_loadl_epi64(static_cast<const __m128i*>(static_cast<const void*>(&input[i])))));
}

benchmark::DoNotOptimize(output);
}
state.SetItemsProcessed(int64_t(state.iterations()) * int64_t(state.range(0)));
}
BENCHMARK(hardware_mm_cvtph_ps)->RangeMultiplier(2)->Range(1<<10, 64<<20);

static void hardware_mm256_cvtph_ps(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
auto rng = std::bind(std::uniform_real_distribution<float>(-1.0f, 1.0f), std::mt19937(seed));

std::vector<uint16_t> fp16(state.range(0));
std::vector<float> fp32(state.range(0));
std::generate(fp16.begin(), fp16.end(),
[&rng]{ return fp16_ieee_from_fp32_value(rng()); });

while (state.KeepRunning()) {
uint16_t* input = fp16.data();
benchmark::DoNotOptimize(input);

float* output = fp32.data();
const size_t n = state.range(0);
for (size_t i = 0; i < n; i += 8) {
_mm256_storeu_ps(&output[i],
_mm256_cvtph_ps(
_mm_loadu_si128(static_cast<const __m128i*>(static_cast<const void*>(&input[i])))));
}

benchmark::DoNotOptimize(output);
}
state.SetItemsProcessed(int64_t(state.iterations()) * int64_t(state.range(0)));
}
BENCHMARK(hardware_mm256_cvtph_ps)->RangeMultiplier(2)->Range(1<<10, 64<<20);
#endif

#if defined(__ARM_NEON_FP) && (__ARM_NEON_FP & 0x2) || defined(__aarch64__)
static void hardware_vcvt_f32_f16(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
auto rng = std::bind(std::uniform_real_distribution<float>(-1.0f, 1.0f), std::mt19937(seed));

std::vector<uint16_t> fp16(state.range(0));
std::vector<float> fp32(state.range(0));
std::generate(fp16.begin(), fp16.end(),
[&rng]{ return fp16_ieee_from_fp32_value(rng()); });

while (state.KeepRunning()) {
uint16_t* input = fp16.data();
benchmark::DoNotOptimize(input);

float* output = fp32.data();
const size_t n = state.range(0);
#if defined(__aarch64__)
unsigned int fpcr;
__asm__ __volatile__("MRS %[fpcr], fpcr" : [fpcr] "=r" (fpcr));
/* Disable flush-to-zero (bit 24) and Alternative FP16 format (bit 26) */
__asm__ __volatile__("MSR fpcr, %[fpcr]" :
: [fpcr] "r" (fpcr & 0xF6FFFFFFu));
#else
unsigned int fpscr;
__asm__ __volatile__ ("VMRS %[fpscr], fpscr" : [fpscr] "=r" (fpscr));
/* Disable flush-to-zero (bit 24) and Alternative FP16 format (bit 26) */
__asm__ __volatile__ ("VMSR fpscr, %[fpscr]" :
: [fpscr] "r" (fpscr & 0xF6FFFFFFu));
#endif
for (size_t i = 0; i < n; i += 4) {
vst1q_f32(&output[i],
vcvt_f32_f16(
(float16x4_t) vld1_u16(&input[i])));
}
#if defined(__aarch64__)
__asm__ __volatile__("MSR fpcr, %[fpcr]" :: [fpcr] "r" (fpcr));
#else
__asm__ __volatile__ ("VMSR fpscr, %[fpscr]" :: [fpscr] "r" (fpscr));
#endif

benchmark::DoNotOptimize(output);
}
state.SetItemsProcessed(int64_t(state.iterations()) * int64_t(state.range(0)));
}
BENCHMARK(hardware_vcvt_f32_f16)->RangeMultiplier(2)->Range(1<<10, 64<<20);
#endif

#ifdef FP16_COMPARATIVE_BENCHMARKS
static void TH_halfbits2float(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
Expand Down
18 changes: 0 additions & 18 deletions bench/ieee-element.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

#include <fp16.h>

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
#include <immintrin.h>
#endif

#ifdef FP16_COMPARATIVE_BENCHMARKS
#include <third-party/THHalf.h>
#include <third-party/npy-halffloat.h>
Expand Down Expand Up @@ -141,20 +137,6 @@ static void fp16_ieee_from_fp32_value(benchmark::State& state) {
}
BENCHMARK(fp16_ieee_from_fp32_value);

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
static void fp16_ieee_from_fp32_hardware(benchmark::State& state) {
uint32_t fp32 = UINT32_C(0x7F800000);
while (state.KeepRunning()) {
const uint16_t fp16 = static_cast<uint16_t>(
_mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(fp32), _MM_FROUND_CUR_DIRECTION)));

fp32 = next_xorshift32(fp32);
benchmark::DoNotOptimize(fp16);
}
}
BENCHMARK(fp16_ieee_from_fp32_hardware);
#endif

#ifdef FP16_COMPARATIVE_BENCHMARKS
static void TH_float2halfbits(benchmark::State& state) {
uint32_t fp32 = UINT32_C(0x7F800000);
Expand Down
8 changes: 0 additions & 8 deletions bench/to-alt-array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@
#include <functional>
#include <algorithm>

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
#include <immintrin.h>
#endif

#if defined(__ARM_NEON__) || defined(__aarch64__)
#include <arm_neon.h>
#endif


static void fp16_alt_from_fp32_value(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
Expand Down
108 changes: 0 additions & 108 deletions bench/to-ieee-array.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@
#include <functional>
#include <algorithm>

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
#include <immintrin.h>
#endif

#if defined(__ARM_NEON__) || defined(__aarch64__)
#include <arm_neon.h>
#endif

#ifdef FP16_COMPARATIVE_BENCHMARKS
#include <third-party/THHalf.h>
#include <third-party/npy-halffloat.h>
Expand Down Expand Up @@ -49,106 +41,6 @@ static void fp16_ieee_from_fp32_value(benchmark::State& state) {
}
BENCHMARK(fp16_ieee_from_fp32_value)->RangeMultiplier(2)->Range(1<<10, 64<<20);

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
static void hardware_mm_cvtps_ph(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
auto rng = std::bind(std::uniform_real_distribution<float>(-1.0f, 1.0f), std::mt19937(seed));

std::vector<float> fp32(state.range(0));
std::vector<uint16_t> fp16(state.range(0));
std::generate(fp32.begin(), fp32.end(), std::ref(rng));

while (state.KeepRunning()) {
float* input = fp32.data();
benchmark::DoNotOptimize(input);

uint16_t* output = fp16.data();
const size_t n = state.range(0);
for (size_t i = 0; i < n; i += 4) {
_mm_storel_epi64(
static_cast<__m128i*>(static_cast<void*>(&output[i])),
_mm_cvtps_ph(_mm_loadu_ps(&input[i]), _MM_FROUND_CUR_DIRECTION));
}

benchmark::DoNotOptimize(output);
}
state.SetItemsProcessed(int64_t(state.iterations()) * int64_t(state.range(0)));
}
BENCHMARK(hardware_mm_cvtps_ph)->RangeMultiplier(2)->Range(1<<10, 64<<20);

static void hardware_mm256_cvtps_ph(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
auto rng = std::bind(std::uniform_real_distribution<float>(-1.0f, 1.0f), std::mt19937(seed));

std::vector<float> fp32(state.range(0));
std::vector<uint16_t> fp16(state.range(0));
std::generate(fp32.begin(), fp32.end(), std::ref(rng));

while (state.KeepRunning()) {
float* input = fp32.data();
benchmark::DoNotOptimize(input);

uint16_t* output = fp16.data();
const size_t n = state.range(0);
for (size_t i = 0; i < n; i += 8) {
_mm_storeu_si128(
static_cast<__m128i*>(static_cast<void*>(&output[i])),
_mm256_cvtps_ph(_mm256_loadu_ps(&input[i]), _MM_FROUND_CUR_DIRECTION));
}

benchmark::DoNotOptimize(output);
}
state.SetItemsProcessed(int64_t(state.iterations()) * int64_t(state.range(0)));
}
BENCHMARK(hardware_mm256_cvtps_ph)->RangeMultiplier(2)->Range(1<<10, 64<<20);
#endif

#if defined(__ARM_NEON_FP) && (__ARM_NEON_FP & 0x2) || defined(__aarch64__)
static void hardware_vcvt_f16_f32(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
auto rng = std::bind(std::uniform_real_distribution<float>(-1.0f, 1.0f), std::mt19937(seed));

std::vector<float> fp32(state.range(0));
std::vector<uint16_t> fp16(state.range(0));
std::generate(fp32.begin(), fp32.end(), std::ref(rng));

while (state.KeepRunning()) {
float* input = fp32.data();
benchmark::DoNotOptimize(input);

uint16_t* output = fp16.data();
const size_t n = state.range(0);
#if defined(__aarch64__)
unsigned int fpcr;
__asm__ __volatile__("MRS %[fpcr], fpcr" : [fpcr] "=r" (fpcr));
/* Disable flush-to-zero (bit 24) and Alternative FP16 format (bit 26) */
__asm__ __volatile__("MSR fpcr, %[fpcr]" :
: [fpcr] "r" (fpcr & 0xF6FFFFFFu));
#else
unsigned int fpscr;
__asm__ __volatile__ ("VMRS %[fpscr], fpscr" : [fpscr] "=r" (fpscr));
/* Disable flush-to-zero (bit 24) and Alternative FP16 format (bit 26) */
__asm__ __volatile__ ("VMSR fpscr, %[fpscr]" :
: [fpscr] "r" (fpscr & 0xF6FFFFFFu));
#endif
for (size_t i = 0; i < n; i += 4) {
vst1_u16(&output[i],
(uint16x4_t) vcvt_f16_f32(
vld1q_f32(&input[i])));
}
#if defined(__aarch64__)
__asm__ __volatile__("MSR fpcr, %[fpcr]" :: [fpcr] "r" (fpcr));
#else
__asm__ __volatile__ ("VMSR fpscr, %[fpscr]" :: [fpscr] "r" (fpscr));
#endif

benchmark::DoNotOptimize(output);
}
state.SetItemsProcessed(int64_t(state.iterations()) * int64_t(state.range(0)));
}
BENCHMARK(hardware_vcvt_f16_f32)->RangeMultiplier(2)->Range(1<<10, 64<<20);
#endif

#ifdef FP16_COMPARATIVE_BENCHMARKS
static void TH_float2halfbits(benchmark::State& state) {
const uint_fast32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
Expand Down
3 changes: 0 additions & 3 deletions test/alt-from-fp32-value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
#include <fp16.h>
#include <tables.h>

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
#include <x86intrin.h>
#endif


TEST(FP16_ALT_FROM_FP32_VALUE, normalized_powers_of_2) {
Expand Down
21 changes: 0 additions & 21 deletions test/ieee-from-fp32-value.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
#include <fp16.h>
#include <tables.h>

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
#include <x86intrin.h>
#endif


TEST(FP16_IEEE_FROM_FP32_VALUE, normalized_powers_of_2) {
const uint16_t min_po2_f16 = UINT16_C(0x0400);
Expand Down Expand Up @@ -504,20 +500,3 @@ TEST(FP16_IEEE_FROM_FP32_VALUE, negative_normalized_values) {
}
}
}

#if (defined(__i386__) || defined(__x86_64__)) && defined(__F16C__)
TEST(FP16_IEEE_FROM_FP32_VALUE, match_hardware) {
const uint32_t min_nonzero = UINT32_C(0x00000001);
const uint32_t max_finite = UINT32_C(0x7F800000);
for (uint32_t bits = min_nonzero; bits < max_finite; bits++) {
float value;
memcpy(&value, &bits, sizeof(value));
const uint16_t reference = uint16_t(_mm_cvtsi128_si32(_mm_cvtps_ph(_mm_set_ss(value), _MM_FROUND_CUR_DIRECTION)));
ASSERT_EQ(reference, fp16_ieee_from_fp32_value(value)) <<
std::hex << std::uppercase << std::setfill('0') <<
"F32 = 0x" << std::setw(8) << bits << ", " <<
"F16(F32) = 0x" << std::setw(4) << fp16_ieee_from_fp32_value(value) << ", " <<
"F16 = 0x" << std::setw(4) << reference;
}
}
#endif

0 comments on commit 9b81155

Please sign in to comment.