Skip to content

Unified threading model in MIP solver - #1099

Merged
rapids-bot[bot] merged 56 commits into
NVIDIA:mainfrom
nguidotti:omp-migration
May 11, 2026
Merged

Unified threading model in MIP solver#1099
rapids-bot[bot] merged 56 commits into
NVIDIA:mainfrom
nguidotti:omp-migration

Conversation

@nguidotti

@nguidottinguidotti commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

In this PR, we migrate almost all parts of the MIP solver from std::thread to OpenMP (in particular, the tasking model of OpenMP). The only exception is the Papilo presolver that uses Intel TBB and the LP solver.

More specifically, this PR

  • Solves the CPU oversubscription problem. The solver now respect the number of threads set to the user, with the exception of Papilo or threads created by the CUDA runtime.
  • Removes overheads from creating and destroying std::thread.
  • Migrates RINS from std::thread to omp task. Similar to previous logic, one instance of RINS can run at a time.
  • Migrates CPU FJ from std::thread to omp task. There are a few limitations
    • scratch_cpu_fj_on_lp_opt and scratch_cpu_fj are running for the entire program. This essentially allocate two dedicated threads to these functions, while other routines needs to share the remaining CPU resources. This may hurt the performance for low core count CPUs.
    • Since there is a small delay between the task creation and its start (since the threads may be busy), the GPU FJ may finish before the CPU FJ even start when racing.
  • Migrate early FJ to omp task.
  • Only a single parallel region created at the beginning of the solver, so it can be shared across the MIP solver.
  • Eliminate cpu_worker_thread and other redundant code
  • Fixed incorrect loop ordering in the the probing cache.

MIPLIB2017:
GH200, 10min time limit, cbs-cta excluded (see #978)

================================================================================
main-190326-2 (1) vs unified-parallel-model (2)
================================================================================
------------------------------------------------------------------------------------------------------------------------------
| | Run 1 | Run 2 | Abs. Diff. | Rel. Diff. (%) |
------------------------------------------------------------------------------------------------------------------------------
| Feasible 226 227 +1 --- |
| Optimal 70 74 +4 --- |
| Solutions with <0.1% primal gap 121 124 +3 --- |
| Nodes explored (mean) 4283972.9121 4684918.2469 +400945.3347 +8.558 |
| Nodes explored (shifted geomean) 6202.3471 7545.9821 +1343.6350 +17.806 |
| Relative MIP gap (mean) 0.3382 0.3279 -0.0103 -3.037 |
| Relative MIP gap (shifted geomean) 0.1193 0.1146 -0.0047 -3.919 |
| Solve time (mean) 450.2347 449.6831 -0.5517 -0.123 |
| Solve time (shifted geomean) 221.4772 239.4322 +17.9549 +7.499 |
| Primal gap (mean) 11.4459 11.3227 -0.1232 -1.076 |
| Primal gap (shifted geomean) 0.6591 0.6122 -0.0469 -7.109 |
| Primal integral (mean) 49.9109 54.1269 +4.2160 +7.789 |
| Primal integral (shifted geomean) 11.5672 13.7114 +2.1442 +15.638 |
------------------------------------------------------------------------------------------------------------------------------
================================================================================
main-190326 (1) vs omp-migration (2)
================================================================================
------------------------------------------------------------------------------------------------------------------------------
| | Run 1 | Run 2 | Abs. Diff. | Rel. Diff. (%) |
------------------------------------------------------------------------------------------------------------------------------
| Feasible 225 225 +0 --- |
| Optimal 70 72 +2 --- |
| Solutions with <0.1% primal gap 122 125 +3 --- |
| Nodes explored (mean) 4471749.9038 4615040.2887 +143290.3849 +3.105 |
| Nodes explored (shifted geomean) 7063.6974 7312.7210 +249.0235 +3.405 |
| Relative MIP gap (mean) 0.3255 0.3223 -0.0032 -0.969 |
| Relative MIP gap (shifted geomean) 0.1185 0.1159 -0.0026 -2.156 |
| Solve time (mean) 451.3237 446.7403 -4.5834 -1.016 |
| Solve time (shifted geomean) 224.6465 234.9078 +10.2613 +4.368 |
| Primal gap (mean) 11.6840 11.6531 -0.0309 -0.265 |
| Primal gap (shifted geomean) 0.6616 0.6369 -0.0248 -3.746 |
| Primal integral (mean) 51.1565 52.9541 +1.7976 +3.395 |
| Primal integral (shifted geomean) 12.5468 12.7091 +0.1623 +1.277 |
------------------------------------------------------------------------------------------------------------------------------

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

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

Labels

improvementImproves an existing functionalitymipnon-breakingIntroduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEA] Respect CPU thread limits

6 participants

@nguidotti@akifcorduk@ramakrishnap-nv@aliceb-nv@chris-maes@anandhkb