From 7d3d1b923b7793f1cf5e29c78bfda2582522cf25 Mon Sep 17 00:00:00 2001 From: Georgios Pinitas Date: Thu, 12 Oct 2017 17:34:20 +0100 Subject: COMPMID-619: Logging interface Change-Id: I73d1433ee7a682aeabb7540aa2ea1f6564f90aae Reviewed-on: http://mpd-gerrit.cambridge.arm.com/91775 Tested-by: Kaizen Reviewed-by: Anthony Barbier --- SConscript | 1 + SConstruct | 4 + arm_compute/core/Logger.h | 71 --------- arm_compute/core/utils/io/FileHandler.h | 76 ++++++++++ arm_compute/core/utils/logging/FilePrinter.h | 54 +++++++ arm_compute/core/utils/logging/Helpers.h | 77 ++++++++++ arm_compute/core/utils/logging/IPrinter.h | 74 +++++++++ arm_compute/core/utils/logging/LogMsgDecorators.h | 140 +++++++++++++++++ arm_compute/core/utils/logging/Logger.h | 176 ++++++++++++++++++++++ arm_compute/core/utils/logging/LoggerRegistry.h | 88 +++++++++++ arm_compute/core/utils/logging/Macros.h | 68 +++++++++ arm_compute/core/utils/logging/Printers.h | 31 ++++ arm_compute/core/utils/logging/StdPrinter.h | 47 ++++++ arm_compute/core/utils/logging/Types.h | 58 +++++++ arm_compute/graph/Types.h | 9 ++ examples/graph_alexnet.cpp | 5 +- examples/graph_lenet.cpp | 5 +- src/core/Logger.cpp | 56 ------- src/core/utils/io/FileHandler.cpp | 66 ++++++++ src/core/utils/logging/FilePrinter.cpp | 37 +++++ src/core/utils/logging/Helpers.cpp | 42 ++++++ src/core/utils/logging/Logger.cpp | 154 +++++++++++++++++++ src/core/utils/logging/LoggerRegistry.cpp | 79 ++++++++++ src/graph/nodes/ActivationLayer.cpp | 17 ++- src/graph/nodes/BatchNormalizationLayer.cpp | 13 +- src/graph/nodes/ConvolutionLayer.cpp | 23 ++- src/graph/nodes/FloorLayer.cpp | 13 +- src/graph/nodes/FullyConnectedLayer.cpp | 15 +- src/graph/nodes/L2NormalizeLayer.cpp | 13 +- src/graph/nodes/NormalizationLayer.cpp | 13 +- src/graph/nodes/PoolingLayer.cpp | 11 +- src/graph/nodes/SoftmaxLayer.cpp | 11 +- support/ToolchainSupport.h | 42 +++++- 33 files changed, 1390 insertions(+), 199 deletions(-) delete mode 100644 arm_compute/core/Logger.h create mode 100644 arm_compute/core/utils/io/FileHandler.h create mode 100644 arm_compute/core/utils/logging/FilePrinter.h create mode 100644 arm_compute/core/utils/logging/Helpers.h create mode 100644 arm_compute/core/utils/logging/IPrinter.h create mode 100644 arm_compute/core/utils/logging/LogMsgDecorators.h create mode 100644 arm_compute/core/utils/logging/Logger.h create mode 100644 arm_compute/core/utils/logging/LoggerRegistry.h create mode 100644 arm_compute/core/utils/logging/Macros.h create mode 100644 arm_compute/core/utils/logging/Printers.h create mode 100644 arm_compute/core/utils/logging/StdPrinter.h create mode 100644 arm_compute/core/utils/logging/Types.h delete mode 100644 src/core/Logger.cpp create mode 100644 src/core/utils/io/FileHandler.cpp create mode 100644 src/core/utils/logging/FilePrinter.cpp create mode 100644 src/core/utils/logging/Helpers.cpp create mode 100644 src/core/utils/logging/Logger.cpp create mode 100644 src/core/utils/logging/LoggerRegistry.cpp diff --git a/SConscript b/SConscript index 79f6bf37fd..195eff18bd 100644 --- a/SConscript +++ b/SConscript @@ -137,6 +137,7 @@ arm_compute_env.Append(LIBS = ['dl']) core_files = Glob('src/core/*.cpp') core_files += Glob('src/core/CPP/*.cpp') core_files += Glob('src/core/CPP/kernels/*.cpp') +core_files += Glob('src/core/utils/*/*.cpp') runtime_files = Glob('src/runtime/*.cpp') # CLHarrisCorners uses the Scheduler to run CPP kernels diff --git a/SConstruct b/SConstruct index 4ef67efe0c..c2c76fbf99 100644 --- a/SConstruct +++ b/SConstruct @@ -39,6 +39,7 @@ vars = Variables("scons") vars.AddVariables( BoolVariable("debug", "Debug", False), BoolVariable("asserts", "Enable asserts (this flag is forced to 1 for debug=1)", False), + BoolVariable("logging", "Logging", False), EnumVariable("arch", "Target Architecture", "armv7a", allowed_values=("armv7a", "arm64-v8a", "arm64-v8.2-a", "x86_32", "x86_64")), EnumVariable("os", "Target OS", "linux", allowed_values=("linux", "android", "bare_metal")), EnumVariable("build", "Build type", "cross_compile", allowed_values=("native", "cross_compile")), @@ -207,6 +208,9 @@ if env['asserts']: env.Append(CPPDEFINES = ['ARM_COMPUTE_ASSERTS_ENABLED']) env.Append(CXXFLAGS = ['-fstack-protector-strong']) +if env['logging']: + env.Append(CPPDEFINES = ['ARM_COMPUTE_LOGGING_ENABLED']) + env.Append(CPPPATH = ['#/include', "#"]) env.Append(CXXFLAGS = env['extra_cxx_flags']) diff --git a/arm_compute/core/Logger.h b/arm_compute/core/Logger.h deleted file mode 100644 index 0848479d37..0000000000 --- a/arm_compute/core/Logger.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2017 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_LOGGER_H__ -#define __ARM_COMPUTE_LOGGER_H__ - -#include -#include - -#ifdef ARM_COMPUTE_DEBUG_ENABLED -#define ARM_COMPUTE_LOG(x) (arm_compute::Logger::get().log_info() << x) -#else /* ARM_COMPUTE_DEBUG_ENABLED */ -#define ARM_COMPUTE_LOG(...) -#endif /* ARM_COMPUTE_DEBUG_ENABLED */ - -namespace arm_compute -{ -/**< Verbosity of the logger */ -enum class LoggerVerbosity -{ - NONE, /**< No info */ - INFO /**< Log info */ -}; - -/** Logger singleton class */ -class Logger -{ -public: - static Logger &get(); - void set_logger(std::ostream &ostream, LoggerVerbosity verbosity); - std::ostream &log_info(); - -private: - /** Default constructor */ - Logger(); - /** Allow instances of this class to be moved */ - Logger(Logger &&) = default; - /** Prevent instances of this class from being copied (As this class contains pointers) */ - Logger(const Logger &) = delete; - /** Prevent instances of this class from being copied (As this class contains pointers) */ - Logger &operator=(const Logger &) = delete; - /** Allow instances of this class to be moved */ - Logger &operator=(Logger &&) = default; - - std::ostream *_ostream; - std::ostream _nullstream; - LoggerVerbosity _verbosity; -}; -} // arm_compute -#endif /* __ARM_COMPUTE_LOGGER_H__ */ \ No newline at end of file diff --git a/arm_compute/core/utils/io/FileHandler.h b/arm_compute/core/utils/io/FileHandler.h new file mode 100644 index 0000000000..d915dbe286 --- /dev/null +++ b/arm_compute/core/utils/io/FileHandler.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017 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_IO_FILE_HANDLER_H__ +#define __ARM_COMPUTE_IO_FILE_HANDLER_H__ + +#include +#include + +namespace arm_compute +{ +namespace io +{ +/** File Handling interface */ +class FileHandler +{ +public: + /** Default Constructor */ + FileHandler(); + /** Default Destructor */ + ~FileHandler(); + /** Allow instances of this class to be moved */ + FileHandler(FileHandler &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + FileHandler(const FileHandler &) = delete; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + FileHandler &operator=(const FileHandler &) = delete; + /** Allow instances of this class to be moved */ + FileHandler &operator=(FileHandler &&) = default; + /** Opens file + * + * @param[in] filename File name + * @param[in] mode File open mode + */ + void open(const std::string &filename, std::ios_base::openmode mode); + /** Closes file */ + void close(); + /** Returns the file stream + * + * @return File stream + */ + std::fstream &stream(); + /** Returns filename of the handled file + * + * @return File filename + */ + std::string filename() const; + +private: + std::fstream _filestream; + std::string _filename; + std::ios_base::openmode _mode; +}; +} // namespace io +} // namespace arm_compute +#endif /* __ARM_COMPUTE_IO_FILE_HANDLER_H__ */ diff --git a/arm_compute/core/utils/logging/FilePrinter.h b/arm_compute/core/utils/logging/FilePrinter.h new file mode 100644 index 0000000000..e2ae95208a --- /dev/null +++ b/arm_compute/core/utils/logging/FilePrinter.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 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_LOGGING_FILE_PRINTER_H__ +#define __ARM_COMPUTE_LOGGING_FILE_PRINTER_H__ + +#include "arm_compute/core/utils/logging/IPrinter.h" + +#include "arm_compute/core/utils/io/FileHandler.h" + +namespace arm_compute +{ +namespace logging +{ +/** File Printer */ +class FilePrinter final : public Printer +{ +public: + /** Default Constructor + * + * @param[in] filename File name + */ + FilePrinter(const std::string &filename); + +private: + // Inherited methods overridden: + void print_internal(const std::string &msg) override; + +private: + io::FileHandler _handler; +}; +} // namespace logging +} // namespace arm_compute +#endif /* __ARM_COMPUTE_LOGGING_FILE_PRINTER_H__ */ diff --git a/arm_compute/core/utils/logging/Helpers.h b/arm_compute/core/utils/logging/Helpers.h new file mode 100644 index 0000000000..4bc54e80db --- /dev/null +++ b/arm_compute/core/utils/logging/Helpers.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2017 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_LOGGING_HELPERS_H__ +#define __ARM_COMPUTE_LOGGING_HELPERS_H__ + +#include "arm_compute/core/utils/logging/Types.h" +#include "support/ToolchainSupport.h" + +#include +#include +#include +#include +#include + +namespace arm_compute +{ +namespace logging +{ +/** Create a string given a format + * + * @param[in] fmt String format + * @param[in] args Arguments + * + * @return The formatted string + */ +template +inline std::string string_with_format(const std::string &fmt, Ts &&... args) +{ + size_t size = support::cpp11::snprintf(nullptr, 0, fmt.c_str(), args...) + 1; + auto char_str = support::cpp14::make_unique(size); + support::cpp11::snprintf(char_str.get(), size, fmt.c_str(), args...); + return std::string(char_str.get(), char_str.get() + size - 1); +} +/** Wraps a value with angles and returns the string + * + * @param[in] val Value to wrap + * + * @return Wrapped string + */ +template +inline std::string angle_wrap_value(const T &val) +{ + std::ostringstream ss; + ss << "[" << val << "]"; + return ss.str(); +} +/** Translates a given log level to a string. + * + * @param[in] log_level @ref LogLevel to be translated to string. + * + * @return The string describing the logging level. + */ +const std::string &string_from_log_level(LogLevel log_level); +} // namespace logging +} // namespace arm_compute +#endif /* __ARM_COMPUTE_LOGGING_HELPERS_H__ */ diff --git a/arm_compute/core/utils/logging/IPrinter.h b/arm_compute/core/utils/logging/IPrinter.h new file mode 100644 index 0000000000..6b410d4d12 --- /dev/null +++ b/arm_compute/core/utils/logging/IPrinter.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2017 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_LOGGING_PRINTER_H__ +#define __ARM_COMPUTE_LOGGING_PRINTER_H__ + +#include "support/Mutex.h" + +namespace arm_compute +{ +namespace logging +{ +/** Base printer class to be inherited by other printer classes */ +class Printer +{ +public: + /** Default Constructor */ + Printer() + : _mtx() + { + } + /** Prevent instances of this class from being copied */ + Printer(const Printer &) = delete; + /** Prevent instances of this class from being copied */ + Printer &operator=(const Printer &) = delete; + /** Prevent instances of this class from being moved */ + Printer(Printer &&) = delete; + /** Prevent instances of this class from being moved */ + Printer &operator=(Printer &&) = delete; + /** Defaults Destructor */ + virtual ~Printer() = default; + /** Print message + * + * @param[in] msg Message to print + */ + inline void print(const std::string &msg) + { + std::lock_guard lock(_mtx); + print_internal(msg); + } + +private: + /** Interface to be implemented by the child to print a message + * + * @param[in] msg Message to print + */ + virtual void print_internal(const std::string &msg) = 0; + +private: + arm_compute::Mutex _mtx; +}; +} // namespace logging +} // namespace arm_compute +#endif /* __ARM_COMPUTE_LOGGING_PRINTER_H__ */ diff --git a/arm_compute/core/utils/logging/LogMsgDecorators.h b/arm_compute/core/utils/logging/LogMsgDecorators.h new file mode 100644 index 0000000000..32cb977bf2 --- /dev/null +++ b/arm_compute/core/utils/logging/LogMsgDecorators.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2016, 2017 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_LOGGING_LOG_MSG_DECORATORS_H__ +#define __ARM_COMPUTE_LOGGING_LOG_MSG_DECORATORS_H__ + +#include "arm_compute/core/utils/logging/Helpers.h" +#include "arm_compute/core/utils/logging/Types.h" + +#include +#include +#include +#include + +namespace arm_compute +{ +namespace logging +{ +/** Log message decorator interface */ +class IDecorator +{ +public: + /** Default Destructor */ + virtual ~IDecorator() = default; + /** Decorates log message + * + * @param[in] log_msg Log message to decorate + */ + virtual void decorate(LogMsg &log_msg) = 0; +}; + +/** String Decorator + * + * Appends a user defined string in the log message + */ +class StringDecorator : public IDecorator +{ +public: + /** Defaults constructor + * + * @param str Sting to append + */ + StringDecorator(const std::string &str) + : _str(str) + { + _str = angle_wrap_value(str); + } + + // Inherited methods overridden: + void decorate(LogMsg &log_msg) override + { + log_msg.raw_ += _str; + } + +private: + std::string _str; +}; + +/** Date Decorator + * + * Appends the date and time in the log message + */ +class DateDecorator : public IDecorator +{ +public: + // Inherited methods overridden: + void decorate(LogMsg &log_msg) override + { + log_msg.raw_ += angle_wrap_value(get_time()); + } + +private: + /** Gets current system local time + * + * @return Local time + */ + std::string get_time() + { + auto now = std::chrono::system_clock::now(); + auto time = std::chrono::system_clock::to_time_t(now); + + // TODO: use put_time for gcc > 4.9 + char buf[100] = { 0 }; + std::strftime(buf, sizeof(buf), "%d-%m-%Y %I:%M:%S", std::localtime(&time)); + return buf; + } +}; + +/** Thread ID Decorator + * + * Appends the thread ID in the log message + */ +class ThreadIdDecorator : public IDecorator +{ +public: + // Inherited methods overridden: + void decorate(LogMsg &log_msg) override + { +#ifndef NO_MULTI_THREADING + log_msg.raw_ += angle_wrap_value(std::this_thread::get_id()); +#endif /* NO_MULTI_THREADING */ + } +}; + +/** Log Level Decorator + * + * Appends the logging level in the log message + */ +class LogLevelDecorator : public IDecorator +{ +public: + // Inherited methods overridden: + void decorate(LogMsg &log_msg) override + { + log_msg.raw_ += angle_wrap_value(string_from_log_level(log_msg.log_level_)); + } +}; +} // namespace logging +} // namespace arm_compute +#endif /* __ARM_COMPUTE_LOGGING_LOG_MSG_DECORATORS_H__ */ diff --git a/arm_compute/core/utils/logging/Logger.h b/arm_compute/core/utils/logging/Logger.h new file mode 100644 index 0000000000..eb9bdd2e36 --- /dev/null +++ b/arm_compute/core/utils/logging/Logger.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2017 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_LOGGING_LOGGER_H__ +#define __ARM_COMPUTE_LOGGING_LOGGER_H__ + +#include "arm_compute/core/utils/logging/Helpers.h" +#include "arm_compute/core/utils/logging/IPrinter.h" +#include "arm_compute/core/utils/logging/LogMsgDecorators.h" +#include "arm_compute/core/utils/logging/Types.h" + +#include +#include +#include +#include + +namespace arm_compute +{ +namespace logging +{ +/** Logger class */ +class Logger +{ +public: + /** Default Constructor + * + * @param[in] name Name of the logger + * @param[in] log_level Logger log level + * @param[in] printer Printer to push the messages + */ + Logger(std::string name, LogLevel log_level, std::shared_ptr printer); + /** Default Constructor + * + * @param[in] name Name of the logger + * @param[in] log_level Logger log level + * @param[in] printers Printers to push the messages + */ + Logger(std::string name, LogLevel log_level, std::vector> printers = {}); + /** Default Constructor + * + * @param[in] name Name of the logger + * @param[in] log_level Logger log level + * @param[in] printers Printers to push the messages + * @param[in] decorators Message decorators, which append information in the logged message + */ + Logger(std::string name, + LogLevel log_level, + std::vector> printers, + std::vector> decorators); + /** Allow instances of this class to be moved */ + Logger(Logger &&) = default; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + Logger(const Logger &) = delete; + /** Prevent instances of this class from being copied (As this class contains pointers) */ + Logger &operator=(const Logger &) = delete; + /** Allow instances of this class to be moved */ + Logger &operator=(Logger &&) = default; + /** Logs a message + * + * @param[in] log_level Log level of the message + * @param[in] msg Message to log + */ + void log(LogLevel log_level, const std::string &msg); + /** Logs a formatted message + * + * @param[in] log_level Log level of the message + * @param[in] fmt Message format + * @param[in] args Message arguments + */ + template + void log(LogLevel log_level, const std::string &fmt, Ts &&... args); + /** Sets log level of the logger + * + * @warning Not thread-safe + * + * @param[in] log_level Log level to set + */ + void set_log_level(LogLevel log_level); + /** Returns logger's log level + * + * @return Logger's log level + */ + LogLevel log_level() const; + /** Returns logger's name + * + * @return Logger's name + */ + std::string name() const; + /** Adds a printer to the logger + * + * @warning Not thread-safe + * + * @param[in] printer + */ + void add_printer(std::shared_ptr printer); + /** Adds a log message decorator to the logger + * + * @warning Not thread-safe + * + * @param[in] decorator + */ + void add_decorator(std::unique_ptr decorator); + +private: + /** Set default message decorators */ + void set_default_decorators(); + /** Checks if a message should be logged depending + * on the message log level and the loggers one + * + * @param[in] log_level Log level + * + * @return True if message should be logged else false + */ + bool is_loggable(LogLevel log_level); + /** Decorate log message + * + * @param[in] Log message to decorate + */ + void decorate_log_msg(LogMsg &msg); + /** Creates final log message by creating the prefix + * + * @param[in] str Log message + * @param[in] log_level Message's log level + * + * @return Final log message to print + */ + std::string create_log_msg(const std::string &str, LogLevel log_level); + /** Prints the message to all the printers + * + * @param[in] msg Message to print + */ + void print_all(const std::string &msg); + +private: + std::string _name; + LogLevel _log_level; + std::vector> _printers; + std::vector> _decorators; +}; + +template +inline void Logger::log(LogLevel log_level, const std::string &fmt, Ts &&... args) +{ + // Return if message shouldn't be logged + // i.e. if log level does not match the logger's + if(!is_loggable(log_level)) + { + return; + } + + // Print message to all printers + print_all(create_log_msg(string_with_format(fmt, args...), log_level)); +} +} // namespace logging +} // namespace arm_compute +#endif /* __ARM_COMPUTE_LOGGING_LOGGER_H__ */ diff --git a/arm_compute/core/utils/logging/LoggerRegistry.h b/arm_compute/core/utils/logging/LoggerRegistry.h new file mode 100644 index 0000000000..d861476fea --- /dev/null +++ b/arm_compute/core/utils/logging/LoggerRegistry.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017 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_LOGGING_LOGGER_REGISTRY_H__ +#define __ARM_COMPUTE_LOGGING_LOGGER_REGISTRY_H__ + +#include "arm_compute/core/utils/logging/Logger.h" +#include "arm_compute/core/utils/logging/Printers.h" +#include "arm_compute/core/utils/logging/Types.h" +#include "support/Mutex.h" + +#include +#include +#include + +namespace arm_compute +{ +namespace logging +{ +/** Registry class holding all the instantiated loggers */ +class LoggerRegistry final +{ +public: + /** Gets registry instance + * + * @return Logger registry instance + */ + static LoggerRegistry &get(); + /** Creates a logger + * + * @note Some names are reserved e.g. [CORE, RUNTIME, GRAPH] + * + * @param[in] name Logger's name + * @param[in] log_level Logger's log level + * @param[in] printers Printers to attach to the system loggers + */ + void create_logger(const std::string &name, LogLevel log_level, std::vector> printers = {}); + /** Remove a logger + * + * @param name Logger's name + */ + void remove_logger(const std::string &name); + /** Returns a logger instance + * + * @param[in] name Logger to return + * + * @return Logger + */ + std::shared_ptr logger(const std::string &name); + /** Creates reserved library loggers + * + * @param[in] log_level Logger's log level + * @param[in] printers Printers to attach to the system loggers + */ + void create_reserved_loggers(LogLevel log_level, std::vector> printers = {}); + +private: + /** Default constructor */ + LoggerRegistry(); + +private: + arm_compute::Mutex _mtx; + std::unordered_map> _loggers; + static std::set _reserved_loggers; +}; +} // namespace logging +} // namespace arm_compute +#endif /* __ARM_COMPUTE_LOGGING_LOGGER_REGISTRY_H__ */ diff --git a/arm_compute/core/utils/logging/Macros.h b/arm_compute/core/utils/logging/Macros.h new file mode 100644 index 0000000000..b17354bed7 --- /dev/null +++ b/arm_compute/core/utils/logging/Macros.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2017 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_LOGGING_MACROS_H__ +#define __ARM_COMPUTE_LOGGING_MACROS_H__ + +#include "arm_compute/core/utils/logging/LoggerRegistry.h" + +#include + +#ifdef ARM_COMPUTE_LOGGING_ENABLED + +#define ARM_COMPUTE_LOG_MSG(logger_name, log_level, msg) \ + { \ + auto logger = arm_compute::logging::LoggerRegistry::get().logger(logger_name); \ + if(logger != nullptr) \ + { \ + logger->log(log_level, msg); \ + } \ + } + +#define ARM_COMPUTE_LOG_MSG_WITH_FORMAT(logger_name, log_level, fmt, ...) \ + { \ + auto logger = arm_compute::logging::LoggerRegistry::get().logger(logger_name); \ + if(logger != nullptr) \ + { \ + logger->log(log_level, fmt, __VA_ARGS__); \ + } \ + } + +#define ARM_COMPUTE_LOG_STREAM(logger_name, log_level, stream) \ + { \ + auto logger = arm_compute::logging::LoggerRegistry::get().logger(logger_name); \ + if(logger != nullptr) \ + { \ + logger->log(log_level, static_cast(std::ostringstream() << stream).str()); \ + } \ + } + +#else /* ARM_COMPUTE_LOGGING_ENABLED */ + +#define ARM_COMPUTE_LOG_MSG(logger_name, log_level, msg) +#define ARM_COMPUTE_LOG_MSG_WITH_FORMAT(logger_name, log_level, fmt, ...) +#define ARM_COMPUTE_LOG_STREAM(logger_name, log_level, stream) + +#endif /* ARM_COMPUTE_LOGGING_ENABLED */ + +#endif /* __ARM_COMPUTE_LOGGING_MACROS_H__ */ diff --git a/arm_compute/core/utils/logging/Printers.h b/arm_compute/core/utils/logging/Printers.h new file mode 100644 index 0000000000..7e5eef6a04 --- /dev/null +++ b/arm_compute/core/utils/logging/Printers.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 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_LOGGING_PRINTERS_H__ +#define __ARM_COMPUTE_LOGGING_PRINTERS_H__ + +#include "arm_compute/core/utils/logging/FilePrinter.h" +#include "arm_compute/core/utils/logging/IPrinter.h" +#include "arm_compute/core/utils/logging/StdPrinter.h" + +#endif /* __ARM_COMPUTE_LOGGING_PRINTERS_H__ */ diff --git a/arm_compute/core/utils/logging/StdPrinter.h b/arm_compute/core/utils/logging/StdPrinter.h new file mode 100644 index 0000000000..0b41b26022 --- /dev/null +++ b/arm_compute/core/utils/logging/StdPrinter.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 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_LOGGING_STD_PRINTER_H__ +#define __ARM_COMPUTE_LOGGING_STD_PRINTER_H__ + +#include "arm_compute/core/utils/logging/IPrinter.h" + +#include + +namespace arm_compute +{ +namespace logging +{ +/** Std Printer */ +class StdPrinter final : public Printer +{ +private: + // Inherited methods overridden: + void print_internal(const std::string &msg) override + { + std::cout << msg << std::endl; + } +}; +} // namespace logging +} // namespace arm_compute +#endif /* __ARM_COMPUTE_LOGGING_STD_PRINTER_H__ */ diff --git a/arm_compute/core/utils/logging/Types.h b/arm_compute/core/utils/logging/Types.h new file mode 100644 index 0000000000..171270d4ef --- /dev/null +++ b/arm_compute/core/utils/logging/Types.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016, 2017 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_LOGGING_TYPES_H__ +#define __ARM_COMPUTE_LOGGING_TYPES_H__ + +#include + +namespace arm_compute +{ +namespace logging +{ +/** Logging level enumeration */ +enum class LogLevel : unsigned int +{ + VERBOSE, /**< All logging messages */ + INFO, /**< Information log level */ + WARN, /**< Warning log level */ + OFF /**< No logging */ +}; + +struct LogMsg +{ + LogMsg() + : raw_(), log_level_(LogLevel::OFF) + { + } + LogMsg(std::string msg, LogLevel log_level = LogLevel::OFF) + : raw_(msg), log_level_(log_level) + { + } + + std::string raw_; + LogLevel log_level_; +}; +} // namespace logging +} // namespace arm_compute +#endif /* __ARM_COMPUTE_TYPES_H__ */ diff --git a/arm_compute/graph/Types.h b/arm_compute/graph/Types.h index c4396412a7..f02fa7df3f 100644 --- a/arm_compute/graph/Types.h +++ b/arm_compute/graph/Types.h @@ -27,6 +27,13 @@ #include "arm_compute/core/ITensor.h" #include "arm_compute/core/SubTensorInfo.h" #include "arm_compute/core/TensorInfo.h" +#include "arm_compute/core/utils/logging/Macros.h" + +#define ARM_COMPUTE_LOG_GRAPH(log_level, x) \ + ARM_COMPUTE_LOG_STREAM("GRAPH", log_level, x) + +#define ARM_COMPUTE_LOG_GRAPH_INFO(x) \ + ARM_COMPUTE_LOG_STREAM("GRAPH", arm_compute::logging::LogLevel::INFO, x) namespace arm_compute { @@ -47,6 +54,8 @@ using arm_compute::TensorInfo; using arm_compute::TensorShape; using arm_compute::WeightsInfo; +using arm_compute::logging::LogLevel; + /**< Execution hint to the graph executor */ enum class TargetHint { diff --git a/examples/graph_alexnet.cpp b/examples/graph_alexnet.cpp index dce7132785..9a747b6b0c 100644 --- a/examples/graph_alexnet.cpp +++ b/examples/graph_alexnet.cpp @@ -25,7 +25,7 @@ #error "This example needs to be built with -DARM_COMPUTE_CL" #endif /* ARM_COMPUTE_CL */ -#include "arm_compute/core/Logger.h" +#include "arm_compute/core/utils/logging/LoggerRegistry.h" #include "arm_compute/graph/Graph.h" #include "arm_compute/graph/Nodes.h" #include "arm_compute/runtime/CL/CLScheduler.h" @@ -41,6 +41,7 @@ using namespace arm_compute::graph; using namespace arm_compute::graph_utils; +using namespace arm_compute::logging; /** Generates appropriate accessor according to the specified path * @@ -103,7 +104,7 @@ void main_graph_alexnet(int argc, const char **argv) } Graph graph; - arm_compute::Logger::get().set_logger(std::cout, arm_compute::LoggerVerbosity::INFO); + LoggerRegistry::get().create_reserved_loggers(LogLevel::INFO, { std::make_shared() }); graph << hint << Tensor(TensorInfo(TensorShape(227U, 227U, 3U, batches), 1, DataType::F32), DummyAccessor()) diff --git a/examples/graph_lenet.cpp b/examples/graph_lenet.cpp index 1427abe15f..82f4c5a4c1 100644 --- a/examples/graph_lenet.cpp +++ b/examples/graph_lenet.cpp @@ -25,7 +25,7 @@ #error "This example needs to be built with -DARM_COMPUTE_CL" #endif /* ARM_COMPUTE_CL */ -#include "arm_compute/core/Logger.h" +#include "arm_compute/core/utils/logging/LoggerRegistry.h" #include "arm_compute/graph/Graph.h" #include "arm_compute/graph/Nodes.h" #include "arm_compute/runtime/CL/CLScheduler.h" @@ -40,6 +40,7 @@ using namespace arm_compute::graph; using namespace arm_compute::graph_utils; +using namespace arm_compute::logging; /** Generates appropriate accessor according to the specified path * @@ -102,7 +103,7 @@ void main_graph_lenet(int argc, const char **argv) } Graph graph; - arm_compute::Logger::get().set_logger(std::cout, arm_compute::LoggerVerbosity::INFO); + LoggerRegistry::get().create_reserved_loggers(LogLevel::INFO, { std::make_shared() }); //conv1 << pool1 << conv2 << pool2 << fc1 << act1 << fc2 << smx graph << hint diff --git a/src/core/Logger.cpp b/src/core/Logger.cpp deleted file mode 100644 index 9c3bf263a6..0000000000 --- a/src/core/Logger.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 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. - */ - -#include "arm_compute/core/Logger.h" - -using namespace arm_compute; - -Logger::Logger() - : _ostream(&std::cout), _nullstream(nullptr), _verbosity(LoggerVerbosity::NONE) -{ -} - -Logger &Logger::get() -{ - static Logger _instance; - return _instance; -} - -void Logger::set_logger(std::ostream &ostream, LoggerVerbosity verbosity) -{ - _ostream = &ostream; - _verbosity = verbosity; -} - -std::ostream &Logger::log_info() -{ - if(_verbosity == LoggerVerbosity::INFO) - { - return *_ostream; - } - else - { - return _nullstream; - } -} \ No newline at end of file diff --git a/src/core/utils/io/FileHandler.cpp b/src/core/utils/io/FileHandler.cpp new file mode 100644 index 0000000000..70bce42b0b --- /dev/null +++ b/src/core/utils/io/FileHandler.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2017 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. + */ +#include + +#include "arm_compute/core/utils/io/FileHandler.h" + +#include "arm_compute/core/Error.h" +#include "support/ToolchainSupport.h" + +using namespace arm_compute::io; + +FileHandler::FileHandler() + : _filestream(), _filename(" "), _mode() +{ +} + +FileHandler::~FileHandler() +{ + close(); +} + +void FileHandler::open(const std::string &filename, std::ios_base::openmode mode) +{ + close(); + ; + _filestream.open(filename, mode); + ARM_COMPUTE_ERROR_ON(!_filestream.good()); + _filename = filename; + _mode = mode; +} + +void FileHandler::close() +{ + _filestream.close(); +} + +std::fstream &FileHandler::stream() +{ + return _filestream; +} + +std::string FileHandler::filename() const +{ + return _filename; +} diff --git a/src/core/utils/logging/FilePrinter.cpp b/src/core/utils/logging/FilePrinter.cpp new file mode 100644 index 0000000000..b699afc22a --- /dev/null +++ b/src/core/utils/logging/FilePrinter.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 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. + */ +#include "arm_compute/core/utils/logging/FilePrinter.h" + +using namespace arm_compute::logging; + +FilePrinter::FilePrinter(const std::string &filename) + : _handler() +{ + _handler.open(filename, std::fstream::out | std::fstream::trunc); +} + +void FilePrinter::print_internal(const std::string &msg) +{ + _handler.stream() << msg << std::endl; +} \ No newline at end of file diff --git a/src/core/utils/logging/Helpers.cpp b/src/core/utils/logging/Helpers.cpp new file mode 100644 index 0000000000..f5ab608c3a --- /dev/null +++ b/src/core/utils/logging/Helpers.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 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. + */ +#include "arm_compute/core/utils/logging/Helpers.h" + +#include +#include + +using namespace arm_compute::logging; + +const std::string &arm_compute::logging::string_from_log_level(LogLevel log_level) +{ + static std::map log_level_map = + { + { LogLevel::VERBOSE, "VERBOSE" }, + { LogLevel::INFO, "INFO" }, + { LogLevel::WARN, "WARN" }, + { LogLevel::OFF, "OFF" }, + }; + + return log_level_map[log_level]; +} \ No newline at end of file diff --git a/src/core/utils/logging/Logger.cpp b/src/core/utils/logging/Logger.cpp new file mode 100644 index 0000000000..b025ca8097 --- /dev/null +++ b/src/core/utils/logging/Logger.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2017 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. + */ +#include "arm_compute/core/utils/logging/Logger.h" + +#include "arm_compute/core/Error.h" +#include "support/ToolchainSupport.h" + +using namespace arm_compute::logging; + +Logger::Logger(std::string name, LogLevel log_level, std::shared_ptr printer) + : _name(std::move(name)), _log_level(log_level), _printers( +{ + std::move(printer) +}), _decorators() +{ + // Check printer + ARM_COMPUTE_ERROR_ON(printer == nullptr); + + // Set default message decorators + set_default_decorators(); +} + +Logger::Logger(std::string name, LogLevel log_level, std::vector> printers) + : _name(std::move(name)), _log_level(log_level), _printers(std::move(printers)), _decorators() +{ + // Check printers + for(const auto &p : _printers) + { + ARM_COMPUTE_UNUSED(p); + ARM_COMPUTE_ERROR_ON(p == nullptr); + } + // Set default message decorators + set_default_decorators(); +} + +Logger::Logger(std::string name, + LogLevel log_level, + std::vector> printers, + std::vector> decorators) + : _name(std::move(name)), _log_level(log_level), _printers(std::move(printers)), _decorators(std::move(decorators)) +{ + // Check printers + for(const auto &p : _printers) + { + ARM_COMPUTE_UNUSED(p); + ARM_COMPUTE_ERROR_ON(p == nullptr); + } + // Check decorators + for(const auto &d : _decorators) + { + ARM_COMPUTE_UNUSED(d); + ARM_COMPUTE_ERROR_ON(d == nullptr); + } +} + +void Logger::log(LogLevel log_level, const std::string &msg) +{ + // Return if message shouldn't be logged + // i.e. if log level does not match the logger's + if(!is_loggable(log_level)) + { + return; + } + + // Print message to all printers + print_all(create_log_msg(msg, log_level)); +} + +void Logger::set_log_level(LogLevel log_level) +{ + _log_level = log_level; +} + +LogLevel Logger::log_level() const +{ + return _log_level; +} + +std::string Logger::name() const +{ + return _name; +} + +void Logger::add_printer(std::shared_ptr printer) +{ + ARM_COMPUTE_ERROR_ON(printer == nullptr); + _printers.push_back(std::move(printer)); +} + +void Logger::add_decorator(std::unique_ptr decorator) +{ + ARM_COMPUTE_ERROR_ON(decorator == nullptr); + _decorators.push_back(std::move(decorator)); +} + +void Logger::set_default_decorators() +{ + _decorators.emplace_back(support::cpp14::make_unique(_name)); + _decorators.emplace_back(support::cpp14::make_unique()); + _decorators.emplace_back(support::cpp14::make_unique()); +} + +bool Logger::is_loggable(LogLevel log_level) +{ + return (log_level >= _log_level); +} + +void Logger::decorate_log_msg(LogMsg &msg) +{ + for(const auto &d : _decorators) + { + d->decorate(msg); + } + msg.raw_ += std::string(" "); +} + +std::string Logger::create_log_msg(const std::string &str, LogLevel log_level) +{ + // Adding space string to avoid Android failures + LogMsg log_msg(" ", log_level); + decorate_log_msg(log_msg); + std::ostringstream ss; + ss << log_msg.raw_ << " " << str; + return ss.str(); +} + +void Logger::print_all(const std::string &msg) +{ + for(auto &p : _printers) + { + p->print(msg); + } +} \ No newline at end of file diff --git a/src/core/utils/logging/LoggerRegistry.cpp b/src/core/utils/logging/LoggerRegistry.cpp new file mode 100644 index 0000000000..99236d25c3 --- /dev/null +++ b/src/core/utils/logging/LoggerRegistry.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 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. + */ +#include "arm_compute/core/utils/logging/LoggerRegistry.h" + +#include "arm_compute/core/Error.h" +#include "support/ToolchainSupport.h" + +using namespace arm_compute::logging; + +/** Reserved logger used by the library */ +std::set LoggerRegistry::_reserved_loggers = { "CORE", "RUNTIME", "GRAPH" }; + +LoggerRegistry::LoggerRegistry() + : _mtx(), _loggers() +{ +} + +LoggerRegistry &LoggerRegistry::get() +{ + static LoggerRegistry _instance; + return _instance; +} + +void LoggerRegistry::create_logger(const std::string &name, LogLevel log_level, std::vector> printers) +{ + std::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, std::move(printers)); + } +} + +void LoggerRegistry::remove_logger(const std::string &name) +{ + std::lock_guard lock(_mtx); + if(_loggers.find(name) != _loggers.end()) + { + _loggers.erase(name); + } +} + +std::shared_ptr LoggerRegistry::logger(const std::string &name) +{ + std::lock_guard lock(_mtx); + return (_loggers.find(name) != _loggers.end()) ? _loggers[name] : nullptr; +} + +void LoggerRegistry::create_reserved_loggers(LogLevel log_level, std::vector> printers) +{ + std::lock_guard lock(_mtx); + for(const auto &r : _reserved_loggers) + { + if(_loggers.find(r) == _loggers.end()) + { + _loggers[r] = std::make_shared(r, log_level, printers); + } + } +} diff --git a/src/graph/nodes/ActivationLayer.cpp b/src/graph/nodes/ActivationLayer.cpp index 5e75c28bc7..df73ba7078 100644 --- a/src/graph/nodes/ActivationLayer.cpp +++ b/src/graph/nodes/ActivationLayer.cpp @@ -23,7 +23,6 @@ */ #include "arm_compute/graph/nodes/ActivationLayer.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/functions/CLActivationLayer.h" #include "arm_compute/runtime/NEON/functions/NEActivationLayer.h" @@ -82,18 +81,20 @@ std::unique_ptr ActivationLayer::instantiate_node(GraphC if(_target_hint == TargetHint::OPENCL) { func = instantiate(in, out, _activation_info); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLActivationLayer"); } else { func = instantiate(in, out, _activation_info); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEActivationLayer"); } - ARM_COMPUTE_LOG(" Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Activation function: " << _activation_info.activation() - << " a: " << _activation_info.a() - << " b: " << _activation_info.b() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() + << " Input shape: " << in->info()->tensor_shape() + << " Output shape: " << out->info()->tensor_shape() + << " Activation function: " << _activation_info.activation() + << " a: " << _activation_info.a() + << " b: " << _activation_info.b() + << std::endl); return func; } diff --git a/src/graph/nodes/BatchNormalizationLayer.cpp b/src/graph/nodes/BatchNormalizationLayer.cpp index 25e9e9bffb..db809f4ee4 100644 --- a/src/graph/nodes/BatchNormalizationLayer.cpp +++ b/src/graph/nodes/BatchNormalizationLayer.cpp @@ -23,7 +23,6 @@ */ #include "arm_compute/graph/nodes/BatchNormalizationLayer.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/functions/CLBatchNormalizationLayer.h" #include "arm_compute/runtime/NEON/functions/NEBatchNormalizationLayer.h" @@ -100,18 +99,18 @@ std::unique_ptr BatchNormalizationLayer::instantiate_nod if(_target_hint == TargetHint::OPENCL) { func = instantiate(in, out, _mean, _var, _beta, _gamma, _epsilon); - ARM_COMPUTE_LOG("Instantiating CLBatchNormalizationLayer"); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLBatchNormalizationLayer"); } else { func = instantiate(in, out, _mean, _var, _beta, _gamma, _epsilon); - ARM_COMPUTE_LOG("Instantiating NEBatchNormalizationLayer"); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEBatchNormalizationLayer"); } - ARM_COMPUTE_LOG(" Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() + << " Input shape: " << in->info()->tensor_shape() + << " Output shape: " << out->info()->tensor_shape() + << std::endl); return func; } \ No newline at end of file diff --git a/src/graph/nodes/ConvolutionLayer.cpp b/src/graph/nodes/ConvolutionLayer.cpp index 303780ff35..07d42617e2 100644 --- a/src/graph/nodes/ConvolutionLayer.cpp +++ b/src/graph/nodes/ConvolutionLayer.cpp @@ -23,7 +23,6 @@ */ #include "arm_compute/graph/nodes/ConvolutionLayer.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/functions/CLConvolutionLayer.h" #include "arm_compute/runtime/CL/functions/CLDirectConvolutionLayer.h" #include "arm_compute/runtime/IFunction.h" @@ -217,12 +216,12 @@ std::unique_ptr ConvolutionLayer::instantiate_node(Graph if(_num_groups == 1) { func = instantiate_convolution(in, out, conv_method_hint); - ARM_COMPUTE_LOG("Instantiating CLConvolutionLayer"); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLConvolutionLayer"); } else { func = instantiate_grouped_convolution(in, out, conv_method_hint); - ARM_COMPUTE_LOG("Instantiating NEConvolutionLayer"); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEConvolutionLayer"); } // Fill weights @@ -236,15 +235,15 @@ std::unique_ptr ConvolutionLayer::instantiate_node(Graph _biases.allocate_and_fill_if_needed(); } - ARM_COMPUTE_LOG(" Data Type: " << in->info()->data_type() - << " Input Shape: " << in->info()->tensor_shape() - << " Weights shape: " << _weights.info().tensor_shape() - << " Biases Shape: " << _biases.info().tensor_shape() - << " Output Shape: " << out->info()->tensor_shape() - << " PadStrideInfo: " << _conv_info - << " Groups: " << _num_groups - << " WeightsInfo: " << _weights_info - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() + << " Input Shape: " << in->info()->tensor_shape() + << " Weights shape: " << _weights.info().tensor_shape() + << " Biases Shape: " << _biases.info().tensor_shape() + << " Output Shape: " << out->info()->tensor_shape() + << " PadStrideInfo: " << _conv_info + << " Groups: " << _num_groups + << " WeightsInfo: " << _weights_info + << std::endl); return func; } diff --git a/src/graph/nodes/FloorLayer.cpp b/src/graph/nodes/FloorLayer.cpp index 3224799e3e..45e2c3ee41 100644 --- a/src/graph/nodes/FloorLayer.cpp +++ b/src/graph/nodes/FloorLayer.cpp @@ -23,7 +23,6 @@ */ #include "arm_compute/graph/nodes/FloorLayer.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/functions/CLFloor.h" #include "arm_compute/runtime/NEON/functions/NEFloor.h" @@ -76,18 +75,18 @@ std::unique_ptr FloorLayer::instantiate_node(GraphContex if(_target_hint == TargetHint::OPENCL) { func = instantiate(in, out); - ARM_COMPUTE_LOG("Instantiating CLFloorLayer"); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLFloorLayer"); } else { func = instantiate(in, out); - ARM_COMPUTE_LOG("Instantiating NEFloorLayer"); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEFloorLayer"); } - ARM_COMPUTE_LOG(" Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() + << " Input shape: " << in->info()->tensor_shape() + << " Output shape: " << out->info()->tensor_shape() + << std::endl); return func; } diff --git a/src/graph/nodes/FullyConnectedLayer.cpp b/src/graph/nodes/FullyConnectedLayer.cpp index fa5ead8bdd..5f4807ad48 100644 --- a/src/graph/nodes/FullyConnectedLayer.cpp +++ b/src/graph/nodes/FullyConnectedLayer.cpp @@ -24,7 +24,6 @@ #include "arm_compute/graph/nodes/FullyConnectedLayer.h" #include "arm_compute/core/Helpers.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h" #include "arm_compute/runtime/NEON/functions/NEFullyConnectedLayer.h" #include "support/ToolchainSupport.h" @@ -123,18 +122,20 @@ std::unique_ptr FullyConnectedLayer::instantiate_node(Gr if(_target_hint == TargetHint::OPENCL) { func = instantiate(in, _weights, _biases, out); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLFullyConnectedLayer"); } else { func = instantiate(in, _weights, _biases, out); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEFullyConnectedLayer"); } - ARM_COMPUTE_LOG(" Type: " << in->info()->data_type() - << " Input Shape: " << in->info()->tensor_shape() - << " Weights shape: " << _weights.info().tensor_shape() - << " Biases Shape: " << _biases.info().tensor_shape() - << " Output Shape: " << out->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Type: " << in->info()->data_type() + << " Input Shape: " << in->info()->tensor_shape() + << " Weights shape: " << _weights.info().tensor_shape() + << " Biases Shape: " << _biases.info().tensor_shape() + << " Output Shape: " << out->info()->tensor_shape() + << std::endl); return func; } diff --git a/src/graph/nodes/L2NormalizeLayer.cpp b/src/graph/nodes/L2NormalizeLayer.cpp index 7abc69c13a..c5689e159a 100644 --- a/src/graph/nodes/L2NormalizeLayer.cpp +++ b/src/graph/nodes/L2NormalizeLayer.cpp @@ -23,7 +23,6 @@ */ #include "arm_compute/graph/nodes/L2NormalizeLayer.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/functions/CLL2Normalize.h" #include "arm_compute/runtime/NEON/functions/NEL2Normalize.h" @@ -78,18 +77,18 @@ std::unique_ptr L2NormalizeLayer::instantiate_node(Graph if(_target_hint == TargetHint::OPENCL) { func = instantiate(in, out, _axis, _epsilon); - ARM_COMPUTE_LOG("Instantiating CLL2NormalizeLayer"); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLL2NormalizeLayer"); } else { func = instantiate(in, out, _axis, _epsilon); - ARM_COMPUTE_LOG("Instantiating NEL2NormalizeLayer"); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEL2NormalizeLayer"); } - ARM_COMPUTE_LOG(" Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() + << " Input shape: " << in->info()->tensor_shape() + << " Output shape: " << out->info()->tensor_shape() + << std::endl); return func; } diff --git a/src/graph/nodes/NormalizationLayer.cpp b/src/graph/nodes/NormalizationLayer.cpp index 319a4252b6..680925a2b9 100644 --- a/src/graph/nodes/NormalizationLayer.cpp +++ b/src/graph/nodes/NormalizationLayer.cpp @@ -23,7 +23,6 @@ */ #include "arm_compute/graph/nodes/NormalizationLayer.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/functions/CLNormalizationLayer.h" #include "arm_compute/runtime/NEON/functions/NENormalizationLayer.h" @@ -82,17 +81,19 @@ std::unique_ptr NormalizationLayer::instantiate_node(Gra if(_target_hint == TargetHint::OPENCL) { func = instantiate(in, out, _norm_info); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLNormalizationLayer"); } else { func = instantiate(in, out, _norm_info); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NENormalizationLayer"); } - ARM_COMPUTE_LOG(" Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Normalization info: " << _norm_info - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() + << " Input shape: " << in->info()->tensor_shape() + << " Output shape: " << out->info()->tensor_shape() + << " Normalization info: " << _norm_info + << std::endl); return func; } diff --git a/src/graph/nodes/PoolingLayer.cpp b/src/graph/nodes/PoolingLayer.cpp index 904ba18169..63579155cb 100644 --- a/src/graph/nodes/PoolingLayer.cpp +++ b/src/graph/nodes/PoolingLayer.cpp @@ -23,7 +23,6 @@ */ #include "arm_compute/graph/nodes/PoolingLayer.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/functions/CLPoolingLayer.h" #include "arm_compute/runtime/NEON/functions/NEPoolingLayer.h" @@ -82,16 +81,18 @@ std::unique_ptr PoolingLayer::instantiate_node(GraphCont if(_target_hint == TargetHint::OPENCL) { func = instantiate(in, out, _pool_info); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLPoolingLayer"); } else { func = instantiate(in, out, _pool_info); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NEPoolingLayer"); } - ARM_COMPUTE_LOG(" Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << " Pooling info: " << _pool_info << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() + << " Input shape: " << in->info()->tensor_shape() + << " Output shape: " << out->info()->tensor_shape() + << " Pooling info: " << _pool_info << std::endl); return func; } diff --git a/src/graph/nodes/SoftmaxLayer.cpp b/src/graph/nodes/SoftmaxLayer.cpp index e3345f1400..3cdbc9c96a 100644 --- a/src/graph/nodes/SoftmaxLayer.cpp +++ b/src/graph/nodes/SoftmaxLayer.cpp @@ -23,7 +23,6 @@ */ #include "arm_compute/graph/nodes/SoftmaxLayer.h" -#include "arm_compute/core/Logger.h" #include "arm_compute/runtime/CL/CLTensor.h" #include "arm_compute/runtime/CL/functions/CLSoftmaxLayer.h" #include "arm_compute/runtime/NEON/functions/NESoftmaxLayer.h" @@ -76,16 +75,18 @@ std::unique_ptr SoftmaxLayer::instantiate_node(GraphCont if(_target_hint == TargetHint::OPENCL) { func = instantiate(in, out); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating CLSoftmaxLayer"); } else { func = instantiate(in, out); + ARM_COMPUTE_LOG_GRAPH_INFO("Instantiating NESoftmaxLayer"); } - ARM_COMPUTE_LOG(" Data Type: " << in->info()->data_type() - << " Input shape: " << in->info()->tensor_shape() - << " Output shape: " << out->info()->tensor_shape() - << std::endl); + ARM_COMPUTE_LOG_GRAPH_INFO(" Data Type: " << in->info()->data_type() + << " Input shape: " << in->info()->tensor_shape() + << " Output shape: " << out->info()->tensor_shape() + << std::endl); return func; } diff --git a/support/ToolchainSupport.h b/support/ToolchainSupport.h index b9d9103652..ab2a9fe80f 100644 --- a/support/ToolchainSupport.h +++ b/support/ToolchainSupport.h @@ -144,8 +144,8 @@ inline T trunc(T value) * @note This function implements the same behaviour as std::copysign except that it doesn't * support Integral type. The latter is not in the namespace std in some Android toolchains. * - * @param[in] x value that contains the magnitued to be used in constructing the result. - * @param[in] y value that contains the sign to be used in constructin the result. + * @param[in] x value that contains the magnitude to be used in constructing the result. + * @param[in] y value that contains the sign to be used in construct in the result. * * @return Floating-point value with magnitude of @p x and sign of @p y. */ @@ -154,6 +154,23 @@ inline T copysign(T x, T y) { return ::copysign(x, y); } + +/** Loads the data from the given location, converts them to character string equivalents + * 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] 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. + */ +template +inline int snprintf(char *s, size_t n, const char *fmt, Ts &&... args) +{ + return ::snprintf(s, n, fmt, std::forward(args)...); +} #else /* (__ANDROID__ || BARE_METAL) */ /** Convert integer and float values to string. * @@ -250,8 +267,8 @@ inline T trunc(T value) * @note This function implements the same behaviour as std::copysign except that it doesn't * support Integral type. The latter is not in the namespace std in some Android toolchains. * - * @param[in] x value that contains the magnitued to be used in constructing the result. - * @param[in] y value that contains the sign to be used in constructin the result. + * @param[in] x value that contains the magnitude to be used in constructing the result. + * @param[in] y value that contains the sign to be used in construct in the result. * * @return Floating-point value with magnitude of @p x and sign of @p y. */ @@ -260,6 +277,23 @@ inline T copysign(T x, T y) { return std::copysign(x, y); } + +/** Loads the data from the given location, converts them to character string equivalents + * 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] 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. + */ +template +inline int snprintf(char *s, std::size_t n, const char *fmt, Ts &&... args) +{ + return std::snprintf(s, n, fmt, std::forward(args)...); +} #endif /* (__ANDROID__ || BARE_METAL) */ inline std::string to_string(bool value) -- cgit v1.2.1