Skip to content

Conversation

@nguidotti
Copy link
Contributor

@nguidotti nguidotti commented Dec 15, 2025

This PR adjusts the column spacing the B&B logs to allow 2 letter symbols when finding a feasible solution. This PR allows specifying the opening mode for the logger (used for debugging).

Checklist

  • I am familiar with the Contributing Guidelines.
  • Testing
    • New or existing tests cover these changes
    • Added tests
    • Created an issue to follow-up
    • NA
  • Documentation
    • The documentation is up to date with these changes
    • Added new documentation
    • NA

Summary by CodeRabbit

  • New Features

    • Unified per-node reporting and heuristic reporting; added average iterations-per-node metric for clearer node-level diagnostics.
  • Bug Fixes

    • Improved log formatting, spacing and alignment; node headers now include depth, branch direction and status; optional LP-status blocks added.
    • Feasible-solution symbols now include a trailing space for consistent alignment.
  • Chores

    • Logging API updated to accept explicit file open modes and more robust file handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@nguidotti nguidotti requested a review from a team as a code owner December 15, 2025 11:31
@nguidotti nguidotti requested review from hlinsen and kaatish December 15, 2025 11:31
@nguidotti nguidotti self-assigned this Dec 15, 2025
@nguidotti nguidotti added non-breaking Introduces a non-breaking change mip labels Dec 15, 2025
@nguidotti nguidotti added this to the 26.02 milestone Dec 15, 2025
@nguidotti nguidotti added the improvement Improves an existing functionality label Dec 15, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 15, 2025

📝 Walkthrough

Walkthrough

Added centralized per-node logging and heuristic reporting to branch-and-bound (new report and report_heuristic methods), widened gap formatting and adjusted infinity spacing, introduced iter_node metric, extended node log headers and conditional LP-status logs, and consolidated file logging API to set_log_file(filename, mode).

Changes

Cohort / File(s) Summary
Logger API
cpp/src/dual_simplex/logger.hpp
Changed signatures: enable_log_to_file(std::string)enable_log_to_file(const char*); set_log_file(const std::string&)set_log_file(const std::string&, const char* mode = "w"). set_log_file now forwards mode to enable_log_to_file. fopen call uses the C-string mode; close_log_file resets log_file = nullptr and log_to_file = false.
Branch-and-bound reporting & formatting
cpp/src/dual_simplex/branch_and_bound.hpp, cpp/src/dual_simplex/branch_and_bound.cpp
Added report_heuristic(f_t) and report(std::string,f_t,f_t,i_t) and replaced many inline node/heuristic logs with these calls. Introduced iter_node = total_lp_iters / max(nodes_explored,1) and added it to node output. Adjusted numeric gap width to %5.1f%% and changed infinity-case spacing from " - " to " - ". Feasible-solution symbols now include a trailing space ("B ", "D ", "U "). Extended node headers to include depth, branch direction and vstatus; added conditional LP-status lines under LOG_NODE_SIMPLEX. Replaced prior set_log_filename(...); enable_log_to_file("a+") usages with set_log_file(logname, "a"). Initialized exploration_stats_.nodes_explored to 1 in final run setup and made minor spacing/format tweaks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Verify new report_heuristic and report declarations match definitions and are correctly placed.
  • Check iter_node computation uses max(nodes_explored, 1) as intended and that nodes_explored initialization change (to 1) is correct.
  • Confirm all file-log usages migrated to set_log_file(..., "a") and no old enable_log_to_file("a+") calls remain.
  • Ensure enable_log_to_file(const char*) passes a valid C-string (lifetime) into fopen.
  • Review formatting changes (gap width, infinity spacing, added trailing space in feasible-solution symbols) for any downstream string-parse assumptions.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: adjusting column spacing in branch-and-bound logs, which aligns with the primary modifications to logging formatting and symbols throughout the codebase.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
cpp/src/dual_simplex/logger.hpp (1)

33-44: Logger file-mode API change looks good; consider tightening cleanup.

The switch to const char* mode and the new set_log_file(filename, mode) overload are straightforward and keep existing behavior via the default "w", while enabling append/debug modes. One minor improvement would be to make close_log_file() also set log_file = nullptr and log_to_file = false after std::fclose to avoid any chance of accidental double-close or stale state if it’s called multiple times.

cpp/src/dual_simplex/branch_and_bound.cpp (3)

537-547: New Iter/Node metric is useful; consider avoiding integer division.

Computing iter_node as total_lp_iters / nodes_explored and logging it in the feasible-solution line adds a helpful performance indicator without influencing B&B logic. To avoid truncation from integer division, you might cast the numerator or denominator to f_t:

-    f_t iter_node   = nodes_explored > 0 ? exploration_stats_.total_lp_iters / nodes_explored : 0;
+    f_t iter_node   = nodes_explored > 0
+                        ? static_cast<f_t>(exploration_stats_.total_lp_iters) /
+                            static_cast<f_t>(nodes_explored)
+                        : static_cast<f_t>(0);

820-829: Progress log in exploration_ramp_up gains Iter/Node metric; mind integer division.

The ramp-up progress line now includes Iter/Node, computed as total_lp_iters / nodes_explored, which improves interpretability of solver effort per node. As with the feasible-solution line, consider casting to f_t in the division to avoid truncation and keep the metric numerically meaningful for small averages.


950-960: Best-first exploration progress log mirrors ramp-up format.

The best-first thread’s periodic log now matches the ramp-up format, including Iter/Node and the adjusted spacing. This keeps monitoring output consistent across exploration phases; only logging is affected. You can apply the same optional static_cast<f_t> tweak here to avoid integer division in iter_node.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89ebcbb and 06d531a.

📒 Files selected for processing (2)
  • cpp/src/dual_simplex/branch_and_bound.cpp (8 hunks)
  • cpp/src/dual_simplex/logger.hpp (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{cu,cuh,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cu,cuh,cpp,hpp,h}: Track GPU device memory allocations and deallocations to prevent memory leaks; ensure cudaMalloc/cudaFree balance and cleanup of streams/events
Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results
Check numerical stability: prevent overflow/underflow, precision loss, division by zero/near-zero, and use epsilon comparisons for floating-point equality checks
Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)
Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations
For concurrent CUDA operations (barriers, async operations), explicitly create and manage dedicated streams instead of reusing the default stream; document stream lifecycle
Eliminate unnecessary host-device synchronization (cudaDeviceSynchronize) in hot paths that blocks GPU pipeline; use streams and events for async execution
Assess algorithmic complexity for large-scale problems (millions of variables/constraints); ensure O(n log n) or better complexity, not O(n²) or worse
Verify correct problem size checks before expensive GPU/CPU operations; prevent resource exhaustion on oversized problems
Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)
Ensure race conditions are absent in multi-GPU code and multi-threaded server implementations; verify proper synchronization of shared state
Refactor code duplication in solver components (3+ occurrences) into shared utilities; for GPU kernels, use templated device functions to avoid duplication
Check that hard-coded GPU de...

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
  • cpp/src/dual_simplex/logger.hpp
