From eef9a4fa9a39d4349ed699b097a3e3ff6c78cbc4 Mon Sep 17 00:00:00 2001 From: Vyas Ramasubramani Date: Mon, 30 Dec 2024 11:48:07 -0800 Subject: [PATCH] Switch over to rapids-logger (#2530) This PR removes raft's implementation of a logger in favor of the centralized one in [rapids-logger](https://github.com/rapidsai/rapids-logger). Consumers still get the benefits of a PImpl idiom, but now that is primarily handled by using the appropriate targets (if necessary the impl header is of course still available for direct inclusion). This change paves the way for ensuring consistent fmt/spdlog (lack of) linkage throughout RAPIDS conda and wheel packages. This PR requires https://github.com/rapidsai/rapids-logger/pull/1 Contributes to https://github.com/rapidsai/build-planning/issues/104 Authors: - Vyas Ramasubramani (https://github.com/vyasr) Approvers: - Bradley Dice (https://github.com/bdice) - Corey J. Nolet (https://github.com/cjnolet) URL: https://github.com/rapidsai/raft/pull/2530 --- cpp/CMakeLists.txt | 28 +++- cpp/include/raft/cluster/detail/kmeans.cuh | 8 +- .../raft/cluster/detail/kmeans_balanced.cuh | 1 + cpp/include/raft/cluster/kmeans_types.hpp | 2 +- cpp/include/raft/common/logger.hpp | 24 --- cpp/include/raft/core/cublas_macros.hpp | 3 - cpp/include/raft/core/cusolver_macros.hpp | 7 +- cpp/include/raft/core/cusparse_macros.hpp | 2 - .../raft/core/detail/callback_sink.hpp | 71 -------- .../core/detail/fail_container_policy.hpp | 2 +- cpp/include/raft/core/detail/logger.hpp | 24 --- cpp/include/raft/core/logger-ext.hpp | 152 ----------------- cpp/include/raft/core/logger-inl.hpp | 153 ------------------ cpp/include/raft/core/logger-macros.hpp | 95 ++--------- cpp/include/raft/core/logger.hpp | 23 --- .../raft/neighbors/detail/ivf_flat_build.cuh | 1 + .../neighbors/detail/ivf_flat_search-inl.cuh | 3 +- .../raft/solver/detail/lap_kernels.cuh | 3 +- .../raft/sparse/solver/detail/lanczos.cuh | 2 +- cpp/src/core/logger.cpp | 16 -- cpp/test/CMakeLists.txt | 5 + cpp/test/core/device_resources_manager.cpp | 2 +- cpp/test/core/logger.cpp | 57 +++---- docs/source/developer_guide.md | 4 +- 24 files changed, 87 insertions(+), 601 deletions(-) delete mode 100644 cpp/include/raft/common/logger.hpp delete mode 100644 cpp/include/raft/core/detail/callback_sink.hpp delete mode 100644 cpp/include/raft/core/detail/logger.hpp delete mode 100644 cpp/include/raft/core/logger-ext.hpp delete mode 100644 cpp/include/raft/core/logger-inl.hpp delete mode 100644 cpp/include/raft/core/logger.hpp delete mode 100644 cpp/src/core/logger.cpp diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 78a4dbb913..06531941aa 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -100,6 +100,17 @@ set_property( ) message(VERBOSE "RAFT: RMM_LOGGING_LEVEL = '${RMM_LOGGING_LEVEL}'.") +# Set logging level +set(LIBRAFT_LOGGING_LEVEL + "INFO" + CACHE STRING "Choose the logging level." +) +set_property( + CACHE LIBRAFT_LOGGING_LEVEL PROPERTY STRINGS "TRACE" "DEBUG" "INFO" "WARN" "ERROR" "CRITICAL" + "OFF" +) +message(VERBOSE "RAFT: LIBRAFT_LOGGING_LEVEL = '${LIBRAFT_LOGGING_LEVEL}'.") + # ################################################################################################## # * Conda environment detection ---------------------------------------------- @@ -152,6 +163,13 @@ include(cmake/modules/ConfigureCUDA.cmake) # add third party dependencies using CPM rapids_cpm_init() +# Not using rapids-cmake since we never want to find, always download. +CPMAddPackage( + NAME rapids_logger GITHUB_REPOSITORY rapidsai/rapids-logger GIT_SHALLOW FALSE GIT_TAG + 4df3ee70c6746fd1b6c0dc14209dae2e2d4378c6 VERSION 4df3ee70c6746fd1b6c0dc14209dae2e2d4378c6 +) +rapids_make_logger(raft LOGGER_HEADER_DIR include/raft/core EXPORT_SET raft-exports) + # CCCL before rmm/cuco so we get the right version of CCCL include(cmake/thirdparty/get_cccl.cmake) include(cmake/thirdparty/get_rmm.cmake) @@ -182,7 +200,7 @@ target_include_directories( # Keep RAFT as lightweight as possible. Only CUDA libs and rmm should be used in global target. target_link_libraries( raft INTERFACE rmm::rmm rmm::rmm_logger spdlog::spdlog_header_only cuco::cuco - nvidia::cutlass::cutlass CCCL::CCCL + nvidia::cutlass::cutlass CCCL::CCCL raft_logger ) target_compile_features(raft INTERFACE cxx_std_17 $) @@ -190,6 +208,9 @@ target_compile_options( raft INTERFACE $<$:--expt-extended-lambda --expt-relaxed-constexpr> ) +target_compile_definitions( + raft INTERFACE "RAFT_LOG_ACTIVE_LEVEL=RAFT_LOG_LEVEL_${LIBRAFT_LOGGING_LEVEL}" +) set(RAFT_CUSOLVER_DEPENDENCY CUDA::cusolver${_ctk_static_suffix}) set(RAFT_CUBLAS_DEPENDENCY CUDA::cublas${_ctk_static_suffix}) @@ -265,7 +286,6 @@ set_target_properties(raft_compiled PROPERTIES EXPORT_NAME compiled) if(RAFT_COMPILE_LIBRARY) add_library( raft_objs OBJECT - src/core/logger.cpp src/linalg/detail/coalesced_reduction.cu src/raft_runtime/random/rmat_rectangular_generator_int64_double.cu src/raft_runtime/random/rmat_rectangular_generator_int64_float.cu @@ -318,8 +338,8 @@ if(RAFT_COMPILE_LIBRARY) # ensure CUDA symbols aren't relocated to the middle of the debug build binaries target_link_options(${target} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/fatbin.ld") endforeach() - target_link_libraries(raft_lib PRIVATE rmm::rmm_logger_impl) - target_link_libraries(raft_lib_static PRIVATE rmm::rmm_logger_impl) + target_link_libraries(raft_lib PRIVATE rmm::rmm_logger_impl raft_logger_impl) + target_link_libraries(raft_lib_static PRIVATE rmm::rmm_logger_impl raft_logger_impl) endif() if(TARGET raft_lib AND (NOT TARGET raft::raft_lib)) diff --git a/cpp/include/raft/cluster/detail/kmeans.cuh b/cpp/include/raft/cluster/detail/kmeans.cuh index 4efeedcbaa..4203f0969b 100644 --- a/cpp/include/raft/cluster/detail/kmeans.cuh +++ b/cpp/include/raft/cluster/detail/kmeans.cuh @@ -369,7 +369,7 @@ void kmeans_fit_main(raft::resources const& handle, rmm::device_uvector& workspace) { common::nvtx::range fun_scope("kmeans_fit_main"); - logger::get(RAFT_NAME).set_level(params.verbosity); + default_logger().set_level(params.verbosity); cudaStream_t stream = resource::get_cuda_stream(handle); auto n_samples = X.extent(0); auto n_features = X.extent(1); @@ -865,7 +865,7 @@ void kmeans_fit(raft::resources const& handle, params.n_clusters); } - logger::get(RAFT_NAME).set_level(params.verbosity); + default_logger().set_level(params.verbosity); // Allocate memory rmm::device_uvector workspace(0, stream); @@ -1010,7 +1010,7 @@ void kmeans_predict(raft::resources const& handle, RAFT_EXPECTS(centroids.extent(1) == n_features, "invalid parameter (centroids.extent(1) != n_features)"); - logger::get(RAFT_NAME).set_level(params.verbosity); + default_logger().set_level(params.verbosity); auto metric = params.metric; // Allocate memory @@ -1201,7 +1201,7 @@ void kmeans_transform(raft::resources const& handle, raft::device_matrix_view X_new) { common::nvtx::range fun_scope("kmeans_transform"); - logger::get(RAFT_NAME).set_level(params.verbosity); + default_logger().set_level(params.verbosity); cudaStream_t stream = resource::get_cuda_stream(handle); auto n_samples = X.extent(0); auto n_features = X.extent(1); diff --git a/cpp/include/raft/cluster/detail/kmeans_balanced.cuh b/cpp/include/raft/cluster/detail/kmeans_balanced.cuh index 0a5a3ba5aa..5dcd679bd5 100644 --- a/cpp/include/raft/cluster/detail/kmeans_balanced.cuh +++ b/cpp/include/raft/cluster/detail/kmeans_balanced.cuh @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/cpp/include/raft/cluster/kmeans_types.hpp b/cpp/include/raft/cluster/kmeans_types.hpp index 4d956ad7a0..fbedd58417 100644 --- a/cpp/include/raft/cluster/kmeans_types.hpp +++ b/cpp/include/raft/cluster/kmeans_types.hpp @@ -82,7 +82,7 @@ struct KMeansParams : kmeans_base_params { /** * verbosity level. */ - int verbosity = RAFT_LEVEL_INFO; + level_enum verbosity = level_enum::info; /** * Seed to the random number generator. diff --git a/cpp/include/raft/common/logger.hpp b/cpp/include/raft/common/logger.hpp deleted file mode 100644 index 77483e577d..0000000000 --- a/cpp/include/raft/common/logger.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2022, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This file is deprecated and will be removed in release 22.08. - * Please use the include/core/logger.hpp instead. - */ - -#pragma once - -#include \ No newline at end of file diff --git a/cpp/include/raft/core/cublas_macros.hpp b/cpp/include/raft/core/cublas_macros.hpp index b69b121161..6c195d8a6f 100644 --- a/cpp/include/raft/core/cublas_macros.hpp +++ b/cpp/include/raft/core/cublas_macros.hpp @@ -23,9 +23,6 @@ #include -///@todo: enable this once we have logger enabled -// #include - #include #define _CUBLAS_ERR_TO_STR(err) \ diff --git a/cpp/include/raft/core/cusolver_macros.hpp b/cpp/include/raft/core/cusolver_macros.hpp index 74a8b7c36c..beaf2d74dc 100644 --- a/cpp/include/raft/core/cusolver_macros.hpp +++ b/cpp/include/raft/core/cusolver_macros.hpp @@ -19,11 +19,10 @@ #pragma once +#include + #include #include -///@todo: enable this once logging is enabled -// #include -#include #include @@ -135,4 +134,4 @@ inline const char* cusolver_error_to_string(cusolverStatus_t err) #define CUSOLVER_CHECK_NO_THROW(call) CUSOLVER_TRY_NO_THROW(call) #endif -#endif \ No newline at end of file +#endif diff --git a/cpp/include/raft/core/cusparse_macros.hpp b/cpp/include/raft/core/cusparse_macros.hpp index 5a1968b529..2a1df14345 100644 --- a/cpp/include/raft/core/cusparse_macros.hpp +++ b/cpp/include/raft/core/cusparse_macros.hpp @@ -19,8 +19,6 @@ #include #include -///@todo: enable this once logging is enabled -// #include #define _CUSPARSE_ERR_TO_STR(err) \ case err: return #err; diff --git a/cpp/include/raft/core/detail/callback_sink.hpp b/cpp/include/raft/core/detail/callback_sink.hpp deleted file mode 100644 index a110af5c76..0000000000 --- a/cpp/include/raft/core/detail/callback_sink.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2020-2022, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include - -#define SPDLOG_HEADER_ONLY -#include -#include -#include - -namespace spdlog::sinks { - -typedef void (*LogCallback)(int lvl, const char* msg); - -template -class CallbackSink : public base_sink { - public: - explicit CallbackSink(std::string tag = "spdlog", - LogCallback callback = nullptr, - void (*flush)() = nullptr) - : _callback{callback}, _flush{flush} {}; - - void set_callback(LogCallback callback) { _callback = callback; } - void set_flush(void (*flush)()) { _flush = flush; } - - protected: - void sink_it_(const details::log_msg& msg) override - { - spdlog::memory_buf_t formatted; - base_sink::formatter_->format(msg, formatted); - std::string msg_string = fmt::to_string(formatted); - - if (_callback) { - _callback(static_cast(msg.level), msg_string.c_str()); - } else { - std::cout << msg_string; - } - } - - void flush_() override - { - if (_flush) { - _flush(); - } else { - std::cout << std::flush; - } - } - - LogCallback _callback; - void (*_flush)(); -}; - -using callback_sink_mt = CallbackSink; -using callback_sink_st = CallbackSink; - -} // end namespace spdlog::sinks diff --git a/cpp/include/raft/core/detail/fail_container_policy.hpp b/cpp/include/raft/core/detail/fail_container_policy.hpp index cf9d0887dd..f5f1bfb377 100644 --- a/cpp/include/raft/core/detail/fail_container_policy.hpp +++ b/cpp/include/raft/core/detail/fail_container_policy.hpp @@ -16,7 +16,7 @@ #pragma once #include -#include +#include #include #include diff --git a/cpp/include/raft/core/detail/logger.hpp b/cpp/include/raft/core/detail/logger.hpp deleted file mode 100644 index f3f52b46ae..0000000000 --- a/cpp/include/raft/core/detail/logger.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2022-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#ifndef RAFT_HIDE_DEPRECATION_WARNINGS -#pragma message(__FILE__ \ - " is deprecated and will be removed in future releases." \ - " Please use the version instead.") -#endif - -#include diff --git a/cpp/include/raft/core/logger-ext.hpp b/cpp/include/raft/core/logger-ext.hpp deleted file mode 100644 index 73fe463aba..0000000000 --- a/cpp/include/raft/core/logger-ext.hpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2022-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include // RAFT_INLINE_CONDITIONAL - -#include // std::unique_ptr -#include // std::string -#include // std::unordered_map - -namespace raft { - -static const std::string RAFT_NAME = "raft"; -static const std::string default_log_pattern("[%L] [%H:%M:%S.%f] %v"); - -namespace detail { -RAFT_INLINE_CONDITIONAL std::string format(const char* fmt, ...); -} -/** - * @brief The main Logging class for raft library. - * - * This class acts as a thin wrapper over the underlying `spdlog` interface. The - * design is done in this way in order to avoid us having to also ship `spdlog` - * header files in our installation. - * - * @todo This currently only supports logging to stdout. Need to add support in - * future to add custom loggers as well [Issue #2046] - */ -class logger { - public: - // @todo setting the logger once per process with - logger(std::string const& name_ = ""); - /** - * @brief Singleton method to get the underlying logger object - * - * @return the singleton logger object - */ - static logger& get(std::string const& name = ""); - - /** - * @brief Set the logging level. - * - * Only messages with level equal or above this will be printed - * - * @param[in] level logging level - * - * @note The log level will actually be set only if the input is within the - * range [RAFT_LEVEL_TRACE, RAFT_LEVEL_OFF]. If it is not, then it'll - * be ignored. See documentation of decisiontree for how this gets used - */ - void set_level(int level); - - /** - * @brief Set the logging pattern - * - * @param[in] pattern the pattern to be set. Refer this link - * https://github.com/gabime/spdlog/wiki/3.-Custom-formatting - * to know the right syntax of this pattern - */ - void set_pattern(const std::string& pattern); - - /** - * @brief Register a callback function to be run in place of usual log call - * - * @param[in] callback the function to be run on all logged messages - */ - void set_callback(void (*callback)(int lvl, const char* msg)); - - /** - * @brief Register a flush function compatible with the registered callback - * - * @param[in] flush the function to use when flushing logs - */ - void set_flush(void (*flush)()); - - /** - * @brief Tells whether messages will be logged for the given log level - * - * @param[in] level log level to be checked for - * @return true if messages will be logged for this level, else false - */ - bool should_log_for(int level) const; - /** - * @brief Query for the current log level - * - * @return the current log level - */ - int get_level() const; - - /** - * @brief Get the current logging pattern - * @return the pattern - */ - std::string get_pattern() const; - - /** - * @brief Main logging method - * - * @param[in] level logging level of this message - * @param[in] fmt C-like format string, followed by respective params - */ - void log(int level, const char* fmt, ...); - - /** - * @brief Flush logs by calling flush on underlying logger - */ - void flush(); - - ~logger(); - - private: - logger(); - // pimpl pattern: - // https://learn.microsoft.com/en-us/cpp/cpp/pimpl-for-compile-time-encapsulation-modern-cpp?view=msvc-170 - class impl; - std::unique_ptr pimpl; - static inline std::unordered_map> log_map; -}; // class logger - -/** - * @brief An object used for scoped log level setting - * - * Instances of `raft::log_level_setter` will set RAFT logging to the level - * indicated on construction and will revert to the previous set level on - * destruction. - */ -struct log_level_setter { - explicit log_level_setter(int level) - { - prev_level_ = logger::get(RAFT_NAME).get_level(); - logger::get(RAFT_NAME).set_level(level); - } - ~log_level_setter() { logger::get(RAFT_NAME).set_level(prev_level_); } - - private: - int prev_level_; -}; // class log_level_setter - -}; // namespace raft diff --git a/cpp/include/raft/core/logger-inl.hpp b/cpp/include/raft/core/logger-inl.hpp deleted file mode 100644 index ea5f4ea26e..0000000000 --- a/cpp/include/raft/core/logger-inl.hpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2022-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "logger-macros.hpp" - -#include - -#include -#include -#include -#include -#include -#include -// The logger-ext.hpp file contains the class declaration of the logger class. -// In this case, it is okay to include the logger-ext.hpp file because it -// contains no RAFT_EXPLICIT template instantiations. -#include "logger-ext.hpp" - -#define SPDLOG_HEADER_ONLY -#include -#include // RAFT_INLINE_CONDITIONAL - -#include // NOLINT -#include // NOLINT - -namespace raft { - -namespace detail { - -inline std::string format(const char* fmt, va_list& vl) -{ - va_list vl_copy; - va_copy(vl_copy, vl); - int length = std::vsnprintf(nullptr, 0, fmt, vl_copy); - assert(length >= 0); - std::vector buf(length + 1); - std::vsnprintf(buf.data(), length + 1, fmt, vl); - return std::string(buf.data()); -} - -RAFT_INLINE_CONDITIONAL std::string format(const char* fmt, ...) -{ - va_list vl; - va_start(vl, fmt); - std::string str = format(fmt, vl); - va_end(vl); - return str; -} - -inline int convert_level_to_spdlog(int level) -{ - level = std::max(RAFT_LEVEL_OFF, std::min(RAFT_LEVEL_TRACE, level)); - return RAFT_LEVEL_TRACE - level; -} - -} // namespace detail - -class logger::impl { // defined privately here - // ... all private data and functions: all of these - // can now change without recompiling callers ... - public: - std::shared_ptr sink; - std::shared_ptr spdlogger; - std::string cur_pattern; - int cur_level; - - impl(std::string const& name_ = "") - : sink{std::make_shared()}, - spdlogger{std::make_shared(name_, sink)}, - cur_pattern() - { - } -}; // class logger::impl - -RAFT_INLINE_CONDITIONAL logger::logger(std::string const& name_) : pimpl(new impl(name_)) -{ - set_pattern(default_log_pattern); - set_level(RAFT_ACTIVE_LEVEL); -} - -RAFT_INLINE_CONDITIONAL logger& logger::get(std::string const& name) -{ - if (log_map.find(name) == log_map.end()) { log_map[name] = std::make_shared(name); } - return *log_map[name]; -} - -RAFT_INLINE_CONDITIONAL void logger::set_level(int level) -{ - level = raft::detail::convert_level_to_spdlog(level); - pimpl->spdlogger->set_level(static_cast(level)); -} - -RAFT_INLINE_CONDITIONAL void logger::set_pattern(const std::string& pattern) -{ - pimpl->cur_pattern = pattern; - pimpl->spdlogger->set_pattern(pattern); -} - -RAFT_INLINE_CONDITIONAL void logger::set_callback(void (*callback)(int lvl, const char* msg)) -{ - pimpl->sink->set_callback(callback); -} - -RAFT_INLINE_CONDITIONAL void logger::set_flush(void (*flush)()) { pimpl->sink->set_flush(flush); } - -RAFT_INLINE_CONDITIONAL bool logger::should_log_for(int level) const -{ - level = raft::detail::convert_level_to_spdlog(level); - auto level_e = static_cast(level); - return pimpl->spdlogger->should_log(level_e); -} - -RAFT_INLINE_CONDITIONAL int logger::get_level() const -{ - auto level_e = pimpl->spdlogger->level(); - return RAFT_LEVEL_TRACE - static_cast(level_e); -} - -RAFT_INLINE_CONDITIONAL std::string logger::get_pattern() const { return pimpl->cur_pattern; } - -RAFT_INLINE_CONDITIONAL void logger::log(int level, const char* fmt, ...) -{ - level = raft::detail::convert_level_to_spdlog(level); - auto level_e = static_cast(level); - // explicit check to make sure that we only expand messages when required - if (pimpl->spdlogger->should_log(level_e)) { - va_list vl; - va_start(vl, fmt); - auto msg = raft::detail::format(fmt, vl); - va_end(vl); - pimpl->spdlogger->log(level_e, msg); - } -} - -RAFT_INLINE_CONDITIONAL void logger::flush() { pimpl->spdlogger->flush(); } - -RAFT_INLINE_CONDITIONAL logger::~logger() {} - -}; // namespace raft diff --git a/cpp/include/raft/core/logger-macros.hpp b/cpp/include/raft/core/logger-macros.hpp index 5ddb072067..e32440dcce 100644 --- a/cpp/include/raft/core/logger-macros.hpp +++ b/cpp/include/raft/core/logger-macros.hpp @@ -15,92 +15,17 @@ */ #pragma once -/** - * @defgroup logging levels used in raft - * - * @note exactly match the corresponding ones (but reverse in terms of value) - * in spdlog for wrapping purposes - * - * @{ - */ -#define RAFT_LEVEL_TRACE 6 -#define RAFT_LEVEL_DEBUG 5 -#define RAFT_LEVEL_INFO 4 -#define RAFT_LEVEL_WARN 3 -#define RAFT_LEVEL_ERROR 2 -#define RAFT_LEVEL_CRITICAL 1 -#define RAFT_LEVEL_OFF 0 -/** @} */ - -#if !defined(RAFT_ACTIVE_LEVEL) -#define RAFT_ACTIVE_LEVEL RAFT_LEVEL_INFO -#endif - -/** - * @defgroup loggerMacros Helper macros for dealing with logging - * @{ - */ -#if (RAFT_ACTIVE_LEVEL >= RAFT_LEVEL_TRACE) -#define RAFT_LOG_TRACE(fmt, ...) \ - do { \ - std::stringstream ss; \ - ss << raft::detail::format("%s:%d ", __FILE__, __LINE__); \ - ss << raft::detail::format(fmt, ##__VA_ARGS__); \ - raft::logger::get(RAFT_NAME).log(RAFT_LEVEL_TRACE, ss.str().c_str()); \ - } while (0) -#else -#define RAFT_LOG_TRACE(fmt, ...) void(0) -#endif - -#if (RAFT_ACTIVE_LEVEL >= RAFT_LEVEL_TRACE) -#define RAFT_LOG_TRACE_VEC(ptr, len) \ - do { \ - std::stringstream ss; \ - ss << raft::detail::format("%s:%d ", __FILE__, __LINE__); \ - print_vector(#ptr, ptr, len, ss); \ - raft::logger::get(RAFT_NAME).log(RAFT_LEVEL_TRACE, ss.str().c_str()); \ +#include + +#if (RAFT_LOG_ACTIVE_LEVEL <= RAFT_LOG_LEVEL_TRACE) +#define RAFT_LOG_TRACE_VEC(ptr, len) \ + do { \ + std::stringstream ss; \ + ss << raft::detail::format("%s:%d ", __FILE__, __LINE__); \ + print_vector(#ptr, ptr, len, ss); \ + raft::logger::get(RAFT_NAME).log(RAFT_LEVEL_TRACE, ss.str().c_str()); \ + RAFT_LOGGER_CALL(raft::default_logger(), raft::level_enum::trace, __VA_ARGS__) \ } while (0) #else #define RAFT_LOG_TRACE_VEC(ptr, len) void(0) #endif - -#if (RAFT_ACTIVE_LEVEL >= RAFT_LEVEL_DEBUG) -#define RAFT_LOG_DEBUG(fmt, ...) \ - do { \ - std::stringstream ss; \ - ss << raft::detail::format("%s:%d ", __FILE__, __LINE__); \ - ss << raft::detail::format(fmt, ##__VA_ARGS__); \ - raft::logger::get(RAFT_NAME).log(RAFT_LEVEL_DEBUG, ss.str().c_str()); \ - } while (0) -#else -#define RAFT_LOG_DEBUG(fmt, ...) void(0) -#endif - -#if (RAFT_ACTIVE_LEVEL >= RAFT_LEVEL_INFO) -#define RAFT_LOG_INFO(fmt, ...) \ - raft::logger::get(RAFT_NAME).log(RAFT_LEVEL_INFO, fmt, ##__VA_ARGS__) -#else -#define RAFT_LOG_INFO(fmt, ...) void(0) -#endif - -#if (RAFT_ACTIVE_LEVEL >= RAFT_LEVEL_WARN) -#define RAFT_LOG_WARN(fmt, ...) \ - raft::logger::get(RAFT_NAME).log(RAFT_LEVEL_WARN, fmt, ##__VA_ARGS__) -#else -#define RAFT_LOG_WARN(fmt, ...) void(0) -#endif - -#if (RAFT_ACTIVE_LEVEL >= RAFT_LEVEL_ERROR) -#define RAFT_LOG_ERROR(fmt, ...) \ - raft::logger::get(RAFT_NAME).log(RAFT_LEVEL_ERROR, fmt, ##__VA_ARGS__) -#else -#define RAFT_LOG_ERROR(fmt, ...) void(0) -#endif - -#if (RAFT_ACTIVE_LEVEL >= RAFT_LEVEL_CRITICAL) -#define RAFT_LOG_CRITICAL(fmt, ...) \ - raft::logger::get(RAFT_NAME).log(RAFT_LEVEL_CRITICAL, fmt, ##__VA_ARGS__) -#else -#define RAFT_LOG_CRITICAL(fmt, ...) void(0) -#endif -/** @} */ diff --git a/cpp/include/raft/core/logger.hpp b/cpp/include/raft/core/logger.hpp deleted file mode 100644 index e64a0db257..0000000000 --- a/cpp/include/raft/core/logger.hpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2022-2024, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "logger-ext.hpp" -#include "logger-macros.hpp" - -#if !defined(RAFT_COMPILED) -#include "logger-inl.hpp" -#endif diff --git a/cpp/include/raft/neighbors/detail/ivf_flat_build.cuh b/cpp/include/raft/neighbors/detail/ivf_flat_build.cuh index 55184cc615..0e00ef571f 100644 --- a/cpp/include/raft/neighbors/detail/ivf_flat_build.cuh +++ b/cpp/include/raft/neighbors/detail/ivf_flat_build.cuh @@ -17,6 +17,7 @@ #pragma once #include +#include #include #include #include diff --git a/cpp/include/raft/neighbors/detail/ivf_flat_search-inl.cuh b/cpp/include/raft/neighbors/detail/ivf_flat_search-inl.cuh index 388dd60f14..44d55c36de 100644 --- a/cpp/include/raft/neighbors/detail/ivf_flat_search-inl.cuh +++ b/cpp/include/raft/neighbors/detail/ivf_flat_search-inl.cuh @@ -16,7 +16,8 @@ #pragma once -#include // RAFT_LOG_TRACE +#include +#include #include #include // raft::resources #include // is_min_close, DistanceType diff --git a/cpp/include/raft/solver/detail/lap_kernels.cuh b/cpp/include/raft/solver/detail/lap_kernels.cuh index 383c3ab713..3c25852240 100644 --- a/cpp/include/raft/solver/detail/lap_kernels.cuh +++ b/cpp/include/raft/solver/detail/lap_kernels.cuh @@ -26,6 +26,7 @@ #include "../linear_assignment_types.hpp" +#include #include #include @@ -552,4 +553,4 @@ RAFT_KERNEL kernel_calcObjValPrimal(weight_t* d_obj_val_primal, } } -} // namespace raft::solver::detail \ No newline at end of file +} // namespace raft::solver::detail diff --git a/cpp/include/raft/sparse/solver/detail/lanczos.cuh b/cpp/include/raft/sparse/solver/detail/lanczos.cuh index 02a77a0d99..6f03f77bc0 100644 --- a/cpp/include/raft/sparse/solver/detail/lanczos.cuh +++ b/cpp/include/raft/sparse/solver/detail/lanczos.cuh @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/cpp/src/core/logger.cpp b/cpp/src/core/logger.cpp deleted file mode 100644 index 8f81cf2926..0000000000 --- a/cpp/src/core/logger.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023, NVIDIA CORPORATION. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include diff --git a/cpp/test/CMakeLists.txt b/cpp/test/CMakeLists.txt index 621ee6c160..4cd0a32f51 100644 --- a/cpp/test/CMakeLists.txt +++ b/cpp/test/CMakeLists.txt @@ -55,6 +55,7 @@ function(ConfigureTest) ${RAFT_CTK_MATH_DEPENDENCIES} $ $ + raft_test_logger ) set_target_properties( ${TEST_NAME} @@ -87,6 +88,10 @@ function(ConfigureTest) ) endfunction() +# Create an object library for the logger so that we don't have to recompile it. +add_library(raft_test_logger OBJECT) +target_link_libraries(raft_test_logger PRIVATE raft_logger_impl) + # ################################################################################################## # test sources ################################################################################## # ################################################################################################## diff --git a/cpp/test/core/device_resources_manager.cpp b/cpp/test/core/device_resources_manager.cpp index c63d5896e5..007b57378f 100644 --- a/cpp/test/core/device_resources_manager.cpp +++ b/cpp/test/core/device_resources_manager.cpp @@ -89,7 +89,7 @@ TEST(DeviceResourcesManager, ObeysSetters) // Suppress the many warnings from testing use of setters after initial // get_device_resources call - auto scoped_log_level = log_level_setter{RAFT_LEVEL_ERROR}; + auto scoped_log_level = log_level_setter{level_enum::error}; omp_set_dynamic(0); #pragma omp parallel for num_threads(5) diff --git a/cpp/test/core/logger.cpp b/cpp/test/core/logger.cpp index 7f31beed71..10adb71dda 100644 --- a/cpp/test/core/logger.cpp +++ b/cpp/test/core/logger.cpp @@ -14,10 +14,10 @@ * limitations under the License. */ -// We set RAFT_ACTIVE_LEVEL to a value that would enable testing trace and debug logs +// We set RAFT_LOG_ACTIVE_LEVEL to a value that would enable testing trace and debug logs // (otherwise trace and debug logs are desabled by default). -#undef RAFT_ACTIVE_LEVEL -#define RAFT_ACTIVE_LEVEL 6 +#undef RAFT_LOG_ACTIVE_LEVEL +#define RAFT_LOG_ACTIVE_LEVEL RAFT_LOG_LEVEL_TRACE #include @@ -34,15 +34,15 @@ TEST(logger, Test) RAFT_LOG_WARN("This is a warning message"); RAFT_LOG_INFO("This is an info message"); - logger::get(RAFT_NAME).set_level(RAFT_LEVEL_WARN); - ASSERT_EQ(RAFT_LEVEL_WARN, logger::get(RAFT_NAME).get_level()); - logger::get(RAFT_NAME).set_level(RAFT_LEVEL_INFO); - ASSERT_EQ(RAFT_LEVEL_INFO, logger::get(RAFT_NAME).get_level()); + default_logger().set_level(raft::level_enum::warn); + ASSERT_EQ(raft::level_enum::warn, default_logger().level()); + default_logger().set_level(raft::level_enum::info); + ASSERT_EQ(raft::level_enum::info, default_logger().level()); - ASSERT_FALSE(logger::get(RAFT_NAME).should_log_for(RAFT_LEVEL_TRACE)); - ASSERT_FALSE(logger::get(RAFT_NAME).should_log_for(RAFT_LEVEL_DEBUG)); - ASSERT_TRUE(logger::get(RAFT_NAME).should_log_for(RAFT_LEVEL_INFO)); - ASSERT_TRUE(logger::get(RAFT_NAME).should_log_for(RAFT_LEVEL_WARN)); + ASSERT_FALSE(default_logger().should_log(raft::level_enum::trace)); + ASSERT_FALSE(default_logger().should_log(raft::level_enum::debug)); + ASSERT_TRUE(default_logger().should_log(raft::level_enum::info)); + ASSERT_TRUE(default_logger().should_log(raft::level_enum::warn)); } std::string logged = ""; @@ -57,60 +57,61 @@ class loggerTest : public ::testing::Test { { flushCount = 0; logged = ""; - logger::get(RAFT_NAME).set_level(RAFT_LEVEL_TRACE); + default_logger().set_level(raft::level_enum::trace); } void TearDown() override { - logger::get(RAFT_NAME).set_callback(nullptr); - logger::get(RAFT_NAME).set_flush(nullptr); - logger::get(RAFT_NAME).set_level(RAFT_LEVEL_INFO); + default_logger().sinks().pop_back(); + default_logger().set_level(raft::level_enum::info); } }; -// The logging macros depend on `RAFT_ACTIVE_LEVEL` as well as the logger verbosity; -// The verbosity is set to `RAFT_LEVEL_TRACE`, but `RAFT_ACTIVE_LEVEL` is set outside of here. -auto check_if_logged(const std::string& msg, int log_level_def) -> bool +// The logging macros depend on `RAFT_LOG_ACTIVE_LEVEL` as well as the logger verbosity; +// The verbosity is set to `RAFT_LOG_LEVEL_TRACE`, but `RAFT_LOG_ACTIVE_LEVEL` is set outside of +// here. +auto check_if_logged(const std::string& msg, raft::level_enum log_level_def) -> bool { bool actually_logged = logged.find(msg) != std::string::npos; - bool should_be_logged = RAFT_ACTIVE_LEVEL >= log_level_def; + bool should_be_logged = RAFT_LOG_ACTIVE_LEVEL <= static_cast(log_level_def); return actually_logged == should_be_logged; } TEST_F(loggerTest, callback) { std::string testMsg; - logger::get(RAFT_NAME).set_callback(exampleCallback); + default_logger().sinks().push_back(std::make_shared(exampleCallback)); testMsg = "This is a critical message"; RAFT_LOG_CRITICAL(testMsg.c_str()); - ASSERT_TRUE(check_if_logged(testMsg, RAFT_LEVEL_CRITICAL)); + ASSERT_TRUE(check_if_logged(testMsg, raft::level_enum::critical)); testMsg = "This is an error message"; RAFT_LOG_ERROR(testMsg.c_str()); - ASSERT_TRUE(check_if_logged(testMsg, RAFT_LEVEL_ERROR)); + ASSERT_TRUE(check_if_logged(testMsg, raft::level_enum::error)); testMsg = "This is a warning message"; RAFT_LOG_WARN(testMsg.c_str()); - ASSERT_TRUE(check_if_logged(testMsg, RAFT_LEVEL_WARN)); + ASSERT_TRUE(check_if_logged(testMsg, raft::level_enum::warn)); testMsg = "This is an info message"; RAFT_LOG_INFO(testMsg.c_str()); - ASSERT_TRUE(check_if_logged(testMsg, RAFT_LEVEL_INFO)); + ASSERT_TRUE(check_if_logged(testMsg, raft::level_enum::info)); testMsg = "This is a debug message"; RAFT_LOG_DEBUG(testMsg.c_str()); - ASSERT_TRUE(check_if_logged(testMsg, RAFT_LEVEL_DEBUG)); + ASSERT_TRUE(check_if_logged(testMsg, raft::level_enum::debug)); testMsg = "This is a trace message"; RAFT_LOG_TRACE(testMsg.c_str()); - ASSERT_TRUE(check_if_logged(testMsg, RAFT_LEVEL_TRACE)); + ASSERT_TRUE(check_if_logged(testMsg, raft::level_enum::trace)); } TEST_F(loggerTest, flush) { - logger::get(RAFT_NAME).set_flush(exampleFlush); - logger::get(RAFT_NAME).flush(); + default_logger().sinks().push_back( + std::make_shared(exampleCallback, exampleFlush)); + default_logger().flush(); ASSERT_EQ(1, flushCount); } diff --git a/docs/source/developer_guide.md b/docs/source/developer_guide.md index 5cc694dc8f..6240b2638b 100644 --- a/docs/source/developer_guide.md +++ b/docs/source/developer_guide.md @@ -256,14 +256,14 @@ There are 7 logging levels with each successive level becoming quieter: 7. RAFT_LEVEL_OFF Pass one of these as per your needs into the `set_level()` method as follows: ```cpp -raft::logger::get().set_level(RAFT_LEVEL_WARN); +raft::default_logger().set_level(RAFT_LEVEL_WARN); // From now onwards, this will print only WARN and above kind of messages ``` ### Changing logging pattern Pass the [format string](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) as follows in order use a different logging pattern than the default. ```cpp -raft::logger::get.set_pattern(YourFavoriteFormat); +raft::default_logger().set_pattern(YourFavoriteFormat); ``` One can also use the corresponding `get_pattern()` method to know the current format as well.