Skip to content

[FEA] Reduce libcuopt.so binary size #1607

Description

@ramakrishnap-nv

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:

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

Metadata

Metadata

Assignees

Labels

awaiting responseThis expects a response from maintainer or contributor depending on who requested in last comment.feature requestNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions