NVIDIA / NVIDIA/cuopt

[FEA] Reduce libcuopt.so binary size

Open
#1,607 2 comments 0 reactions 1 assignee View on GitHub

@chris-maes is already working on this.

Since Jul 23, 2026.

awaiting response feature request
Dominant language
Cuda
Stars
1k
Forks
233
Avg merge
4d 4h
Merged PRs (30d)
95

Description

Problem

libcuopt.so is currently ~90 MB in a local development build (3 architectures). A CI release build targets 6–8 CUDA architectures and the binary reaches ~250–300 MB based on the per-arch fatbin growth rate observed below. This creates friction for:

  • Container images that embed the library
  • Java/C# wrappers that vendor the .so
  • Wheel size (see #410)
  • Load time and memory-mapped footprint at runtime

Measured breakdown (local build, sm_30/70/75)

Section Size
.nv_fatbin (CUDA fatbin) 60.6 MB
Text + rodata (CPU code) ~18 MB
Exported dynamic symbols 11 601
Global (externally visible) text symbols 1 046
Dynamic NEEDED entries 27

The fatbin is 67 % of the binary and grows linearly with each added CUDA architecture.

Opportunities

1. CUDA fatbin (biggest lever, ~60 %+ of binary)
  • The local build includes sm_30 (Kepler), which has been EOL since CUDA 12 and should be removed from the supported-arch list.
  • For release builds the RAPIDS preset adds sm_70/75/80/86/89/90 — each architecture adds ~10–15 MB. Defining a cuOpt-specific minimum supported arch (e.g. sm_70 / Volta) and removing architectures below it would shrink the fatbin proportionally.
  • Alternatively, ship one PTX image (for forward-compat) plus only the real .cubin for currently-released GPU families, dropping cubin entries for archs that share the same code path.
2. Symbol visibility

libcuopt.so currently exports 1 046 global text symbols with no project-wide -fvisibility=hidden flag set in cpp/CMakeLists.txt. Many of these are C++ internal symbols that users should not call directly; only the stable C API surface (declared in include/cuopt/) needs to be exported.

Recommended changes:

set_target_properties(cuopt PROPERTIES
    CXX_VISIBILITY_PRESET     hidden
    VISIBILITY_INLINES_HIDDEN ON
)

Plus an export-map / version script that explicitly lists only the cuopt_* C API symbols, so internal C++ templates, helper classes, and third-party headers inlined into the translation units are not exported. This also speeds up dlopen and reduces symbol-table size.

3. Dynamic dependency count (27 NEEDED entries)

This overlaps with #1203 (static-link gRPC/protobuf/abseil/TBB/libgomp). Reducing external dynamic dependencies also reduces the runtime footprint of the loaded image.

4. Debug info in development builds

Confirm release/package builds use -g0 (no debug info). A -g2 slip doubles the binary size; currently the dev build is 90 MB unstripped vs 80 MB fully stripped, suggesting minimal DWARF is embedded, but this should be explicitly enforced in the CI packaging CMake preset.

Expected outcome

Change Estimated savings
Drop sm_30 (Kepler, EOL) ~10–12 MB
Drop below-Volta archs in release ~10–20 MB (depends on arch count)
-fvisibility=hidden + export map ~5–10 MB (smaller symbol tables, better dead-code elim)
Static-link gRPC/protobuf/abseil + strip (see #1203) reduces NEEDED count; net size depends on what is stripped

Targeting a release binary under 200 MB for a full-arch build appears achievable without removing any current functionality.

Related

  • #1203 — static-link gRPC/protobuf/abseil/TBB/libgomp
  • #410 — wheel contents inspection (19 000 files, HTML/headers in wheel)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.