739 Commits
Author SHA1 Message Date
KawrakowandGitHub 1dede1d79e Adding Muse-Glimmer support (#2293)
* Adding Muse-Glimmer support

* Different rms_eps for post norm ops

* Need attn_post_norm split for Muse-Flimmer

* WIP: split mode graph

* Forgot this file

* Clean it up

* Minor

* Muse-glimmer: Slightly better split mode graph (+2% TG)
2026-08-12 15:53:54 +02:00
26ceed9d40 CUDA: clear MMQ row padding on partially offloaded quantized weights (#2292)
Co-authored-by: Joel Farthing <262452229+joelfarthing@users.noreply.github.com>
2026-08-11 09:07:01 +02:00
KawrakowandGitHub 5763a901de DSA: do not copy V rows when V == K (#2287) 2026-08-10 18:49:05 +02:00
KawrakowandGitHub b37189aae4 Actually fix quantized indexer cache on CUDA (#2286) 2026-08-10 18:46:02 +02:00
KawrakowandGitHub b8b3034b0f Indexer topk: on the CPU repack Q8_0 indexer cache (#2285) 2026-08-10 18:45:43 +02:00
KawrakowandGitHub 7642ac3eca Fix massive inefficiency in CUDA Q->f32/f16 and f32/f16->Q copies (#2279)
* CUDA indexer topk: this is better for PP

* Don't overstep

* Cleanup

* Allow Q8_0 cache in the CUDA DSA implementation

* DS4: do not cast caches to f32

* Fix massive inefficiency in CUDA Q->f32/f16 and f32/f16->Q copies

* Re-enable -ictk | --indexer-cache-type-k
2026-08-08 17:26:59 +03:00
KawrakowandGitHub 76c1942716 Allow Q8_0 cache in the CUDA DSA implementation (#2276)
* CUDA indexer topk: this is better for PP

* Don't overstep

* Cleanup

* Allow Q8_0 cache in the CUDA DSA implementation
2026-08-08 17:18:36 +03:00
KawrakowandGitHub c5f37f0fba Indexer topk optimization (#2274)
* CUDA indexer topk: this is better for PP

* Don't overstep

* Cleanup
2026-08-08 17:14:18 +03:00
40dffce685 CUDA: Fix non-F16 indexer top-k (#2272)
* CUDA: Fix non-F16 indexer top-k

* CUDA: Handle strided F32 indexer keys

---------

Co-authored-by: Joel Farthing <262452229+joelfarthing@users.noreply.github.com>
2026-08-07 19:35:17 +03:00
KawrakowandGitHub 61b37f5f44 Reduce the indexer temporary buffer size (#2271) 2026-08-07 17:09:18 +03:00
KawrakowandGitHub 466d9bb15f Merged up/gate for DS4 (#2257)
* Merged up/gate for DS4

* Just in case

* WIP

* Fix CUDA silu kernel for merged up/gate with limit
2026-08-07 07:51:58 +03:00
KawrakowandGitHub 113f426a3c Do not include ggml-impl.h in ggml-cuda.cu (#2264) 2026-08-07 07:23:43 +03:00
KawrakowandGitHub b4be4b17a0 Another minor indexer optimization on the CPU (#2231)
* Convert and repacl f16 K to 4-row-interleaved f32 on AVX2

* Cleanup
2026-08-05 08:15:41 +03:00
KawrakowandGitHub 1474935e31 Bucket top_k (CPU): ~3% better TG at 128k context (#2225) 2026-08-05 07:50:41 +03:00
KawrakowandGitHub 7257cabc49 Fix #2201 (#2255) 2026-08-05 07:48:20 +03:00
Petr VilímandGitHub af4e0cbdb6 ggml : fuse the delta-net recurrent state copy into the op (#2251)
* ggml : assert the delta-net value head dim equals the key head dim

The CPU forward sizes its result from the value head dim (src[2]->ne[0]) but
indexes it with the key head dim (src[0]->ne[0]). A model where the two differ
was mis-indexed silently. The CUDA op has asserted this all along.

* ggml : fuse the delta-net recurrent state copy into the op

The problem: the delta-net op produces the new recurrent state into the tail of
its result. Then llama copies that tail into the KV slot the state was read
from. The copy buys nothing - the kernel could write the slot itself.

The change: the slot's two halves are written by two narrow CPY nodes instead of
one CONCAT. That isolates the state write in an ordinary node, which the
scheduler places by the rules it already has. A backend that recognises the
pattern lets the kernel write the slot directly and skips that node. One that
does not implement the fusion runs the copy as before. No public header changes.

Notes: this leaves ggml_concat_inplace(), added in #1777 for exactly this site,
without a caller.
2026-08-04 19:27:27 +03:00
NexesenexandGitHub f8b5664c18 Chores : Typos fixing round 3 (project wide, ggml dir included, comments and user facing msg only) (#2249)
* ggml: fix typos in comments across ggml/src

Corrects misspellings found in source comments (no code/logic changes):

CUDA:
- quantize.cu / quantize_id.cu: 'memroy' -> 'memory', stray 'Exchange' word in reduction comment
- fattn-mma-f16.cuh / fattn-new-mma.cu: 'synchonization' -> 'synchronization'
- fattn-new-mma.cu / fattn-vec-common.cuh: 'at lease' -> 'at least'
- fattn-vec-f32.cuh: 'Currenlty'/'dose' -> 'Currently'/'does'
- mmq_id_common.cuh: 'alays' -> 'always'
- softmax.cu: 'noncontigous' -> 'noncontiguous'

CPU / quantization:
- ggml-quants.c: 'At leat' -> 'At least'
- ggml.c: 'repeatition' -> 'repetition'

CANN:
- aclnn_ops.cpp: 'alloced' -> 'allocated', 'contigous' -> 'contiguous'
- kernels/dup.cpp: 'contigous' -> 'contiguous'

IQK:
- iqk_gemm_1bit.cpp: 'explicitely' -> 'explicitly'
- iqk_gemm_ktquants.cpp: 'nn AVX2' -> 'in AVX2'

Vulkan:
- ggml-vulkan.cpp: duplicated 'in in' -> 'in'

* ggml: fix less-common typos in comments (spellchecker pass)

Second sweep using a spell-check pass with edit-distance filtering to catch
typos missed by the common-misspelling list. Comment/comment-context fixes
only, no code changes:

- aclnn_ops.cpp: 'performace' -> 'performance'
- acl_tensor.cpp: 'shoule in' -> 'should be in'
- common.h: 'opertors'/'available' -> 'operators'/'available'
- ggml-cuda.cu: 'resepctive' -> 'respective', 'resinding' -> 'residing'
- conv2d.cu: 'ouptut_chanles' -> 'output_channels'
- scale.cu: 'Whehn' -> 'When'
- mmq_id_common.cuh: 'renameing' -> 'renaming'
- solve_tri.cu: 'supress' -> 'suppress'
- ggml-quants.c: 'ptoducts' -> 'products', 'quckly' -> 'quickly',
  'Acummulate' -> 'Accumulate'
- ggml-sycl.cpp: 'solutino'/'walkaroud' -> 'solution'/'workaround'
- ggml-vulkan.cpp: 'aross' -> 'across'
- ggml.c unified base: signficantly -> significantly (recorded in iqk too)

Also fixed duplicate word 'get get' in the quckly comments (line 14272/14488).

* Fix typo: correct hard-to-count words in comments/docs across common/examples

Spellcheckedtypos across common/, examples/, tests/ and include/ (from
typos2.txt): preserve->preserving, replacement->replacemnt,
enhance->enchance, imatrix/ima->imatrix, correct->corerct,
parameter->parmeter, utilizing->utilitizing, backward->backwrad,
manipulate->manupulate, together->togather, incomplete->parial,
sentence->dentence, retrieval->retie, prepared->prepa, partial->parial,
randomly->Randonly. Comment/prose only, no code changes.

* fixing typos (public_simplechat example)

* fixing typos (examples subdirs)
2026-08-04 07:15:28 +03:00
KawrakowandGitHub bee545824a Allow concatenating quantized tensors (#2232)
* Allow concatenating quantized tensors

* Missed this assert

* Allow K to be f32 in ggml_cuda_op_indexer_topk
2026-08-03 08:01:57 +03:00
KawrakowandGitHub 5692312327 Fix IQ4_NL_R4 GEMM on CPUs with FANCY_SIMD enabled (#2233) 2026-08-02 11:15:36 +03:00
KawrakowandGitHub f2bde5749b Faster indexer top_k for very long context (CPU) (#2206)
* Faster indexer top_k for very long context (CPU)

* Minor
2026-08-01 09:17:51 +03:00
KawrakowandGitHub a8ae4fb36f Fix IQ3_XXS CPU GEMM (#2224) 2026-08-01 08:51:59 +03:00
KawrakowandGitHub 74cccfd71d Chunked experts (CPU) (#2202)
* Chunked experts

* Option to turn it off at compile time
2026-07-30 13:16:02 +03:00
KawrakowandGitHub 707374b3c3 DS4: faster long-context TG (#2201)
* DS4: faster long-context TG

* Also this
2026-07-30 13:13:42 +03:00
KawrakowandGitHub 6647db9c27 DS4: streamline RoPE (#2198)
* Use RoPE in-place to skip concatenating tensors

* Remove some code duplication

* Remove commented out code
2026-07-29 07:36:53 +03:00
KawrakowandGitHub b054a8b983 Revert CUDA concat change in #2179 (#2200) 2026-07-28 12:22:55 +03:00
KawrakowandGitHub f0f6ae4bb0 MXFP4_R8 (#2196)
* Adding MXFP4_R8 with AVX2 implementation

* Also offline repack

* Add AVX512 implementation for MXFP4_R8
2026-07-28 08:03:59 +03:00
KawrakowandGitHub 5f063b7bba DS4 refactoring (#2190)
* DS4 refactoring

* Minor
2026-07-27 09:14:35 +03:00
KawrakowandGitHub e84c038310 DS4 optimizations (part 2) (#2179)
* DS4 optimizations (part 2)

* This is slightly better

* Another minor tweak

* Increase max. number of graph splitinputs to 64

Else with DS4 we can trun into an assert for specific offload
situations with more than one GPU.
2026-07-26 16:03:56 +03:00
KawrakowandGitHub bd342d624f DS4 optimizations (#2169)
* Adding ds4_comp op with CPU implementation

* ds4_comp on CUDA

* ds4_comp: ratio = 4 specialization

Surprisingly small performance gain

* Also handle HCA via ds4_comp

But much smaller gain, if any.

* Delete commented out stuff

* Remove the [(size_t) il] noise

* Minor

* Fix quantized cache
2026-07-25 08:52:38 +03:00
31018dc511 openpangu: fused latent attention op (GGML_OP_LATENT_ATTN) (#2168)
Adds ggml_latent_attn_prefix_ext / ggml_latent_attn_indexed_ext: MLA
latent-cache attention with an always-visible learned K/V prefix
(openPangu's 128 param_sink rows), joint softmax over [prefix | cache],
reading the raw F32/F16/Q8_0 latent cache directly. CUDA implementation
plus a scalar CPU reference that pins the op's semantics; the CPU
backend reports support truthfully, and openPangu adopts the op only on
a non-CPU backend as builder policy.

openPangu routes its dense/SWA/MTP full-span attention and the gathered
DSA path through the op, capability-gated per layer on the attention
output projection's scheduled backend, with the latent cache required
resident on that same backend (--no-kv-offload keeps the unfused
chain); any layer whose backend cannot run the candidate keeps the
exact unfused chain.

Co-authored-by: Joel Farthing <262452229+joelfarthing@users.noreply.github.com>
2026-07-23 14:50:45 +03:00
3861e045fc indexer_topk: fix quantized q8_1 scratch sizing on CUDA (#2158)
* indexer_topk: fix quantized q8_1 scratch sizing on CUDA

The quantized-K path under-sized its q8_1 scratch buffer: it allocated q->ne[1]*max_rows blocks using the unpadded head dim, but quantize_mmq_q8_1_cuda writes q_padded/QK8_1 blocks per row and must process all q->ne[1]*nrows rows. Size the buffer by (q_padded/QK8_1) blocks x (q->ne[1]*max_rows) rows and pass the full q->ne[1]*nrows row count so the scratch cannot be overrun and every query row is quantized.

CUDA graph identity: INDEXER_TOPK dispatches a source-type-specialized kernel (dense F16 vs quantized cache, F32 vs F16 mask). Source addresses alone do not identify the captured kernel, so snapshot each source type in ggml_graph_node_properties and force re-capture when an INDEXER_TOPK source type changes, preventing a reused graph from replaying the wrong kernel variant when sources are reallocated at the same address.

CPU backend: report INDEXER_TOPK support via iqk_indexer_topk_supported (guarded by GGML_USE_IQK_MULMAT) so the scheduler places the node on a backend that can run it. Harden the scheduler's pass-5 node-assignment check from assert to GGML_ASSERT so a node no backend supports fails as a defined abort under NDEBUG instead of indexing sched->backends[-1].

* indexer_topk: drop CPU capability predicate

* indexer_topk: fall back when unsupported

* cuda: drop speculative INDEXER_TOPK graph type matching

---------

Co-authored-by: Joel Farthing <262452229+joelfarthing@users.noreply.github.com>
2026-07-22 17:20:10 +03:00
7945404458 DS4: slowly approaching a meaningful performance (#2165)
* initial map to load deepseek 4 arch

* wip

* wip: match graph build and attn logic for dpv4

* wip: Enhance DeepSeek-V4 architecture with new tensor types and sqrtsoftplus gating function

* Update DeepSeek-V4 to support raw key indexing with read/write indices

* fix mismatch in attn_raw

* Enable FA with CSA/HCA

* Fix logit mismatch with FA path

* Clean traces and logs for debug

* Refactor DSV4 tensor handling for MTP execution and improve raw context management

* Refactor DeepSeek4 tensor operations: replace manual weighted sum and post-processing with new helper functions

* Share mHC pre-projection and fix packed DSV4 writes

* DSV4: add shared top-k selection and improve mask handling

* Fix DSV4 c2048 view stride and duplicate loader instantiation

* Reuse shared RMS normalization in DSV4 graph

* Replace DSV4 indexer rotation with shared Hadamard

* Share CSA visibility mask with DSV4 LID

* dsv4: document dependency ordering and reset state

* Remove DSV4 zero-dependency graph shim

* Fix DSV4 packed stream execution

* Remove DSV4 l_out backend override

* Enable DSV4 quantized K-only cache

* Revert "Enable DSV4 quantized K-only cache"

This reverts commit 04f9b42532.

* Fix DSV4 quantized cache accounting

* Fail closed on unsupported DSV4 cache lifecycle operations

* Various optimizations

* llama: fix GGML_METAL=ON build - missing ggml-metal.h include in llama-dflash.cpp (#2134)

llama-dflash.cpp calls ggml_backend_is_metal() and
ggml_backend_metal_set_n_cb() inside an #ifdef GGML_USE_METAL block but
never includes ggml-metal.h, so any Metal-enabled build fails to
compile. Add the same guarded include llama.cpp already uses.

* New op: ggml_sum_rows_ext (#2132)

* Add ggml_sum_rows_ext

* openPangu: use ggml_sum_rows_ext also in mhc_post

* openPangu: use ggml_sum_rows_ext also in mhc_tail

* Minor

* Reuse shared inverse RoPE operation for DSV4

* Reuse maintainer CUDA concat implementation

* WIP

* hc_pre

* hc_post

* Remove unnecessary mask manipulations

* WIP

* Take into account swiglu limits

* Turn on fused indexer by default

* Give names to mat mul results

* More named ops

* dsv4: do not uselessly copy the KV cache

+20% TG at 32k tokens

* mask_to_index and make CPU FA work with that

* Much better CPU-only, CUDA still not functional

* Better CPU TG

I'm now at 9.7 t/s for zero context and 6.5 t/s for context of 32k.
PP is 120 t/s for short context and 101 t/s at 32k.

* Even better CPU TG

I'm now at 8.1 t/s for context of 32k tokens.

* Turn off DSA on CUDA for now

* Fix CUDA DSA

* Remove again the unnecessary softmax result buffer

* Experiments

* Various

* More named ops

* Forgot to uncomment

---------

Co-authored-by: samuel <samueloliveira32df@gmail.com>
Co-authored-by: hchengit <95317477+hchengit@users.noreply.github.com>
2026-07-22 17:18:57 +03:00
KawrakowandGitHub fbcc743c70 Fix race in indexer topk on CUDA (#2148) 2026-07-17 18:08:18 +03:00
hchengitandGitHub 2b8d0d5011 metal: implement ROPE_MULTI (mrope/imrope) kernels (#2140)
The Metal backend lacked GGML_ROPE_TYPE_MROPE/IMROPE support, so models
whose GGUF carries rope_sections (e.g. Qwen 3.5 hybrids) could not run
fully offloaded on Apple Silicon.

Add rope_multi_f32/f16 kernels with section-based position handling
(t/h/w/e blocks, 4 position ids per token), imrope's interleaved section
selection, and the corresponding dispatch in ggml-metal.m. Vision-mode
mrope is not implemented and is asserted out explicitly.

Validated on M2: kernel output matches the CPU backend, and Qwen 3.5-9B
(Q4_K_M, -ngl 99) WikiText-2 perplexity over 145 chunks lands within
0.006 of the same model's CPU baseline.
2026-07-17 17:49:13 +03:00
7ae6b337a7 P100 tile-f32 exact-retile: half2 K/V smem staging (2-blocks/SM + leaner inner loop) (#2142)
Faster fp32-class replacement for the tile_f32 flash-attention inner path on P100
(sm_60). Bit-identical fp32 arithmetic to the un-retiled kernel (same-top 99.28% =
the float-reorder floor; QK differs only in accumulation order, ~1 ulp; P.V
bit-identical), restructured via half2 K/V shared-memory staging that both cuts
shared memory and leans the inner loop.

Measured +4-9% vs the un-retiled fp32 tile kernel, back-to-back. The speedup is a
COMPOUND of two effects the staging produces together (shares not isolated):
  (1) occupancy: smem 36992 -> 28800 B/block admits 2 blocks/SM where the un-retiled
      kernel fits only 1 (2*28800=57600<=65536; 80 regs would allow 3, smem is the
      ceiling); a genuine 1->2 gain, corroborated by a cross-family perf panel;
  (2) a leaner inner loop: ~2x fewer QK-loop smem loads, the dropped score round-trip,
      one fewer barrier.
__launch_bounds__(...,2) only PINS the target the smem reduction already reaches (a
(...,1) bound compiles bit-identically), so the directive is not itself a lever, and a
3rd block does not help (cost-curve + an implemented regs-80->124 attempt confirm smem
caps occupancy at 2).

Validated on P100 as the drop-in for the carve-out path (pr-p100-fp16). Reviewed by a
6-model Claude council + a cross-family cloud perf panel; the panel corrected an earlier
'not occupancy' framing to this compound one.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 17:40:41 +03:00
7174a124ca CUDA: route P100 (sm_60) decode flash-attention to fp32 vec kernel (#2144)
On P100 (GP100, sm_60) the fp16 vec kernel used for decode (batch<=8)
accumulates the online-softmax denominator and the P*V product in fp16,
flipping ~3-4% of decode top-1 tokens vs an all-fp32 reference
(llama.cpp#25593). Decode is memory-bandwidth-bound on P100, so routing
sm_60 decode to the in-tree vec_f32 kernel is free (tg128 ~identical).

Gated on cc == CC_PASCAL && Q->ne[1] <= 8 (decode only) inside the
!fp16_mma_available block, so the prefill tile_f16 path, the D=256 prefill
vec path, and fast_fp16_available() are untouched, and the
is_pascal_mla_absorbed_decode early-return (MLA) is unaffected.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 17:40:06 +03:00
a0a10da5a9 CUDA: re-capture the graph when a CPY node's read-source address changes (#2136)
ggml_graph_node_has_matching_properties exempted every GGML_OP_CPY node from the source-address check, for both operands. The exemption is needed for KV-cache write copies, whose destination advances each step through the indirect-destination path. It also skips a CPY whose read source (src[0]) moves between graph replays while the surrounding subgraph stays shape-stable, so the captured kernel replays against a stale source pointer and reads the previous step's bytes.

Keep the exemption for the destination operand (src[1]) only, and compare a CPY's read source (src[0]) like any other node. Stable-source copies are unaffected and force no additional re-captures; a CPY whose read source genuinely moves now re-captures instead of reading stale memory.

Co-authored-by: Joel Farthing <262452229+joelfarthing@users.noreply.github.com>
2026-07-17 14:06:33 +03:00
a5b130389b Fix build on macOS (#2137)
* Fix build on macOS

* Add forgotten check

---------

Co-authored-by: Iwan Kawrakow <iwan.kawrakow@gmail.com>
2026-07-17 14:05:55 +03:00
KawrakowandGitHub 1fddd12ba8 New op: ggml_sum_rows_ext (#2132)
* Add ggml_sum_rows_ext

* openPangu: use ggml_sum_rows_ext also in mhc_post

* openPangu: use ggml_sum_rows_ext also in mhc_tail

* Minor
2026-07-15 16:21:17 +03:00
Kawrakow 7937465ff1 Compiler warning 2026-07-13 10:34:26 +00:00
KawrakowandGitHub 593a196f78 DSA: Better way to build the attention mask (#2119)
* WIP: indexer_topk on CUDA

* Forgot these

* WIP

* WIP

* This seems to work

* Minor

* Fix bug. Fix suggested by @sayap using GLM-5.2

* GLM-DSA: much better PP long context performance (CUDA)

* DSA: Better way to build the attention mask
2026-07-13 13:28:05 +03:00
KawrakowandGitHub 0d5d1330e2 GLM-DSA: much better PP long context performance (CUDA) (#2109)
* WIP: indexer_topk on CUDA

* Forgot these

* WIP

* WIP

* This seems to work

* Minor

* Fix bug. Fix suggested by @sayap using GLM-5.2

* GLM-DSA: much better PP long context performance (CUDA)
2026-07-12 19:33:33 +03:00
8e2d83cfee Fix per_layer_token_embedding (#2117)
Co-authored-by: cora4 <you@example.com>
2026-07-12 11:58:09 +03:00
97bc869552 ggml: add fused sinkhorn op (eps + output-layout params) (#2115)
* ggml: add fused sinkhorn op (eps + output-layout params); use it for openPangu mHC

* openpangu: call ggml_sinkhorn directly from mhc_post

---------

Co-authored-by: Joel Farthing <262452229+joelfarthing@users.noreply.github.com>
2026-07-12 09:59:50 +03:00
cora4andGitHub 0a1dd13c95 Set GGML_AVXVNNI to OFF by default (#2116) 2026-07-12 08:26:38 +03:00
KawrakowandGitHub e913807605 Fused indexer top_k (CUDA) (#2103)
* WIP: indexer_topk on CUDA

* Forgot these

* WIP

* WIP

* This seems to work

* Minor

* Fix bug. Fix suggested by @sayap using GLM-5.2
2026-07-12 08:08:04 +03:00
fedb48fa74 mtmd: add MiniMax M3 vision support (#2086)
Co-authored-by: Smart <smart@augmented-special.services>
2026-07-12 07:19:14 +03:00
NexesenexandGitHub 3a9d373411 IQK AVX2: Replace MM256_SET_M128I(x, x) identity broadcasts with _mm256_broadcastsi128_si256 (#2107)
* IQK AVX2: Replace MM256_SET_M128I(x, x) identity broadcasts with _mm256_broadcastsi128_si256

## Summary

Replace all 132 instances of the identity-broadcast pattern
`MM256_SET_M128I(x, x)` with `_mm256_broadcastsi128_si256(x)` across
8 files in ggml/src/iqk/.

## Correctness

The transformation is bit-exact. The `MM256_SET_M128I(a, b)` macro
expands to:
    _mm256_insertf128_si256(_mm256_castsi128_si256(b), a, 1)
which places `a` in the high 128-bit lane and `b` in the low lane.
When `a == b == x`, the result is x replicated to both lanes:
    [x_lo: x_hi] = {x, x}

`_mm256_broadcastsi128_si256(x)` produces the identical register state:
it copies the 128-bit input to both lanes in a single micro-op.

Perplexity was verified identical on llama-3.2-1b-Q8_0 and
google-gemma-3-4b-Q4_0-IQ4_XS before and after the change.
The transformation is a pure intrinsic substitution with
zero semantic difference.

## Performance

### Micro-architecture analysis

The old pattern compiles to:
    vinsertf128 ymm, ymm, xmm, 1   -- 3 uops, port 5, 3-cycle latency

The new pattern compiles to:
    vbroadcasti128 ymm, xmm         -- 1 uop, port 5, 1-cycle latency

Both instructions execute on port 5 (Intel), but vbroadcasti128:
  - Uses 1/3 the dispatch slots (fewer pipeline stalls)
  - Has 3x better latency (1 vs 3 cycles)
  - Is not lane-crossing (no bypass delay between 128-bit halves)

### Measured results

#### Test 1: llama-3.2-1b-Q8_0, 2048 ctx, -b 128 -ub 128

Compiler      | Metric | Before  | After   | Change
--------------|--------|---------|---------|-------
MSVC 19.44    | PP t/s | 596.89  | 604.57  | +1.29% (noise imo)
MSVC 19.44    | TG t/s | 55.13   | 55.72   | +1.07% (noise)
Clang 19.1.5  | PP t/s | 645.72  | 700.93  | +8.55% (systematic gain)
Clang 19.1.5  | TG t/s | 54.26   | 54.06   | -0.37% (noise)

#### Test 2: google-gemma-3-4b-Q4_0-IQ4_XS, 4096 ctx, -b 512

Compiler      | Metric   | Before   | After    | Change
--------------|----------|----------|----------|-------
Clang 19.1.5  | PP t/s   | 262.40   | 314.79   | +19.96% (systematic gain)
Clang 19.1.5  | TG t/s   | 30.78    | 32.32    | +5.00% (noise, TG oscilates between 31.5 and 33 t/s before / after)
Clang 19.1.5  | Total ms | 48881    | 44696    | -8.56%

Both tests ran on Intel Core Ultra 265K, 18 threads, flash_attn=1

The IQ4_XS result shows a dramatic PP improvement (+20%) because this
quantization format uses significantly more identity broadcasts in its
dequantization path (lookup-table expansion, scale duplication). The
compressed 4-bit representation requires more setup per block, making
the broadcast-to-256 step a measurable bottleneck that the 1-uop
vbroadcasti128 eliminates.

### Why these 132 instances matter

Every dequantization path (IQ2_XXS through IQ6_K, Q4_0 through Q8_1,
MXFP4) starts by broadcasting a 128-bit lookup table or scale vector
to 256 bits. These are in the inner loop of every quantization format's
dot-product kernel. Reducing each broadcast from 3 uops to 1 uop
cumulatively reduces port-5 pressure across the entire dequant
pipeline.

## Scope

This change touches only the identity-broadcast case (both MM256_SET_M128I
arguments are identical).

* IQK AVX2: Introduce MM256_SET1_M128I(x) wrapper for identity-broadcast pattern

Per Ikawrakow's review: replace direct _mm256_broadcastsi128_si256(x) with
a new macro MM256_SET1_M128I(x) wrapping the intrinsic, so that if the
broadcast turns out harmful on some CPU, only the macro definition needs
changing, not 132 call sites.

  #define MM256_SET1_M128I(x)   _mm256_broadcastsi128_si256(x)

The 132 identity-broadcast MM256_SET_M128I(x, x) call sites across 8 files
now use MM256_SET1_M128I(x) instead of the raw intrinsic.
2026-07-12 06:55:16 +03:00
dmaivelandGitHub 6a909f4ff6 Add --prefetch-experts to stream mmap'd MoE experts into page cache (#2101)
* Add --prefetch-experts to stream mmap'd MoE experts into page cache

* Drop fds, fault experts in with MADV_POPULATE_READ instead of pread

* Remove stale note about pread workers

* Move MoE prefetch behind ggml_backend_prefetch_* wrappers

* Cleanup stale comments

* Add --prefetch-experts-threads, drop GGML_MOE_PREFETCH_THREADS env var
2026-07-11 10:43:42 +03:00
KawrakowandGitHub 6d30fa2fe6 Fused indexer top_k (CPU only) (#2098)
* Indexer topk op - CPU only

We do save memory, but it is somehow much slower than what we have on
main.

* Make it a command line option
2026-07-09 18:04:41 +03:00