Skip to content

Fix thrust tuple includes + more timer checks#902

Merged
rapids-bot[bot] merged 4 commits intoNVIDIA:mainfrom
aliceb-nv:fix-thrust-build
Feb 24, 2026
Merged

Fix thrust tuple includes + more timer checks#902
rapids-bot[bot] merged 4 commits intoNVIDIA:mainfrom
aliceb-nv:fix-thrust-build

Conversation

@aliceb-nv
Copy link
Copy Markdown
Contributor

@aliceb-nv aliceb-nv commented Feb 24, 2026

This PR fixes compilation by adding thrust/tuple.hpp includes to files that previously relied on transitive includes for the thrust::tuple typedef.

Timer checks are also added to ensure timeouts are respected more closely when they occur within the presolve phases.

Description

Issue

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

  • Bug Fixes

    • Stricter time-limit enforcement across solving stages: long-running presolve and solve phases are now short-circuited when time is exhausted, returning a partial/infeasible solution and preserving solver statistics.
  • Chores

    • Updated internal utility headers to support tuple utilities in GPU-related code.

@aliceb-nv aliceb-nv added this to the 26.04 milestone Feb 24, 2026
@aliceb-nv aliceb-nv requested a review from a team as a code owner February 24, 2026 16:12
@aliceb-nv aliceb-nv added bug Something isn't working improvement Improves an existing functionality labels Feb 24, 2026
@akifcorduk akifcorduk removed the improvement Improves an existing functionality label Feb 24, 2026
@rgsl888prabhu rgsl888prabhu added non-breaking Introduces a non-breaking change improvement Improves an existing functionality labels Feb 24, 2026
@akifcorduk akifcorduk removed the improvement Improves an existing functionality label Feb 24, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Adds early time-limit checks in multiple MIP solve stages (diversity presolve, solve init, solver presolve and B&B setup) to short-circuit and return partial solutions when time is exhausted. Also adds thrust/tuple.h includes to several CUDA/utility files and updates a copyright year.

Changes

