Skip to content

CUDA build silently omits posdef/resize/restrict/splinc: 11 FF_CUDA:: entry points are undefined symbols at runtime #80

Description

@balbasty

Agent:claude-jitfields-to-fastfields

libfastfields-cuda.so is built from a MODULES list that omits four of the eleven .cpp files present in the CUDA library. The hub calls into those four unconditionally on the CUDA path, so 11 public CUDA entry points resolve to nothing at runtime — while both the CUDA compile and the hub link report success.

Evidence

fastfields-cuda-lib/Makefile (2b2ad55), MODULES:

distance reg_field reg_field_rls reg_flow reg_flow_rls pushpull pushpull_backward

Source files actually present in that repo:

distance.cpp posdef.cpp pushpull.cpp pushpull_backward.cpp reg_field.cpp
reg_field_rls.cpp reg_flow.cpp reg_flow_rls.cpp resize.cpp restrict.cpp splinc.cpp

posdef.cpp, resize.cpp, restrict.cpp, splinc.cpp are never compiled and never linked into the shared object. Their headers (posdef.h, resize.h, restrict.h, splinc.h) are shipped, so every consumer compiles cleanly against declarations that have no definition.

Contrast fastfields-cpu-lib, whose MODULES lists all ten of its .cpp files — the gap is CUDA-only.

The 11 dead symbols

The hub calls each of these directly under #ifdef FF_WITH_CUDA / if (IS_CUDA(...)) — these are real dispatches, not throw-stubs:

hub filecall
posdef.cppFF_CUDA::sym_matvec, sym_matvec_backward, sym_addmatvec_, sym_submatvec_, sym_solve, sym_solve_, sym_invert, sym_invert_
resize.cppFF_CUDA::resample
restrict.cppFF_CUDA::restriction
splinc.cppFF_CUDA::spline_coeff

e.g. posdef.cpp:22-25:

require_same_device(out, hessian, inp);
#ifdef FF_WITH_CUDA
if (IS_CUDA(out))
returnFF_CUDA::sym_matvec(out, hessian, inp, stream);

So a FF_WITH_CUDA build of libfastfields.so on GPU input reaches an undefined symbol for the whole Posdef family and all of Resampling.

Why CI never caught it

Two independent reasons, and both need fixing:

  1. The hub links without -Wl,--no-undefined.Makefile:113 is CUDA_LDFLAGS = -L$(BUILDDIR)/lib -lfastfields-cuda, and the link line at :218 adds no --no-undefined. Undefined symbols in a shared object are legal by default, so ld is silent and the build is "green".
  2. No GPU in CI, so nothing ever loads the library and calls these paths. Per the accepted CUDA policy (shared kernel math is CPU-tested; CUDA-only glue is validated by compile+link), compile+link is the bar — which makes it important that the link is actually strict enough to be a bar.

This is not a kernel-math bug: the fastfields-cuda-impl headers for these four modules exist and compile. It is purely a build-system omission.

Proposed fix

  1. Add posdef, resize, restrict, splinc to the CUDA MODULES.
  2. Add -Wl,--no-undefined to the hub's CUDA link so a future omission fails the build instead of deferring to runtime.
  3. Confirm nvcc peak memory still fits the runner. The existing MODULES split is deliberate — the comment above it records that ptxas peaks at ~3.8 GB per split module vs ~6–7 GB combined, and that a 16 GB runner survives -j2 only in the split form. These four modules are far lighter than reg_field, but the addition should be measured, not assumed, and the -O1 CI setting kept.

Scope note

FF_CUDA::field_cg is not part of this: solve_field.cpp:42 deliberately throws "fastfields: field_cg is not implemented on CUDA yet" rather than dispatching, so it is honest and link-safe. CUDA CG/FMG remains tracked by #34.

Timing

Filed here rather than on fastfields-cuda-lib because that repo is being folded into this one by the consolidation; post-consolidation the paths become src/lib-cuda/ and the CUDA module list moves into the corresponding make/ fragment. Whoever fixes this should apply it to the consolidated layout, not the pre-consolidation one.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions