feat(bpu): D-Robotics RDK BPU backend with on-board compilation - #69
Open
lvyufeng wants to merge 1 commit into
Open
feat(bpu): D-Robotics RDK BPU backend with on-board compilation#69lvyufeng wants to merge 1 commit into
lvyufeng wants to merge 1 commit into
Conversation
lvyufeng
force-pushed
the
feat/s600-bpu-backend
branch
from
August 8, 2026 00:17
57740f7 to
6a676be
Compare
Merge the RDK BPU support into torch-fl as ACCELERATOR=bpu. This is a graph-compile backend (torch.compile(backend="bpu")) rather than per-op kernels: the BPU executes whole .hbm artifacts produced by hbdk4, so there are no PrivateUse1 operator registrations and eager ops reach cpu_fallback. Key decisions: - Eager: real device memory (hbUCPMallocCached) + CPU compute (no per-op BPU kernels). Tensors genuinely live in UCP memory so the compile path can be zero-copy where dtype matches. - Compile: on-board via box64-wrapped x86_64 hbdk4. No VM, no separate host, and no kernel rebuild — the earlier conclusion that a 4KB-page kernel was required turned out to be wrong; current box64 handles 64KB pages itself. - One torch-fl package: no separate torch_bpu repo. ACCELERATOR=bpu builds it, import torch_fl registers the backend. Build system: - CMakeLists.txt: bpu branch bypasses CUDA requirements, links Horizon runtime (libbpu, libhbucp, libhbdnn). - setup.py: bpu turns off all kernel sets (CUDA/FlagGems/MetaX/Ascend), installs torch_fl/backends/bpu/*.py. - csrc/runtime/accelerator/bpu/: UCP allocator + device/stream/event stubs. PyTorch 2.10 pin: - pyproject.toml + setup.py: require torch>=2.10,<2.11. The checked-in csrc/aten/generated/* is version-sensitive; a mismatch surfaces as compile errors, not resolver failures. - torch_fl/codegen_skip_ops.txt: add 16 named-tensor factory variants (empty.names, zeros.names, ...) removed in PyTorch 2.13. Delete their declarations from the four generated files (pure deletions, verified via git diff --numstat). These route to cpu_fallback, which is fine since a named tensor cannot live on a custom device anyway. Convolution registration (csrc/aten/register.cc): - aten::convolution dispatches PrivateUse1 to convolution_overrideable, and the only other kernel is a CompositeExplicitAutograd stub that raises. The boxed cpu_fallback cannot help: it moves args to CPU and redispatches the *same* op, landing back on the stub. Register explicit wrappers that call at::convolution_symint on CPU tensors. On-board hbdk4 (torch_fl/backends/bpu/compiler.py): - x86_emulator() probes box64/qemu-x86_64-static with a source-built box64 as FLAGOS_BPU_X86_EMULATOR. Distro box64 0.2.6 fails; current versions handle 64KB pages at runtime. - x86_env() sets BOX64_LD_LIBRARY_PATH (_mlir_libs for the hbdk4 .so tree), PYTHONPATH (stubs for numba/torch — both cause segfaults under box64 but are only imported, never executed on the ONNX path), and LD_PRELOAD (libhbtl.so with RTLD_GLOBAL — _hbdk.so needs hbtl symbols but doesn't list libhbtl in DT_NEEDED). - _compile_via_x86_emulator() tolerates post-compile AllocError (hbdk4 loads the artifact back for validation, which can fail in emulation after a complete .hbm is written). - scripts/setup_bpu_hbdk4.sh: idempotent setup (box64 build, x86 python, hbdk4 wheels, stubs). Zero-copy (torch_fl/backends/bpu/runtime.py): - _device_view(): wrap a flagos tensor's UCP storage in a numpy array in-place (verified: address == data_ptr(), writes through the view are visible to torch). No D2H copy inbound. Quantization still copies (dtype changes float32->int8), and hbm_runtime.run allocates its own outputs. Exit-time leak (csrc/runtime/allocator/caching_device_allocator.cc): - Skip block release on BPU, same as tsingmicro. The allocator is a function-local static, so its dtor runs from __run_exit_handlers after libhbucp's FINI_ARRAY may have released the heap. Calling torch_fl._C._empty_cache() before exit frees cleanly, confirming only the ordering is at fault. Tests (tests/unit/bpu/): - 8 files, 65 tests covering partition, qdq, decompose, freeze, splice, eager device ops (elementwise, matmul, reduction, conv2d forward/backward), zero-copy numpy views, and x86 environment construction. - All BPU tests pass (65); the 4 profiler failures on this board predate this branch (they need libcupti and real GPU kernels). ruff clean. Measured performance: 6-layer conv stack @224x224, 72.06ms eager -> 3.75ms BPU (19.2x), int8 quantized with ~3% relative error. Docs: docs/bpu.md covers architecture, quantization, weight freezing, on-board hbdk4 setup, calibration, environment variables, and known limits. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lvyufeng
force-pushed
the
feat/s600-bpu-backend
branch
from
August 8, 2026 05:21
6a676be to
5d27f3b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merges D-Robotics RDK BPU support into torch-fl as
ACCELERATOR=bpu— one torch-fl package, no separate torch_bpu repo, no VM dependency.Key changes
ACCELERATOR=bpu, skip CUDA/kernel requirementshbUCPMallocCached) for real device memory, device/stream/event stubscpu_fallback;convolution_overrideablehas explicit wrappers (the boxed fallback cannot serve it — it redispatches the same op and lands back on the raising stub)torch.compile(backend="bpu")auto-registered, partitions aten graph → ONNX → hbdk4 → .hbm → hbm_runtimescripts/setup_bpu_hbdk4.shautomates the setup.Testing
_empty_cache()before exit frees the same blocks cleanly, which confirms only the ordering is at fault)ruff check/ruff format --checkcleantest_profiler_privateuse1.pyfail on this board — they need libcupti and real GPU kernel events. That file is untouched by this branch; the failures come from feat(profiler): torch-cuda parity for PrivateUse1 — flows, device time, kernel metadata #55 and are not reproducible without a GPU.torch-2.13 compat fix (affects all platforms)
PyTorch 2.13 removed named tensors (
at::DimnameListno longer exists), but checked-in generated files still declared 16 named-tensor factory variants. This blocked every platform on 2.13. Fixed by adding them tocodegen_skip_ops.txtand surgically deleting from the four generated files (pure deletions, 0 additions, verified withgit diff --numstat). Did not re-run full codegen: CI pins torch 2.10, and a full regen would bake in 2.13-only signature drift + silently emptyflaggems_python_kernels.ccwhen flag_gems is not installed.Docs
docs/bpu.md: architecture rationale, on-board hbdk4 setup, quantization, calibration, env vars, known limitsREADME.md: BPU build instructions, new env varsBenchmark
6-layer conv stack @ 224×224, measured on-board with artifacts compiled on-board: 3.75 ms (BPU) vs 72.06 ms (eager CPU) = 19.2×, int8 quantized with ~3% relative error. Toy nets are a wash — submission overhead dominates.
Dependencies
None beyond the board image.
libhbucp/libbpuship at/usr/hobot/libwith headers at/usr/include/hobot, so there is no SDK root to configure. hbdk4 is optional: without it the backend warns and runs every partition on the CPU, so the install stays usable.