Cohort / File(s) Summary
Time Limit Checks in MIP Heuristics
cpp/src/mip_heuristics/diversity/diversity_manager.cu, cpp/src/mip_heuristics/solve.cu, cpp/src/mip_heuristics/solver.cu
Inserted timer checks that skip presolve or solving phases when the time limit is reached; each new path logs, finalizes a partial solution from current problem state, updates solve time/stats, applies post-processing, and returns early.
Thrust tuple includes (CUDA/utilities)
cpp/src/pdlp/swap_and_resize_helper.cuh, cpp/src/pdlp/utils.cuh, cpp/src/utilities/copy_helpers.hpp, cpp/src/utilities/cuda_helpers.cuh
Added #include <thrust/tuple.h> to enable use of thrust::tuple. No API or logic changes beyond the include.
Routing: copyright + include
cpp/src/routing/utilities/check_input.cu
Updated copyright year and added #include <thrust/tuple.h>. No functional logic changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes both main changes: adding thrust tuple includes and implementing timer checks in presolve/solving phases.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@akifcorduk akifcorduk added non-breaking Introduces a non-breaking change and removed non-breaking Introduces a non-breaking change labels Feb 24, 2026
Copy link
Copy Markdown

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cpp/src/mip_heuristics/solve.cu`:
- Around line 156-160: When returning early for time limit in
mip_heuristics::solve, the code calls solver.get_solver_stats() which still has
total_solve_time == 0; fix by capturing the stats object, set its
total_solve_time to the timer's elapsed time, and pass that updated stats to
detail::solution_t<i_t,f_t>::get_solution. Concretely: replace the direct
solver.get_solver_stats() call with auto stats = solver.get_solver_stats();
stats.total_solve_time = timer.elapsed_time(); then return
sol.get_solution(false, stats, false) while keeping the existing
timer.check_time_limit(), CUOPT_LOG_INFO and solution construction
(detail::solution_t<i_t, f_t> sol(problem)).

In `@cpp/src/mip_heuristics/solver.cu`:
- Around line 137-143: The early-return on time limit creates a default
solution_t<i_t, f_t> and calls context.problem_ptr->post_process_solution(sol)
without marking it as fully reduced; update both time-limit branches (the
timer_.check_time_limit() blocks that log via CUOPT_LOG_INFO) to call
sol.set_problem_fully_reduced() on the freshly constructed solution before
calling post_process_solution(sol), so post_process_assignment() does not read
an uninitialized assignment and matches the other early-return paths.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d54b193 and d559b34.

📒 Files selected for processing (7)
  • cpp/src/mip_heuristics/diversity/diversity_manager.cu
  • cpp/src/mip_heuristics/solve.cu
  • cpp/src/mip_heuristics/solver.cu
  • cpp/src/pdlp/swap_and_resize_helper.cuh
  • cpp/src/pdlp/utils.cuh
  • cpp/src/utilities/copy_helpers.hpp
  • cpp/src/utilities/cuda_helpers.cuh

Comment on lines +137 to +143
if (timer_.check_time_limit()) {
CUOPT_LOG_INFO("Time limit reached after presolve");
solution_t<i_t, f_t> sol(*context.problem_ptr);
context.stats.total_solve_time = timer_.elapsed_time();
context.problem_ptr->post_process_solution(sol);
return sol;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find the post_process_solution implementation
rg -n "post_process_solution" --include="*.{cu,cuh,cpp,hpp,h}" -A 5 | head -100

Repository: NVIDIA/cuopt

Length of output: 497


🏁 Script executed:

#!/bin/bash
# Find all call sites of post_process_solution and the context around them
rg -n "post_process_solution" --include="*.{cu,cuh,cpp,hpp,h}" -B 2 -A 1

Repository: NVIDIA/cuopt

Length of output: 497


🏁 Script executed:

#!/bin/bash
# Check the specific file and lines mentioned in the review
cat -n cpp/src/mip_heuristics/solver.cu | sed -n '100,150p'

Repository: NVIDIA/cuopt

Length of output: 2752


🏁 Script executed:

#!/bin/bash
# Also check the other time-limit path mentioned
cat -n cpp/src/mip_heuristics/solver.cu | sed -n '290,310p'

Repository: NVIDIA/cuopt

Length of output: 1207


🏁 Script executed:

#!/bin/bash
# Search for post_process_solution method definition using ast-grep
ast-grep --pattern 'post_process_solution($_) {
  $$$
}'

Repository: NVIDIA/cuopt

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for post_process_solution using rg with correct syntax (without --include)
rg "post_process_solution" -t cpp -t cuda -B 2 -A 5

Repository: NVIDIA/cuopt

Length of output: 84


🏁 Script executed:

#!/bin/bash
# Find the definition in the problem class
fd -e cu -e cuh -e cpp -e hpp -e h | xargs grep -l "post_process_solution" | head -5

Repository: NVIDIA/cuopt

Length of output: 269


🏁 Script executed:

#!/bin/bash
# Count occurrences of the 4-line pattern: sol construction + elapsed_time + post_process + return
# Look for the exact pattern in the file
rg "solution_t.*sol.*context\.problem_ptr" cpp/src/mip_heuristics/solver.cu -A 3 | grep -c "post_process_solution"

Repository: NVIDIA/cuopt

Length of output: 57


🏁 Script executed:

#!/bin/bash
# Look for post_process_solution definition in problem files
cat cpp/src/mip_heuristics/problem/problem.cuh | grep -n "post_process_solution" -A 10 | head -30

Repository: NVIDIA/cuopt

Length of output: 736


🏁 Script executed:

#!/bin/bash
# Check problem.cu for the implementation
cat cpp/src/mip_heuristics/problem/problem.cu | grep -n "post_process_solution" -A 15 | head -50

Repository: NVIDIA/cuopt

Length of output: 816


🏁 Script executed:

#!/bin/bash
# Find all instances of sol construction + post_process_solution pattern in solver.cu
grep -n "solution_t.*sol.*context\.problem_ptr" cpp/src/mip_heuristics/solver.cu -A 3

Repository: NVIDIA/cuopt

Length of output: 1440


🏁 Script executed:

#!/bin/bash
# Find the presolve_data.post_process_solution implementation
cat cpp/src/mip_heuristics/problem/presolve_data.cu | grep -n "post_process_solution" -A 20 | head -80

Repository: NVIDIA/cuopt

Length of output: 1146


🏁 Script executed:

#!/bin/bash
# Also check the header for the declaration
cat cpp/src/mip_heuristics/problem/presolve_data.cuh | grep -n "post_process_solution" -A 5

Repository: NVIDIA/cuopt

Length of output: 454


🏁 Script executed:

#!/bin/bash
# Count the actual occurrences of the 4-line duplication pattern more precisely
# Pattern: solution_t creation + elapsed_time + post_process + return on consecutive lines
awk '/solution_t.*sol.*context\.problem_ptr/ {
  getline; line1=$0;
  getline; line2=$0;
  getline; line3=$0;
  getline; line4=$0;
  if (line1 ~ /elapsed_time/ && line2 ~ /post_process_solution/ && line3 ~ /return/) {
    print NR-4 ": Found pattern"
    print $0; print line1; print line2; print line3
  }
}' cpp/src/mip_heuristics/solver.cu

Repository: NVIDIA/cuopt

Length of output: 367


post_process_solution called on default-constructed solution without set_problem_fully_reduced()

Both time-limit early returns (lines 137–143 and 298–302) call post_process_solution(sol) on a solution_t without calling set_problem_fully_reduced() first, unlike all other early-return paths (lines 100, 119, 126). The post_process_solution implementation accesses solution.assignment in post_process_assignment() on an uninitialized assignment. While this won't break functional correctness (the solution is marked infeasible downstream), this inconsistency should be resolved for clarity and consistency with other code paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cpp/src/mip_heuristics/solver.cu` around lines 137 - 143, The early-return on
time limit creates a default solution_t<i_t, f_t> and calls
context.problem_ptr->post_process_solution(sol) without marking it as fully
reduced; update both time-limit branches (the timer_.check_time_limit() blocks
that log via CUOPT_LOG_INFO) to call sol.set_problem_fully_reduced() on the
freshly constructed solution before calling post_process_solution(sol), so
post_process_assignment() does not read an uninitialized assignment and matches
the other early-return paths.

