summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2021-03-09 08:43:35 +0000
committerArne Juul <arnej@verizonmedia.com>2021-03-09 08:43:35 +0000
commitc0d50a1c0ccd6b957e7cf93f38b053e99a9fc7b9 (patch)
treed19e30fa9a6ab1ddc007a7f14623e04e4d996ad7
parent2a4b09916eeccbccd855c94885b3ff438ba37261 (diff)
add Int8Float class
-rw-r--r--eval/CMakeLists.txt1
-rw-r--r--eval/src/tests/eval/int8float/CMakeLists.txt9
-rw-r--r--eval/src/tests/eval/int8float/int8float_test.cpp59
-rw-r--r--eval/src/vespa/eval/eval/CMakeLists.txt1
-rw-r--r--eval/src/vespa/eval/eval/int8float.cpp3
-rw-r--r--eval/src/vespa/eval/eval/int8float.h46
6 files changed, 119 insertions, 0 deletions
diff --git a/eval/CMakeLists.txt b/eval/CMakeLists.txt
index 05ac4cb78ab..7d3d94d7ed6 100644
--- a/eval/CMakeLists.txt
+++ b/eval/CMakeLists.txt
@@ -21,6 +21,7 @@ vespa_define_module(
src/tests/eval/gbdt
src/tests/eval/gen_spec
src/tests/eval/inline_operation
+ src/tests/eval/int8float
src/tests/eval/interpreted_function
src/tests/eval/multiply_add
src/tests/eval/nested_loop
diff --git a/eval/src/tests/eval/int8float/CMakeLists.txt b/eval/src/tests/eval/int8float/CMakeLists.txt
new file mode 100644
index 00000000000..fb258f46fc2
--- /dev/null
+++ b/eval/src/tests/eval/int8float/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(eval_int8float_test_app TEST
+ SOURCES
+ int8float_test.cpp
+ DEPENDS
+ vespaeval
+ GTest::GTest
+)
+vespa_add_test(NAME eval_int8float_test_app COMMAND eval_int8float_test_app)
diff --git a/eval/src/tests/eval/int8float/int8float_test.cpp b/eval/src/tests/eval/int8float/int8float_test.cpp
new file mode 100644
index 00000000000..9debf712150
--- /dev/null
+++ b/eval/src/tests/eval/int8float/int8float_test.cpp
@@ -0,0 +1,59 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include <vespa/eval/eval/int8float.h>
+#include <vespa/vespalib/objects/nbostream.h>
+#include <vespa/vespalib/gtest/gtest.h>
+#include <cmath>
+
+using namespace vespalib;
+using namespace vespalib::eval;
+
+static std::vector<float> simple_values = {
+ 0.0, 1.0, -1.0, -17.0, 42.0, 127.0, -128.0
+};
+
+TEST(Int8FloatTest, normal_usage) {
+ EXPECT_EQ(sizeof(float), 4);
+ EXPECT_EQ(sizeof(Int8Float), 1);
+ Int8Float answer = 42;
+ double fortytwo = answer;
+ EXPECT_EQ(fortytwo, 42);
+ for (float value : simple_values) {
+ Int8Float b = value;
+ float recover = b;
+ EXPECT_EQ(value, recover);
+ }
+ // undefined behavior here:
+ Int8Float b1 = 128.0;
+ EXPECT_NE(float(b1), 128.0);
+ Int8Float b2 = -129.0;
+ EXPECT_NE(float(b2), -129.0);
+}
+
+TEST(Int8FloatTest, with_nbostream) {
+ nbostream buf;
+ for (Int8Float value : simple_values) {
+ buf << value;
+ }
+ for (float value : simple_values) {
+ Int8Float stored;
+ buf >> stored;
+ EXPECT_EQ(float(stored), value);
+ }
+}
+
+TEST(Int8FloatTest, traits_check) {
+ EXPECT_TRUE(std::is_trivially_constructible<Int8Float>::value);
+ EXPECT_TRUE(std::is_trivially_move_constructible<Int8Float>::value);
+ EXPECT_TRUE(std::is_trivially_default_constructible<Int8Float>::value);
+ EXPECT_TRUE((std::is_trivially_assignable<Int8Float,Int8Float>::value));
+ EXPECT_TRUE(std::is_trivially_move_assignable<Int8Float>::value);
+ EXPECT_TRUE(std::is_trivially_copy_assignable<Int8Float>::value);
+ EXPECT_TRUE(std::is_trivially_copyable<Int8Float>::value);
+ EXPECT_TRUE(std::is_trivially_destructible<Int8Float>::value);
+ EXPECT_TRUE(std::is_trivial<Int8Float>::value);
+ EXPECT_TRUE(std::is_swappable<Int8Float>::value);
+ EXPECT_TRUE(std::has_unique_object_representations<Int8Float>::value);
+}
+
+GTEST_MAIN_RUN_ALL_TESTS()
diff --git a/eval/src/vespa/eval/eval/CMakeLists.txt b/eval/src/vespa/eval/eval/CMakeLists.txt
index 2c0922e617c..639ac3b5864 100644
--- a/eval/src/vespa/eval/eval/CMakeLists.txt
+++ b/eval/src/vespa/eval/eval/CMakeLists.txt
@@ -15,6 +15,7 @@ vespa_add_library(eval_eval OBJECT
fast_value.cpp
function.cpp
gbdt.cpp
+ int8float.cpp
interpreted_function.cpp
key_gen.cpp
lazy_params.cpp
diff --git a/eval/src/vespa/eval/eval/int8float.cpp b/eval/src/vespa/eval/eval/int8float.cpp
new file mode 100644
index 00000000000..38af441fd08
--- /dev/null
+++ b/eval/src/vespa/eval/eval/int8float.cpp
@@ -0,0 +1,3 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "int8float.h"
diff --git a/eval/src/vespa/eval/eval/int8float.h b/eval/src/vespa/eval/eval/int8float.h
new file mode 100644
index 00000000000..7279d519bed
--- /dev/null
+++ b/eval/src/vespa/eval/eval/int8float.h
@@ -0,0 +1,46 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <cstdint>
+#include <vespa/vespalib/objects/nbostream.h>
+
+namespace vespalib::eval {
+
+/**
+ * Class holding an 8-bit integer which decays into float.
+ **/
+class Int8Float {
+private:
+ int8_t _bits;
+public:
+ constexpr Int8Float(float value) noexcept : _bits(value) {}
+ Int8Float() noexcept = default;
+ ~Int8Float() noexcept = default;
+ constexpr Int8Float(const Int8Float &other) noexcept = default;
+ constexpr Int8Float(Int8Float &&other) noexcept = default;
+ constexpr Int8Float& operator=(const Int8Float &other) noexcept = default;
+ constexpr Int8Float& operator=(Int8Float &&other) noexcept = default;
+ constexpr Int8Float& operator=(float value) noexcept {
+ _bits = value;
+ return *this;
+ }
+
+ constexpr operator float () const noexcept { return _bits; }
+
+ constexpr float to_float() const noexcept { return _bits; }
+ constexpr void assign(float value) noexcept { _bits = value; }
+
+ constexpr int8_t get_bits() const { return _bits; }
+ constexpr void assign_bits(int8_t value) noexcept { _bits = value; }
+};
+
+inline nbostream & operator << (nbostream &stream, Int8Float v) { return stream << v.get_bits(); }
+inline nbostream & operator >> (nbostream &stream, Int8Float & v) {
+ int8_t byte;
+ stream >> byte;
+ v.assign_bits(byte);
+ return stream;
+}
+
+}