diff options
-rw-r--r-- | libs/math/Android.bp | 20 | ||||
-rw-r--r-- | libs/math/include/math/HashCombine.h | 38 | ||||
-rw-r--r-- | libs/math/include/math/TVecHelpers.h | 26 | ||||
-rw-r--r-- | libs/math/include/math/half.h | 7 | ||||
-rw-r--r-- | libs/math/tests/Android.bp | 7 | ||||
-rw-r--r-- | libs/math/tests/half_test.cpp | 9 | ||||
-rw-r--r-- | libs/math/tests/hashcombine_test.cpp | 43 |
7 files changed, 150 insertions, 0 deletions
diff --git a/libs/math/Android.bp b/libs/math/Android.bp index 22d471204a..ab969504b1 100644 --- a/libs/math/Android.bp +++ b/libs/math/Android.bp @@ -22,6 +22,7 @@ cc_library_static { "com.android.media.swcodec", "com.android.neuralnetworks", ], + min_sdk_version: "29", export_include_dirs: ["include"], @@ -32,4 +33,23 @@ cc_library_static { } } +cc_library_headers { + name: "libmath_headers", + export_include_dirs: ["include"], + host_supported: true, + vendor_available: true, + + apex_available: [ + "//apex_available:anyapex", + "//apex_available:platform", + ], + min_sdk_version: "apex_inherit", + + target: { + windows: { + enabled: true, + } + } +} + subdirs = ["tests"] diff --git a/libs/math/include/math/HashCombine.h b/libs/math/include/math/HashCombine.h new file mode 100644 index 0000000000..e91b52ba98 --- /dev/null +++ b/libs/math/include/math/HashCombine.h @@ -0,0 +1,38 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <functional> + +namespace android { +static inline void hashCombineSingleHashed(size_t& combinedHash, size_t hash) { + combinedHash = 31 * combinedHash + hash; +} + +template<typename T> +static inline void hashCombineSingle(size_t& combinedHash, const T& val) { + hashCombineSingleHashed(combinedHash, std::hash<T>{}(val)); +} + +template<typename... Types> +static inline size_t hashCombine(const Types& ... args) { + size_t hash = 0; + ( hashCombineSingle(hash, args), ... ); + return hash; +} + +} // namespace android
\ No newline at end of file diff --git a/libs/math/include/math/TVecHelpers.h b/libs/math/include/math/TVecHelpers.h index 20f852fd9f..0dac662e97 100644 --- a/libs/math/include/math/TVecHelpers.h +++ b/libs/math/include/math/TVecHelpers.h @@ -19,9 +19,11 @@ #include <math.h> #include <stdint.h> +#include <math/HashCombine.h> #include <sys/types.h> #include <cmath> +#include <functional> #include <limits> #include <iostream> @@ -250,6 +252,17 @@ public: } return r; } + + // This isn't strictly a unary operator, but it is a common place shared between both + // matrix and vector classes + size_t hash() const { + VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this)); + size_t hashed = 0; + for (size_t i = 0; i < rv.size(); i++) { + android::hashCombineSingle(hashed, rv[i]); + } + return hashed; + } }; /* @@ -606,3 +619,16 @@ public: // ------------------------------------------------------------------------------------- } // namespace details } // namespace android + +namespace std { + template<template<typename T> class VECTOR, typename T> + struct hash<VECTOR<T>> { + static constexpr bool IS_VECTOR = + std::is_base_of<android::details::TVecUnaryOperators<VECTOR, T>, VECTOR<T>>::value; + + typename std::enable_if<IS_VECTOR, size_t>::type + operator()(const VECTOR<T>& v) const { + return v.hash(); + } + }; +} diff --git a/libs/math/include/math/half.h b/libs/math/include/math/half.h index 617a0ab5d2..5ec9bf7b40 100644 --- a/libs/math/include/math/half.h +++ b/libs/math/include/math/half.h @@ -17,6 +17,7 @@ #pragma once #include <stdint.h> +#include <functional> #include <iosfwd> #include <limits> #include <type_traits> @@ -202,6 +203,12 @@ public: inline static constexpr type signaling_NaN() noexcept { return android::half(android::half::binary, 0x7dff); } }; +template<> struct hash<android::half> { + size_t operator()(const android::half& half) { + return std::hash<float>{}(half); + } +}; + } // namespace std #ifdef LIKELY_DEFINED_LOCAL diff --git a/libs/math/tests/Android.bp b/libs/math/tests/Android.bp index 0184f56dc4..472d3379f7 100644 --- a/libs/math/tests/Android.bp +++ b/libs/math/tests/Android.bp @@ -41,3 +41,10 @@ cc_test { static_libs: ["libmath"], cflags: ["-Wall", "-Werror"], } + +cc_test { + name: "hashcombine_test", + srcs: ["hashcombine_test.cpp"], + static_libs: ["libmath"], + cflags: ["-Wall", "-Werror"], +} diff --git a/libs/math/tests/half_test.cpp b/libs/math/tests/half_test.cpp index 604072e557..a514d986e4 100644 --- a/libs/math/tests/half_test.cpp +++ b/libs/math/tests/half_test.cpp @@ -94,4 +94,13 @@ TEST_F(HalfTest, Vec) { EXPECT_EQ(f4.xy, h2); } + +TEST_F(HalfTest, Hash) { + float4 f4a(1,2,3,4); + float4 f4b(2,2,3,4); + half4 h4a(f4a), h4b(f4b); + + EXPECT_NE(std::hash<half4>{}(h4a), std::hash<half4>{}(h4b)); +} + }; // namespace android diff --git a/libs/math/tests/hashcombine_test.cpp b/libs/math/tests/hashcombine_test.cpp new file mode 100644 index 0000000000..96c6e81588 --- /dev/null +++ b/libs/math/tests/hashcombine_test.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "HashCombineTest" + +#include <math.h> +#include <stdlib.h> + +#include <math/half.h> +#include <math/vec4.h> + +#include <gtest/gtest.h> + +namespace android { + +class HashCombineTest : public testing::Test { +protected: +}; + +TEST_F(HashCombineTest, Basics) { + char a = 40; + int b = 32; + int c = 55; + float d = 42.f; + float d_ = 42.1f; + + EXPECT_NE(hashCombine(a, b, c, d), hashCombine(a, b, c, d_)); +} + +}; // namespace android |