@aliceb-nv
Copy link
Copy Markdown
Contributor Author

/ok to test a15424f

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
cpp/src/routing/utilities/check_input.cu (1)

20-20: LGTM — explicit thrust/tuple.h include correctly fixes the transitive dependency.

The .h extension is consistent with all other Thrust includes in this file (thrust/equal.h, thrust/extrema.h, etc.), and directly provides thrust::make_tuple / thrust::get used at lines 66, 71, 94, 99, 113, and 118.

As an optional forward-looking note: Thrust provides an implementation of std::tuple pulled in from libcu++, and the CCCL documentation recommends replacing thrust::tuple with cuda::std::tuple. Migrating the existing thrust::make_tuple / thrust::get usages is out of scope here but worth tracking as a future refactor.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cpp/src/routing/utilities/check_input.cu` at line 20, The transitive
dependency on thrust::make_tuple / thrust::get was missing; add an explicit
include of thrust/tuple.h to cpp/src/routing/utilities/check_input.cu so the
file directly provides thrust::make_tuple and thrust::get (used at the sites
around lines referencing uses at 66, 71, 94, 99, 113, 118); no further changes
to uses of thrust::tuple are required now (migration to cuda::std::tuple can be
considered later).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@cpp/src/routing/utilities/check_input.cu`:
- Line 20: The transitive dependency on thrust::make_tuple / thrust::get was
missing; add an explicit include of thrust/tuple.h to
cpp/src/routing/utilities/check_input.cu so the file directly provides
thrust::make_tuple and thrust::get (used at the sites around lines referencing
uses at 66, 71, 94, 99, 113, 118); no further changes to uses of thrust::tuple
are required now (migration to cuda::std::tuple can be considered later).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d559b34 and a15424f.

📒 Files selected for processing (2)
  • cpp/src/mip_heuristics/solve.cu
  • cpp/src/routing/utilities/check_input.cu
🚧 Files skipped from review as they are similar to previous changes (1)
  • cpp/src/mip_heuristics/solve.cu

@tmckayus
Copy link
Copy Markdown
Contributor

/merge

@rapids-bot rapids-bot bot merged commit 51addf5 into NVIDIA:main Feb 24, 2026
183 of 185 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants