Raw dependency graph data (JSON)
ncnn
Author: Ludovic HENRY ludovic.henry@qti.qualcomm.com
Date: 2026-08-30
Readiness: Blue
Optimization level: partial
Scope: RISC-V (riscv64/linux) support status for ncnn
Audience: Technical leadership, resource allocation strategy
Verification policy: Every claim is cross-referenced to a primary upstream source. Items that could not be verified against a second source are marked [NEEDS VERIFICATION].
1. Project Overview
ncnn is a high-performance neural network inference framework optimized for mobile and embedded deployment. It is written in C++ with no external runtime dependencies for inference, supports a wide range of neural network operators, and provides model conversion tools from ONNX, Caffe, and other formats. The project is licensed under BSD 3-Clause, copyright Tencent 2017.
Governance: Corporate BDFL. A single maintainer, GitHub handle nihui, a Tencent employee confirmed via GitHub org membership, drives approximately 2,690 of roughly 3,100 total commits (approximately 87%). There is no CODEOWNERS file, no MAINTAINERS file, no TSC, and no documented contribution process beyond acknowledgements in CONTRIBUTING.md. Secondary contributors include BUG1989 (Axera, int8 quantization), zchrissirhcz (71 commits, general), and tpoisonooo (37 commits, general). No CLA is documented.
RISE Project involvement: None. ncnn is not a named RISE project, has no RISE blog coverage, is not tracked in the RISE AI/ML Working Group projects list, and does not use RISE riscv64 CI runners. The RISE wheel builder redirects ncnn PyPI queries directly to upstream PyPI rather than maintaining a separate build. SpacemiT (a RISE member) hardware appears in ncnn benchmarks, and SiFive (a RISE member) U74 cores power the VisionFive2 board used in ncnn CI, but neither constitutes RISE project involvement.
Community stance on new ports: Pragmatically open but nihui-gated. No formal RFC or proposal process. New architecture support has historically been accepted when nihui or a trusted contributor does the work and adds CI. Community channels are QQ groups, Telegram (t.me/ncnnyes), and Discord (discord.gg/YRsxgmF).
2. Port History and Upstreaming Timeline
All RISC-V work is fully upstream in the main Tencent/ncnn repository. There is no downstream fork or staging branch.
| Date | Event | Source |
|---|---|---|
| 2020-07-22 | First riscv64 Linux CI added | PR #1951 |
| 2021-04-24 | First RISC-V commit: runtime V detection, initial C906 toolchain | commit 45bf3cd779a7 |
| 2021-04-26 | RVV spec 0.7.1 support for C906 | PR #2868 |
| 2021-05-04 | RVV CI coverage added | PR #2886 |
| 2021-06-12 | RVV optimization for AbsVal and ReLU | PR #3001 |
| 2021-08-12 | Riscv64 C906/D1 RVV 0.7.1 operator batch | PR #3159 |
| 2021-12-25 | C906 v223 toolchain added | PR #3449 |
| 2022-06-18 | Winograd convolution for RISC-V | PR #3921 |
| 2022-10-01 | Clang CI for RVV; new segment load/store interface | PR #4118 |
| 2022-10-02 | C906 build CI | PR #4232 |
| 2022-10-12 | TH1520 toolchain support | PR #4267 |
| 2023-09-22 | Fix build with vanilla C906 toolchain | PR #5048 |
| 2023-10-20 | RISC-V float32 GEMM | PR #4903 |
| 2024-12-04 | Port all RVV intrinsics from 0.7.1 to ratified RVV 1.0 standard | PR #5642 |
| 2024-12-22 | ruapu updated to detect zfh, zvfh, xtheadvector | PR #5841 |
| 2024-12-25 | XuanTie C908 CI added | PR #5850 |
| 2024-12-25 | SpacemiT X60 CI added | PR #5852 |
| 2026-01-09 | Python riscv64 wheels released to PyPI | PR #6494 |
| 2026-02-20 | DeformableConv2D RVV implementation | PR #6540 |
| 2026-02-27 | RISC-V GEMM fp16 | PR #5311 |
| 2026-04-17 | RVV 1.0 Quantize layer | PR #6636 |
| 2026-05-18 | RVV 1.0 Dequantize and Requantize layers | PR #6658, PR #6695 |
| 2026-05-20 | Packed convolution optimization | PR #6731 |
| 2026-05-21 | SDPA (attention) RVV support | PR #6557 |
| 2026-05-25 | im2col GEMM and Winograd convolution optimization; CI toolchain update | PR #6740, PR #6742 |
| 2026-08-04 | GEMM block quantization optimization (multi-arch including RISC-V) | PR #6831 |
Key contributors to RISC-V work: nihui (Tencent, primary), MollySophia (PR #5354, int8 convolution WIP), Deepdive543443/Justin Fung (PR #6763, packed INT8 convolution), and a set of community contributors adding individual operator RVV implementations.
The port is fully upstream. No downstream staging exists.
3. Upstream Support Tier
No formal tier policy is documented. There is no PLATFORMS.md, SUPPORT.md, or equivalent. The implicit tier structure, inferred from CI coverage and release artifact presence, is:
| Tier | Platforms | Evidence |
|---|---|---|
| Tier 1 (prebuilt binaries + CI) | Android, iOS, Windows (VS2015-VS2022), Ubuntu 22.04/24.04 (x86_64/aarch64), macOS, WebAssembly, HarmonyOS | GitHub release assets present |
| Tier 2 (CI only, no prebuilt binaries) | Linux riscv64, ppc64, mips, mips64, loongarch64, arm, aarch64 | CI workflows present; no release zips |
| Tier 3 (community/bare-metal) | elf-riscv32/64, ESP32 | Spike simulator CI; no Linux userspace |
riscv64 is Tier 2. CI builds and tests pass. No prebuilt binary release artifacts exist for riscv64 in any GitHub release (verified against releases 20260526, 20260113, 20250916). The Ubuntu release zips target x86_64 and aarch64 only.
| Dimension | amd64 | arm64 | riscv64 |
|---|---|---|---|
| CI builds | Yes | Yes | Yes |
| CI tests run | Yes | Yes | Yes (QEMU) |
| Prebuilt release binary | Yes | Yes | No |
| Ubuntu .deb package | No | No | No |
| PyPI wheel | Yes | Yes | Yes (cp38-cp314) |
| Android NDK build | Yes | Yes | Yes (build-only) |
ncnn is not packaged in Ubuntu at all (libncnn-dev absent from resolute/questing/noble/jammy). The PyPI wheel is the only upstream-published riscv64 binary artifact.
4. Technical Architecture and RISC-V-Specific Subsystems
ncnn’s architecture is a hand-optimized layer library. Each neural network operator has a platform-specific implementation directory. For RISC-V, this is src/layer/riscv/, containing 180 files.
ISA extension coverage:
| Extension | Usage in riscv64 layer code |
|---|---|
RVV 1.0 (__riscv_vector) |
Primary SIMD path for all layer kernels; vfloat32mN_t, vint32mN_t, vfmacc intrinsics |
Zvfh (__riscv_zvfh) |
FP16 vector ops; vfloat16mN_t; all *_zfh.cpp files |
Zfh (__riscv_zfh) |
Scalar FP16 fallback when Zvfh unavailable |
| XTheadVector | T-Head pre-standard vector (C906/C910); separate dispatch path |
| Zba/Zbb/Zbc/Zbs | Toolchain -march= flags only; no intrinsics in layer code |
| Zvbb/Zvbc/Zvkb | Not used in any layer code |
| BF16/Zvfbfmin | Probed in ruapu but no layer implementation uses it |
Component comparison:
| Component | amd64 | arm64 | riscv64 |
|---|---|---|---|
| GEMM (FP32) | AVX/AVX2/AVX512 intrinsics | NEON/ASIMD intrinsics | RVV 1.0 intrinsics, VLEN-adaptive |
| GEMM (FP16) | F16C intrinsics | NEON fp16 | RVV 1.0 Zvfh intrinsics |
| GEMM (INT8) | VNNI intrinsics | dotprod intrinsics | RVV 1.0 intrinsics (merged); packed INT8 conv pending PR #6763 |
| GEMM (INT4 weight block) | Merged (#6831) | Merged (#6831) | Merged (#6831); INT4 extension pending PR #6890 |
| Winograd convolution | Yes | Yes | Yes (RVV 1.0) |
| Depthwise convolution | Yes | Yes | Yes (RVV 1.0, 3x3 and 5x5 packn) |
| Attention (SDPA) | Yes | Yes | Yes (RVV 1.0, merged 2026-05-21) |
| Transcendentals (exp, log, sin, cos, tanh, sigmoid) | Yes | Yes | Yes (rvv_mathfun.h, 85 KB, LMUL 1/2/4/8) |
| FP16 transcendentals | Yes | Yes | Yes (rvv_mathfun_fp16s.h, 55 KB) |
| LSTM | Yes | Yes | No RVV path (PR #6736 open) |
| ELU/ERF/GELU/SELU | Yes | Yes | No RVV path (PR #6608 open) |
| Scale operator | Yes | Yes | No RVV path (PR #6931 open) |
| Runtime CPU dispatch | Yes | Yes | Yes (ruapu, csrr_vlenb) |
| JIT | No | No | No |
| Assembly (.S files) | No | No | No |
VLEN adaptivity: csrr_vlenb() is used at runtime in kernel headers (e.g., gemm_wq_int8.h) to select 128-bit vs 256-bit tile sizes. This is correct behavior for RVV’s variable-length model.
Dispatch model: CMake probes at configure time for RVV 1.0 tuple intrinsics (__riscv_vcreate_v_f32m1x2), Zfh, Zvfh, and XTheadVector. Each layer registers separate compiled variants (*_rvv, *_zfh, *_xtheadvector) via ncnn_add_arch_opt_layer. Runtime selection uses cpu_support_riscv_v(), cpu_support_riscv_zvfh(), and cpu_support_riscv_xtheadvector() from src/cpu.cpp.
5. Build System, Cross-Compilation, and Toolchain
Toolchain minimum versions:
| Toolchain | Minimum for RVV 1.0 | CI version | Why |
|---|---|---|---|
| GCC (upstream riscv-gnu-toolchain) | GCC 12 (basic); GCC 14 recommended | 2026.05.19 nightly | CMake probes __riscv_vcreate_v_f32m1x2 (RVV 1.0 tuple intrinsic); absent in GCC < 12 |
| Clang/LLVM | LLVM 17 | Same nightly bundle | LLVM 17 added full RVV 1.0 intrinsics including tuple types |
| Ubuntu 22.04 distro GCC 11 | Fails RVV 1.0 probe | N/A | NCNN_RVV forced OFF with warning |
| Ubuntu 24.04 distro GCC 13 | Likely passes | N/A | Basic RVV 1.0 present [NEEDS VERIFICATION] |
| Xuantie-900-gcc | V3.1.0 minimum; V3.4.0 in CI | V3.4.0 | xtheadvector is a vendor extension absent from upstream GCC |
| SpacemiT toolchain | v1.2.4 (CI version) | v1.2.4 | Required for SpacemiT K1 -march=rv64gc_zba_zbb_zbc_zbs_zicbop |
Generic riscv64 Linux build (distro cross-compiler, no RVV):
sudo apt-get install g++-riscv64-linux-gnu
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/riscv64-linux-gnu.toolchain.cmake \
-DNCNN_BUILD_TESTS=ON ..
cmake --build . -j$(nproc)
TESTS_EXECUTABLE_LOADER=qemu-riscv64 \
TESTS_EXECUTABLE_LOADER_ARGUMENTS="-L;/usr/riscv64-linux-gnu" \
ctest --output-on-failure -j$(nproc)
RVV 1.0 build (upstream toolchain):
export RISCV_ROOT_PATH=/path/to/riscv64-glibc-toolchain
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/riscv64-unknown-linux-gnu.toolchain.cmake \
-DNCNN_BUILD_TESTS=ON ..
cmake --build . -j$(nproc)
TESTS_EXECUTABLE_LOADER=qemu-riscv64 \
TESTS_EXECUTABLE_LOADER_ARGUMENTS="-cpu;rv64,v=true,zfh=true,zvfh=true,vlen=256,elen=64,vext_spec=v1.0;-L;/path/to/sysroot" \
ctest --output-on-failure -j8
T-Head C906 build:
export RISCV_ROOT_PATH=/path/to/Xuantie-900-gcc-linux-6.6.36-glibc-x86_64-V3.4.0
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/c906-v310.toolchain.cmake \
-DNCNN_OPENMP=OFF -DNCNN_THREADS=OFF -DNCNN_RUNTIME_CPU=OFF \
-DNCNN_RVV=OFF -DNCNN_XTHEADVECTOR=ON -DNCNN_ZFH=ON -DNCNN_ZVFH=OFF \
-DNCNN_SIMPLEOCV=ON -DNCNN_BUILD_EXAMPLES=ON ..
cmake --build . -j4
SpacemiT K1 build:
export RISCV_ROOT_PATH=/path/to/spacemit-toolchain-linux-glibc-x86_64-v1.2.4
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/k1.toolchain.cmake \
-DNCNN_OPENMP=ON -DNCNN_THREADS=ON -DNCNN_RUNTIME_CPU=OFF \
-DNCNN_RVV=ON -DNCNN_XTHEADVECTOR=OFF -DNCNN_ZFH=ON -DNCNN_ZVFH=ON \
-DNCNN_SIMPLEOCV=ON -DNCNN_BUILD_TESTS=ON ..
cmake --build . -j8
QEMU note: The gcc-riscv64 CI job builds QEMU from source at commit f5643914 with a custom patch (0007-linux-user-Expose-risc-v-V-isa-bit-in-get_elf_hwcap.patch) to expose the V extension capability bit in AT_HWCAP. Without this patch, NCNN_RUNTIME_CPU=ON builds fail to detect RVV support under QEMU user-mode. Self-hosted jobs use xuantie-qemu V5.4.1 (T-Head targets) and jdsk-qemu v10.0.2 (SpacemiT target).
Key CMake flags for riscv64:
| Flag | Default | When to override |
|---|---|---|
NCNN_RVV |
ON if compiler supports | OFF for C906/C910 (use XTheadVector); OFF for distro GCC 11 |
NCNN_XTHEADVECTOR |
ON if compiler supports | OFF for C908 and upstream GCC/Clang |
NCNN_ZVFH |
ON if conditions met | OFF for C906/C910 |
NCNN_RUNTIME_CPU |
ON | Always OFF for cross-compilation to a fixed target |
NCNN_OPENMP |
ON | OFF for C906 (single-core) and bare-metal |
NCNN_BUILD_TOOLS |
ON | OFF for cross-compilation (tools run on host) |
NCNN_SIMPLEOCV |
OFF | ON for embedded targets without libopencv |
6. Feature Coverage and Gap Analysis vs arm64 and amd64
Functional gaps (operations with no RVV path as of 2026-08-28):
| Operator | arm64 | amd64 | riscv64 | Open PR |
|---|---|---|---|---|
| LSTM | RVV-equivalent | Yes | Scalar only | PR #6736 |
| ELU/ERF/GELU/SELU | Yes | Yes | Scalar only | PR #6608 |
| Scale | Yes | Yes | Scalar only | PR #6931 |
| Packed INT8 convolution | Yes (dotprod) | Yes (VNNI) | Pending | PR #6763 |
| INT4 weight block quant GEMM | Merged | Merged | Pending | PR #6890 |
| GEMM microkernel (refactored) | Stable | Stable | Refactor pending | PR #6752 |
Performance gaps (benchmark data from benchmark/README.md):
The most significant performance gap is INT8 inference. On all tested RISC-V hardware, INT8 is slower than FP32 because the packed INT8 convolution kernel (PR #6763) is not yet merged. Once merged, the PR author reports 9-28x speedup on SpacemiT X60 for standard models.
FP32 inference on RISC-V is 20-45x slower than comparable ARM64 (Cortex-A76) hardware:
| Model | SpacemiT X60 8T FP32 (ms) | RK3588 A76 4T FP32 (ms) | Ratio |
|---|---|---|---|
| squeezenet | 195.61 | 7.07 | 28x slower |
| mobilenet | 266.42 | 5.72 | 47x slower |
| googlenet | 788.60 | 16.65 | 47x slower |
| resnet18 | 869.32 | 15.08 | 58x slower |
| resnet50 | 1825.00 | 28.28 | 65x slower |
This gap reflects hardware clock speed and core count differences, not solely software optimization gaps. The SpacemiT X60 runs at 1.6 GHz with 8 cores; the RK3588 A76 runs at 2.4 GHz with 4 cores. The software optimization gap (missing packed INT8, missing LSTM/ELU/GELU RVV) is a secondary contributor.
GPU (Vulkan) on RISC-V boards: PowerVR BXE/BXM series GPUs present on VisionFive2 and SpacemiT MUSE Pi Pro are consistently slower than the CPU RVV path for most models. On VisionFive2, GPU is 2.4-3.0x slower than CPU for squeezenet and mobilenet. On SpacemiT MUSE Pi Pro, GPU is 1.95-2.99x slower for small models; GPU is faster only for vgg16 (5796ms GPU vs 8405ms CPU). This is a hardware characteristic, not an ncnn software issue.
Correctness issues: See Section 11.
Floating-point semantics: No documented riscv64-specific NaN or floating-point semantics divergence found in research. [NEEDS VERIFICATION - no dedicated floating-point conformance testing data found in research findings.]
7. CI/CD Infrastructure
riscv64 CI exists and tests pass. The linux-riscv64.yml workflow triggers on push and pull_request to master, path-filtered to riscv layer files, tests, examples, and benchmark.
| Job | Runner | Toolchain | Test execution |
|---|---|---|---|
gcc-riscv64 |
ubuntu-latest (GitHub-hosted x86) |
g++-riscv64-linux-gnu (apt) |
Custom QEMU from source (f5643914 + RVV hwcap patch); qemu-riscv64 -L /usr/riscv64-linux-gnu |
xuantie (c906, c910, c908, c907) |
self-hosted, linux, ubuntu |
Xuantie-900-gcc V3.4.0 | xuantie-qemu V5.4.1; CPUs: c906fdv, c910v, c908v, c907fdv-rv64 |
spacemit (x60) |
self-hosted, linux, ubuntu |
SpacemiT GCC v1.2.4 + LLVM | jdsk-qemu v10.0.2; CPU: max,vlen=256,elen=64,vext_spec=v1.0 |
gcc-rvv |
self-hosted, linux, ubuntu |
riscv-gnu-toolchain 2026.05.19 | QEMU at /data/action/osd/qemu-install; vlen=256 and vlen=128 |
clang-rvv |
self-hosted, linux, ubuntu |
Same toolchain, LLVM frontend | Same QEMU; vlen=256 and vlen=128 |
rv64gc (elf) |
self-hosted, linux, centos |
riscv64-unknown-elf bare-metal | Spike ISA simulator; --isa=rv64gc |
Additional riscv64 coverage in test-coverage.yml: linux-gcc-cross (riscv64, self-hosted ubuntu25, debug+coverage+OpenMP) and linux-gcc-riscv64-rvv (RVV=ON, ZFH=ON, ZVFH=ON, vlen=256 and vlen=128, lcov).
No native riscv64 runners are used. All execution is QEMU user-mode or Spike ISA simulation on x86 self-hosted machines. No RISE riscv64 runners are used.
| Dimension | amd64 | arm64 | riscv64 |
|---|---|---|---|
| CI builds | Yes | Yes | Yes |
| CI tests run | Yes | Yes | Yes (QEMU) |
| Native hardware CI | Yes | Yes | No |
| Multiple ISA variants tested | N/A | N/A | Yes (c906, c908, c910, c907, x60, generic rvv) |
| Coverage reporting | Yes | Yes | Yes (lcov) |
| RISE runners | No | No | No |
8. Distribution and Release Status
GitHub releases: No riscv64 binary assets in any release. Releases 20260526, 20260113, and 20250916 were verified. Ubuntu release zips target x86_64 and aarch64 only.
PyPI: Full riscv64 coverage. Latest version 1.0.20260526 ships 14 riscv64 wheels across 7 CPython versions (cp38-cp314), both manylinux_2_39_riscv64 and musllinux_1_2_riscv64. The manylinux_2_39 tag requires glibc >= 2.39; Ubuntu 26.04 ships glibc 2.41, so the wheel is compatible. These wheels are built by the upstream ncnn project via release-python.yml using docker/setup-qemu-action + cibuildwheel with EXTRA_CMAKE_ARGS=-DNCNN_XTHEADVECTOR=OFF. The RISE wheel builder redirects ncnn queries to upstream PyPI rather than maintaining a separate build.
Ubuntu/Debian packages: ncnn is not packaged in Ubuntu (absent from resolute, questing, noble, jammy). libncnn-dev does not exist in any Ubuntu suite. [NEEDS VERIFICATION for Debian - research findings confirm Ubuntu absence but did not check Debian directly.]
Arch Linux RISC-V: Data not available: Arch Linux RISC-V package status was not searched in research findings.
What a user must do to get a working riscv64 binary:
- Python users:
pip install ncnn- installs the manylinux_2_39_riscv64 wheel directly. - C++ users: build from source using the upstream riscv-gnu-toolchain 2026.05.19 or newer. No prebuilt C++ library exists for riscv64.
9. Dependencies
Summary table:
| Dependency | Role | riscv64 build | riscv64 test | riscv64 release | Blocking for ncnn |
|---|---|---|---|---|---|
| Vulkan (optional) | GPU compute backend | Yes | Unknown | Yes (libvulkan-dev in Ubuntu 26.04) | No (NCNN_VULKAN=OFF default) |
| glslang + SPIRV-Tools (optional) | GLSL-to-SPIR-V for Vulkan | Yes | Unknown | Yes (Ubuntu 26.04) | No (optional) |
| OpenMP (libgomp/libomp) | Thread parallelism | Yes | Partial (riscv64 Linux functional; riscv32 issues only) | Yes (Ubuntu 26.04) | No (NCNN_SIMPLEOMP fallback) |
| Protobuf | Model conversion tools only, not inference | Yes | Yes (riscv64 merged 2024-03) | Yes (Ubuntu 26.04) | No (conversion tools only) |
| OpenCV (optional) | Image I/O for examples | Yes | Partial (issue #28852: RVV DNN engine regression open 2026-04-22) | Yes (Ubuntu 26.04) | No (NCNN_SIMPLEOCV=ON fallback) |
| Eigen | Linear algebra (pnnx tool) | Yes (allow_failure:true) | Partial (allow_failure:true; RVV not in any release) | Yes (header-only, Ubuntu 26.04) | No (pnnx tool only) |
| FlatBuffers | Serialization (pnnx model format) | Yes | None (no upstream riscv64 CI) | Yes (Debian sid) | No (pnnx tool only) |
| OpenBLAS (optional) | BLAS backend | Yes | Partial (cross-compile only; no native test) | Yes (Ubuntu 26.04) | No (ncnn has own kernels) |
| XNNPACK (optional) | NN kernels (pnnx/executorch path) | Yes | Partial (issue #9886: Zvfh dispatch regression Jan 2026) | No (no Ubuntu package) | No (not used in core inference) |
| ruy (optional) | Dense matmul (LiteRT path) | Yes (scalar only) | None | Yes (Ubuntu noble) | No (optional path) |
| zlib | Compression (model I/O) | Yes | Partial (OpenBSD QEMU only; no Linux riscv64 CI) | Yes (Ubuntu 26.04) | No |