Skip to content

refactor: make to_optimization_problem a free function - #1802

Draft
ramakrishnap-nv wants to merge 1 commit into
split/1-host-device-tusfrom
split/2-devirtualize-to-optimization-problem
Draft

refactor: make to_optimization_problem a free function#1802
ramakrishnap-nv wants to merge 1 commit into
split/1-host-device-tusfrom
split/2-devirtualize-to-optimization-problem

Conversation

@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator

2 of 4 toward a CUDA-free client library. Stacked on #1801 — review that first; the base will move to main once it lands.

The problem

to_optimization_problem() was a virtual member on optimization_problem_interface_t, so it occupied a slot in the vtable of every implementer — including cpu_optimization_problem_t, whose vtable therefore held an entry only libcuopt can define.

Vtable relocations are resolved eagerly at load time, unlike ordinary function calls. So this cannot be deferred, hidden behind lazy binding, or worked around with a dispatch hook: any library carrying that vtable is unloadable without libcuopt.so present.

The change

Now a free function declared in optimization_problem.hpp, defined in cpu_optimization_problem_to_gpu.cpp, dispatching on the concrete type:

-  auto gpu = problem->to_optimization_problem(&handle);
+  auto gpu = to_optimization_problem(*problem, &handle);

The GPU override was a one-line return nullptr ("already a GPU problem"), so the dispatch is a single dynamic_cast and semantics are unchanged — a GPU-backed problem still yields nullptr. cpu_optimization_problem_t befriends the function to reach its host-side storage.

6 call sites updated: pdlp/solve.cu, mip_heuristics/solve.cu, grpc/server/grpc_worker.cpp, and two in solution_interface_test.cu.

Bonus

Moving the definition to its own TU also keeps <optimization_problem.hpp> and the raft handle out of cpu_optimization_problem.cpp, which is otherwise pure host code.

Discussion point

This trades a virtual for a dynamic_cast. That's the deliberate choice — the alternative (keeping it virtual and dispatching through a registered function pointer) doesn't work, because the vtable slot still needs a definition at load time. Happy to discuss if there's a third option I've missed.

Testing

Full build + 126 test binaries, 0 errors. 111/125 pass; the 14 failures are cudaErrorUnknown from a locally wedged nvidia_uvm, identical on unmodified main.

🤖 Generated with Claude Code

cpu_optimization_problem_t::to_optimization_problem() was a virtual member on
optimization_problem_interface_t. That put it in the vtable of every implementer,
including the CPU one -- so cpu_optimization_problem_t's vtable held an entry that
only libcuopt can define.

Vtable relocations are resolved eagerly at load time, unlike ordinary function
calls, so this cannot be deferred or hidden behind lazy binding. Any library
carrying that vtable is unloadable without libcuopt.so present.

It is now a free function declared in optimization_problem.hpp and defined in
cpu_optimization_problem_to_gpu.cpp, dispatching on the concrete type:

    auto gpu = to_optimization_problem(problem, &handle);

The GPU override was a one-line `return nullptr` ("already a GPU problem"), so the
dispatch is a single dynamic_cast and the semantics are unchanged -- a GPU-backed
problem still yields nullptr. cpu_optimization_problem_t befriends the function to
reach its host-side storage.

Six call sites updated across pdlp/solve.cu, mip_heuristics/solve.cu,
grpc/server/grpc_worker.cpp and solution_interface_test.cu.

Splitting the definition into its own translation unit also keeps
<optimization_problem.hpp> and the raft handle out of cpu_optimization_problem.cpp,
which is otherwise pure host code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator Author

/ok to test

@github-actions

Copy link
Copy Markdown

CI Test Summary

⏭️ All 5 test job(s) skipped.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant