aboutsummaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
Diffstat (limited to 'support')
-rw-r--r--support/AclRequires.h (renamed from support/Requires.h)11
-rw-r--r--support/BUILD.bazel28
-rw-r--r--support/Bfloat16.h47
-rw-r--r--support/Cast.h4
-rw-r--r--support/DeepCopy.h187
-rw-r--r--support/Half.h9
-rw-r--r--support/Iterable.h3
-rw-r--r--support/Mutex.h20
-rw-r--r--support/Random.h7
-rw-r--r--support/Rounding.h11
-rw-r--r--support/SaturateCast.h1
-rw-r--r--support/Semaphore.h16
-rw-r--r--support/StringSupport.h28
-rw-r--r--support/ToolchainSupport.h76
14 files changed, 346 insertions, 102 deletions
diff --git a/support/Requires.h b/support/AclRequires.h
index 21c98ca766..1c20f7fbc3 100644
--- a/support/Requires.h
+++ b/support/AclRequires.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021 Arm Limited.
+ * Copyright (c) 2018-2021, 2023 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -21,15 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#ifndef ARM_COMPUTE_UTILS_REQUIRES_H
-#define ARM_COMPUTE_UTILS_REQUIRES_H
+#ifndef ARM_COMPUTE_UTILS_ACLREQUIRES_H
+#define ARM_COMPUTE_UTILS_ACLREQUIRES_H
namespace arm_compute
{
namespace utils
{
-namespace requires
-{
// *INDENT-OFF*
// clang-format off
namespace detail
@@ -42,10 +40,9 @@ enum class enabler
/** Requirements as template */
#define ARM_COMPUTE_REQUIRES_T(...) template <bool Cond = (__VA_ARGS__), typename std::enable_if<Cond, int>::type = 0>
/** Requirements as template argument */
-#define ARM_COMPUTE_REQUIRES_TA(...) typename = typename std::enable_if<(__VA_ARGS__), arm_compute::utils::requires::detail::enabler>::type
+#define ARM_COMPUTE_REQUIRES_TA(...) typename = typename std::enable_if<(__VA_ARGS__), arm_compute::utils::detail::enabler>::type
// clang-format on
// *INDENT-ON*
-} // namespace requires
} // namespace utils
} // namespace arm_compute
#endif /*ARM_COMPUTE_UTILS_REQUIRES_H */
diff --git a/support/BUILD.bazel b/support/BUILD.bazel
new file mode 100644
index 0000000000..c2173d45b2
--- /dev/null
+++ b/support/BUILD.bazel
@@ -0,0 +1,28 @@
+# Copyright (c) 2023 Arm Limited.
+#
+# SPDX-License-Identifier: MIT
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+cc_library(
+ name = "support",
+ hdrs = glob(["*.h"]),
+ visibility = ["//visibility:public"],
+ deps = ["//include"],
+)
diff --git a/support/Bfloat16.h b/support/Bfloat16.h
index 173f2d16e2..02772898a8 100644
--- a/support/Bfloat16.h
+++ b/support/Bfloat16.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Arm Limited.
+ * Copyright (c) 2020-2022,2024 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -21,12 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#ifndef ARM_COMPUTE_BFLOAT16_H
-#define ARM_COMPUTE_BFLOAT16_H
+#ifndef ACL_SUPPORT_BFLOAT16_H
+#define ACL_SUPPORT_BFLOAT16_H
#include <cstdint>
#include <cstring>
-
+#include <ostream>
namespace arm_compute
{
namespace
@@ -40,25 +40,24 @@ namespace
inline uint16_t float_to_bf16(const float v)
{
const uint32_t *fromptr = reinterpret_cast<const uint32_t *>(&v);
-#if defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) || defined(ARM_COMPUTE_FORCE_BF16)
+#if defined(ARM_COMPUTE_ENABLE_BF16)
uint16_t res;
- __asm __volatile(
- "ldr s0, [%[fromptr]]\n"
- ".inst 0x1e634000\n" // BFCVT h0, s0
- "str h0, [%[toptr]]\n"
- :
- : [fromptr] "r"(fromptr), [toptr] "r"(&res)
- : "v0", "memory");
-#else /* defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) || defined(ARM_COMPUTE_FORCE_BF16) */
+ __asm __volatile("ldr s0, [%[fromptr]]\n"
+ ".inst 0x1e634000\n" // BFCVT h0, s0
+ "str h0, [%[toptr]]\n"
+ :
+ : [fromptr] "r"(fromptr), [toptr] "r"(&res)
+ : "v0", "memory");
+#else /* defined(ARM_COMPUTE_ENABLE_BF16) */
uint16_t res = (*fromptr >> 16);
const uint16_t error = (*fromptr & 0x0000ffff);
uint16_t bf_l = res & 0x0001;
- if((error > 0x8000) || ((error == 0x8000) && (bf_l != 0)))
+ if ((error > 0x8000) || ((error == 0x8000) && (bf_l != 0)))
{
res += 1;
}
-#endif /* defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) || defined(ARM_COMPUTE_FORCE_BF16) */
+#endif /* defined(ARM_COMPUTE_ENABLE_BF16) */
return res;
}
@@ -75,23 +74,21 @@ inline float bf16_to_float(const uint16_t &v)
memcpy(&fp, &lv, sizeof(lv));
return fp;
}
-}
+} // namespace
/** Brain floating point representation class */
class bfloat16 final
{
public:
/** Default Constructor */
- bfloat16()
- : value(0)
+ bfloat16() : value(0)
{
}
/** Constructor
*
* @param[in] v Floating-point value
*/
- explicit bfloat16(float v)
- : value(float_to_bf16(v))
+ bfloat16(float v) : value(float_to_bf16(v))
{
}
/** Assignment operator
@@ -134,8 +131,16 @@ public:
return val;
}
+ bfloat16 &operator+=(float v)
+ {
+ value = float_to_bf16(bf16_to_float(value) + v);
+ return *this;
+ }
+
+ friend std::ostream &operator<<(std::ostream &os, const bfloat16 &arg);
+
private:
uint16_t value;
};
} // namespace arm_compute
-#endif /* ARM_COMPUTE_BFLOAT16_H */
+#endif // ACL_SUPPORT_BFLOAT16_H
diff --git a/support/Cast.h b/support/Cast.h
index 53d5f68065..5fd763690b 100644
--- a/support/Cast.h
+++ b/support/Cast.h
@@ -46,7 +46,7 @@ namespace cast
template <typename Target, typename Source>
inline Target polymorphic_cast(Source *v)
{
- if(dynamic_cast<Target>(v) == nullptr)
+ if (dynamic_cast<Target>(v) == nullptr)
{
ARM_COMPUTE_THROW(std::bad_cast());
}
@@ -86,7 +86,7 @@ inline Target polymorphic_downcast(Source *v)
template <typename Target, typename Source, typename Deleter>
std::unique_ptr<Target, Deleter> polymorphic_cast_unique_ptr(std::unique_ptr<Source, Deleter> &&v)
{
- if(dynamic_cast<Target *>(v.get()) == nullptr)
+ if (dynamic_cast<Target *>(v.get()) == nullptr)
{
ARM_COMPUTE_THROW(std::bad_cast());
}
diff --git a/support/DeepCopy.h b/support/DeepCopy.h
new file mode 100644
index 0000000000..c0279284c0
--- /dev/null
+++ b/support/DeepCopy.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2022 Arm Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ARM_COMPUTE_MISC_ITERABLE_H
+#define ARM_COMPUTE_MISC_ITERABLE_H
+namespace arm_compute
+{
+namespace utils
+{
+namespace memory
+{
+namespace
+{
+/** Default polymorphic deep copy function, used by deep_unique_ptr
+ *
+ * @param ptr Potentially polymorphic object to be deep copied
+ * @return template <typename Base, typename Derived>*
+ */
+template <typename Base, typename Derived>
+Base *default_polymorphic_copy(const Base *ptr)
+{
+ static_assert(std::is_base_of<Base, Derived>::value, "Derived is not a specialization of Base");
+ if (ptr == nullptr)
+ {
+ return nullptr;
+ }
+ return new Derived(*static_cast<const Derived *>(ptr));
+}
+} // namespace
+
+/** A deep-copying unique pointer that also supports polymorphic cloning behavior
+ *
+ * @note The == operator compares the dereferenced value instead of the pointer itself.
+ *
+ * @tparam Base Base type
+ */
+template <typename Base>
+class deep_unique_ptr
+{
+public:
+ using CopyFunc = std::function<Base *(const Base *)>;
+
+ deep_unique_ptr(std::nullptr_t val = nullptr) noexcept : _val{val}, _copy{}
+ {
+ }
+ template <typename Derived, typename CopyFuncDerived>
+ deep_unique_ptr(Derived *value, const CopyFuncDerived &copy) noexcept : _val{value}, _copy{std::move(copy)}
+ {
+ static_assert(std::is_base_of<Base, Derived>::value, "Derived is not a specialization of Base");
+ static_assert(std::is_constructible<CopyFunc, CopyFuncDerived>::value,
+ "CopyFuncDerived is not valid for a copy functor");
+ }
+
+ deep_unique_ptr(const deep_unique_ptr<Base> &ptr) : deep_unique_ptr(ptr.clone())
+ {
+ }
+ deep_unique_ptr &operator=(const deep_unique_ptr<Base> &ptr)
+ {
+ deep_unique_ptr<Base> tmp(ptr);
+ swap(*this, tmp);
+ return *this;
+ }
+
+ deep_unique_ptr(deep_unique_ptr<Base> &&ptr) = default;
+ deep_unique_ptr &operator=(deep_unique_ptr<Base> &&ptr) = default;
+ ~deep_unique_ptr() = default;
+ friend void swap(deep_unique_ptr &ptr0, deep_unique_ptr<Base> &ptr1) noexcept
+ {
+ using std::swap;
+ swap(ptr0._val, ptr1._val);
+ swap(ptr0._copy, ptr1._copy);
+ }
+ Base &operator*() noexcept
+ {
+ return *_val;
+ }
+
+ const Base &operator*() const noexcept
+ {
+ return *_val;
+ }
+
+ Base *operator->() noexcept
+ {
+ return _val.operator->();
+ }
+
+ const Base *operator->() const noexcept
+ {
+ return _val.operator->();
+ }
+
+ Base *get() noexcept
+ {
+ return _val.get();
+ }
+ const Base *get() const noexcept
+ {
+ return _val.get();
+ }
+
+ explicit operator bool() const noexcept
+ {
+ return static_cast<bool>(_val);
+ }
+
+ bool operator==(const deep_unique_ptr<Base> &rhs) const
+ {
+ if (rhs.get() == nullptr && _val == nullptr)
+ {
+ return true;
+ }
+ else if (rhs.get() == nullptr || _val == nullptr)
+ {
+ return false;
+ }
+ else
+ {
+ return (*_val == *rhs);
+ }
+ }
+
+private:
+ deep_unique_ptr clone() const
+ {
+ return {_copy(_val.get()), CopyFunc(_copy)};
+ }
+ std::unique_ptr<Base> _val{nullptr};
+ CopyFunc _copy{};
+};
+
+/** Utility function to create a polymorphic deep-copying unique pointer
+ *
+ * @tparam Base
+ * @tparam Derived
+ * @tparam CopyFunc
+ * @param temp
+ * @param copy
+ * @return deep_unique_ptr<Base>
+ */
+template <typename Base, typename Derived, typename CopyFunc>
+deep_unique_ptr<Base> make_deep_unique(Derived &&temp, CopyFunc copy)
+{
+ return {new Derived(std::move(temp)), CopyFunc{std::move(copy)}};
+}
+
+template <typename Base, typename Derived>
+deep_unique_ptr<Base> make_deep_unique(Derived &&temp)
+{
+ static_assert(std::is_base_of<Base, Derived>::value, "Derived is not a specialization of Base");
+
+ return make_deep_unique<Base, Derived>(std::move(temp), default_polymorphic_copy<Base, Derived>);
+}
+
+template <typename Base, typename Derived, typename... Args>
+deep_unique_ptr<Base> make_deep_unique(Args &&...args)
+{
+ static_assert(std::is_constructible<Derived, Args...>::value, "Cannot instantiate Derived from arguments");
+
+ return make_deep_unique<Base, Derived>(std::move(Derived{std::forward<Args>(args)...}));
+}
+
+} // namespace memory
+} // namespace utils
+} // namespace arm_compute
+#endif // ARM_COMPUTE_MISC_ITERABLE_H
diff --git a/support/Half.h b/support/Half.h
index 5bea26c6e8..f5c27da2d3 100644
--- a/support/Half.h
+++ b/support/Half.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Arm Limited.
+ * Copyright (c) 2017, 2021 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -24,13 +24,12 @@
#ifndef __ARM_COMPUTE_HALF_H__
#define __ARM_COMPUTE_HALF_H__
-#if(__ANDROID__ || BARE_METAL)
-// Android toolchain is broken and doesn't support all CPP11 math functions.
+#if (BARE_METAL)
#define HALF_ENABLE_CPP11_CMATH 0
-#endif /* __ANDROID__ || BARE_METAL */
+#endif /* BARE_METAL */
// Set style to round to nearest
-#define HALF_ROUND_STYLE 1
+#define HALF_ROUND_STYLE 1
#define HALF_ROUND_TIES_TO_EVEN 1
#include "half/half.hpp"
diff --git a/support/Iterable.h b/support/Iterable.h
index a0bafaf4ce..8d99e70196 100644
--- a/support/Iterable.h
+++ b/support/Iterable.h
@@ -44,8 +44,7 @@ public:
*
* @param[in] it Value to reverse iterate on
*/
- explicit reverse_iterable(T &it)
- : _it(it)
+ explicit reverse_iterable(T &it) : _it(it)
{
}
diff --git a/support/Mutex.h b/support/Mutex.h
index 6e68fa5248..9c2b55c3ac 100644
--- a/support/Mutex.h
+++ b/support/Mutex.h
@@ -50,10 +50,10 @@ public:
~Mutex() = default;
/** Lock */
- void lock() {};
+ void lock(){};
/** Unlock */
- void unlock() {};
+ void unlock(){};
/** Try the lock.
*
@@ -73,8 +73,7 @@ public:
typedef Mutex mutex_type;
public:
- explicit lock_guard(Mutex &m_)
- : m(m_)
+ explicit lock_guard(Mutex &m_) : m(m_)
{
}
~lock_guard()
@@ -97,15 +96,14 @@ public:
unique_lock() noexcept : m(nullptr)
{
}
- explicit unique_lock(mutex_type &m)
- : m(&m)
+ explicit unique_lock(mutex_type &m) : m(&m)
{
}
- unique_lock(const unique_lock &) = delete;
- unique_lock(unique_lock &&) = default;
+ unique_lock(const unique_lock &) = delete;
+ unique_lock(unique_lock &&) = default;
unique_lock &operator=(const unique_lock &) = delete;
- unique_lock &operator=(unique_lock &&) = default;
- ~unique_lock() = default;
+ unique_lock &operator=(unique_lock &&) = default;
+ ~unique_lock() = default;
void lock()
{
}
@@ -121,5 +119,5 @@ private:
mutex_type *m;
};
#endif /* NO_MULTI_THREADING */
-}
+} // namespace arm_compute
#endif /* __ARM_COMPUTE_MUTEX_H__ */
diff --git a/support/Random.h b/support/Random.h
index 7658e6d529..1a804d3290 100644
--- a/support/Random.h
+++ b/support/Random.h
@@ -25,6 +25,7 @@
#define ARM_COMPUTE_MISC_RANDOM_H
#include "arm_compute/core/Error.h"
+
#include "utils/Utils.h"
#include <random>
@@ -47,7 +48,9 @@ public:
static constexpr bool is_fp_16bit = std::is_same<T, half>::value || std::is_same<T, bfloat16>::value;
static constexpr bool is_integral = std::is_integral<T>::value && !is_fp_16bit;
- using fp_dist = typename std::conditional<is_fp_16bit, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<T>>::type;
+ using fp_dist = typename std::conditional<is_fp_16bit,
+ arm_compute::utils::uniform_real_distribution_16bit<T>,
+ std::uniform_real_distribution<T>>::type;
using DT = typename std::conditional<is_integral, std::uniform_int_distribution<T>, fp_dist>::type;
using result_type = T;
using range_pair = std::pair<result_type, result_type>;
@@ -62,7 +65,7 @@ public:
: _distributions(), _selector()
{
result_type clow = low;
- for(const auto &erange : exclude_ranges)
+ for (const auto &erange : exclude_ranges)
{
result_type epsilon = is_integral ? result_type(1) : result_type(std::numeric_limits<T>::epsilon());
diff --git a/support/Rounding.h b/support/Rounding.h
index 47c8f76834..5691a6680b 100644
--- a/support/Rounding.h
+++ b/support/Rounding.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021 Arm Limited.
+ * Copyright (c) 2018-2021, 2023 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -26,7 +26,8 @@
#include "arm_compute/core/Error.h"
#include "arm_compute/core/utils/misc/Traits.h"
-#include "support/Requires.h"
+
+#include "support/AclRequires.h"
#include "support/ToolchainSupport.h"
#include <cmath>
@@ -153,10 +154,10 @@ inline T round_half_even(T value, T epsilon = std::numeric_limits<T>::epsilon())
T ipart = 0;
std::modf(positive_value, &ipart);
// If 'value' is exactly halfway between two integers
- if(std::abs(positive_value - (ipart + 0.5f)) < epsilon)
+ if (std::abs(positive_value - (ipart + 0.5f)) < epsilon)
{
// If 'ipart' is even then return 'ipart'
- if(std::fmod(ipart, 2.f) < epsilon)
+ if (std::fmod(ipart, 2.f) < epsilon)
{
return support::cpp11::copysign(ipart, value);
}
@@ -179,7 +180,7 @@ inline T round_half_even(T value, T epsilon = std::numeric_limits<T>::epsilon())
template <typename T, ARM_COMPUTE_REQUIRES_TA(traits::is_floating_point<T>::value)>
inline T round(T value, RoundingMode rounding_mode)
{
- switch(rounding_mode)
+ switch (rounding_mode)
{
case RoundingMode::TO_ZERO:
return round_to_zero(value);
diff --git a/support/SaturateCast.h b/support/SaturateCast.h
index a9982d8e96..7af9f983ed 100644
--- a/support/SaturateCast.h
+++ b/support/SaturateCast.h
@@ -26,6 +26,7 @@
#include "arm_compute/core/utils/misc/Traits.h"
#include "arm_compute/core/utils/misc/Utility.h"
+
#include "support/Rounding.h"
namespace arm_compute
diff --git a/support/Semaphore.h b/support/Semaphore.h
index e182b53a2d..f44179332b 100644
--- a/support/Semaphore.h
+++ b/support/Semaphore.h
@@ -24,8 +24,9 @@
#ifndef __ARM_COMPUTE_UTILS_SEMAMPHORE_H__
#define __ARM_COMPUTE_UTILS_SEMAMPHORE_H__
-#include "Mutex.h"
#include "support/Mutex.h"
+
+#include "Mutex.h"
#include <condition_variable>
namespace arm_compute
@@ -39,8 +40,7 @@ public:
*
* @param[in] value Semaphore initial value
*/
- Semaphore(int value = 0)
- : _value(value), _m(), _cv()
+ Semaphore(int value = 0) : _value(value), _m(), _cv()
{
}
/** Signals a semaphore */
@@ -56,10 +56,7 @@ public:
inline void wait()
{
std::unique_lock<std::mutex> lock(_m);
- _cv.wait(lock, [this]()
- {
- return _value > 0;
- });
+ _cv.wait(lock, [this]() { return _value > 0; });
--_value;
}
@@ -73,8 +70,7 @@ private:
class Semaphore
{
public:
- Semaphore(int value = 0)
- : _value(value)
+ Semaphore(int value = 0) : _value(value)
{
(void)_value;
}
@@ -93,5 +89,5 @@ private:
int _value;
};
#endif /* NO_MULTI_THREADING */
-} // arm_compute
+} // namespace arm_compute
#endif /* __ARM_COMPUTE_UTILS_SEMAMPHORE_H__ */
diff --git a/support/StringSupport.h b/support/StringSupport.h
index 5e237c7dff..7d1b5e7778 100644
--- a/support/StringSupport.h
+++ b/support/StringSupport.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020 Arm Limited.
+ * Copyright (c) 2017-2022 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -57,14 +57,14 @@ inline int stoi(const std::string &str, std::size_t *pos = 0, NumericBase base =
assert(base == NumericBase::BASE_10 || base == NumericBase::BASE_16);
unsigned int x;
std::stringstream ss;
- if(base == NumericBase::BASE_16)
+ if (base == NumericBase::BASE_16)
{
ss << std::hex;
}
ss << str;
ss >> x;
- if(pos)
+ if (pos)
{
std::string s;
std::stringstream ss_p;
@@ -93,14 +93,14 @@ inline unsigned long stoul(const std::string &str, std::size_t *pos = 0, Numeric
assert(base == NumericBase::BASE_10 || base == NumericBase::BASE_16);
std::stringstream stream;
unsigned long value = 0;
- if(base == NumericBase::BASE_16)
+ if (base == NumericBase::BASE_16)
{
stream << std::hex;
}
stream << str;
stream >> value;
- if(pos)
+ if (pos)
{
std::string s;
std::stringstream ss_p;
@@ -113,7 +113,7 @@ inline unsigned long stoul(const std::string &str, std::size_t *pos = 0, Numeric
return value;
}
-#if(__ANDROID__ || BARE_METAL)
+#if (__ANDROID__ || BARE_METAL)
/** Convert integer and float values to string.
*
* @note This function implements the same behaviour as std::to_string. The
@@ -124,13 +124,19 @@ inline unsigned long stoul(const std::string &str, std::size_t *pos = 0, Numeric
* @return String representation of @p value.
*/
template <typename T, typename std::enable_if<std::is_arithmetic<typename std::decay<T>::type>::value, int>::type = 0>
-inline std::string to_string(T && value)
+inline std::string to_string(T &&value)
{
std::stringstream stream;
stream << std::forward<T>(value);
return stream.str();
}
+// Specialization for const std::string&
+inline std::string to_string(const std::string &value)
+{
+ return value;
+}
+
/** Convert string values to float.
*
* @note This function implements the same behaviour as std::stof. The latter
@@ -164,6 +170,12 @@ inline std::string to_string(T &&value)
return ::std::to_string(std::forward<T>(value));
}
+// Specialization for const std::string&
+inline std::string to_string(const std::string &value)
+{
+ return value;
+}
+
/** Convert string values to float.
*
* @note This function acts as a convenience wrapper around std::stof. The
@@ -174,7 +186,7 @@ inline std::string to_string(T &&value)
* @return Float representation of input string.
*/
template <typename... Ts>
-int stof(Ts &&... args)
+int stof(Ts &&...args)
{
return ::std::stof(std::forward<Ts>(args)...);
}
diff --git a/support/ToolchainSupport.h b/support/ToolchainSupport.h
index d8c14411e8..accbb643c2 100644
--- a/support/ToolchainSupport.h
+++ b/support/ToolchainSupport.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021 Arm Limited.
+ * Copyright (c) 2017-2023 Arm Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -21,8 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#ifndef ARM_COMPUTE_SUPPORT_TOOLCHAINSUPPORT
-#define ARM_COMPUTE_SUPPORT_TOOLCHAINSUPPORT
+#ifndef ACL_SUPPORT_TOOLCHAINSUPPORT_H
+#define ACL_SUPPORT_TOOLCHAINSUPPORT_H
+
+#include "support/Bfloat16.h"
+#include "support/Half.h"
#include <cassert>
#include <cmath>
@@ -33,24 +36,21 @@
#include <string>
#include <type_traits>
-#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
-#include <arm_neon.h>
-#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
-
-#include "support/Bfloat16.h"
-#include "support/Half.h"
-
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif // M_PI
namespace arm_compute
{
+#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
+typedef __fp16 float16_t;
+#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
+
namespace support
{
namespace cpp11
{
-#if(__ANDROID__ || BARE_METAL)
+#if (__ANDROID__ || BARE_METAL)
template <typename T>
inline T nearbyint(T value)
{
@@ -129,11 +129,12 @@ inline T copysign(T x, T y)
*
* @return Result floating point value equal to (x*y) + z.c
*/
-template < typename T, typename = typename std::enable_if < std::is_floating_point<T>::value
+template <typename T,
+ typename = typename std::enable_if<std::is_floating_point<T>::value
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
- || std::is_same<T, float16_t>::value
+ || std::is_same<T, float16_t>::value
#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
- >::type >
+ >::type>
inline T fma(T x, T y, T z)
{
return ::fma(x, y, z);
@@ -143,15 +144,15 @@ inline T fma(T x, T y, T z)
* and writes the result to a character string buffer.
*
* @param[in] s Pointer to a character string to write to
- * @param[in] n Up to buf_size - 1 characters may be written, plus the null terminator
- * @param[in] fmt Pointer to a null-terminated multibyte string specifying how to interpret the data.
+ * @param[in] n Up to buf_size - 1 characters may be written, plus the null ending character
+ * @param[in] fmt Pointer to a null-ended multibyte string specifying how to interpret the data.
* @param[in] args Arguments forwarded to snprintf.
*
* @return Number of characters that would have been written for a sufficiently large buffer
- * if successful (not including the terminating null character), or a negative value if an error occurred.
+ * if successful (not including the ending null character), or a negative value if an error occurred.
*/
template <typename... Ts>
-inline int snprintf(char *s, size_t n, const char *fmt, Ts &&... args)
+inline int snprintf(char *s, size_t n, const char *fmt, Ts &&...args)
{
return ::snprintf(s, n, fmt, std::forward<Ts>(args)...);
}
@@ -183,8 +184,7 @@ inline T nearbyint(T value)
template <typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
inline T round(T value)
{
- //Workaround Valgrind's mismatches: when running from Valgrind the call to std::round(-4.500000) == -4.000000 instead of 5.00000
- return (value < 0.f) ? static_cast<int>(value - 0.5f) : static_cast<int>(value + 0.5f);
+ return std::round(value);
}
/** Round floating-point value with half value rounding away from zero and cast to long
@@ -244,11 +244,12 @@ inline T copysign(T x, T y)
*
* @return Result floating point value equal to (x*y) + z.
*/
-template < typename T, typename = typename std::enable_if < std::is_floating_point<T>::value
+template <typename T,
+ typename = typename std::enable_if<std::is_floating_point<T>::value
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
- || std::is_same<T, float16_t>::value
+ || std::is_same<T, float16_t>::value
#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
- >::type >
+ >::type>
inline T fma(T x, T y, T z)
{
return std::fma(x, y, z);
@@ -258,15 +259,15 @@ inline T fma(T x, T y, T z)
* and writes the result to a character string buffer.
*
* @param[in] s Pointer to a character string to write to
- * @param[in] n Up to buf_size - 1 characters may be written, plus the null terminator
- * @param[in] fmt Pointer to a null-terminated multibyte string specifying how to interpret the data.
+ * @param[in] n Up to buf_size - 1 characters may be written, plus the null ending character
+ * @param[in] fmt Pointer to a null-ended multibyte string specifying how to interpret the data.
* @param[in] args Arguments forwarded to std::snprintf.
*
* @return Number of characters that would have been written for a sufficiently large buffer
- * if successful (not including the terminating null character), or a negative value if an error occurred.
+ * if successful (not including the ending null character), or a negative value if an error occurred.
*/
template <typename... Ts>
-inline int snprintf(char *s, std::size_t n, const char *fmt, Ts &&... args)
+inline int snprintf(char *s, std::size_t n, const char *fmt, Ts &&...args)
{
return std::snprintf(s, n, fmt, std::forward<Ts>(args)...);
}
@@ -297,7 +298,7 @@ inline bfloat16 lowest<bfloat16>()
template <typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
inline bool isfinite(T value)
{
- return std::isfinite(value);
+ return std::isfinite(static_cast<double>(value));
}
inline bool isfinite(half_float::half value)
@@ -309,7 +310,24 @@ inline bool isfinite(bfloat16 value)
{
return std::isfinite(float(value));
}
+
+// std::signbit
+template <typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
+inline bool signbit(T value)
+{
+ return std::signbit(static_cast<double>(value));
+}
+
+inline bool signbit(half_float::half value)
+{
+ return half_float::signbit(value);
+}
+
+inline bool signbit(bfloat16 value)
+{
+ return std::signbit(float(value));
+}
} // namespace cpp11
} // namespace support
} // namespace arm_compute
-#endif /* ARM_COMPUTE_SUPPORT_TOOLCHAINSUPPORT */
+#endif // ACL_SUPPORT_TOOLCHAINSUPPORT_H