**/*.{cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cpp,hpp,h}: Check for unclosed file handles when reading MPS/QPS problem files; ensure RAII patterns or proper cleanup in exception paths
Validate input sanitization to prevent buffer overflows and resource exhaustion attacks; avoid unsafe deserialization of problem files
Prevent thread-unsafe use of global and static variables; use proper mutex/synchronization in server code accessing shared solver state

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
  • cpp/src/dual_simplex/logger.hpp
**/*.{cu,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

Avoid inappropriate use of exceptions in performance-critical GPU operation paths; prefer error codes or CUDA error checking for latency-sensitive code

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
  • cpp/src/dual_simplex/logger.hpp
**/*.{h,hpp,py}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

Verify C API does not break ABI stability (no struct layout changes, field reordering); maintain backward compatibility in Python and server APIs with deprecation warnings

Files:

  • cpp/src/dual_simplex/logger.hpp
🧠 Learnings (5)
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Reduce tight coupling between solver components (presolve, simplex, basis, barrier); increase modularity and reusability of optimization algorithms

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-12-04T20:09:09.264Z
Learnt from: chris-maes
Repo: NVIDIA/cuopt PR: 602
File: cpp/src/linear_programming/solve.cu:732-742
Timestamp: 2025-12-04T20:09:09.264Z
Learning: In cpp/src/linear_programming/solve.cu, the barrier solver does not currently return INFEASIBLE or UNBOUNDED status. It only returns OPTIMAL, TIME_LIMIT, NUMERICAL_ISSUES, or CONCURRENT_LIMIT.

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
🧬 Code graph analysis (2)
cpp/src/dual_simplex/branch_and_bound.cpp (4)
cpp/src/dual_simplex/mip_node.hpp (6)
  • lower (94-105)
  • lower (94-96)
  • lower (109-127)
  • lower (109-111)
  • node_ptr (288-294)
  • node_ptr (288-288)
cpp/src/dual_simplex/branch_and_bound.hpp (4)
  • lp_settings (118-118)
  • node_ptr (243-254)
  • node_ptr (257-257)
  • node (217-220)
cpp/src/dual_simplex/pseudo_costs.hpp (1)
  • node_ptr (31-31)
cpp/src/dual_simplex/diving_queue.hpp (4)
  • node (45-50)
  • node (45-45)
  • node (52-57)
  • node (52-52)
cpp/src/dual_simplex/logger.hpp (1)
cpp/src/dual_simplex/simplex_solver_settings.hpp (2)
  • log_filename (85-85)
  • log_filename (85-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-sh-client / 13.0.2, 3.10, amd64, rockylinux8
  • GitHub Check: checks / check-style
🔇 Additional comments (6)
cpp/src/dual_simplex/branch_and_bound.cpp (6)

195-201: Two-character feasible-solution symbols align with new table layout.

Returning "B ", "D ", and "U " from feasible_solution_symbol matches the new log table where the first “symbol” column is two characters wide, and keeps single-letter semantics while reserving space for future two-letter codes. No behavioral impact on B&B decisions.


313-317: Heuristic solution summary line formatting is consistent with the new table.

The updated H line format string now lines up objective, bound, gap, and time with the main B&B table columns, while keeping the same values and conditions as before. This is a pure formatting change and does not affect solution handling.


425-431: Repaired-solution summary log matches heuristic solution formatting.

The repaired-heuristic H line now uses the same column spacing as other summary lines, keeping logs visually consistent without altering the feasibility checks, incumbent updates, or callbacks.


608-628: LOG_NODE_SIMPLEX per-node logging integrates cleanly with new file API.

Using lp_settings.log.set_log_file(logname, "a") with log_to_console = false and the detailed current node printf provides richer per-node diagnostics into a per-thread file without touching core solve logic. The format string and arguments (id, depth, branch var/dir, fractional value, bounds, vstatus) are consistent and gated under LOG_NODE_SIMPLEX, so there is no impact on normal runs.


690-692: Additional LP-status line under LOG_NODE_SIMPLEX.

Logging lp_status at the end of solve_node when LOG_NODE_SIMPLEX is defined is a low-cost way to correlate node metadata with LP outcomes in the node-specific log file; it doesn’t affect control flow or statuses returned to the B&B engine.


1450-1452: Header line correctly reflects new columns and spacing.

The updated header row adds the Iter/Node column and widens spacing, matching the new data rows from feasible-solution and progress logs. This keeps B&B logs self-descriptive without touching any algorithmic behavior.

@nguidotti nguidotti requested review from akifcorduk and aliceb-nv and removed request for hlinsen and kaatish December 15, 2025 12:42
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 06d531a and eb5c695.

📒 Files selected for processing (2)
  • cpp/src/dual_simplex/branch_and_bound.cpp (8 hunks)
  • cpp/src/dual_simplex/logger.hpp (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • cpp/src/dual_simplex/logger.hpp
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cu,cuh,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cu,cuh,cpp,hpp,h}: Track GPU device memory allocations and deallocations to prevent memory leaks; ensure cudaMalloc/cudaFree balance and cleanup of streams/events
Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results
Check numerical stability: prevent overflow/underflow, precision loss, division by zero/near-zero, and use epsilon comparisons for floating-point equality checks
Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)
Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations
For concurrent CUDA operations (barriers, async operations), explicitly create and manage dedicated streams instead of reusing the default stream; document stream lifecycle
Eliminate unnecessary host-device synchronization (cudaDeviceSynchronize) in hot paths that blocks GPU pipeline; use streams and events for async execution
Assess algorithmic complexity for large-scale problems (millions of variables/constraints); ensure O(n log n) or better complexity, not O(n²) or worse
Verify correct problem size checks before expensive GPU/CPU operations; prevent resource exhaustion on oversized problems
Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)
Ensure race conditions are absent in multi-GPU code and multi-threaded server implementations; verify proper synchronization of shared state
Refactor code duplication in solver components (3+ occurrences) into shared utilities; for GPU kernels, use templated device functions to avoid duplication
Check that hard-coded GPU de...

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
**/*.{cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cpp,hpp,h}: Check for unclosed file handles when reading MPS/QPS problem files; ensure RAII patterns or proper cleanup in exception paths
Validate input sanitization to prevent buffer overflows and resource exhaustion attacks; avoid unsafe deserialization of problem files
Prevent thread-unsafe use of global and static variables; use proper mutex/synchronization in server code accessing shared solver state

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
**/*.{cu,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

Avoid inappropriate use of exceptions in performance-critical GPU operation paths; prefer error codes or CUDA error checking for latency-sensitive code

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
🧠 Learnings (5)
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Reduce tight coupling between solver components (presolve, simplex, basis, barrier); increase modularity and reusability of optimization algorithms

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-12-04T20:09:09.264Z
Learnt from: chris-maes
Repo: NVIDIA/cuopt PR: 602
File: cpp/src/linear_programming/solve.cu:732-742
Timestamp: 2025-12-04T20:09:09.264Z
Learning: In cpp/src/linear_programming/solve.cu, the barrier solver does not currently return INFEASIBLE or UNBOUNDED status. It only returns OPTIMAL, TIME_LIMIT, NUMERICAL_ISSUES, or CONCURRENT_LIMIT.

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
🧬 Code graph analysis (1)
cpp/src/dual_simplex/branch_and_bound.cpp (3)
cpp/src/dual_simplex/mip_node.hpp (6)
  • lower (94-105)
  • lower (94-96)
  • lower (109-127)
  • lower (109-111)
  • node_ptr (288-294)
  • node_ptr (288-288)
cpp/src/dual_simplex/branch_and_bound.hpp (3)
  • node_ptr (243-254)
  • node_ptr (257-257)
  • node (217-220)
cpp/src/dual_simplex/diving_queue.hpp (4)
  • node (45-50)
  • node (45-45)
  • node (52-57)
  • node (52-52)
🔇 Additional comments (5)
cpp/src/dual_simplex/branch_and_bound.cpp (5)

195-202: LGTM!

The trailing spaces ensure consistent 2-character width for feasible solution symbols, improving column alignment in B&B logs.


312-317: LGTM!

Format string correctly adjusted for column alignment with heuristic solution output.


425-430: LGTM!

Format string consistent with the other heuristic solution output at line 313.


614-628: LGTM!

The consolidated set_log_file(logname, "a") API is cleaner than the previous two-call pattern. The mode "a" (append-only) is appropriate since reading is not required for log output. The enhanced node logging provides valuable debugging information.


690-692: LGTM!

Useful diagnostic output for LP status, appropriately guarded by LOG_NODE_SIMPLEX.

@nguidotti nguidotti mentioned this pull request Dec 16, 2025
8 tasks
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
cpp/src/dual_simplex/branch_and_bound.cpp (3)

537-549: Format specifier mismatch remains unresolved from previous reviews.

The iter_node floating-point division fix is correct (lines 537-539), but the format specifier issue flagged in previous reviews at line 540 was not addressed: %10lu expects unsigned long, but nodes_unexplored is i_t (typically int). This causes undefined behavior on some platforms.

Apply the format/cast fix from previous review:

-    settings_.log.printf("%s%10d   %10lu    %+13.6e    %+10.6e   %6d   %7.1e     %s %9.2f\n",
+    settings_.log.printf("%s%10d   %10d    %+13.6e    %+10.6e   %6d   %7.1e     %s %9.2f\n",
                          feasible_solution_symbol(thread_type),
                          nodes_explored,
-                         nodes_unexplored,
+                         static_cast<int>(nodes_unexplored),
                          obj,

821-833: Format specifier mismatch remains unresolved from previous reviews.

Same issue as lines 537-549: line 825 uses %10lu for nodes_unexplored which is i_t (int), causing undefined behavior. This was flagged in previous reviews.

Apply the fix:

-      settings_.log.printf("  %10d   %10lu    %+13.6e    %+10.6e   %6d   %7.1e     %s %9.2f\n",
+      settings_.log.printf("  %10d   %10d    %+13.6e    %+10.6e   %6d   %7.1e     %s %9.2f\n",
                            nodes_explored,
-                           nodes_unexplored,
+                           static_cast<int>(nodes_unexplored),
                            obj,

954-966: Format specifier mismatch remains unresolved from previous reviews.

Same issue as lines 537-549 and 821-833: line 958 uses %10lu for nodes_unexplored which is i_t (int). This was flagged in previous reviews.

Apply the fix:

-        settings_.log.printf("  %10d   %10lu    %+13.6e    %+10.6e   %6d   %7.1e     %s %9.2f\n",
+        settings_.log.printf("  %10d   %10d    %+13.6e    %+10.6e   %6d   %7.1e     %s %9.2f\n",
                              nodes_explored,
-                             nodes_unexplored,
+                             static_cast<int>(nodes_unexplored),
                              obj,
🧹 Nitpick comments (1)
cpp/src/dual_simplex/branch_and_bound.cpp (1)

537-549: Consider refactoring duplicated logging logic.

The progress logging format appears three times with nearly identical structure. Per coding guidelines, 3+ occurrences of duplicated code should be refactored into shared utilities. Consider extracting a helper function like:

void log_progress(const char* prefix, i_t nodes_explored, i_t nodes_unexplored, 
                  f_t obj, f_t lower, i_t depth, f_t iter_node, 
                  const std::string& gap, f_t time);

This would improve maintainability and ensure consistency across all logging sites.

Also applies to: 821-833, 954-966

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9effdc8 and 98f670f.

📒 Files selected for processing (1)
  • cpp/src/dual_simplex/branch_and_bound.cpp (8 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cu,cuh,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cu,cuh,cpp,hpp,h}: Track GPU device memory allocations and deallocations to prevent memory leaks; ensure cudaMalloc/cudaFree balance and cleanup of streams/events
Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results
Check numerical stability: prevent overflow/underflow, precision loss, division by zero/near-zero, and use epsilon comparisons for floating-point equality checks
Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)
Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations
For concurrent CUDA operations (barriers, async operations), explicitly create and manage dedicated streams instead of reusing the default stream; document stream lifecycle
Eliminate unnecessary host-device synchronization (cudaDeviceSynchronize) in hot paths that blocks GPU pipeline; use streams and events for async execution
Assess algorithmic complexity for large-scale problems (millions of variables/constraints); ensure O(n log n) or better complexity, not O(n²) or worse
Verify correct problem size checks before expensive GPU/CPU operations; prevent resource exhaustion on oversized problems
Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)
Ensure race conditions are absent in multi-GPU code and multi-threaded server implementations; verify proper synchronization of shared state
Refactor code duplication in solver components (3+ occurrences) into shared utilities; for GPU kernels, use templated device functions to avoid duplication
Check that hard-coded GPU de...

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
**/*.{cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cpp,hpp,h}: Check for unclosed file handles when reading MPS/QPS problem files; ensure RAII patterns or proper cleanup in exception paths
Validate input sanitization to prevent buffer overflows and resource exhaustion attacks; avoid unsafe deserialization of problem files
Prevent thread-unsafe use of global and static variables; use proper mutex/synchronization in server code accessing shared solver state

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
**/*.{cu,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

Avoid inappropriate use of exceptions in performance-critical GPU operation paths; prefer error codes or CUDA error checking for latency-sensitive code

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
🧠 Learnings (7)
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Reduce tight coupling between solver components (presolve, simplex, basis, barrier); increase modularity and reusability of optimization algorithms

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Add tests for algorithm phase transitions: verify correct initialization of bounds and state when transitioning from presolve to simplex to diving to crossover

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-12-04T20:09:09.264Z
Learnt from: chris-maes
Repo: NVIDIA/cuopt PR: 602
File: cpp/src/linear_programming/solve.cu:732-742
Timestamp: 2025-12-04T20:09:09.264Z
Learning: In cpp/src/linear_programming/solve.cu, the barrier solver does not currently return INFEASIBLE or UNBOUNDED status. It only returns OPTIMAL, TIME_LIMIT, NUMERICAL_ISSUES, or CONCURRENT_LIMIT.

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
🧬 Code graph analysis (1)
cpp/src/dual_simplex/branch_and_bound.cpp (2)
cpp/src/dual_simplex/mip_node.hpp (6)
  • lower (94-105)
  • lower (94-96)
  • lower (109-127)
  • lower (109-111)
  • node_ptr (288-294)
  • node_ptr (288-288)
cpp/src/dual_simplex/branch_and_bound.hpp (3)
  • node_ptr (243-254)
  • node_ptr (257-257)
  • node (217-220)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: wheel-build-cuopt-sh-client / 13.0.2, 3.10, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, arm64, rockylinux8
  • GitHub Check: checks / other-checks
🔇 Additional comments (5)
cpp/src/dual_simplex/branch_and_bound.cpp (5)

186-192: LGTM - Column spacing adjustments align with PR objectives.

The spacing adjustments in the gap formatting (including the " - " placeholder and percentage format) are consistent with the stated goal of improving B&B log column alignment.


195-202: LGTM - Trailing spaces enable two-letter symbol support.

The trailing space in each return value aligns with the PR objective of allowing two-letter symbols in B&B logs while maintaining column alignment. This is a deliberate formatting change referenced in the PR description.


313-317: LGTM - Heuristic solution log formatting updated.

The format adjustments for heuristic solution logs maintain consistency with the expanded column layout introduced in this PR.

Also applies to: 426-430


616-630: LGTM - Logger API updated and node debugging enhanced.

The consolidation to set_log_file(logname, "a") aligns with the logger API changes described in the PR. The expanded per-node logging (depth, branch direction, bounds, vstatus) provides valuable debugging context without affecting production behavior (guarded by LOG_NODE_SIMPLEX).


692-695: LGTM - LP status logging aids debugging.

The LP status output under LOG_NODE_SIMPLEX provides useful debugging information without affecting production builds.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
cpp/src/dual_simplex/branch_and_bound.cpp (1)

289-311: Fix integer division and format specifier mismatch.

Two critical issues in the report method:

  1. Line 299 - Integer division truncates result: exploration_stats_.total_lp_iters / nodes_explored performs integer division because both operands are integer types (omp_atomic_t<i_t>), truncating the fractional part before assignment to f_t.

  2. Line 301 - Format specifier mismatch: %10lu expects unsigned long, but nodes_unexplored is type i_t (typically int), causing undefined behavior.

🔎 Apply this diff to fix both issues:
-  f_t iter_node        = exploration_stats_.total_lp_iters / nodes_explored;
+  f_t iter_node        = nodes_explored > 0 ? static_cast<f_t>(exploration_stats_.total_lp_iters) / static_cast<f_t>(nodes_explored) : static_cast<f_t>(0);
   std::string user_gap = user_mip_gap<f_t>(user_obj, user_lower);
-  settings_.log.printf("%s%10d   %10lu    %+13.6e    %+10.6e  %6d    %7.1e     %s %9.2f\n",
+  settings_.log.printf("%s%10d   %10d    %+13.6e    %+10.6e  %6d    %7.1e     %s %9.2f\n",
                        symbol.c_str(),
                        nodes_explored,
-                       nodes_unexplored,
+                       static_cast<int>(nodes_unexplored),
                        user_obj,

Based on learnings: Validate algorithm correctness in optimization logic.

🧹 Nitpick comments (1)
cpp/src/dual_simplex/branch_and_bound.hpp (1)

202-203: Pass string parameter by const reference.

The report method takes std::string symbol by value, which incurs unnecessary copying overhead. Since the parameter is not modified, pass it by const reference for better performance.

🔎 Apply this diff to pass the string by const reference:
-  void report(std::string symbol, f_t obj, f_t lower_bound, i_t node_depth);
+  void report(const std::string& symbol, f_t obj, f_t lower_bound, i_t node_depth);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98f670f and fbb9966.

📒 Files selected for processing (2)
  • cpp/src/dual_simplex/branch_and_bound.cpp (10 hunks)
  • cpp/src/dual_simplex/branch_and_bound.hpp (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{cu,cuh,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cu,cuh,cpp,hpp,h}: Track GPU device memory allocations and deallocations to prevent memory leaks; ensure cudaMalloc/cudaFree balance and cleanup of streams/events
Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results
Check numerical stability: prevent overflow/underflow, precision loss, division by zero/near-zero, and use epsilon comparisons for floating-point equality checks
Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)
Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations
For concurrent CUDA operations (barriers, async operations), explicitly create and manage dedicated streams instead of reusing the default stream; document stream lifecycle
Eliminate unnecessary host-device synchronization (cudaDeviceSynchronize) in hot paths that blocks GPU pipeline; use streams and events for async execution
Assess algorithmic complexity for large-scale problems (millions of variables/constraints); ensure O(n log n) or better complexity, not O(n²) or worse
Verify correct problem size checks before expensive GPU/CPU operations; prevent resource exhaustion on oversized problems
Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)
Ensure race conditions are absent in multi-GPU code and multi-threaded server implementations; verify proper synchronization of shared state
Refactor code duplication in solver components (3+ occurrences) into shared utilities; for GPU kernels, use templated device functions to avoid duplication
Check that hard-coded GPU de...

Files:

  • cpp/src/dual_simplex/branch_and_bound.hpp
  • cpp/src/dual_simplex/branch_and_bound.cpp
**/*.{h,hpp,py}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

Verify C API does not break ABI stability (no struct layout changes, field reordering); maintain backward compatibility in Python and server APIs with deprecation warnings

Files:

  • cpp/src/dual_simplex/branch_and_bound.hpp
**/*.{cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cpp,hpp,h}: Check for unclosed file handles when reading MPS/QPS problem files; ensure RAII patterns or proper cleanup in exception paths
Validate input sanitization to prevent buffer overflows and resource exhaustion attacks; avoid unsafe deserialization of problem files
Prevent thread-unsafe use of global and static variables; use proper mutex/synchronization in server code accessing shared solver state

Files:

  • cpp/src/dual_simplex/branch_and_bound.hpp
  • cpp/src/dual_simplex/branch_and_bound.cpp
**/*.{cu,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

Avoid inappropriate use of exceptions in performance-critical GPU operation paths; prefer error codes or CUDA error checking for latency-sensitive code

Files:

  • cpp/src/dual_simplex/branch_and_bound.hpp
  • cpp/src/dual_simplex/branch_and_bound.cpp
🧠 Learnings (7)
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.hpp
  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Reduce tight coupling between solver components (presolve, simplex, basis, barrier); increase modularity and reusability of optimization algorithms

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Add tests for algorithm phase transitions: verify correct initialization of bounds and state when transitioning from presolve to simplex to diving to crossover

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-12-04T20:09:09.264Z
Learnt from: chris-maes
Repo: NVIDIA/cuopt PR: 602
File: cpp/src/linear_programming/solve.cu:732-742
Timestamp: 2025-12-04T20:09:09.264Z
Learning: In cpp/src/linear_programming/solve.cu, the barrier solver does not currently return INFEASIBLE or UNBOUNDED status. It only returns OPTIMAL, TIME_LIMIT, NUMERICAL_ISSUES, or CONCURRENT_LIMIT.

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
🧬 Code graph analysis (1)
cpp/src/dual_simplex/branch_and_bound.cpp (3)
cpp/src/dual_simplex/branch_and_bound.hpp (3)
  • obj (202-202)
  • symbol (203-203)
  • node (220-223)
cpp/src/dual_simplex/solve.cpp (6)
  • compute_user_objective (88-93)
  • compute_user_objective (88-88)
  • compute_user_objective (96-100)
  • compute_user_objective (96-96)
  • compute_user_objective (661-662)
  • compute_user_objective (664-664)
cpp/src/dual_simplex/solve.hpp (2)
  • compute_user_objective (37-37)
  • compute_user_objective (40-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, amd64, rockylinux8
🔇 Additional comments (6)
cpp/src/dual_simplex/branch_and_bound.cpp (6)

181-193: LGTM - Column spacing adjustments.

The spacing changes in the user_mip_gap function align with the PR objective to adjust column spacing in B&B logs. The " - " return value and "%5.1f%%" format maintain consistent column widths.


195-202: LGTM - Trailing space for two-letter symbol support.

The trailing space in the return values ("B ", "D ", "U ") accommodates the PR's goal to allow two-letter symbols for feasible solutions while maintaining column alignment.


268-287: LGTM - Heuristic reporting consolidation.

The report_heuristic method correctly consolidates heuristic solution logging, computes user-scaled objectives and gaps, and handles both running and non-running solver states appropriately.


351-351: LGTM - Correct usage of report_heuristic.

The call to report_heuristic(obj) appropriately replaces inline logging after validating the feasible solution.


615-628: LGTM - Logger API update and enhanced diagnostics.

The change from set_log_filename to set_log_file(logname, "a") aligns with the updated logger API mentioned in the PR description. The enhanced logging now includes depth, branch direction, and vstatus information, improving debugging capabilities.


1429-1429: LGTM - Root node counted as explored.

Initializing nodes_explored to 1 instead of 0 correctly counts the root node as explored and prevents potential division-by-zero issues. This aligns with the past review discussion.

Copy link
Contributor

@chris-maes chris-maes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we discuss before merging?

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbb9966 and 78f38a4.

📒 Files selected for processing (1)
  • cpp/src/dual_simplex/branch_and_bound.cpp (10 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cu,cuh,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cu,cuh,cpp,hpp,h}: Track GPU device memory allocations and deallocations to prevent memory leaks; ensure cudaMalloc/cudaFree balance and cleanup of streams/events
Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results
Check numerical stability: prevent overflow/underflow, precision loss, division by zero/near-zero, and use epsilon comparisons for floating-point equality checks
Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)
Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations
For concurrent CUDA operations (barriers, async operations), explicitly create and manage dedicated streams instead of reusing the default stream; document stream lifecycle
Eliminate unnecessary host-device synchronization (cudaDeviceSynchronize) in hot paths that blocks GPU pipeline; use streams and events for async execution
Assess algorithmic complexity for large-scale problems (millions of variables/constraints); ensure O(n log n) or better complexity, not O(n²) or worse
Verify correct problem size checks before expensive GPU/CPU operations; prevent resource exhaustion on oversized problems
Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)
Ensure race conditions are absent in multi-GPU code and multi-threaded server implementations; verify proper synchronization of shared state
Refactor code duplication in solver components (3+ occurrences) into shared utilities; for GPU kernels, use templated device functions to avoid duplication
Check that hard-coded GPU de...

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
**/*.{cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cpp,hpp,h}: Check for unclosed file handles when reading MPS/QPS problem files; ensure RAII patterns or proper cleanup in exception paths
Validate input sanitization to prevent buffer overflows and resource exhaustion attacks; avoid unsafe deserialization of problem files
Prevent thread-unsafe use of global and static variables; use proper mutex/synchronization in server code accessing shared solver state

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
**/*.{cu,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

Avoid inappropriate use of exceptions in performance-critical GPU operation paths; prefer error codes or CUDA error checking for latency-sensitive code

Files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
🧠 Learnings (7)
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Reduce tight coupling between solver components (presolve, simplex, basis, barrier); increase modularity and reusability of optimization algorithms

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*test*.{cpp,cu,py} : Add tests for algorithm phase transitions: verify correct initialization of bounds and state when transitioning from presolve to simplex to diving to crossover

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
📚 Learning: 2025-12-04T20:09:09.264Z
Learnt from: chris-maes
Repo: NVIDIA/cuopt PR: 602
File: cpp/src/linear_programming/solve.cu:732-742
Timestamp: 2025-12-04T20:09:09.264Z
Learning: In cpp/src/linear_programming/solve.cu, the barrier solver does not currently return INFEASIBLE or UNBOUNDED status. It only returns OPTIMAL, TIME_LIMIT, NUMERICAL_ISSUES, or CONCURRENT_LIMIT.

Applied to files:

  • cpp/src/dual_simplex/branch_and_bound.cpp
🧬 Code graph analysis (1)
cpp/src/dual_simplex/branch_and_bound.cpp (3)
cpp/src/dual_simplex/branch_and_bound.hpp (3)
  • obj (202-202)
  • symbol (203-203)
  • node (220-223)
cpp/src/dual_simplex/solve.cpp (6)
  • compute_user_objective (88-93)
  • compute_user_objective (88-88)
  • compute_user_objective (96-100)
  • compute_user_objective (96-96)
  • compute_user_objective (661-662)
  • compute_user_objective (664-664)
cpp/src/dual_simplex/solve.hpp (2)
  • compute_user_objective (37-37)
  • compute_user_objective (40-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-sh-client / 13.0.2, 3.10, amd64, rockylinux8
🔇 Additional comments (5)
cpp/src/dual_simplex/branch_and_bound.cpp (5)

186-190: LGTM! Column spacing adjustments look good.

The format changes for the gap display are consistent with the PR objective to adjust column spacing in B&B logs.


198-200: LGTM! Symbol format updated correctly.

Adding trailing spaces to feasible solution symbols is consistent with the PR objective to support two-letter symbols in B&B logs.


615-615: LGTM! Logging API consolidated correctly.

The change from set_log_filename + enable_log_to_file to the unified set_log_file(filename, mode) API improves clarity. Using mode "a" (append-only) is appropriate for logging.


618-628: LGTM! Enhanced debug logging is helpful.

The expanded node logging format provides more detailed information for debugging, including depth, branch direction, bounds, and variable status. Since this is within #ifdef LOG_NODE_SIMPLEX, it has no production impact.


1426-1429: LGTM! Header and initialization changes are correct.

The updated log header matches the new format, and initializing nodes_explored to 1 correctly counts the root node as explored, which is consistent with the discussion in past review comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality mip non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants