3962 Commits

Author SHA1 Message Date
dependabot[bot] c15904bb89 Bump pypa/cibuildwheel from 4.3.0 to 4.3.1 (#7110)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v4.3.0...v4.3.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 4.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-15 07:24:51 +08:00
nihui fcde729c7b riscv: add int8 convolution winograd (#7093) 2026-10-14 14:58:05 +08:00
nihui b0f97f43f2 riscv: add int8 convolution im2col gemm (#7090)
* riscv: add tiled int8 convolution im2col gemm

Pack weights and input in cache-sized M/N/K tiles with a 1x1 input shortcut.
Use vector-length-agnostic 8/4/2/1-position microkernels with signed
widening accumulation, including an XTheadVector-compatible path.

Reuse bounded per-worker input panels across output-channel tiles and
keep split-K partial sums in the existing int32 output. Wire the GEMM
option into the int8 pipeline while retaining direct convolution and
existing requantization, dequantization and activation handling.

Add focused tests for actual pipeline selection, packing, tails,
split-K accumulation, full-range int8 values and thread-count changes.

* riscv: fix int8 convolution split-K test sizing

A tile balanced for a large artificial K can be smaller than the cache
limit. Choosing that tile size plus one does not guarantee that the
actual test shape splits K, as exposed by the C907 and C908 CI jobs.

Query the tiler for each actual candidate K and grow the candidate until
it spans multiple panels. Keep the transformed-weight K-row assertion
and numerical checks, and report a missing split separately from an
incorrect pipeline selection.

* riscv: write int8 convolution gemm blocks explicitly

* riscv: separate full int8 gemm channel blocks and tails

* riscv: widen int8 convolution gemm to m4 accumulators

* apply code-format changes

* riscv: keep int8 convolution partial sums in packed tiles

* riscv: align int8 convolution gemm helpers with ncnn style

* apply code-format changes

* riscv: unify int8 convolution gemm channel loops

* riscv: reduce int8 im2col indexing and single-k tile overhead

* riscv: use scalar 2x2 int8 gemm and consolidate convolution tests

* mips, loongarch: fix packed int8 im2col K tile offsets

---------

Co-authored-by: nihui <171016+nihui@users.noreply.github.com>
2026-10-13 13:11:17 +08:00
LI d8227bbe4f Fix Python custom layer factory lifetime (#7049)
* fix(python): scope custom layer factories to Net lifetime

Replace the process-global ten-slot callback table with stable per-Net userdata. Preserve registrations across clear() and destroy layers before releasing their factories.

Add real-binding regression coverage for repeated and simultaneous Nets, numeric and named registrations, reloads, callback lifetime, subclassing and interpreter shutdown.

Fixes #4560

* fix(python): release superseded custom layer callbacks

* fix(python): guard unencodable named custom layer slots
2026-10-12 15:27:04 +08:00
LI f4e86ad88f fix lrn even across-channel window size (#7070) 2026-10-12 14:08:14 +08:00
LI bd38ca5b0c arm/riscv: avoid fp16 GELU overflow (#7060) 2026-10-12 14:07:42 +08:00
LI 4a0e0dba89 fix(vulkan): include element packing in BinaryOp shape hints (#7040) 2026-10-12 14:07:04 +08:00
Dreladwyn 201145bdd9 fix crash reading past end of memory-mapped model file (#7021)
* fix crash reading past end of memory-mapped model file

DataReaderFromMemory used by mapped model loading was unbounded:
read()/reference() advanced past the mapped region, so a truncated
or corrupt .bin crashed with an access violation inside
ModelBinFromDataReader instead of failing cleanly.

Add a size-aware DataReaderFromMemory ctor that clamps reads and
fails references past the end, use it in the mapped branches of
Net::load_model, and propagate load_model()'s return value which
was previously dropped.

* fix bounded memory reader scans and add loading regressions

* f

* reuse bounded memory reader scan buffer

---------

Co-authored-by: Dr3ladwyn <Dr3ladwyn@users.noreply.github.com>
Co-authored-by: nihui <nihuini@tencent.com>
2026-10-12 00:01:46 +08:00
風的彷徨 1dd0355612 Fix Vulkan fallback crash with empty optional inputs (#6870)
* test net transfers with empty optional inputs
2026-10-10 23:18:27 +08:00
風的彷徨 ab3790faca fix MHA singleton mask broadcast across backends (#6869)
Keep persistent KV caches on the blob allocator, broadcast single-channel attention masks across heads on CPU and Vulkan paths, and add long multi-token cache regressions.
2026-10-10 19:47:13 +08:00
nihui 1efcd3ac4a fix interp scale factor sampling and pnnx recomputed sizes (#7075)
* fix interp scale factor sampling and pnnx recomputed sizes

Use the original scale factor for linear and cubic interpolation instead
of deriving coordinates from the truncated output size. Preserve explicit
sizes, reference sizes, and size expressions across CPU and Vulkan paths.
Keep same-axis linear behavior, resample non-unit same-size bicubic input,
and clamp interpolation taps for short axes without out-of-bounds reads.

Lower recompute_scale_factor to runtime size expressions, retain the flag
when importing nn.Upsample, and avoid deleting non-unit same-size resizes.

Add independent ncnn reference checks and pnnx static/dynamic round-trip
tests covering fractional up/downscales, recomputed sizes, short axes,
align_corners, and nn.Upsample.

Validated CPU interpolation tests, ASan/UBSan, Vulkan llvmpipe, and pnnx
TorchScript interpolation tests against PyTorch 2.10.0 CPU. The original
bilinear/bicubic reproductions fail on the base and pass with this fix.

Refs: Tencent/ncnn#6836, Tencent/ncnn#6837, Tencent/ncnn#6844

---------

Co-authored-by: Acture <acturea@gmail.com>
Co-authored-by: xy200303 <3483421977@qq.com>
Co-authored-by: nihui <171016+nihui@users.noreply.github.com>
2026-10-10 00:00:45 +08:00
Layla b9af93c74b Add percentile PTQ method in ncnn2table (#6854) 2026-10-09 10:33:34 +08:00
nihui c4b34c591d fix compare-binary-size-pr-comment.yml (#7056) 2026-10-08 21:21:17 +08:00
Stern bbaca40c35 x86: reduce Col2im memory access for non-overlapping deconvolution (#7015)
* Reduce memory access in x86 deconvolution Col2im

The SGEMM path fills the output with bias, then reads and updates each
output value. When kernel tiles do not overlap, each value has one source.
Write the source plus bias once, and fill only the output padding.

Use this path for rectangular kernels with unit dilation and stride equal
to the kernel size. Support packs of 1, 4, and 8. Split input rows between
workers when there are fewer output channel groups than threads. Each
worker writes separate output rows. Keep the existing path for other
cases. Add 32 test cases to test_deconvolution.

Test Plan
---------
These commands passed in the local benchmark workspace:

```bash
ctest --test-dir .tools/ncnn-col2im-build -R '^test_deconvolution$' --output-on-failure
.venv-esp/bin/python results/oss/col2im_transfer_20260920/generalization/test_ncnn.py --parallel
.venv-esp/bin/python results/oss/col2im_transfer_20260920/generalization/sanitize_ncnn.py
```

The complete forward test gave equal output bits for 236 cases and
1,433,578 values. The extracted loops passed ASan and UBSan for 300 cases.
The sanitizer test uses a small Mat substitute, not a full sanitizer build.
The local probe scripts are outside this repository.

The final format check and git diff --check passed. The format changes do
not change the tested operations.

This change was prepared with help from an AI assistant.
2026-10-08 19:44:27 +08:00
風的彷徨 c4393a13b0 pnnx: preserve batch semantics across reshape and flatten (#6934)
Co-authored-by: nihui <nihuini@tencent.com>
2026-10-08 19:08:41 +08:00
Giulio Corradi 0481595ce8 vulkan: route download through staging when blob memory is not HOST_CACHED (#6864)
VkCompute::record_download() skips the staging buffer whenever the blob
allocator is mappable. On an integrated GPU the blob allocator prefers
DEVICE_LOCAL|HOST_VISIBLE "unified" memory, which is mappable but
WRITE-COMBINED rather than HOST_CACHED, so the result is memcpy'd out of
uncached memory.

Uploads are unaffected -- writing to write-combined memory is fast. Only
the device-to-host read collapses, giving a large upload/download
asymmetry on the very same buffers.

Measured on a Radeon 8060S (Strix Halo, RADV GFX1151, 256 GB/s unified
LPDDR5X), 128 MB transfer, median of 3 runs:

    host memcpy (reference)      23.0 GB/s
    ncnn upload                  10.0 GB/s
    ncnn download   before        0.32 GB/s
    ncnn download   after         4.19 GB/s     13.1x

The staging allocator is the one that asks for HOST_CACHED, and it was
bypassed in exactly the case where it is needed.

Add VulkanDevice::is_cached() mirroring is_coherent(), track it as a
`cached` flag on VkAllocator alongside `mappable` / `coherent`, and
extend the record_download() test to require both.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: nihui <nihuini@tencent.com>
2026-10-08 19:01:14 +08:00
acture c798db5525 RotaryEmbed: support full-width cos/sin cache for 2D / vision RoPE (#6834)
* RotaryEmbed: support full-width cos/sin cache for 2D / vision RoPE

The non-interleaved path read only the first embed_dim/2 values of the
cos/sin cache and reused them for both halves of each head vector. That is
correct for standard 1-D RoPE (cos = concat(freqs, freqs), identical halves),
but the pnnx fuse_convert_rotaryembed pass lowers the general expression
x*cos + rotate_half(x)*sin — with a full-width cos — into this op without
checking that the halves are equal. For 2-D / vision RoPE where the halves
differ (cos = concat(cos_h, cos_w), e.g. the Penguin-VL vision encoder) the
second half was rotated with the wrong frequencies, silently producing
wrong output (max|diff| ~3.4 vs PyTorch on the Penguin-VL vision encoder).

Read the second half's cos/sin for the second output half. Backward
compatible via a cache-width guard: when the cache is full width (== embed_dim)
the two halves are independent; when it is embed_dim/2 (the standard-rope form,
as the unit test supplies) the second half reuses the first, so existing
half-width callers stay bit-identical. Applied to every backend
(naive / arm / x86 / loongarch / mips / vulkan) and its bf16/fp16 paths.

Adds a full-width differing-halves test case; the previous test only exercised
half-width caches, which are trivially identical-halves.

After the fix the Penguin-VL vision encoder converts in-graph at
max|diff| = 6.2e-4 vs PyTorch (fp32).

Fixes #6833

* test: add a pnnx test that can actually fail for the full-width cache fix

tests/test_rotaryembed.cpp cannot detect this bug. ncnn's test_layer() compares
the optimized backends against the naive layer, and this PR changes the naive
layer too, so the test stays green whether the semantics are right or wrong —
rebuilding the PR's test against master's src/layer still exits 0.

tools/pnnx/tests/ncnn/ is the only harness in-tree that pins semantics to an
external reference (torch.allclose against PyTorch), so the check belongs there.

Every input is drawn with torch.rand in forward() parameter order, because the
generated test_ncnn_fuse_rotaryembed_ncnn.py takes no arguments: it reseeds with
manual_seed(0) and regenerates each input the same way. An input built any other
way would leave the two sides comparing different tensors, and the test would
fail unconditionally while appearing to test something.

Random caches are also the stronger choice here: the defect is that the layer
reads one cache row for both halves, so it only shows when the halves differ,
which random values guarantee and a hand-built cat(f, f) cache would hide. A
"standard RoPE stays correct" case is deliberately absent — the cache must stay a
pnnx.Input for the fusion pattern to match, and the generator always randomizes
inputs, so that case cannot be expressed in this harness.

Also parameterizes the interleaved path in tests/test_rotaryembed.cpp. On a
CPU-only build that is code-path coverage rather than a correctness check, for
the reason above; its value is on the Vulkan backend.

Not run here: building pnnx needs libtorch. Worth confirming under ctest that the
generated .param really contains RotaryEmbed layers — if the fusion does not
fire, the test passes without exercising anything.

* fix pnnx rotaryembed regression test layout and fusion checks

---------

Co-authored-by: nihui <nihuini@tencent.com>
2026-10-08 18:56:24 +08:00
dependabot[bot] 3798be64cf Bump pypa/cibuildwheel from 4.2.1 to 4.3.0 (#7052)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 4.2.1 to 4.3.0.
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v4.2.1...v4.3.0)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-08 11:10:06 +08:00
Lune 16bdc2da54 x86: optimize permute with SIMD (#6762)
Co-authored-by: nihui <nihuini@tencent.com>
2026-10-07 23:21:38 +08:00
風的彷徨 123a97c4c5 fix stft detect to support torchaudio.transforms.MelSpectrogram (#6548)
* pnnx: preserve leading dimensions in spectrogram lowering
* pnnx: fix linear leading dimensions and spectrogram tests
* pnnx: fix padding on native batch axes

---------

Co-authored-by: nihui <nihuini@tencent.com>
2026-10-07 16:05:39 +08:00
losewayy 51f3b0bf03 vulkan: implement tile (#7027) 2026-10-06 21:27:08 +08:00
Matteo Forzan 1624ee3f07 Add RVV implementation for scale (#6931)
Signed-off-by: darkavatar23 <matteo.forzan95@gmail.com>
2026-10-06 17:00:12 +08:00
dependabot[bot] 46ae9d4c97 Bump actions/checkout from 6 to 7 (#7045)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-06 13:22:30 +08:00
dependabot[bot] 19e0cb6189 Bump actions/cache from 5 to 6 (#7046)
Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-06 13:22:15 +08:00
風的彷徨 09cd564e9f support rv elu erf gelu selu (#6608) 2026-10-06 13:15:28 +08:00
Justin Fung 6a1fce7802 RVV1.0 Packed INT8 Convolution (#6763)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: nihui <nihuini@tencent.com>
Co-authored-by: nihui <shuizhuyuanluo@126.com>
2026-10-05 23:03:55 +08:00
nihui c7ad4fc6a8 fix test mat batch fp16/bf16 cast (#7044) 2026-10-05 15:22:37 +08:00
Molly Sophia f947448a04 ci: Add test for macos arm (#5680)
Signed-off-by: Molly Sophia <mollysophia379@gmail.com>
2026-10-05 14:19:35 +08:00
nihui 41f031e045 reduce redundant tests that do not contribute to coverage (#7042)
* adjust tests
* opt shader coverage op
* update gpu_coverage.cpp atomicor coalesce
2026-10-05 08:57:20 +08:00
nihui 5e338165fd refactor riscv gemm microkernel, mha sdpa rvv (#6752)
* riscv mha and sdpa, opt gemm wq int8
2026-10-04 23:01:02 +08:00
nihui 9f9d4ec815 reduce gpu test cases (#7017) 2026-10-01 23:33:05 +08:00
nihui c6b351b56f optimize gemm cooperative matrix pack4 load with interleaved index (#7024) 2026-09-24 21:58:45 +08:00
nihui d48ccde9e9 cooperative matrix shader without shared memory padding is actually faster (#7022) 2026-09-24 15:30:31 +08:00
nihui 6c52e59dfb fix cooperative matrix load store alignment and amd bf16 round rtz issue (#7020) 2026-09-23 10:19:30 +08:00
nihui 050ba22657 vulkan add shader line coverage with NCNN_COVERAGE (#7016) 2026-09-21 10:14:53 +08:00
Lune 1857775c98 x86: optimize normalize with SIMD (#6761)
Co-authored-by: nihui <nihuini@tencent.com>
2026-09-20 10:49:20 +08:00
Lune 70e7bfd608 x86: optimize Reduction with SIMD (#6743)
* [test] reduction: add perf_reduction harness target
* [feat] reduction: add x86 optimized Reduction layer

Co-authored-by: nihui <nihuini@tencent.com>
2026-09-18 18:37:24 +08:00
Lune b931b0ca63 x86: optimize CumulativeSum with SIMD Kogge-Stone prefix scan (#6693)
Co-authored-by: nihui <nihuini@tencent.com>
2026-09-18 17:24:37 +08:00
nihui dae7741b49 update pnnx ci torch 2.14 (#7013)
* do not dce graph input, update transformer tests
2026-09-18 13:07:28 +08:00
dependabot[bot] 21a26cda69 Bump pypa/cibuildwheel from 3.4.1 to 4.2.1 (#6969)
Bumps [pypa/cibuildwheel](https://github.com/pypa/cibuildwheel) from 3.4.1 to 4.2.1.
- [Release notes](https://github.com/pypa/cibuildwheel/releases)
- [Changelog](https://github.com/pypa/cibuildwheel/blob/main/docs/changelog.md)
- [Commits](https://github.com/pypa/cibuildwheel/compare/v3.4.1...v4.2.1)

---
updated-dependencies:
- dependency-name: pypa/cibuildwheel
  dependency-version: 4.2.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-18 10:47:26 +08:00
nihui 8c5bbd0a2d prefer libEGL_nvidia.so.0 for headless t4 ci (#7014) 2026-09-18 10:47:02 +08:00
nihui 902d8ae387 update ci swiftshader (#7012) 2026-09-18 10:46:35 +08:00
禾可 64d633f454 pnnx: handle float16 scalar constant when importing onnx (#6852)
Signed-off-by: 林晨 (Leo Cheng) <leo-cheng@vip.qq.com>
Co-authored-by: nihui <nihuini@tencent.com>
2026-09-17 16:11:57 +08:00
ihb2032 64e3006672 cmake: verify xtheadvector target macro in compiler probe (#7007)
Some toolchains accept -march=*xtheadvector and compile the generic
vector intrinsics without actually selecting the XTheadVector target.
This makes CMake enable XTheadVector code paths incorrectly.

Keep the existing intrinsic checks and append test3() referencing the
__riscv_xtheadvector ISA macro. This verifies the same target mode that
the RISC-V layer sources use, while remaining compatible with the
Xuantie C906/C910 toolchain.
2026-09-17 11:41:35 +08:00
nihui 56e83f813a pnnx do not lower C++20 to C++17 when enabling protobuf (#7010) 2026-09-17 11:21:48 +08:00
primorLee babb819dfa fix: stabilize logaddexp expression evaluation (#6924)
Co-authored-by: nihui <nihuini@tencent.com>
2026-09-17 10:41:00 +08:00
nihui 61ea75123d pnnx requires c++20 for pytorch 2.13+ (#7009) 2026-09-17 10:31:50 +08:00
nihui 8bc95a1e7f pnnx: store bool MemoryData attributes as raw int8 (#7006)
* pnnx: store bool MemoryData attributes as raw int8

Keep bool constants as one byte per element and select MemoryData
load_type=3. Implement the reserved raw int8 ModelBin loading mode and
pad exported bool data to four bytes so subsequent weights stay aligned.
This preserves the byte representation used by the proposed logical ops.

Add regression coverage for scalar and padded bool exports in both fp16
modes, multidimensional MemoryData, raw int8 loading through reference
and copy readers, trailing fp32 weights, and missing padding. Document
the format.

Based on the bool attribute serialization fixes proposed in:
https://github.com/Tencent/ncnn/pull/6956
https://github.com/Tencent/ncnn/pull/6866

Fixes #6855

* tools: preserve byte MemoryData when optimizing models

Save MemoryData load_type so raw int8 constants retain their byte
representation after ModelWriter saves the model. Skip fusion paths that
interpret MemoryData as float32 when its elements are not four bytes.

This change does not add bool arithmetic support or automatic type
promotion. Byte bool storage is intended for future logical, comparison
and selection operators.

Validated ncnnoptimize save and reload for scalar and one-to-five-element
bool constants in fp32 and fp16 storage modes, preserving byte values
and element size in all 12 cases.

---------

Co-authored-by: ktz03 <2484593937@qq.com>
Co-authored-by: Giulio Corradi <53930027+giuliocorradi@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 10:09:00 +08:00
LI 44ada84b98 fix(vulkan): omit zero-count descriptor pool sizes (#6952)
* fix(vulkan): omit zero-count descriptor pool sizes

Fixes #6951

* fix vulkan descriptor pool sampler count

---------

Co-authored-by: nihui <nihuini@tencent.com>
2026-09-16 14:07:37 +08:00
LEKKO2310 2c43fc4f29 vulkan: apply atan2 zero workaround to packed shaders (#6930)
* vulkan: apply atan2 zero workaround to packed shaders

Mesa v3dv has the same broken vector atan(0, 0) behavior as llvmpipe. Apply the existing zero-input workaround for all non-MoltenVK drivers so packed BinaryOp atan2 and ratan2 match the CPU result.

Fixes #6884.

* vulkan: limit packed atan2 zero workaround to llvmpipe and v3dv

---------

Co-authored-by: nihui <nihuini@tencent.com>
2026-09-16 11:44:11 +08:00