Skip to content

is_string type info and unset generated flag for lambda - #61

Merged
borisbat merged 2 commits into
GaijinEntertainment:masterfrom
profelis:master
Jun 17, 2020
Merged

is_string type info and unset generated flag for lambda#61
borisbat merged 2 commits into
GaijinEntertainment:masterfrom
profelis:master

Conversation

@profelis

Copy link
Copy Markdown
Collaborator

No description provided.

@borisbat
borisbat merged commit d0f44fc into GaijinEntertainment:master Jun 17, 2020
aleksisch pushed a commit to aleksisch/daScript that referenced this pull request Dec 9, 2025
borisbat added a commit that referenced this pull request Aug 30, 2026
…12 4.93x llama.cpp

The first CPU arm written under the llama.cpp side-by-side rule (LAWS 2026-08-30): their
kernel's techniques mapped onto our lattice and raced by the probe. The tile rides the
panel route - unpack_iq3s_panel_grp expands grid words + signs into the k5/k6 byte panel
per group (one i32 store per grid word, sign nibble through a 16-entry mask table, negate
(w ^ m) + (m & 0x01010101); magnitudes odd 1..15, no cross-byte carry) - and the gemv
gathers each superblock into an alloca panel through an emitted per-row loop
(emit_iq3s_gather; the grid and mask live as private [512 x i32]/[16 x i32] module
constants). Both ride emit_block_iq4xs's sign-trick lattice with panel loads in place of
the nibble+LUT; the reference tile body flips to the panel dot (kq_grp_row_dot_b fmt 33)
since the batch cell now hands it the unpacked panel.

Also fixed in passing, both found by this arm:
- emit_slice recorded the SAVED body/tails block handles as phi incoming blocks; a
  block-splitting emitter (the gather loop) leaves the builder in its continuation block,
  so the back edges were malformed. Now captures LLVMGetInsertBlock at the branch points -
  identical for every non-splitting emitter.
- HOW_TO QUIRK 21: an emitter-arm edit does NOT invalidate the JIT DLL cache (generator
  bodies are not in the hash) - three fix rounds ran stale stamps byte-identically before
  the cache-hit line gave it away. rm -rf .jitted_scripts after any emitter change.

Gates: probe test mode GEN TUNE TEST OK - every k33 perm 1.9e-6 incl the stamped maddubs
mr8 pair. Side by side, zen2 16t vs llama.cpp b10660 clean-cpu: pp512 516.9 +- 8.4 vs
104.9 (4.93x - the panel amortizes one gather across the 4-token tile; their nrc=1 kernel
re-gathers per token), tg128 52.4 +- 1.0 vs 57.0 (0.92x; the no-panel gemv spelling is
followup_general #61). Stamped e2e on the 1B IQ3_M: 63/64 greedy ids (the flip is the
final token - the stamped near-tie class), gen 44 t/s from 23 on the reference bodies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Aug 31, 2026
…V, tg 0.95x

