Repository navigation
onnx EP: declare and link q4nx_elf_arg_sizes, so the NPU leg builds again - #878
Conversation
#869 gave I8Ctx::args_fit_elf() a call to q4nx_elf_arg_sizes() and the ONNX EP's NPU leg broke twice: the inc header never declared it (npu/forward/include/q4nx_pack.h does, and only the forward route happened to include it first), and onnx/ep's _npu_src list never compiled the file that defines it (npu/forward/src/q4nx_pack.c), so adding the declaration alone moves the failure from compile to link. Both lines are here; -DONEBIT_EP_NPU=ON builds 9 targets again and the forward route is unchanged. closes #874
PR Reviewer Guide 🔍(Review updated until commit b1a8805)Here are some key observations to aid the review process:
|
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY
This closes the break I filed as #874, and I verified the thing my report could not: the whole EP NPU configuration now
links, not just compiles.
cmake -DONEBIT_ORT=ON -DONEBIT_EP_NPU=ON -DONEBIT_NPU_RT_DIR=… -DONEBIT_NPU_ENGINE_INCS=…
[9/11] Linking CXX shared library onnx/ep/libonebit_ep.so
[10/11] Linking CXX executable onnx/ep/onebit_ep_qdq_proof
[11/11] Linking CXX executable onnx/ep/onebit_ep_proof
$ ./onnx/ep/onebit_ep_qdq_proof ./onnx/ep/libonebit_ep.so -> (the five quark cases, as before)
Both halves of the fix are load-bearing and you have them the right way round: #include "q4nx_pack.h" in
npu/ort/onebit_npu_gemm.cpp fixes the compile (‘q4nx_elf_arg_sizes’ was not declared in this scope — the inc file is
included before any header that declares it), and adding npu/forward/src/q4nx_pack.c to _npu_src fixes the link. My
issue named only the first because the syntax-only compile I could run at the time dies before the linker; your comment is
right that CI stayed green because neither NPU configuration is built there.
The comment in onnx/ep/CMakeLists.txt naming #874 at the point where the source is added is the part that keeps this from
coming back, and the include's own comment says which call site needs it (args_fit_elf(), #869).
Worth noting for the #874 follow-up: with this landed, the two ctest entries that live on this path (#853's
onebit_npu_gemm_q8_probe, #882's DEQUANT-independent work) can finally be rebuilt and run in the NPU configuration, so the
"cannot reproduce the device numbers" caveat I attached to #853 goes away.
|
Persistent review updated to latest commit b1a8805 |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY
At b1a88058a (merge of main into the head I reviewed; both files blob-identical, so the content is the content I verified).
Build success at this head.
Evidence: with -DONEBIT_EP_NPU=ON the whole EP NPU configuration now links — libonebit_ep.so, onebit_ep_qdq_proof and onebit_ep_proof all link (11/11 targets), and the QDQ proof runs to PASS … worst |d| = 0/0/0/0 LSB, per-K refused, peak RSS -5616 kB. Both halves are load-bearing: the #include "q4nx_pack.h" fixes the compile (args_fit_elf() declared), adding npu/forward/src/q4nx_pack.c to _npu_src fixes the link. This closes the break I filed as #874, which my syntax-only repro could not see past.
Root cause — it is two defects, not one
#869 (
7e64bbd) gaveI8Ctx::args_fit_elf()a call toq4nx_elf_arg_sizes(), and the ONNX EP's NPU leg broke intwo independent ways:
Undeclared at compile time.
q4nx_elf_arg_sizes()is declared innpu/forward/include/q4nx_pack.h:257.npu/forward/src/q4nx_forward.cpphappens to include that header before pulling innpu_forward/engine-src/npu_engine_i8ctx_inc.h, so the forward route compiles;npu/ort/onebit_npu_gemm.cpp:21does not, so the EP leg does not. The inc header is now self-contained —
q4nx_pack.hjoins the three q4nxheaders it already includes, and it is
extern "C"-guarded for C++ callers and pulls in nothing of its own.Unlinked at link time — which the issue's proposed one-line fix does not cover.
q4nx_elf_arg_sizes()is defined innpu/forward/src/q4nx_pack.c:470, andonnx/ep/CMakeLists.txt's_npu_srclist did not compile that file. With only the#includeadded,onebit_ep.solinks (a sharedlibrary tolerates the undefined symbol) but the two probe executables that share
_npu_srcdo not:So the fix is two lines: the include, and
q4nx_pack.cin_npu_src.q4nx_pack.cis self-contained (its ownheader plus
math.h/stdio.h/string.h), so nothing else comes with it.Measured before/after
Reproducer from the issue, on a clean worktree off
origin/main(23d6972):error: 'q4nx_elf_arg_sizes' was not declared in this scope(line 219), rc 1#includeonlyFull configuration, the one CI never compiles (
cmake -S onnx -B … -DONEBIT_EP_NPU=ON -DONEBIT_NPU_RT_DIR=…):ONEBIT_EP_NPU=ONbuildonebit_ep.so,ort_run,onebit_npu_gemm_probe,onebit_npu_gemm_q8_probe, …), no warningsq4nx_elf_arg_sizesin the probe binariesnm -C | grep -c 'T q4nx_elf_arg_sizes'= 1 each)npu/forward/src/q4nx_forward.cpp, the route that always compiled)Device known-answer probe on the array (the target #869 actually broke, and the one #853/#862 could not rebuild):
onebit_npu_gemm_q8_probe 1024 1024 32 5withONEBIT_EP_NPU_ELFS=32x1024x1024=…/KV_K1024_N1024/design.elf,plus the float probe at ctest's own args — one
npu-holdticket (01793677294039422075.qdq, token after 4 s,die 63 °C, released after 1 s,
amdxdnaerrors thereafter: 0):The device column is the number to read; the 102x "speedup" is an artifact of this build being unoptimized
(no
CMAKE_BUILD_TYPE, the stricter build for correctness), so the host loop it is measured against is-O0—at
-O2the same loop is ~2.5 ms (docs/onnx.md, #853). What the probe proves here is the part #874 is about:the target that could not be built on
mainnow builds, runs the array, and its exact int32 accumulatorsmatch the host element for element.
Not addressed, on purpose
The gap behind it —
.github/workflows/ci.ymlnever setsONEBIT_EP_NPU(orONEBIT_NPU), so this wholeconfiguration can go red on
mainwhile CI is green, exactly as #657 did. I did not add a CI job in this PR: bothconfigurations need the private NPU runtime (
rt.h/npu_rt.h), which CI does not have, so a job needs a stubruntime header first — a separate change with its own review, not a rider on a build fix.
Closes #874.