Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
cdb994e
refactor(logger): give each component library its own logger
ramakrishnap-nv Aug 24, 2026
9e59d0d
fix(logger): address review on guard order and macro propagation
ramakrishnap-nv Aug 24, 2026
651b79e
Merge remote-tracking branch 'origin/main' into refactor/per-library-…
ramakrishnap-nv Aug 24, 2026
3a56336
Merge remote-tracking branch 'origin/main' into refactor/per-library-…
ramakrishnap-nv Aug 25, 2026
0d575bc
fix(logger): correct static destruction order and rewrite the tests
ramakrishnap-nv Aug 26, 2026
ad82df1
fix(logger): keep the depth counter balanced when configure throws
ramakrishnap-nv Aug 26, 2026
72cdfc3
refactor(logger): make log_buffer's state private
ramakrishnap-nv Aug 26, 2026
ba3ca2f
Merge remote-tracking branch 'origin/main' into refactor/per-library-…
ramakrishnap-nv Aug 27, 2026
3f042f8
fix(logger): restore a sink when init_logger_t fails to configure
ramakrishnap-nv Aug 27, 2026
1914d37
refactor(logger): one lifetime mechanism, and make the visibility gua…
ramakrishnap-nv Aug 27, 2026
e031c6b
fix(logger): do not let a stale guard reset a newer configuration
ramakrishnap-nv Aug 27, 2026
fdf6581
test(logger): use a trigger that fails to open for root too
ramakrishnap-nv Aug 27, 2026
ec24e04
Merge branch 'main' into refactor/per-library-logger
ramakrishnap-nv Aug 28, 2026
78583ec
refactor(logger): trim over-explanatory comments
ramakrishnap-nv Aug 28, 2026
2fe7bbf
test(logger): cover mathopt/routing configured to different files tog…
ramakrishnap-nv Aug 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions ci/check_symbols.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,28 @@ for sym in "${required_symbols[@]}"; do
fi
done

# The logger keeps one instance per component library only while its state stays hidden --
# nothing fails to build or test if it becomes visible, since glibc silently merges it back
# into one via STB_GNU_UNIQUE. Assert it's absent from the dynamic symbol table.
logger_state_symbols=(
"cuopt::default_logger()"
"cuopt::global_log_buffer()"
"cuopt::reset_default_logger()"
)

demangled_dyn_syms="$(readelf --dyn-syms --wide "${LIBRARY}" | awk '$7 != "UND" { print $8 }' | c++filt)"

for sym in "${logger_state_symbols[@]}"; do
echo "Checking that logger state '${sym}' is NOT exported..."
if grep -qF "${sym}" <<< "${demangled_dyn_syms}"; then
echo "ERROR: Logger state '${sym}' is exported from ${LIBRARY}."
echo "ERROR: Per-component loggers silently collapse into one shared instance when this"
echo "ERROR: state is visible. Check that cpp/src/utilities/logger.hpp's namespace is not"
echo "ERROR: marked CUOPT_EXPORT and that hidden visibility is still set on the target."
failed=1
fi
done

if [[ "${failed}" -ne 0 ]]; then
exit 1
fi
Expand Down
13 changes: 13 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,13 @@ target_compile_definitions(cuopt_objs
PUBLIC CUSPARSE_ENABLE_EXPERIMENTAL_API
)

# Lets callers reach routing's logger through init_component_logger_t. Also set below on
# cuopt and cuopt_static: $<TARGET_OBJECTS:...> does not carry INTERFACE properties, and
# consumers such as cuopt_cli and the tests link those, not cuopt_objs.
if(NOT SKIP_ROUTING_BUILD)
target_compile_definitions(cuopt_objs PUBLIC CUOPT_HAS_ROUTING)
endif()

target_compile_options(cuopt_objs
PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${CUOPT_CXX_FLAGS}>"
"$<$<COMPILE_LANGUAGE:CUDA>:${CUOPT_CUDA_FLAGS}>"
Expand Down Expand Up @@ -811,6 +818,9 @@ if (BUILD_TESTS)
"CUOPT_LOG_ACTIVE_LEVEL=RAPIDS_LOGGER_LOG_LEVEL_${LIBCUOPT_LOGGING_LEVEL}"
CUSPARSE_ENABLE_EXPERIMENTAL_API
)
if(NOT SKIP_ROUTING_BUILD)
target_compile_definitions(cuopt_static PUBLIC CUOPT_HAS_ROUTING)
endif()
target_link_libraries(cuopt_static PRIVATE $<TARGET_FILE:PSLP>)
add_dependencies(cuopt_static PSLP)
target_link_libraries(cuopt_static PRIVATE $<TARGET_FILE:KaMinPar::KaMinPar>)
Expand Down Expand Up @@ -869,6 +879,9 @@ target_compile_definitions(cuopt
"CUOPT_LOG_ACTIVE_LEVEL=RAPIDS_LOGGER_LOG_LEVEL_${LIBCUOPT_LOGGING_LEVEL}"
CUSPARSE_ENABLE_EXPERIMENTAL_API
)
if(NOT SKIP_ROUTING_BUILD)
target_compile_definitions(cuopt PUBLIC CUOPT_HAS_ROUTING)
endif()

if (WRITE_FATBIN)
file(WRITE "${CUOPT_BINARY_DIR}/fatbin.ld"
Expand Down
10 changes: 8 additions & 2 deletions cpp/cuopt_cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,14 @@ int run_single_file(const std::string& file_path,
cuopt::mathematical_optimization::io::mps_reader_type_t mps_reader,
cuopt::mathematical_optimization::solver_settings_t<int, double>& settings)
{
cuopt::init_logger_t log(settings.get_parameter<std::string>(CUOPT_LOG_FILE),
settings.get_parameter<bool>(CUOPT_LOG_TO_CONSOLE));
// The solver's logger lives in the solver library, reachable only through its exported
// entry point. The CLI's own logger appends rather than truncates, so it does not clear
// the file the solver has just opened.
const auto log_file = settings.get_parameter<std::string>(CUOPT_LOG_FILE);
const auto log_console = settings.get_parameter<bool>(CUOPT_LOG_TO_CONSOLE);

cuopt::init_component_logger_t solver_log(log_file, log_console);
cuopt::init_logger_t log(log_file, log_console, /*truncate=*/false);

std::string base_filename = file_path.substr(file_path.find_last_of("/\\") + 1);

Expand Down
1 change: 0 additions & 1 deletion cpp/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# cmake-format: on

set(UTIL_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/utilities/seed_generator.cu
${CMAKE_CURRENT_SOURCE_DIR}/utilities/logger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/version_info.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/timestamp_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/utilities/work_unit_scheduler.cpp)
Expand Down
1 change: 1 addition & 0 deletions cpp/src/math_optimization/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ list(PREPEND
${CMAKE_CURRENT_SOURCE_DIR}/solution_reader.cu
${CMAKE_CURRENT_SOURCE_DIR}/solution_writer.cu
${CMAKE_CURRENT_SOURCE_DIR}/tic_toc.cpp
${CMAKE_CURRENT_SOURCE_DIR}/logger_entry.cpp
)

set(CUOPT_SRC_FILES ${CUOPT_SRC_FILES}
Expand Down
20 changes: 20 additions & 0 deletions cpp/src/math_optimization/logger_entry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* clang-format off */
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
/* clang-format on */

#include <utilities/logger.hpp>

// Compiled into cuopt_mathopt only, so this reaches mathopt's hidden logger instance.
namespace cuopt::mathematical_optimization {

std::shared_ptr<void> configure_logging(const std::string& log_file,
bool log_to_console,
bool truncate)
{
return cuopt::make_logger_config(log_file, log_to_console, truncate);
}

} // namespace cuopt::mathematical_optimization
1 change: 1 addition & 0 deletions cpp/src/routing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# cmake-format: on

set(ROUTING_SRC_FILES
${CMAKE_CURRENT_SOURCE_DIR}/logger_entry.cpp
${CMAKE_CURRENT_SOURCE_DIR}/local_search/compute_insertions.cu
${CMAKE_CURRENT_SOURCE_DIR}/ges/squeeze.cu
${CMAKE_CURRENT_SOURCE_DIR}/local_search/sliding_window.cu
Expand Down
20 changes: 20 additions & 0 deletions cpp/src/routing/logger_entry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* clang-format off */
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
/* clang-format on */

#include <utilities/logger.hpp>

// Compiled into cuopt_routing only, so this reaches routing's hidden logger instance.
namespace cuopt::routing {

std::shared_ptr<void> configure_logging(const std::string& log_file,
bool log_to_console,
bool truncate)
{
return cuopt::make_logger_config(log_file, log_to_console, truncate);
}

} // namespace cuopt::routing
3 changes: 3 additions & 0 deletions cpp/src/routing/solve.cu
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ template <typename i_t, typename f_t>
assignment_t<i_t> solve(data_model_view_t<i_t, f_t> const& data_model,
solver_settings_t<i_t, f_t> const& settings)
{
// Without this, CUOPT_LOG_ERROR below sinks into the buffer and is never emitted.
init_logger_t log("", settings.get_error_logging_mode());

try {
cuopt::routing::solver_t<i_t, f_t> solver(data_model, settings);
return solver.solve();
Expand Down
191 changes: 0 additions & 191 deletions cpp/src/utilities/logger.cpp

This file was deleted.

Loading
Loading