Skip to content

Run FastFlowLM on the HRX amdxdna runtime - #602

Merged
zaneni6 merged 8 commits into
ROCm:mainfrom
Abhishek-Varma:hrx_native_pr
Aug 7, 2026
Merged

Run FastFlowLM on the HRX amdxdna runtime#602
zaneni6 merged 8 commits into
ROCm:mainfrom
Abhishek-Varma:hrx_native_pr

Conversation

@Abhishek-Varma

@Abhishek-Varma Abhishek-Varma commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Purpose: make the NPU dispatch backend selectable at build time via a single CMake flag (FLM_USE_HRX: 0 = XRT, the default; 1 = HRX amdxdna), so the FastFlowLM application (the flm binary and its runner/server/benchmark entry points) builds and runs against either the production XRT + aiebu runtime or the HRX amdxdna runtime from one source tree. XRT is the default; HRX is opt-in. Prebuilt NPU engine libraries ship per backend for the full model matrix, and the HRX path is wired to a pinned, reproducible HRX release artifact.

Motivation

FastFlowLM must keep building and running on the production XRT + aiebu runtime while also supporting the HRX (amdxdna) runtime as a drop-in alternative. Rather than fork the tree per runtime, a build flag selects the backend behind a neutral flm_rt alias namespace, so device/buffer/kernel/run/dispatch code is written once and compiles against either runtime. This keeps XRT the default and unaffected (so the PR stays mergeable and easy to sync with main) while HRX is available opt-in for validation and bring-up. HRX engines are compiled against a thin namespace hrx layer over libhrx (hrx_cpp/hrx_cpp.hpp) that bypasses the aiebu assembler; XRT engines use the existing XRT + aiebu path.

Technical Details

  • Add the FLM_USE_HRX CMake option (default OFF = XRT) plus a FLM_USE_HRX=1 compile definition on the HRX build. The flag drives runtime headers/namespace, discovery/link, the engine-lib directory, and portable bundling; FLM_RUNTIME_NAME resolves to xrt or hrx.
  • Introduce src/include/device_runtime.hpp: a neutral flm_rt alias that maps to xrt when FLM_USE_HRX is undefined and to hrx when defined. App-facing runtime references across models/runner/server/tests are written as flm_rt:: (device, bo, ext::bo, kernel, hw_context, run, runlist, xclbin, info::device), so one source tree builds against either runtime.
  • Split npu_utils.hpp into a thin dispatcher over npu_utils_xrt.hpp (the main XRT implementation: ELF/module handling via aiebu) and npu_utils_hrx.hpp (HRX: control code from npu_sequence::dump() into an amdxdna direct executable, with a host patch table replacing aiebu-emitted relocations). buffer.hpp keeps the FLM_DEVICE_BUFFER device-buffer path and gates buffer sync per backend — XRT bo::sync(XCL_BO_SYNC_BO_TO/FROM_DEVICE) vs HRX flush()/invalidate().
  • main.cpp preloads the bundled XRT libraries (libxrt_core/libxrt_coreutil/libxrt_driver_xdna) only on the XRT + Linux build (#if !defined(FLM_USE_HRX) && !defined(_WIN32)); the HRX path has no equivalent preload requirement, and Windows retains its own DLL loading.
  • Runtime discovery/link branches by flag: XRT is found via pkg-config with fallbacks to /opt/xilinx/xrt and an optional build-from-source, linking xrt_coreutil (+ aiebu for the ELF assembler used by npu_utils_xrt); HRX is consumed from its public CMake package via find_package(hrx CONFIG REQUIRED), linking hrx::hrx.
  • Reorganize the prebuilt engine libraries into per-backend directories — src/lib/xrt/ (XRT engines + aiebu, XRT-only) and src/lib/hrx/ (HRX engines) — for the full model matrix: Qwen3, Llama3, Qwen2, Phi4, Gemma3, Gemma3-Vision, Gemma4e, Gemma-Embedding, LFM2, Nanbeige, GPT-OSS, Qwen2VL, Qwen3VL, Qwen3.5VL, and Whisper. The flag selects lib/<backend>; shared third-party libs stay in src/lib/. Windows .dll/.lib follow the same xrt/hrx layout.
  • Portable bundling (FLM_PORTABLE_BUILD) is backend-aware through flm-wrapper.sh.in (configured per backend): XRT sets XILINX_XRT, creates the lib/x86_64-linux-gnu multiarch symlinks the loader expects, and rewrites engine-lib RUNPATH to $ORIGIN via patchelf; HRX simply exports LD_LIBRARY_PATH.
  • The HRX path consumes a pinned HRX release artifact instead of a hard-coded source tree.

Test Plan

  • Build the default (XRT) backend and the HRX backend (-DFLM_USE_HRX=ON) from the same tree; confirm each links the expected runtime (libxrt_coreutil + lib/xrt vs libhrx + lib/hrx) and runs a smoke inference on the NPU.
  • Compare XRT vs HRX greedy correctness across the model matrix with identical prompts, and diff the generated output.
  • Run XRT and HRX 1k-context benchmarks across the same matrix through the flm benchmark path.

Test Result

  • Built and ran both backends on accel0: the default XRT build links libxrt_coreutil + src/lib/xrt, and the HRX build (-DFLM_USE_HRX=ON) links libhrx + src/lib/hrx; both answer "2 + 2 = 4".
  • HRX release (pinned): jtuyls/hrx@flm-hrx-amdxdna-v2026.07.20, asset hrx-amdxdna-2026.07.20-amdxdna-hal-native-rel-fcaecde-linux-x86_64.tar.zst.
  • The XRT-vs-HRX numerical-parity and 1k-benchmark results below were captured on the hrx-amdxdna-2026.07.07-... asset. Benchmark input: 1k JSON with max_length=1024 and iterations=5 (values are means). XRT baseline: FLM_xrt_main @ main with the RMSNorm pointer-hoisting fixes cherry-picked (gemma + gpt_oss); the XRT harness runs the same application entry points. No xclbin rebuilds on either side.
  • Greedy correctness was byte-identical HRX == XRT for every decode model that produced diffable output (23 of 24 rows directly; gemma4-it:e4b verified at the engine level via e2b).
  • Auxiliary parity: embed-gemma:300m embeddings are bit-identical across backends; whisper-v3:turbo matches within Whisper's own non-deterministic decode variance.

1k Benchmark Results - XRT vs HRX - LINUX (Driver 2.23.0)

Model XRT TTFT s HRX TTFT s XRT prefill tok/s HRX prefill tok/s XRT decode tok/s HRX decode tok/s
deepseek-r1-0528:8b 3.0771 3.228 315.7323 301.115 10.5393 10.3053
deepseek-r1:8b 3.0809 3.2041 315.6923 303.5423 11.0001 10.7981
gemma3:1b 1.3062 1.2879 750.4893 764.377 36.133 33.4674
gemma3:4b 1.8636 1.9913 525.0627 491.3767 17.1696 16.079
gemma4-it:e2b 1.4302 1.5512 684.4327 632.656 20.1611 18.6656
gemma4-it:e4b 2.273 2.3614 430.5633 415.3733 11.4245 10.9089
gpt-oss-sg:20b 5.1381 5.0229 201.5893 206.566 19.1566 18.448
gpt-oss:20b 5.1441 5.032 201.4073 206.3203 19.0604 18.4768
lfm2-trans:2.6b 1.4012 1.5397 699.845 637.1763 29.0367 28.4334
lfm2.5-it:1.2b 0.6663 0.7799 1475.26 1276.2233 61.3016 58.9528
lfm2.5-tk:1.2b 0.6677 0.788 1472.1567 1268.19 60.1503 54.7446
lfm2:1.2b 0.6557 0.7245 1494.4767 1384.5367 62.5004 57.3767
lfm2:2.6b 1.4932 1.5662 656.1473 626.9897 29.0732 28.2613
llama3.1:8b 3.0757 3.2058 326.2863 313.263 10.9779 10.6625
llama3.2:1b 0.659 0.7469 1526.0333 1362.3233 59.2927 54.3272
llama3.2:3b 1.6425 1.7694 612.6277 567.866 23.4931 22.2932
medgemma1.5:4b 1.8495 2.0224 529.144 484.187 17.0747 16.0736
medgemma:4b 1.7494 2.0089 559.8197 487.297 17.1725 16.0792
nanbeige4.1:3b 1.9442 2.0255 514.8987 493.8817 21.3062 20.4847
phi4-mini-it:4b 1.718 1.8897 565.9747 515.5293 19.633 18.8681
qwen2.5-it:3b 1.6371 1.6987 610.9583 588.4297 23.6126 22.6982
qwen2.5vl-it:3b 1.6955 1.8452 584.0647 536.5083 23.8405 22.212
qwen3-it:4b 2.1865 2.3113 448.356 422.95 18.2857 17.5775
qwen3-tk:4b 2.448 2.5899 433.027 409.044 17.623 16.9092
qwen3.5:0.8b 0.8776 0.9336 1117.9833 1060.4027 35.4598 32.6429
qwen3.5:2b 1.1177 1.2119 876.6547 814.0837 22.7146 21.2391
qwen3.5:4b 2.4869 2.5765 393.763 380.6257 12.3635 11.9897
qwen3.5:9b 3.3264 3.4478 294.121 284.071 7.6199 7.4454
qwen3.6-moe:35b-a3b 8.9214 8.3677 109.6023 117.0307 12.6043 12.2264
qwen3:0.6b 0.7221 0.7645 1362.5333 1292.2367 75.6586 65.2032
qwen3:1.7b 1.1016 1.1186 894.6733 881.4077 38.7787 36.0585
qwen3:4b 2.1745 2.2901 452.311 429.0097 18.2924 17.3263
qwen3:8b 3.0281 3.2032 324.4347 306.4553 10.5634 10.2659
qwen3vl-it:4b 2.1253 2.2492 459.6717 435.169 18.1845 17.4567
translategemma:4b 1.8419 2.0514 532.0083 477.456 17.2352 16.0904

1k Benchmark Results - XRT vs HRX - WINDOWS (Driver 32.0.203.314)

Model XRT TTFT s HRX TTFT s XRT prefill tok/s HRX prefill tok/s XRT decode tok/s HRX decode tok/s
nanbeige4.1:3b 1.929 2.381 520.100 420.620 18.960 13.940
qwen3vl-it:4b 2.149 2.749 456.150 355.800 16.090 11.610
gemma4-it:e2b 1.602 2.118 613.220 463.220 18.630 14.040
gemma4-it:e4b 2.451 3.420 400.600 286.910 10.540 7.960
qwen3.5:0.8b 0.938 1.235 1053.190 799.900 38.010 31.190
qwen3.5:2b 1.169 1.585 842.200 620.680 23.420 16.230
qwen3.5:4b 2.519 3.175 389.660 320.230 12.460 11.330
qwen3.5:9b 3.330 3.342 294.290 293.230 7.640 7.660
qwen3.6-moe:35b-a3b 28.618 28.061 34.130 34.810 12.590 12.660
lfm2:1.2b 0.762 0.741 1293.490 1329.880 42.530 44.940
lfm2:2.6b 1.486 1.476 660.180 663.830 22.910 23.770
lfm2-trans:2.6b 1.529 1.512 641.370 648.480 22.340 22.530
lfm2.5-it:1.2b 0.784 0.740 1258.520 1327.450 46.020 45.030
lfm2.5-tk:1.2b 0.733 0.774 1341.340 1273.480 45.850 43.800
phi4-mini-it:4b 1.766 1.806 552.260 540.000 18.580 17.690
gemma3:1b 1.610 1.551 610.230 632.760 34.180 33.480
gemma3:4b 2.039 2.071 482.100 474.350 16.270 15.870
translategemma:4b 1.995 2.073 492.520 472.800 16.820 16.180
medgemma:4b 1.995 2.045 492.120 479.960 16.590 16.240
medgemma1.5:4b 2.022 2.042 485.160 480.500 16.570 16.240
llama3.2:1b 0.740 0.764 1365.210 1322.890 52.460 51.480
llama3.2:3b 1.601 1.640 629.050 614.170 21.500 20.700
llama3.1:8b 2.833 2.854 354.780 352.250 10.200 10.070
deepseek-r1:8b 2.844 2.762 342.530 352.420 10.180 10.270
deepseek-r1-0528:8b 3.007 3.051 323.780 319.350 9.430 9.400
qwen3:0.6b 0.911 0.922 1088.040 1075.370 53.580 52.150
qwen3:1.7b 1.228 1.233 805.830 801.320 31.300 30.170
qwen3:4b 2.271 2.234 433.350 440.730 15.670 15.890
qwen3:8b 2.908 3.095 337.930 318.080 9.670 9.100
qwen3-tk:4b 2.591 2.646 409.850 401.510 14.870 14.860
qwen3-it:4b 2.258 2.171 433.780 450.580 15.560 16.010
gpt-oss:20b 6.848 6.986 151.390 148.310 17.960 17.600
gpt-oss-sg:20b 6.627 6.834 156.340 151.640 17.760 17.610
qwen2.5-it:3b 1.757 1.670 570.780 598.990 19.910 20.430
qwen2.5vl-it:3b 1.726 1.721 573.930 576.620 20.080 19.720

Submission Checklist

  • flm (runner/server/benchmark + binary) builds and runs on both backends from one source tree via FLM_USE_HRX (XRT default; HRX opt-in), with the runtime selected behind the flm_rt alias.
  • Prebuilt engine libraries reorganized into per-backend src/lib/xrt and src/lib/hrx for the full model matrix (Windows .dll/.lib follow the same layout); portable $ORIGIN RUNPATH, no developer-absolute paths in committed binaries.
  • HRX path consumes a pinned, checksum-verified HRX release artifact via hrx-integration/; missing-artifact failures are clear.
  • XRT vs HRX greedy numerical validation passed across the model matrix (byte-identical; gemma4-it:e4b engine-level via e2b).
  • XRT vs HRX 1k benchmarks completed across the matrix; auxiliary embedding + ASR parity checked.
  • Add NPU CI that runs numerical and benchmark checks across all supported models on both backends when hardware runners are available.

@Abhishek-Varma
Abhishek-Varma force-pushed the hrx_native_pr branch 4 times, most recently from 8cbfc51 to 6695b50 Compare July 17, 2026 06:29
@Abhishek-Varma
Abhishek-Varma force-pushed the hrx_native_pr branch 9 times, most recently from 99a3d53 to f2c2dbe Compare July 28, 2026 09:37
Abhishek-Varma added a commit to Abhishek-Varma/FastFlowLM_JT that referenced this pull request Aug 5, 2026
Rebased onto latest main: reintroduces XRT as the default, selectable NPU
dispatch backend alongside HRX behind a CMake flag (FLM_USE_HRX: 0=XRT
default, 1=HRX), so PR ROCm#602 stays mergeable and easy to sync with main while
HRX remains opt-in. Squashes the prior HRX PR commits + the flag work into a
single change on top of origin/main.

- CMake: FLM_USE_HRX option + compile definition; runtime discovery/link/
  bundle branch between XRT (pkg-config/manual/fetch, xrt_coreutil + aiebu)
  and HRX (find_package(hrx), hrx::hrx); flag-selected engine lib dir.
- device_runtime.hpp: neutral flm_rt alias -> xrt or hrx; app-facing hrx::
  replaced with flm_rt:: across models/runner/server/tests.
- npu_utils.hpp split into _xrt (from main) / _hrx (PR) + dispatcher;
  buffer.hpp bo sync gated (xrt sync() vs hrx flush/invalidate).
- main.cpp: XRT libxrt preload restored under !FLM_USE_HRX.
- Engine libs reorganized into src/lib/xrt (refreshed from latest main) and
  src/lib/hrx (aiebu XRT-only); wrapper + src/test/common.mk backend-aware.
- Folds in main updates: modelscope ctor arg (rest_handler), model_info.json
  install, refreshed gpt_oss/qwen3_6_moe XRT engine libs and xclbins.

Verified on accel0 against latest main: default XRT build links
libxrt_coreutil + lib/xrt and HRX build (-DFLM_USE_HRX=ON) links libhrx +
lib/hrx; both answer "2 + 2 = 4".

Co-authored-by: Cursor <cursoragent@cursor.com>
Abhishek-Varma added a commit to Abhishek-Varma/FastFlowLM_JT that referenced this pull request Aug 5, 2026
Rebased onto latest main: reintroduces XRT as the default, selectable NPU
dispatch backend alongside HRX behind a CMake flag (FLM_USE_HRX: 0=XRT
default, 1=HRX), so PR ROCm#602 stays mergeable and easy to sync with main while
HRX remains opt-in. Squashes the prior HRX PR commits + the flag work into a
single change on top of origin/main.

- CMake: FLM_USE_HRX option + compile definition; runtime discovery/link/
  bundle branch between XRT (pkg-config/manual/fetch, xrt_coreutil + aiebu)
  and HRX (find_package(hrx), hrx::hrx); flag-selected engine lib dir.
- device_runtime.hpp: neutral flm_rt alias -> xrt or hrx; app-facing hrx::
  replaced with flm_rt:: across models/runner/server/tests.
- npu_utils.hpp split into _xrt (from main) / _hrx (PR) + dispatcher;
  buffer.hpp bo sync gated (xrt sync() vs hrx flush/invalidate).
- main.cpp: XRT libxrt preload restored under !FLM_USE_HRX.
- Engine libs reorganized into src/lib/xrt (refreshed from latest main) and
  src/lib/hrx (aiebu XRT-only); wrapper + src/test/common.mk backend-aware.
- Folds in main updates: modelscope ctor arg (rest_handler), model_info.json
  install, refreshed gpt_oss/qwen3_6_moe XRT engine libs and xclbins.

Verified on accel0 against latest main: default XRT build links
libxrt_coreutil + lib/xrt and HRX build (-DFLM_USE_HRX=ON) links libhrx +
lib/hrx; both answer "2 + 2 = 4".

Co-authored-by: Cursor <cursoragent@cursor.com>
Abhishek-Varma added a commit to Abhishek-Varma/FastFlowLM_JT that referenced this pull request Aug 5, 2026
Rebased onto latest main: reintroduces XRT as the default, selectable NPU
dispatch backend alongside HRX behind a CMake flag (FLM_USE_HRX: 0=XRT
default, 1=HRX), so PR ROCm#602 stays mergeable and easy to sync with main while
HRX remains opt-in. Squashes the prior HRX PR commits + the flag work into a
single change on top of origin/main.

- CMake: FLM_USE_HRX option + compile definition; runtime discovery/link/
  bundle branch between XRT (pkg-config/manual/fetch, xrt_coreutil + aiebu)
  and HRX (find_package(hrx), hrx::hrx); flag-selected engine lib dir.
- device_runtime.hpp: neutral flm_rt alias -> xrt or hrx; app-facing hrx::
  replaced with flm_rt:: across models/runner/server/tests.
- npu_utils.hpp split into _xrt (from main) / _hrx (PR) + dispatcher;
  buffer.hpp bo sync gated (xrt sync() vs hrx flush/invalidate).
- main.cpp: XRT libxrt preload restored under !FLM_USE_HRX.
- Engine libs reorganized into src/lib/xrt (refreshed from latest main) and
  src/lib/hrx (aiebu XRT-only); wrapper + src/test/common.mk backend-aware.
- Folds in main updates: modelscope ctor arg (rest_handler), model_info.json
  install, refreshed gpt_oss/qwen3_6_moe XRT engine libs and xclbins.

Verified on accel0 against latest main: default XRT build links
libxrt_coreutil + lib/xrt and HRX build (-DFLM_USE_HRX=ON) links libhrx +
lib/hrx; both answer "2 + 2 = 4".

Co-authored-by: Cursor <cursoragent@cursor.com>
Abhishek-Varma added a commit to Abhishek-Varma/FastFlowLM_JT that referenced this pull request Aug 5, 2026
Rebased onto latest main: reintroduces XRT as the default, selectable NPU
dispatch backend alongside HRX behind a CMake flag (FLM_USE_HRX: 0=XRT
default, 1=HRX), so PR ROCm#602 stays mergeable and easy to sync with main while
HRX remains opt-in. Squashes the prior HRX PR commits + the flag work into a
single change on top of origin/main.

- CMake: FLM_USE_HRX option + compile definition; runtime discovery/link/
  bundle branch between XRT (pkg-config/manual/fetch, xrt_coreutil + aiebu)
  and HRX (find_package(hrx), hrx::hrx); flag-selected engine lib dir.
- device_runtime.hpp: neutral flm_rt alias -> xrt or hrx; app-facing hrx::
  replaced with flm_rt:: across models/runner/server/tests.
- npu_utils.hpp split into _xrt (from main) / _hrx (PR) + dispatcher;
  buffer.hpp bo sync gated (xrt sync() vs hrx flush/invalidate).
- main.cpp: XRT libxrt preload restored under !FLM_USE_HRX.
- Engine libs reorganized into src/lib/xrt (refreshed from latest main) and
  src/lib/hrx (aiebu XRT-only); wrapper + src/test/common.mk backend-aware.
- Folds in main updates: modelscope ctor arg (rest_handler), model_info.json
  install, refreshed gpt_oss/qwen3_6_moe XRT engine libs and xclbins.

Verified on accel0 against latest main: default XRT build links
libxrt_coreutil + lib/xrt and HRX build (-DFLM_USE_HRX=ON) links libhrx +
lib/hrx; both answer "2 + 2 = 4".

Co-authored-by: Cursor <cursoragent@cursor.com>
Rebased onto latest main: reintroduces XRT as the default, selectable NPU
dispatch backend alongside HRX behind a CMake flag (FLM_USE_HRX: 0=XRT
default, 1=HRX), so PR ROCm#602 stays mergeable and easy to sync with main while
HRX remains opt-in. Squashes the prior HRX PR commits + the flag work into a
single change on top of origin/main.

- CMake: FLM_USE_HRX option + compile definition; runtime discovery/link/
  bundle branch between XRT (pkg-config/manual/fetch, xrt_coreutil + aiebu)
  and HRX (find_package(hrx), hrx::hrx); flag-selected engine lib dir.
- device_runtime.hpp: neutral flm_rt alias -> xrt or hrx; app-facing hrx::
  replaced with flm_rt:: across models/runner/server/tests.
- npu_utils.hpp split into _xrt (from main) / _hrx (PR) + dispatcher;
  buffer.hpp bo sync gated (xrt sync() vs hrx flush/invalidate).
- main.cpp: XRT libxrt preload restored under !FLM_USE_HRX.
- Engine libs reorganized into src/lib/xrt (refreshed from latest main) and
  src/lib/hrx (aiebu XRT-only); wrapper + src/test/common.mk backend-aware.
- Folds in main updates: modelscope ctor arg (rest_handler), model_info.json
  install, refreshed gpt_oss/qwen3_6_moe XRT engine libs and xclbins.

Verified on accel0 against latest main: default XRT build links
libxrt_coreutil + lib/xrt and HRX build (-DFLM_USE_HRX=ON) links libhrx +
lib/hrx; both answer "2 + 2 = 4".

Co-authored-by: Cursor <cursoragent@cursor.com>
Abhishek-Varma and others added 3 commits August 5, 2026 05:05
Bump the HRX amdxdna pin to flm-hrx-amdxdna-v2026.07.30 (Linux + Windows
tags/assets/sha256) and refresh src/lib/hrx/*.so with the 23 engine
libraries rebuilt from FastFlowLM_IRON (branch hrx_native_flag) against
that pin. Built with -DFLM_USE_HRX=ON; each lib links libhrx.

Validated on the NPU: 2+2 smoke passes and greedy decode is an exact
match vs the XRT reference for gemma3:1b, qwen3:0.6b, and lfm2.5-it:1.2b.

Co-authored-by: Cursor <cursoragent@cursor.com>
…olchain

Rebuild the 23 HRX engine .so with gcc-toolset-13 (Red Hat GCC 13.3.1)
inside the manylinux_2_28 image so they match the rocm_npu_branch runtime
environment exactly: GLIBC floor 2.22, GLIBCXX 3.4.22, CXXABI 1.3.11,
libpthread/libgomp/libmvec deps, boost-free. Supersedes the Ubuntu 24.04
(glibc 2.39 / GLIBCXX 3.4.32) build, which would not load on EL8.

2+2 smoke re-verified on the NPU for gemma3:1b, qwen3:0.6b, lfm2.5-it:1.2b.

Co-authored-by: Cursor <cursoragent@cursor.com>
…against HRX v2026.07.30

Regenerated the 23 FLM_DLL engine .dll/.lib on Windows (MSVC 14.44, VS2022)
from FastFlowLM_IRON@hrx_native_flag with -DFLM_USE_HRX=ON. Verified each links
hrx.dll (no xrt_coreutil/aiebu) and is boost-free (no boost_* dependency).
flm.exe rebuilt against these; gemma3:1b, qwen3.5:0.8b, lfm2.5-it:1.2b all pass
the 2+2 smoke on the amdxdna NPU.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zaneni6

zaneni6 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Hi! @Abhishek-Varma

I just tested the portable artifacts, which I believe were built against XRT, on both Windows and Linux.

The Windows portable build looks good from my testing and I didn't run into any issues.

On the Linux portable build, however, both flm run llama3.2:1b and flm serve fail with the following library error:

zani@xsjnuckrck04:/scratch/zani/FLM_portable/HRX_pr$ ./flm run llama3.2
Error: No such library '/scratch/zani/FLM_portable/HRX_pr/lib/x86_64-linux-gnu/libxrt_core.so.2'

I didn't see this issue with the latest release build, so it seems specific to this portable artifact.

Abhishek-Varma and others added 2 commits August 5, 2026 21:57
The portable XRT tarball shipped only libxrt_coreutil (flm's single link-time
NEEDED entry). XRT additionally dlopens libxrt_core.so.2 and the
libxrt_driver_xdna plugin at run time via a path it builds as
$XILINX_XRT/lib/x86_64-linux-gnu/<lib>, so those libraries were absent from the
self-contained tree and `flm run` / `flm serve` failed with:

    Error: No such library '.../lib/x86_64-linux-gnu/libxrt_core.so.2'

Bundle the complete libxrt*.so* set from the discovered XRT lib dir, re-root
each real lib's RUNPATH at $ORIGIN so they resolve one another inside lib/, and
mirror them under lib/x86_64-linux-gnu so XRT's internal lookup succeeds
(mirrors the XRT bundling on main). libxrt is now excluded from the flm
dependency closure since this explicit block owns the full runtime set.

Reported on PR ROCm#602 (portable Linux artifact).

Co-authored-by: Cursor <cursoragent@cursor.com>
…dditive

Rework the Linux install/bundling so the XRT build uses the exact same
mechanisms it always has and every HRX-specific step is gated behind
FLM_USE_HRX, instead of a single backend-agnostic closure plus an XRT
add-on.

- Branch the non-Windows bundling by backend:
    * XRT portable -> explicit libxrt*/boost/FFTW copy + $ORIGIN patchelf +
      multiarch mirror (the XRT runtime is dlopen'd, so it cannot be captured
      by a link-time dependency closure).
    * XRT .deb -> plain install; deps resolved via ${shlibs:Depends} +
      libxrt-npu2.
    * HRX (portable + .deb) -> file(GET_RUNTIME_DEPENDENCIES) closure that
      bundles libhrx and the engine .so private deps (libgomp/libmvec).
- Gate the engine .so RUNPATH patchelf under FLM_USE_HRX; XRT engine libs are
  shipped unmodified (the portable wrapper already exposes ./lib via
  LD_LIBRARY_PATH).
- CI is XRT-only: drop the unused HRX artifact fetch / CMAKE_PREFIX_PATH /
  zstd from ubuntu-build, and the HRX fetch + hrx.dll bundling from
  windows-build. ubuntu-build now matches upstream.
- Reword comments that compared against the "main" branch.

Verified on NPU (accel0): both backends configure, build, and run
qwen3:0.6b correctly (2 + 2 = 4).

Co-authored-by: Cursor <cursoragent@cursor.com>
@Abhishek-Varma
Abhishek-Varma marked this pull request as ready for review August 6, 2026 13:12
@Abhishek-Varma

Copy link
Copy Markdown
Contributor Author

Hi @zaneni6 - thanks for testing the patch. Can you try with the latest state of the PR?

If everything looks okay, we can go ahead with merging it (CC: @tawei-amd ).

@zaneni6

zaneni6 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Hi @zaneni6 - thanks for testing the patch. Can you try with the latest state of the PR?

If everything looks okay, we can go ahead with merging it (CC: @tawei-amd ).

Hi @Abhishek-Varma thanks for your update! Tried with the latest linux portable one, got a different lib error:

zani@xsjnuckrck04:/scratch/zani/FLM_portable/HRX_pr_update$ ./flm list
/scratch/zani/FLM_portable/HRX_pr_update/flm-real: error while loading shared libraries: libavformat.so.61: cannot open shared object file: No such file or directory
zani@xsjnuckrck04:/scratch/zani/FLM_portable/HRX_pr_update$ ./flm run llama3.2:1b
/scratch/zani/FLM_portable/HRX_pr_update/flm-real: error while loading shared libraries: libavformat.so.61: cannot open shared object file: No such file or directory

…e builds

The rebase/squash dropped main's portable FFmpeg (and zlib) static-build
logic, so the portable XRT tarball dynamically linked the build host's
FFmpeg. On other machines flm-real then failed at startup with:

    error while loading shared libraries: libavformat.so.61: cannot open
    shared object file: No such file or directory

Restore main's behavior for the XRT path so the portable artifact is
self-contained again:

- Discovery: for FLM_PORTABLE_BUILD (non-HRX, Linux), fetch and build
  FFmpeg (n7.1) and zlib (v1.3.1) as static archives; set
  FFMPEG_BUILT_FROM_SOURCE / ZLIB_BUILT_FROM_SOURCE.
- Deps: only pkg-config the system FFmpeg when NOT building it statically;
  skip the GPL readline/ncurses for portable builds (the CLI already has a
  plain line-reader fallback under the FASTFLOWLM_USE_READLINE guard), so
  the tarball carries no libavformat*/libreadline runtime dependency.
- Link: link the static libav*/libsw* archives + zlib for portable;
  gate FASTFLOWLM_USE_READLINE + readline/ncurses on NOT FLM_PORTABLE_BUILD.
- Bundling: search the standard multiarch/system dirs for
  libboost_program_options.so* independently of where XRT was found, so
  Boost is bundled even when XRT lives under /opt/xilinx.

Verified on NPU (accel0): portable XRT build links no libav*/readline
(readelf NEEDED), the staged tree resolves all deps from bundled lib/,
and qwen3:0.6b answers "2 + 2 = 4".

Reported on PR ROCm#602 (portable Linux artifact).

Co-authored-by: Cursor <cursoragent@cursor.com>
@Abhishek-Varma

Copy link
Copy Markdown
Contributor Author

Hi @zaneni6 - thank you for testing! Can you confirm if the issue stands resolved now?

@zaneni6

zaneni6 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Hi @zaneni6 - thank you for testing! Can you confirm if the issue stands resolved now?

Sure! But it looks like the CI is currently down. I'll do it once the artifacts have been generated.

Review follow-up: keep the XRT build byte-for-byte equivalent to main and
confine every deviation to the HRX delta.

- CMakeLists (non-portable/.deb): install engine .so directly into <prefix>/lib
  with flm RPATH $ORIGIN/../lib, exactly like main. The <prefix>/lib/flm split
  (engines separated from the bundled libhrx) is now gated behind FLM_USE_HRX,
  so only the HRX layout uses it.
- debian/rules: drop the override_dh_shlibdeps block (now identical to main). It
  was only needed to locate the bundled libhrx during HRX .deb packaging; the
  XRT .deb resolves XRT from libxrt-npu2 and its engine libs from <prefix>/lib
  just as main does.
- windows-build.yml: remove an unnecessary comment (now identical to main).
- main.cpp: drop incidental blank-line changes; the only remaining delta vs main
  is the functional XRT/HRX preload gating.
- test/common.mk: drop an incidental blank line.

Verified: non-portable XRT install stages 23 engine libs into /opt/fastflowlm/lib
with flm RPATH $ORIGIN/../lib (matches main); portable and non-portable both
configure cleanly.

Co-authored-by: Cursor <cursoragent@cursor.com>
@Abhishek-Varma

Copy link
Copy Markdown
Contributor Author

Hi @zaneni6 - the CI looks fine now, can you please try out the latest patch? I tried pulling in the Linux portable locally and the issue seems resolved. In case it persists, let me know and I can take a stab at it - else it'd be nice to get this in. :)

@zaneni6
zaneni6 merged commit a432a07 into ROCm:main Aug 7, 2026
10 checks passed
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.

2 participants