The last tier for the format. Blob: an "iq3ss" arm mirroring the iq4xs 20->18 split verbatim
over t.iq3ss (identical strip/d addressing, so kq_scales_of is the iq4xs arm with the plane
swapped), quants at sb0*104, the % 512 off gate joining the split-scale row. Kernels ride
the previous commit's MSL constant tables: iq3s_gw() carries the 512-word grid,
MetalKqGemvIq3s stages it as a float4[512] MAGNITUDE slab (signs applied by select) at 4
rows per simdgroup (llama.cpp's N_R0_IQ3_S), MetalKqMvIq3sT B2/B4 + MetalKqMvB8Iq3s are the
iq4xs shells over the per-32-block lane map with the grid read direct, and MetalKqMulMmK45T
grows an IQ3S arm (threadgroup grid under @template_gate; the chain re-nested - `} else
static_if` is a parse error). Ladders, prefill gates, and the seven-format test cells follow
the iq4xs rows; fixtures at fmt 33 reuse the split-form scale fill with kq_row_ref through
dequant_iq3s_plane_superblock_at.

The decode GEMV got a full race before shipping: eight forms at n=2048 d=8192 (gather
placement x3, gather deleted, signs deleted, llama.cpp's exact geometry, row width, f4 slab)
all land in 127-141 GB/s against k4's 204 and k6's 287 in the same harness - the 9-bit-index
+ per-nibble-sign compose is format-intrinsic on M1, and the f4 slab is the best form and
ships. HOW_TO gains the race table and QUIRK 22 (judge Metal kernel levers with the kernel
probe, not tg128 e2e - +-8 t/s of e2e noise swallowed the +9% winner twice).

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels 2/2 (108s corpus),
e2e decodes the coherent story at gen 227 t/s. Rows vs llama.cpp b10660 Metal (same-run,
IQ3_M): pp512 3237.6 / 3344.3 (0.97x), tg128 199.4 / 209.0 (0.95x, up from 0.82x at the
first cut); M1 CPU pp512 886.2 / 433.6 (2.04x), tg128 57.4 / 66.6 (0.86x - the ledgered tg
tail class, followup #61/#62).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Aug 31, 2026
… grid, format closed

The fourth tier in one day, and the smallest Metal slice of the arc. Blob: the "iq3xxss"
arm mirrors the iq4xs 20->18 split verbatim over t.iq3xxss; quants bind at sb0*96; the
% 512 off gate and kq_fmt_gpu_supported grow the format. Kernels are the iq3s shapes with
three deltas: iq3xxs_gw (the 1 KB HALVED grid through the constant-table hoisting),
ksign7m (the parity sign byte - the ksigns table exists on no GPU tier), and 24-word rows
with one aux word per block. The GEMV ships directly in the crowned iq3s form - float4
magnitude slab, sign selects, 4 rows per simdgroup, dispatch rows/8 (QUIRK 22's race
already ran for this shape); MetalKqMvIq3xxsT B2/B4 + MetalKqMvB8Iq3xxs and the IQ3XXS
mul_mm arm (a gated uint[256] grid, the static_if chain re-nested once more) follow their
iq3s siblings, with every compile/release/enc ladder and test cell mirrored at fmt 34.

One cross-tier fix rode along: the CPU dequant/dot strip reads went SIGNED (int8 cast) to
match the GPU kernels' decode - real strips are 1..31 where the readings agree, but the
shared synthetic test fills carry high-bit bytes and the Metal row-ref would have diverged
from the kernels over them. test_kquant/test_kqformat stay green.

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels 2/2 (108s
corpus); the e2e decodes the SAME story stream as the CPU and Vulkan tiers at gen 218 t/s
(ttft 106ms). Rows vs llama.cpp b10660 (same local requant): M1 Metal pp512 3224.0 /
3429.9 (0.94x), tg128 213.5 / 227.3 (0.94x); M1 CPU pp512 906.0 / 410.5
(2.21x), tg128 53.5 / 74.0 (0.72x); zen2 CPU pp512 507.2 / 136.0 (3.73x), tg128 56.7 /
72.6 (0.78x - with the M1 CPU row, the arc's ledgered tg-tail class, followups #60/#61).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Aug 31, 2026
…first u64-grid format generated

iq2s joins the fmt-33/34 panel form end to end: the tile leaves the packed
lists and reads the byte-expanded panel (new unpack_iq2s_panel_grp - the
10-bit qs|qh index doubled into the u64 grid's low/high word pair, signs
through the shared smask expansion), kq_grp_row_dot_b grows a 23 arm (SIGNED
panel bytes x per-16 UNSIGNED strips under the 33/34 d fold - d pre-eighth-ed
at transcode), and the gemv gathers per superblock via emit_iq2s_gather off a
[2048 x i32] private grid constant. In emit_block_iq4xs the iq2 flag splits
the lo/hi accumulators and loads two ZExt strip vectors per block - per-16
strips cannot share the fused 33/34 dot.

Probe 11/11 k23 perms (maddubs 8.3e-7); the tuner crowns
dot_maddubs_width256_mr8 verdict=beats. QUIRK 15 rerun as written:
run.tune.json still pinned iq2sq8_tile_gen "reference" from Phase A, cleared
by run.das --tune. Gates: test_kquant -jit 229 pass, interp 216/17 skips,
kqformat 18/18, M1 probe + kquant -jit 232/1, lint 0. E2e stamped: gen 41 ->
47 t/s; the fork vs llama.cpp moves step 10 -> 5, a 0.211-logit top-2
near-tie (stamped folds move the flip point, not the class). zen2 16t vs
clean-cpu, the i1 vehicle: pp512 501.5 vs 138.5 (3.62x), tg128 55.8 vs 73.5
(0.76x - the ledgered #60/#61 CPU-decode tail).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Aug 31, 2026
…s the constant-table hoisting

The u64 grid ships as iq2s_gw - an all-literal fixed_array local the
363654b hoisting lowers to a program-scope constant table - so every
kernel reads it DIRECT: no threadgroup slab anywhere (an f4-expanded slab
of 1024 entries would be 32 KB, past the budget; the iq3s gridf form does
not scale to u64 grids). MetalKqGemvIq2s = the iq3s GEMV geometry with
per-word iq3s_sw/iq3s_sx compose and per-16 UNSIGNED strips (plain byte
reads, no ^128 sign trick); the B2/B4/B8 twins split dl per half; the
mul_mm rides a new IQ2S arm. The "iq2ss" blob arm is iq3ss's verbatim twin
([16 strips][2B d8 tail], 18B/sb); ladders across shapes/common/prefill/
layout; fill/rowref arms in the shared test helpers.

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels
2/2, lint 0. E2e (parity --ngl 99, resident Metal decode): ids 40/64 vs
llama.cpp - the fork at step 40 is a 0.0654-logit top-2 near-tie, the
arc's deepest match, on the same story stream as the CPU-JIT tier.
Four-tier table (vs llama.cpp b10660, the i1 vehicle): zen2 3.62x/0.76x,
5060 Vulkan 0.70x/0.81x, M1 CPU 2.14x/0.73x, M1 Metal 0.93x/0.93x - the
CPU/Vulkan tg tails are the ledgered #60/#61 class.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
…12 4.93x llama.cpp

The first CPU arm written under the llama.cpp side-by-side rule (LAWS 2026-08-30): their
kernel's techniques mapped onto our lattice and raced by the probe. The tile rides the
panel route - unpack_iq3s_panel_grp expands grid words + signs into the k5/k6 byte panel
per group (one i32 store per grid word, sign nibble through a 16-entry mask table, negate
(w ^ m) + (m & 0x01010101); magnitudes odd 1..15, no cross-byte carry) - and the gemv
gathers each superblock into an alloca panel through an emitted per-row loop
(emit_iq3s_gather; the grid and mask live as private [512 x i32]/[16 x i32] module
constants). Both ride emit_block_iq4xs's sign-trick lattice with panel loads in place of
the nibble+LUT; the reference tile body flips to the panel dot (kq_grp_row_dot_b fmt 33)
since the batch cell now hands it the unpacked panel.

Also fixed in passing, both found by this arm:
- emit_slice recorded the SAVED body/tails block handles as phi incoming blocks; a
  block-splitting emitter (the gather loop) leaves the builder in its continuation block,
  so the back edges were malformed. Now captures LLVMGetInsertBlock at the branch points -
  identical for every non-splitting emitter.
- HOW_TO QUIRK 21: an emitter-arm edit does NOT invalidate the JIT DLL cache (generator
  bodies are not in the hash) - three fix rounds ran stale stamps byte-identically before
  the cache-hit line gave it away. rm -rf .jitted_scripts after any emitter change.

Gates: probe test mode GEN TUNE TEST OK - every k33 perm 1.9e-6 incl the stamped maddubs
mr8 pair. Side by side, zen2 16t vs llama.cpp b10660 clean-cpu: pp512 516.9 +- 8.4 vs
104.9 (4.93x - the panel amortizes one gather across the 4-token tile; their nrc=1 kernel
re-gathers per token), tg128 52.4 +- 1.0 vs 57.0 (0.92x; the no-panel gemv spelling is
followup_general #61). Stamped e2e on the 1B IQ3_M: 63/64 greedy ids (the flip is the
final token - the stamped near-tie class), gen 44 t/s from 23 on the reference bodies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
…V, tg 0.95x

The last tier for the format. Blob: an "iq3ss" arm mirroring the iq4xs 20->18 split verbatim
over t.iq3ss (identical strip/d addressing, so kq_scales_of is the iq4xs arm with the plane
swapped), quants at sb0*104, the % 512 off gate joining the split-scale row. Kernels ride
the previous commit's MSL constant tables: iq3s_gw() carries the 512-word grid,
MetalKqGemvIq3s stages it as a float4[512] MAGNITUDE slab (signs applied by select) at 4
rows per simdgroup (llama.cpp's N_R0_IQ3_S), MetalKqMvIq3sT B2/B4 + MetalKqMvB8Iq3s are the
iq4xs shells over the per-32-block lane map with the grid read direct, and MetalKqMulMmK45T
grows an IQ3S arm (threadgroup grid under @template_gate; the chain re-nested - `} else
static_if` is a parse error). Ladders, prefill gates, and the seven-format test cells follow
the iq4xs rows; fixtures at fmt 33 reuse the split-form scale fill with kq_row_ref through
dequant_iq3s_plane_superblock_at.

The decode GEMV got a full race before shipping: eight forms at n=2048 d=8192 (gather
placement x3, gather deleted, signs deleted, llama.cpp's exact geometry, row width, f4 slab)
all land in 127-141 GB/s against k4's 204 and k6's 287 in the same harness - the 9-bit-index
+ per-nibble-sign compose is format-intrinsic on M1, and the f4 slab is the best form and
ships. HOW_TO gains the race table and QUIRK 22 (judge Metal kernel levers with the kernel
probe, not tg128 e2e - +-8 t/s of e2e noise swallowed the +9% winner twice).

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels 2/2 (108s corpus),
e2e decodes the coherent story at gen 227 t/s. Rows vs llama.cpp b10660 Metal (same-run,
IQ3_M): pp512 3237.6 / 3344.3 (0.97x), tg128 199.4 / 209.0 (0.95x, up from 0.82x at the
first cut); M1 CPU pp512 886.2 / 433.6 (2.04x), tg128 57.4 / 66.6 (0.86x - the ledgered tg
tail class, followup #61/#62).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
… grid, format closed

The fourth tier in one day, and the smallest Metal slice of the arc. Blob: the "iq3xxss"
arm mirrors the iq4xs 20->18 split verbatim over t.iq3xxss; quants bind at sb0*96; the
% 512 off gate and kq_fmt_gpu_supported grow the format. Kernels are the iq3s shapes with
three deltas: iq3xxs_gw (the 1 KB HALVED grid through the constant-table hoisting),
ksign7m (the parity sign byte - the ksigns table exists on no GPU tier), and 24-word rows
with one aux word per block. The GEMV ships directly in the crowned iq3s form - float4
magnitude slab, sign selects, 4 rows per simdgroup, dispatch rows/8 (QUIRK 22's race
already ran for this shape); MetalKqMvIq3xxsT B2/B4 + MetalKqMvB8Iq3xxs and the IQ3XXS
mul_mm arm (a gated uint[256] grid, the static_if chain re-nested once more) follow their
iq3s siblings, with every compile/release/enc ladder and test cell mirrored at fmt 34.

One cross-tier fix rode along: the CPU dequant/dot strip reads went SIGNED (int8 cast) to
match the GPU kernels' decode - real strips are 1..31 where the readings agree, but the
shared synthetic test fills carry high-bit bytes and the Metal row-ref would have diverged
from the kernels over them. test_kquant/test_kqformat stay green.

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels 2/2 (108s
corpus); the e2e decodes the SAME story stream as the CPU and Vulkan tiers at gen 218 t/s
(ttft 106ms). Rows vs llama.cpp b10660 (same local requant): M1 Metal pp512 3224.0 /
3429.9 (0.94x), tg128 213.5 / 227.3 (0.94x); M1 CPU pp512 906.0 / 410.5
(2.21x), tg128 53.5 / 74.0 (0.72x); zen2 CPU pp512 507.2 / 136.0 (3.73x), tg128 56.7 /
72.6 (0.78x - with the M1 CPU row, the arc's ledgered tg-tail class, followups #60/#61).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
…first u64-grid format generated

iq2s joins the fmt-33/34 panel form end to end: the tile leaves the packed
lists and reads the byte-expanded panel (new unpack_iq2s_panel_grp - the
10-bit qs|qh index doubled into the u64 grid's low/high word pair, signs
through the shared smask expansion), kq_grp_row_dot_b grows a 23 arm (SIGNED
panel bytes x per-16 UNSIGNED strips under the 33/34 d fold - d pre-eighth-ed
at transcode), and the gemv gathers per superblock via emit_iq2s_gather off a
[2048 x i32] private grid constant. In emit_block_iq4xs the iq2 flag splits
the lo/hi accumulators and loads two ZExt strip vectors per block - per-16
strips cannot share the fused 33/34 dot.

Probe 11/11 k23 perms (maddubs 8.3e-7); the tuner crowns
dot_maddubs_width256_mr8 verdict=beats. QUIRK 15 rerun as written:
run.tune.json still pinned iq2sq8_tile_gen "reference" from Phase A, cleared
by run.das --tune. Gates: test_kquant -jit 229 pass, interp 216/17 skips,
kqformat 18/18, M1 probe + kquant -jit 232/1, lint 0. E2e stamped: gen 41 ->
47 t/s; the fork vs llama.cpp moves step 10 -> 5, a 0.211-logit top-2
near-tie (stamped folds move the flip point, not the class). zen2 16t vs
clean-cpu, the i1 vehicle: pp512 501.5 vs 138.5 (3.62x), tg128 55.8 vs 73.5
(0.76x - the ledgered #60/#61 CPU-decode tail).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
…s the constant-table hoisting

The u64 grid ships as iq2s_gw - an all-literal fixed_array local the
363654b hoisting lowers to a program-scope constant table - so every
kernel reads it DIRECT: no threadgroup slab anywhere (an f4-expanded slab
of 1024 entries would be 32 KB, past the budget; the iq3s gridf form does
not scale to u64 grids). MetalKqGemvIq2s = the iq3s GEMV geometry with
per-word iq3s_sw/iq3s_sx compose and per-16 UNSIGNED strips (plain byte
reads, no ^128 sign trick); the B2/B4/B8 twins split dl per half; the
mul_mm rides a new IQ2S arm. The "iq2ss" blob arm is iq3ss's verbatim twin
([16 strips][2B d8 tail], 18B/sb); ladders across shapes/common/prefill/
layout; fill/rowref arms in the shared test helpers.

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels
2/2, lint 0. E2e (parity --ngl 99, resident Metal decode): ids 40/64 vs
llama.cpp - the fork at step 40 is a 0.0654-logit top-2 near-tie, the
arc's deepest match, on the same story stream as the CPU-JIT tier.
Four-tier table (vs llama.cpp b10660, the i1 vehicle): zen2 3.62x/0.76x,
5060 Vulkan 0.70x/0.81x, M1 CPU 2.14x/0.73x, M1 Metal 0.93x/0.93x - the
CPU/Vulkan tg tails are the ledgered #60/#61 class.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
…12 4.93x llama.cpp


The first CPU arm written under the llama.cpp side-by-side rule (LAWS 2026-08-30): their
kernel's techniques mapped onto our lattice and raced by the probe. The tile rides the
panel route - unpack_iq3s_panel_grp expands grid words + signs into the k5/k6 byte panel
per group (one i32 store per grid word, sign nibble through a 16-entry mask table, negate
(w ^ m) + (m & 0x01010101); magnitudes odd 1..15, no cross-byte carry) - and the gemv
gathers each superblock into an alloca panel through an emitted per-row loop
(emit_iq3s_gather; the grid and mask live as private [512 x i32]/[16 x i32] module
constants). Both ride emit_block_iq4xs's sign-trick lattice with panel loads in place of
the nibble+LUT; the reference tile body flips to the panel dot (kq_grp_row_dot_b fmt 33)
since the batch cell now hands it the unpacked panel.

Also fixed in passing, both found by this arm:
- emit_slice recorded the SAVED body/tails block handles as phi incoming blocks; a
  block-splitting emitter (the gather loop) leaves the builder in its continuation block,
  so the back edges were malformed. Now captures LLVMGetInsertBlock at the branch points -
  identical for every non-splitting emitter.
- HOW_TO QUIRK 21: an emitter-arm edit does NOT invalidate the JIT DLL cache (generator
  bodies are not in the hash) - three fix rounds ran stale stamps byte-identically before
  the cache-hit line gave it away. rm -rf .jitted_scripts after any emitter change.

Gates: probe test mode GEN TUNE TEST OK - every k33 perm 1.9e-6 incl the stamped maddubs
mr8 pair. Side by side, zen2 16t vs llama.cpp b10660 clean-cpu: pp512 516.9 +- 8.4 vs
104.9 (4.93x - the panel amortizes one gather across the 4-token tile; their nrc=1 kernel
re-gathers per token), tg128 52.4 +- 1.0 vs 57.0 (0.92x; the no-panel gemv spelling is
followup_general `#61`). Stamped e2e on the 1B IQ3_M: 63/64 greedy ids (the flip is the
final token - the stamped near-tie class), gen 44 t/s from 23 on the reference bodies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
…V, tg 0.95x


The last tier for the format. Blob: an "iq3ss" arm mirroring the iq4xs 20->18 split verbatim
over t.iq3ss (identical strip/d addressing, so kq_scales_of is the iq4xs arm with the plane
swapped), quants at sb0*104, the % 512 off gate joining the split-scale row. Kernels ride
the previous commit's MSL constant tables: iq3s_gw() carries the 512-word grid,
MetalKqGemvIq3s stages it as a float4[512] MAGNITUDE slab (signs applied by select) at 4
rows per simdgroup (llama.cpp's N_R0_IQ3_S), MetalKqMvIq3sT B2/B4 + MetalKqMvB8Iq3s are the
iq4xs shells over the per-32-block lane map with the grid read direct, and MetalKqMulMmK45T
grows an IQ3S arm (threadgroup grid under @template_gate; the chain re-nested - `} else
static_if` is a parse error). Ladders, prefill gates, and the seven-format test cells follow
the iq4xs rows; fixtures at fmt 33 reuse the split-form scale fill with kq_row_ref through
dequant_iq3s_plane_superblock_at.

The decode GEMV got a full race before shipping: eight forms at n=2048 d=8192 (gather
placement x3, gather deleted, signs deleted, llama.cpp's exact geometry, row width, f4 slab)
all land in 127-141 GB/s against k4's 204 and k6's 287 in the same harness - the 9-bit-index
+ per-nibble-sign compose is format-intrinsic on M1, and the f4 slab is the best form and
ships. HOW_TO gains the race table and QUIRK 22 (judge Metal kernel levers with the kernel
probe, not tg128 e2e - +-8 t/s of e2e noise swallowed the +9% winner twice).

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels 2/2 (108s corpus),
e2e decodes the coherent story at gen 227 t/s. Rows vs llama.cpp b10660 Metal (same-run,
IQ3_M): pp512 3237.6 / 3344.3 (0.97x), tg128 199.4 / 209.0 (0.95x, up from 0.82x at the
first cut); M1 CPU pp512 886.2 / 433.6 (2.04x), tg128 57.4 / 66.6 (0.86x - the ledgered tg
tail class, followup `#61`/`#62`).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
… grid, format closed


The fourth tier in one day, and the smallest Metal slice of the arc. Blob: the "iq3xxss"
arm mirrors the iq4xs 20->18 split verbatim over t.iq3xxss; quants bind at sb0*96; the
% 512 off gate and kq_fmt_gpu_supported grow the format. Kernels are the iq3s shapes with
three deltas: iq3xxs_gw (the 1 KB HALVED grid through the constant-table hoisting),
ksign7m (the parity sign byte - the ksigns table exists on no GPU tier), and 24-word rows
with one aux word per block. The GEMV ships directly in the crowned iq3s form - float4
magnitude slab, sign selects, 4 rows per simdgroup, dispatch rows/8 (QUIRK 22's race
already ran for this shape); MetalKqMvIq3xxsT B2/B4 + MetalKqMvB8Iq3xxs and the IQ3XXS
mul_mm arm (a gated uint[256] grid, the static_if chain re-nested once more) follow their
iq3s siblings, with every compile/release/enc ladder and test cell mirrored at fmt 34.

One cross-tier fix rode along: the CPU dequant/dot strip reads went SIGNED (int8 cast) to
match the GPU kernels' decode - real strips are 1..31 where the readings agree, but the
shared synthetic test fills carry high-bit bytes and the Metal row-ref would have diverged
from the kernels over them. test_kquant/test_kqformat stay green.

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels 2/2 (108s
corpus); the e2e decodes the SAME story stream as the CPU and Vulkan tiers at gen 218 t/s
(ttft 106ms). Rows vs llama.cpp b10660 (same local requant): M1 Metal pp512 3224.0 /
3429.9 (0.94x), tg128 213.5 / 227.3 (0.94x); M1 CPU pp512 906.0 / 410.5
(2.21x), tg128 53.5 / 74.0 (0.72x); zen2 CPU pp512 507.2 / 136.0 (3.73x), tg128 56.7 /
72.6 (0.78x - with the M1 CPU row, the arc's ledgered tg-tail class, followups `#60`/`#61`).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
…first u64-grid format generated


iq2s joins the fmt-33/34 panel form end to end: the tile leaves the packed
lists and reads the byte-expanded panel (new unpack_iq2s_panel_grp - the
10-bit qs|qh index doubled into the u64 grid's low/high word pair, signs
through the shared smask expansion), kq_grp_row_dot_b grows a 23 arm (SIGNED
panel bytes x per-16 UNSIGNED strips under the 33/34 d fold - d pre-eighth-ed
at transcode), and the gemv gathers per superblock via emit_iq2s_gather off a
[2048 x i32] private grid constant. In emit_block_iq4xs the iq2 flag splits
the lo/hi accumulators and loads two ZExt strip vectors per block - per-16
strips cannot share the fused 33/34 dot.

Probe 11/11 k23 perms (maddubs 8.3e-7); the tuner crowns
dot_maddubs_width256_mr8 verdict=beats. QUIRK 15 rerun as written:
run.tune.json still pinned iq2sq8_tile_gen "reference" from Phase A, cleared
by run.das --tune. Gates: test_kquant -jit 229 pass, interp 216/17 skips,
kqformat 18/18, M1 probe + kquant -jit 232/1, lint 0. E2e stamped: gen 41 ->
47 t/s; the fork vs llama.cpp moves step 10 -> 5, a 0.211-logit top-2
near-tie (stamped folds move the flip point, not the class). zen2 16t vs
clean-cpu, the i1 vehicle: pp512 501.5 vs 138.5 (3.62x), tg128 55.8 vs 73.5
(0.76x - the ledgered `#60`/`#61` CPU-decode tail).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
borisbat added a commit that referenced this pull request Sep 1, 2026
…s the constant-table hoisting


The u64 grid ships as iq2s_gw - an all-literal fixed_array local the
363654b hoisting lowers to a program-scope constant table - so every
kernel reads it DIRECT: no threadgroup slab anywhere (an f4-expanded slab
of 1024 entries would be 32 KB, past the budget; the iq3s gridf form does
not scale to u64 grids). MetalKqGemvIq2s = the iq3s GEMV geometry with
per-word iq3s_sw/iq3s_sx compose and per-16 UNSIGNED strips (plain byte
reads, no ^128 sign trick); the B2/B4/B8 twins split dl per half; the
mul_mm rides a new IQ2S arm. The "iq2ss" blob arm is iq3ss's verbatim twin
([16 strips][2B d8 tail], 18B/sb); ladders across shapes/common/prefill/
layout; fill/rowref arms in the shared test helpers.

Gates on the M1 Max: test_metal_gemv_kernels 2/2, test_metal_gemm_kernels
2/2, lint 0. E2e (parity --ngl 99, resident Metal decode): ids 40/64 vs
llama.cpp - the fork at step 40 is a 0.0654-logit top-2 near-tie, the
arc's deepest match, on the same story stream as the CPU-JIT tier.
Four-tier table (vs llama.cpp b10660, the i1 vehicle): zen2 3.62x/0.76x,
5060 Vulkan 0.70x/0.81x, M1 CPU 2.14x/0.73x, M1 Metal 0.93x/0.93x - the
CPU/Vulkan tg tails are the ledgered `#60`/`#61` class.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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