From e874ef9b845424dceeac4211ca9dfec24949f03c Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Mon, 9 Sep 2019 17:40:33 +0100 Subject: COMPMID-2646: Wrap thread-related structure to ease bare-metal support Wraps "lock_guard" and "unique_lock" to ease bare-metal support. Adds basic armclang compilation flow. Change-Id: I44ccd042652acd6a9b442c57c879db3891abb0e2 Signed-off-by: Georgios Pinitas Reviewed-on: https://review.mlplatform.org/c/1923 Tested-by: Arm Jenkins Reviewed-by: Pablo Marquez Comments-Addressed: Arm Jenkins --- SConstruct | 11 +++- arm_compute/core/NEON/NEMath.inl | 5 +- arm_compute/core/Utils.h | 38 ++++++++----- arm_compute/core/utils/logging/IPrinter.h | 2 +- arm_compute/core/utils/logging/LogMsgDecorators.h | 4 +- src/core/CPP/kernels/CPPCornerCandidatesKernel.cpp | 6 +- src/core/NEON/kernels/NEHOGDetectorKernel.cpp | 4 +- src/core/NEON/kernels/NEHistogramKernel.cpp | 2 +- src/core/NEON/kernels/NEMeanStdDevKernel.cpp | 2 +- src/core/NEON/kernels/NEMinMaxLayerKernel.cpp | 2 +- src/core/NEON/kernels/NEMinMaxLocationKernel.cpp | 2 +- src/core/utils/logging/LoggerRegistry.cpp | 9 +-- support/Mutex.h | 66 +++++++++++++++++++++- 13 files changed, 122 insertions(+), 31 deletions(-) diff --git a/SConstruct b/SConstruct index 6fea51bbf4..9a12c5d19c 100644 --- a/SConstruct +++ b/SConstruct @@ -146,6 +146,8 @@ if env['os'] == 'android' and ( 'clang++' not in cpp_compiler or 'clang' not in if 'clang++' in cpp_compiler: env.Append(CXXFLAGS = ['-Wno-format-nonliteral','-Wno-deprecated-increment-bool','-Wno-vla-extension','-Wno-mismatched-tags']) +elif 'armclang' in cpp_compiler: + pass else: env.Append(CXXFLAGS = ['-Wlogical-op','-Wnoexcept','-Wstrict-null-sentinel', '-Wno-redundant-move']) @@ -161,6 +163,7 @@ if env['openmp']: env.Append(CXXFLAGS = ['-fopenmp']) env.Append(LINKFLAGS = ['-fopenmp']) +# Add architecture specific flags prefix = "" if env['arch'] == 'armv7a': env.Append(CXXFLAGS = ['-march=armv7-a', '-mthumb', '-mfpu=neon']) @@ -207,6 +210,10 @@ elif env['arch'] == 'x86_64': env.Append(CCFLAGS = ['-m64']) env.Append(LINKFLAGS = ['-m64']) +# Rework flags depending on compiler version +if 'armclang' in cpp_compiler: + if 'NO_DOT_IN_TOOLCHAIN' in env['CPPDEFINES']: env['CPPDEFINES'].remove('NO_DOT_IN_TOOLCHAIN') + if env['build'] == 'native': prefix = "" @@ -227,7 +234,9 @@ if not GetOption("help"): print("ERROR: Compiler '%s' not found" % env['CXX']) Exit(1) - if 'clang++' not in cpp_compiler: + if 'armclang' in cpp_compiler: + pass + elif 'clang++' not in cpp_compiler: if env['arch'] == 'arm64-v8.2-a' and not version_at_least(compiler_ver, '6.2.1'): print("GCC 6.2.1 or newer is required to compile armv8.2-a code") Exit(1) diff --git a/arm_compute/core/NEON/NEMath.inl b/arm_compute/core/NEON/NEMath.inl index eebcdf864f..61315e8dbc 100644 --- a/arm_compute/core/NEON/NEMath.inl +++ b/arm_compute/core/NEON/NEMath.inl @@ -21,9 +21,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - #include +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif // M_PI + namespace arm_compute { /** Exponent polynomial coefficients */ diff --git a/arm_compute/core/Utils.h b/arm_compute/core/Utils.h index 0ce2ee0161..3f04ed9963 100644 --- a/arm_compute/core/Utils.h +++ b/arm_compute/core/Utils.h @@ -1128,7 +1128,10 @@ bool check_value_range(T val, DataType dt, QuantizationInfo qinfo = Quantization switch(dt) { case DataType::U8: - return ((static_cast(val) == val) && val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); + { + const auto val_u8 = static_cast(val); + return ((val_u8 == val) && val_u8 >= std::numeric_limits::lowest() && val_u8 <= std::numeric_limits::max()); + } case DataType::QASYMM8: { double min = static_cast(dequantize_qasymm8(0, qinfo)); @@ -1136,27 +1139,34 @@ bool check_value_range(T val, DataType dt, QuantizationInfo qinfo = Quantization return ((double)val >= min && (double)val <= max); } case DataType::S8: - return ((static_cast(val) == val) && val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); + { + const auto val_s8 = static_cast(val); + return ((val_s8 == val) && val_s8 >= std::numeric_limits::lowest() && val_s8 <= std::numeric_limits::max()); + } case DataType::U16: - return ((static_cast(val) == val) && val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); + { + const auto val_u16 = static_cast(val); + return ((val_u16 == val) && val_u16 >= std::numeric_limits::lowest() && val_u16 <= std::numeric_limits::max()); + } case DataType::S16: - return ((static_cast(val) == val) && val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); + { + const auto val_s16 = static_cast(val); + return ((val_s16 == val) && val_s16 >= std::numeric_limits::lowest() && val_s16 <= std::numeric_limits::max()); + } case DataType::U32: - return ((static_cast(val) == val) && val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); + { + const auto val_u32 = static_cast(val); + return ((val_u32 == val) && val_u32 >= std::numeric_limits::lowest() && val_u32 <= std::numeric_limits::max()); + } case DataType::S32: - return ((static_cast(val) == val) && val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); - case DataType::U64: - return (val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); - case DataType::S64: - return (val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); + { + const auto val_s32 = static_cast(val); + return ((val_s32 == val) && val_s32 >= std::numeric_limits::lowest() && val_s32 <= std::numeric_limits::max()); + } case DataType::F16: return (val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); case DataType::F32: return (val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); - case DataType::F64: - return (val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); - case DataType::SIZET: - return ((static_cast(val) == val) && val >= std::numeric_limits::lowest() && val <= std::numeric_limits::max()); default: ARM_COMPUTE_ERROR("Data type not supported"); return false; diff --git a/arm_compute/core/utils/logging/IPrinter.h b/arm_compute/core/utils/logging/IPrinter.h index 2f399102e2..45ea8368eb 100644 --- a/arm_compute/core/utils/logging/IPrinter.h +++ b/arm_compute/core/utils/logging/IPrinter.h @@ -55,7 +55,7 @@ public: */ inline void print(const std::string &msg) { - std::lock_guard lock(_mtx); + arm_compute::lock_guard lock(_mtx); print_internal(msg); } diff --git a/arm_compute/core/utils/logging/LogMsgDecorators.h b/arm_compute/core/utils/logging/LogMsgDecorators.h index 32cb977bf2..03a2d41f12 100644 --- a/arm_compute/core/utils/logging/LogMsgDecorators.h +++ b/arm_compute/core/utils/logging/LogMsgDecorators.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017 ARM Limited. + * Copyright (c) 2016-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -30,7 +30,9 @@ #include #include #include +#ifndef NO_MULTI_THREADING #include +#endif /* NO_MULTI_THREADING */ namespace arm_compute { diff --git a/src/core/CPP/kernels/CPPCornerCandidatesKernel.cpp b/src/core/CPP/kernels/CPPCornerCandidatesKernel.cpp index 418d349830..739f389fdb 100644 --- a/src/core/CPP/kernels/CPPCornerCandidatesKernel.cpp +++ b/src/core/CPP/kernels/CPPCornerCandidatesKernel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -33,6 +33,8 @@ #include "arm_compute/core/Validate.h" #include "arm_compute/core/Window.h" +#include "support/Mutex.h" + using namespace arm_compute; namespace @@ -42,7 +44,7 @@ inline void check_corner(float x, float y, float strength, InternalKeypoint *out if(strength != 0.0f) { /* Set index and update num_corner_candidate */ - std::unique_lock lock(*corner_candidates_mutex); + arm_compute::unique_lock lock(*corner_candidates_mutex); const int32_t idx = *num_corner_candidates; diff --git a/src/core/NEON/kernels/NEHOGDetectorKernel.cpp b/src/core/NEON/kernels/NEHOGDetectorKernel.cpp index 2c02ab8997..8f523998d8 100644 --- a/src/core/NEON/kernels/NEHOGDetectorKernel.cpp +++ b/src/core/NEON/kernels/NEHOGDetectorKernel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 ARM Limited. + * Copyright (c) 2016-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -177,7 +177,7 @@ void NEHOGDetectorKernel::run(const Window &window, const ThreadInfo &info) win.idx_class = _idx_class; win.score = score; - std::unique_lock lock(_mutex); + arm_compute::unique_lock lock(_mutex); _detection_windows->push_back(win); lock.unlock(); } diff --git a/src/core/NEON/kernels/NEHistogramKernel.cpp b/src/core/NEON/kernels/NEHistogramKernel.cpp index b088a232a8..211ea1ff9c 100644 --- a/src/core/NEON/kernels/NEHistogramKernel.cpp +++ b/src/core/NEON/kernels/NEHistogramKernel.cpp @@ -41,7 +41,7 @@ class Coordinates; inline void NEHistogramKernel::merge_histogram(uint32_t *global_hist, const uint32_t *local_hist, size_t bins) { - std::lock_guard lock(_hist_mtx); + arm_compute::lock_guard lock(_hist_mtx); const unsigned int v_end = (bins / 4) * 4; diff --git a/src/core/NEON/kernels/NEMeanStdDevKernel.cpp b/src/core/NEON/kernels/NEMeanStdDevKernel.cpp index 0af63059fb..afab6d6e51 100644 --- a/src/core/NEON/kernels/NEMeanStdDevKernel.cpp +++ b/src/core/NEON/kernels/NEMeanStdDevKernel.cpp @@ -142,7 +142,7 @@ void NEMeanStdDevKernel::run(const Window &window, const ThreadInfo &info) const float num_pixels = _input->info()->dimension(0) * _input->info()->dimension(1); // Merge sum and calculate mean and stddev - std::unique_lock lock(_mtx); + arm_compute::unique_lock lock(_mtx); *_global_sum += vget_lane_u64(local_sum, 0); diff --git a/src/core/NEON/kernels/NEMinMaxLayerKernel.cpp b/src/core/NEON/kernels/NEMinMaxLayerKernel.cpp index fe3af0b44f..f69c88324b 100644 --- a/src/core/NEON/kernels/NEMinMaxLayerKernel.cpp +++ b/src/core/NEON/kernels/NEMinMaxLayerKernel.cpp @@ -212,7 +212,7 @@ void NEMinMaxLayerKernel::reset() void NEMinMaxLayerKernel::update_min_max(float *out_ptr, float min, float max) { - std::lock_guard lock(_mtx); + arm_compute::lock_guard lock(_mtx); const float32x2_t old_min = vld1_dup_f32(out_ptr); const float32x2_t old_max = vld1_dup_f32(out_ptr + 1); diff --git a/src/core/NEON/kernels/NEMinMaxLocationKernel.cpp b/src/core/NEON/kernels/NEMinMaxLocationKernel.cpp index 08b27e319e..7fa2dc1c8a 100644 --- a/src/core/NEON/kernels/NEMinMaxLocationKernel.cpp +++ b/src/core/NEON/kernels/NEMinMaxLocationKernel.cpp @@ -117,7 +117,7 @@ void NEMinMaxKernel::reset() template void NEMinMaxKernel::update_min_max(const T min, const T max) { - std::lock_guard lock(_mtx); + arm_compute::lock_guard lock(_mtx); using type = typename std::conditional::value, float, int32_t>::type; diff --git a/src/core/utils/logging/LoggerRegistry.cpp b/src/core/utils/logging/LoggerRegistry.cpp index 055e770c75..fe71902ec0 100644 --- a/src/core/utils/logging/LoggerRegistry.cpp +++ b/src/core/utils/logging/LoggerRegistry.cpp @@ -24,6 +24,7 @@ #include "arm_compute/core/utils/logging/LoggerRegistry.h" #include "arm_compute/core/Error.h" +#include "support/Mutex.h" #include "support/ToolchainSupport.h" using namespace arm_compute::logging; @@ -44,7 +45,7 @@ LoggerRegistry &LoggerRegistry::get() void LoggerRegistry::create_logger(const std::string &name, LogLevel log_level, const std::vector> &printers) { - std::lock_guard lock(_mtx); + arm_compute::lock_guard lock(_mtx); if((_loggers.find(name) == _loggers.end()) && (_reserved_loggers.find(name) == _reserved_loggers.end())) { _loggers[name] = std::make_shared(name, log_level, printers); @@ -53,7 +54,7 @@ void LoggerRegistry::create_logger(const std::string &name, LogLevel log_level, void LoggerRegistry::remove_logger(const std::string &name) { - std::lock_guard lock(_mtx); + arm_compute::lock_guard lock(_mtx); if(_loggers.find(name) != _loggers.end()) { _loggers.erase(name); @@ -62,13 +63,13 @@ void LoggerRegistry::remove_logger(const std::string &name) std::shared_ptr LoggerRegistry::logger(const std::string &name) { - std::lock_guard lock(_mtx); + arm_compute::lock_guard lock(_mtx); return (_loggers.find(name) != _loggers.end()) ? _loggers[name] : nullptr; } void LoggerRegistry::create_reserved_loggers(LogLevel log_level, const std::vector> &printers) { - std::lock_guard lock(_mtx); + arm_compute::lock_guard lock(_mtx); for(const auto &r : _reserved_loggers) { if(_loggers.find(r) == _loggers.end()) diff --git a/support/Mutex.h b/support/Mutex.h index d70dd7595b..c398c570af 100644 --- a/support/Mutex.h +++ b/support/Mutex.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -31,6 +31,14 @@ namespace arm_compute #ifndef NO_MULTI_THREADING /** Wrapper of Mutex data-object */ using Mutex = std::mutex; + +/** Wrapper of lock_guard data-object */ +template +using lock_guard = std::lock_guard; + +/** Wrapper of lock_guard data-object */ +template +using unique_lock = std::unique_lock; #else /* NO_MULTI_THREADING */ /** Wrapper implementation of Mutex data-object */ class Mutex @@ -56,6 +64,62 @@ public: return true; } }; + +/** Wrapper implementation of lock-guard data-object */ +template +class lock_guard +{ +public: + typedef Mutex mutex_type; + +public: + explicit lock_guard(Mutex &m_) + : m(m_) + { + } + ~lock_guard() + { + } + lock_guard(const lock_guard &) = delete; + +private: + mutex_type &m; +}; + +/** Wrapper implementation of unique-lock data-object */ +template +class unique_lock +{ +public: + typedef Mutex mutex_type; + +public: + unique_lock() noexcept : m(nullptr) + { + } + explicit unique_lock(mutex_type &m) + : m(&m) + { + } + 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; + void lock() + { + } + bool try_lock() + { + return true; + } + void unlock() + { + } + +private: + mutex_type *m; +}; #endif /* NO_MULTI_THREADING */ } #endif /* __ARM_COMPUTE_MUTEX_H__ */ -- cgit v1.2.1