552 lines
34 KiB
Plaintext
552 lines
34 KiB
Plaintext
MTPLX Qwen runtime shaders
|
|
=========================
|
|
|
|
mtplx-runtime-0.32.2.metallib is an unchanged copy of mlx/lib/mlx.metallib
|
|
from the existing MTPLX reference environment (runtime version 0.32.2).
|
|
|
|
SHA256: dc59d1cceb1a5c7e578232e6e41e28e2c73c9463ac6dbc3886c3ee17ffc270ed
|
|
Source tag: v0.32.2
|
|
Source commit: 1f8e74e3f12f31365464a6867c6579f0e9b29d85
|
|
Source: https://github.com/ml-explore/mlx/tree/v0.32.2
|
|
License: MIT, reproduced in MLX-LM-LICENSE.txt (identical license text).
|
|
|
|
Only GPU shader code is included. No libmlx.dylib, Python inference code,
|
|
or C/C++ application/backend code is linked into DS4Server. Rust selects
|
|
the shader entry points, binds model buffers and owns graph execution.
|
|
|
|
The reference's get_quantized_kernel implementation was verified to call
|
|
Device::get_kernel on the default precompiled library, matching
|
|
mlx/backend/metal/nojit_kernels.cpp at the pinned commit. The shader library
|
|
is reused byte-for-byte, including its precompiled specializations, rather
|
|
than independently rebuilding different kernels or compiler settings.
|
|
|
|
Provenance on the evaluation machine:
|
|
/private/tmp/MTPLX-analysis-20260901/.venv/lib/python3.12/site-packages/mlx/lib/mlx.metallib
|
|
|
|
The Rust test mtplx_runtime_shaders_are_pinned enforces the complete file
|
|
hash. Existing resource packaging includes the metal directory recursively.
|
|
This artifact adds approximately 174 MiB to the resources; it is not a model
|
|
download. Loading is lazy on the first runtime-shader dispatch.
|
|
|
|
The shader identity is not a claim that the complete Rust model graph,
|
|
scheduling, cache behavior, or end-to-end performance has reached parity.
|
|
|
|
Compiled QSA moving offsets
|
|
--------------------------
|
|
|
|
tests/fixtures/mtplx-qsa-update-jit.json records the actual compiled indexer
|
|
scalar shaders and compute_dynamic_offset_int32, observed without changing
|
|
the original compilation by tools/mtplx-jit-reference.py --operation qsa-update.
|
|
Only the contiguous int32[1] scalar specializations are retained; full observed
|
|
library source hashes are included. --check reruns the original compiled core.
|
|
The Dynamic Offset body is used unchanged by the Rust dynamic-copy path;
|
|
its original full source hash is
|
|
48a7309664f797e749aa42d2c2c4db0cf3abedf97297f0068d06b7847d988b93.
|
|
It is Copyright Apple Inc., MIT as reproduced in MLX-LM-LICENSE.txt.
|
|
The following gg1/gg2_dynamic_copybfloat16bfloat16 kernels are taken directly
|
|
from the unchanged runtime metallib. No frontiers are read back to the CPU.
|
|
Clamp/Multiply now feed the connected qsa_compiled_cache_window stage.
|
|
mtplx-qsa-compiled-scalars.json retains the actual generated scalar kernels,
|
|
including all three constant-CSE layouts for the Clamp and an independent
|
|
257/255 specialization check. Only structural integer literals and exported
|
|
symbols change when Rust specializes a kernel; the computations are unchanged.
|
|
mtplx-qsa-compiled-header.metal is the unmodified original compiler prefix;
|
|
SHA256: 2665a76463f3f6ee283c6a50b66e4a527318a114080b31441dfa900042097a39.
|
|
--qsa-header --check compares that prefix with a fresh original compilation.
|
|
Both resources contain runtime shader code, not host runtime code. Most is
|
|
Apple MIT. The unchanged full prefix also retains the Apache-2.0 cexpf.h
|
|
notice (Apple, NVIDIA, Filipe RNC Maia; license text in MTPLX-LICENSE.txt) and
|
|
the full BSD-2-Clause expm1f.h notice/disclaimer (Norbert Juffa 2015-2023).
|
|
Those overloads are retained as original header dependencies, not new Qwen
|
|
complex/exponential computation in the integer scalar kernels.
|
|
26 compiled reference calls verify the complete retained-input cache window.
|
|
They do not establish graph-bank replay, allocation/donation, BFS scheduling
|
|
or production inference parity.
|
|
|
|
tests/fixtures/mtplx-qsa-select-jit.json also retains the actual compiled Add
|
|
kernels for selector row offsets 0/1/2/3. Rust substitutes only the structural
|
|
offset literal and exported symbol, preserving the original +0 dispatch.
|
|
--operation qsa-update --qsa-mode blocks --qsa-score-budget 4096 --qsa-header
|
|
--check reproduces the connected reference selector and its exact sources.
|
|
Query preparation and both selector families now accept GPU frontier leaves
|
|
through the same original kernel dispatch used by the host-frontier entry.
|
|
66 actual compiled reference calls cover all five output modes, chunked
|
|
selection and the connected cache state for retained old input leaves. These
|
|
are functional Q/K-entry checks, not graph-bank, ownership or UI performance
|
|
acceptance. Host integration and the runtime evaluator remain open.
|
|
The retained-input Hidden entry has since been connected through the already
|
|
verified original affine projection kernels to that same Q/K implementation.
|
|
132 actual select_hidden calls cover 4/8-bit, group32/64 projections and all
|
|
five output modes. The combined entry test covers 198 reference calls. No new
|
|
Metal bodies or alternative projection/selection arithmetic are introduced.
|
|
The installed B1/BF16 cache/phase routing is now connected to backing reserve,
|
|
explicit GPU frontiers, those same retained-input arithmetic entries and cache
|
|
commit. 720 actual original host-method decisions and 108 additional complete
|
|
indexer calls cover routing and ongoing state/output transitions. The combined
|
|
host-flow test includes the previous 92 non-compiled calls through the same
|
|
entry. A parameter-bound QSA graph bank now replaces the direct compiled
|
|
expression chains. It rebinds explicit inputs to cached primitive dependencies
|
|
and uses the pinned degree/BFS-width algorithm for a single indexer graph.
|
|
99 optimized original graph contracts, all 198 arithmetic calls, stride-changing
|
|
replay, parameter invalidation and the original connected-call trace/entry
|
|
counters pass. Evaluated constants are omitted from structural fingerprints;
|
|
kernel-source and output checks remain separate. No alternate Metal kernel was
|
|
introduced. The dtype/shape-generic guard, donation/allocator, early release,
|
|
global model scheduling and production integration remain open. Last-use
|
|
graph leaves are now detached after their consumer, separately from explicit
|
|
completion ownership that protects GPU work until its existing CB finishes.
|
|
The shared canonical dispatch bridge holds bound Metal resources through
|
|
completion as well; this fixes four Invalid Resource failures exposed with
|
|
unretained command buffers. Compile/dispatch use scoped autorelease pools.
|
|
The normal and strengthened model-free collections cover 34 tests. This is
|
|
not performance acceptance or evidence of matching whole-model Metal encoder
|
|
timelines. Donation must still account for both descriptor and shared Data
|
|
ownership, including outstanding GPU evaluator holds.
|
|
The canonical test-bound Buffer now separates array/view identity from shared
|
|
Data ownership, including nested native views and completion holds. QSA COW
|
|
checks both Rc<Buffer> sharing and underlying Data sharing. A direct pinned
|
|
QSACache alias/view update and its negative Rust regression check prove that
|
|
array aliases observe replacement while distinct views retain old values.
|
|
The QSA graph now applies the pinned primitive input/sibling-minus-primary-output
|
|
Data retention protocol before the next primitive, rather than re-holding leaves
|
|
at their last consumer. Its scheduler tracks the actually selected sibling, not
|
|
just the producer node. CPU scheduling and GPU ownership-count checks cover that
|
|
distinction, duplicate Data, empty-batch fallback and completion.
|
|
QSA raw/pool DynamicSliceUpdate now performs actual BF16 vector-copy donation
|
|
for exclusive mutable cache state. Retained inputs, snapshots, views and GPU
|
|
Data holds select copying instead. The 16 KiB bound uses root allocation size.
|
|
All 198 core reference cases also run with state snapshots and exclusive state,
|
|
checking old/new hashes and actual Data reuse. No kernels or synchronization
|
|
boundaries changed. Model-wide integration, other primitive donation and generic
|
|
dtype/layout contracts remain open.
|
|
|
|
The allocator policy is now ported from the pinned buffer_cache.h with the same
|
|
best-fit/oldest-equal-size choice, strict reuse ceiling and age-based/90%-clear
|
|
eviction. A 101-event trace from the real installed runtime checks allocation
|
|
identities and active/cached bytes, including cache-limit transitions. Reference page rounding and the
|
|
device maxBufferLength precheck are connected to the test-bound Buffer methods;
|
|
logical views preserve tensor bounds while Data records the rounded root size.
|
|
The explicit Rust Allocator now owns a real 1 MiB untracked/shared Metal heap,
|
|
uses it for requests below 256 bytes with device-allocation fallback, and
|
|
recycles native roots only after the final physical allocation hold releases.
|
|
Its active/cache/peak/resource accounting, cache and memory limits, resource
|
|
pressure GC (including the original unsigned subtraction), zero/null result
|
|
and actual cached storage reuse are checked against the 101-event receipt.
|
|
Residency/wired limits are now connected to this explicit allocator, including
|
|
heap registration, cache retention and erase-before-release. Set selection and
|
|
budgets follow resident.cpp: first fit, oversize/empty-set reuse, 32-set ceiling,
|
|
emptiest fallback and touched-set commits on resize. Native membership and the
|
|
ten original residency lifecycle scenarios are tested. Queue attachment uses
|
|
the published set count and is exercised immediately before test commits;
|
|
The new test-bound Submission owner now attaches automatically at actual native
|
|
commit boundaries through a scoped encoding-thread callback, including flush,
|
|
readback, finish and cleanup paths. Its queue cursor persists across batches;
|
|
scope teardown drains before unregistering the callback. Legacy work outside
|
|
the scope and other queues do not inherit it. Externally wrapped storage,
|
|
the process-wide owner and model-wide routing remain open.
|
|
Existing canonical helpers
|
|
are not globally switched to untracked buffers before encoder dependencies
|
|
are ported. No whole-model allocator/performance parity is claimed.
|
|
|
|
The test-bound Rust Encoder now owns an independent queue with unretained
|
|
command buffers and Concurrent compute encoders, following the pinned
|
|
device.cpp/event.cpp/error.h dependency and completion rules. Access roles,
|
|
barrier epochs, deferred concurrent outputs, cross-encoder fences, temporary
|
|
exclusion and shared-event error propagation are managed in Rust. The bridge
|
|
only issues Metal API calls and reuses the same original kernel dispatcher.
|
|
Commit thresholds count array.data_size() ELEMENTS (as the reference does),
|
|
not allocation bytes; counters persist across encoder boundaries. The three
|
|
new checks include dependent untracked GPU copies, two-queue event transfers
|
|
and safe synthetic error-completion tests. The 48-test suite passes in both
|
|
legacy retention modes. Only these new encoder tests use the independent
|
|
queue. Complete operator access metadata, stream/evaluator integration and
|
|
production routing are still open; this is not a model-performance receipt.
|
|
|
|
Operator scopes now connect the existing normalization and full MoE chain to
|
|
the independent Concurrent encoder and its pooled untracked allocator. Explicit
|
|
binding roles/data_size spans cover routing, sorting, gather/unsort, Gate/Up,
|
|
SwiGLU, casts/norms, affine and gathered quantized projections, Split-K and both
|
|
stock/fused experts plus the shared expert. Sort and split-reduction scratch is
|
|
registered as backend temporaries. RMSNorm's default one and GatherSort's divisor
|
|
are real scalar array bindings, not setBytes replacements. No shaders changed.
|
|
The nine existing fixture groups (540 cases) execute through BOTH encoders with
|
|
unchanged reference-output checks. This does not multiply independent fixtures.
|
|
QSA routing, general array/donation semantics, evaluator/stream integration,
|
|
production instrumentation and complete model/performance acceptance remain open.
|
|
|
|
GDN routing now uses the same typed dispatch/allocator path, including conv,
|
|
mask/cache, Q/K normalization, compute_g/beta, recurrence, fused step and output.
|
|
The direct native fused-step bypass is removed. Scalar operands and custom T
|
|
are original scalar array inputs. Concatenate uses the original concurrent
|
|
disjoint slice writes and dependency join; checked-input copies retain the
|
|
original order and backend-temporary registration. No shader bodies changed.
|
|
Four further existing groups (476 GDN cases) execute in both encoders, bringing
|
|
the dual-encoder total to 1,016 existing cases. This remains operator-level
|
|
correctness coverage, not whole-model scheduling or production parity.
|
|
|
|
QSA static/dynamic copies now bind explicit array data_size metadata rather
|
|
than treating the copied region as the whole bound array. Dynamic offset arrays
|
|
are inputs/backend temporaries. Zero fill, COW/General copies, compiled frontier
|
|
operations and fused query/pool preparation carry access roles. KV concatenate
|
|
uses the reference concurrent slice-write region. The existing 12 backing/copy
|
|
and 26 compiled cache-window cases now run in both encoders (1,054 existing
|
|
dual-encoder cases in total). Eager preparation, score/select operators and full
|
|
graph/production integration remain open. Shader sources/geometries unchanged.
|
|
|
|
Eager QSA preparation now carries access roles and exact slice spans through
|
|
RoPE, mean/RMS pooling and projections; all three RoPE concatenates use the
|
|
reference concurrent writer regions. Scalar arithmetic uses array inputs.
|
|
The fused selector and chunk concatenation also use the same encoder; its three
|
|
frontiers are distinct scalar arrays and its private score plane remains a
|
|
custom-kernel output, not a backend temporary. The existing 210 preparation,
|
|
88 ongoing cache and 75 selector/chunk cases now execute in both encoders,
|
|
bringing the existing dual-encoder total to 1,427 cases. Empty-array placeholder
|
|
storage is unchanged; general zero-storage array semantics and the remaining
|
|
score/eager-selection, evaluator and production paths are still open.
|
|
|
|
Both QSA prefill score producers and the connected score/top-k/chunk route now
|
|
use the independent encoder. FP32 GEMV/Steel/NAX/Split-K, ReLU and reduction
|
|
carry explicit array spans; Maximum/Divide scalars are array inputs. Matmul's
|
|
output is allocated before transpose-copy preparation; those copies and the
|
|
Split-K plane are registered as backend temporaries after their consumers.
|
|
The MPP producer retains its original stride-aware inputs. Prefill top-k
|
|
allocates outputs before checked-input copies, registers those copies after
|
|
dispatch and uses three separately allocated frontier arrays. Shader bodies,
|
|
specializations and dispatch geometries are unchanged. The existing 384 FP32
|
|
score, 146 MPP/top-k/prefill and 96 mixed-producer cases now run in both encoders,
|
|
bringing dual-encoder coverage to 2,053 existing cases. These manual fixture
|
|
batches do not establish general evaluator/stream boundaries or production
|
|
parity; eager selection/output and full graph integration remain open.
|
|
|
|
Eager QSA score masking, ranking and all output branches now carry explicit
|
|
input/output array spans through the independent encoder. Scalar operands are
|
|
real arrays; per-tile mx.eval(top_t) synchronizes that queue before constructing
|
|
the next tile. Tiled index concatenation, decode-tail concatenation, rows-gather
|
|
outputs and dense padding use the original concurrent slice-write regions.
|
|
Dense padding is materialized before concatenation, and rows-gather builds its
|
|
two separate Arange expressions; these restore previously collapsed operations.
|
|
No Metal body or specialization changed.
|
|
|
|
The fixed-signature indexer graph now defers input/sibling Data on the active
|
|
queue rather than retaining fallback descriptors in its returned state. The
|
|
selected output's Data remains excluded, preserving donation. Compiled chunk
|
|
concatenation joins concurrent writers and moving frontiers are four separate
|
|
int32 arrays. Existing empty/nonempty Data-ownership checks run in both queues.
|
|
The existing 540 eager cases and 200 ongoing indexer calls (including compiled
|
|
routes) also execute in both encoders: 2,793 existing dual-encoder cases total.
|
|
Explicit tile eval counts, output/state hashes and graph engagement are checked.
|
|
These bounded fixture batches still do not apply the complete model-wide
|
|
evaluator/stream scheduler and its automatic primitive-level commit policy.
|
|
Production routing/instrumentation and whole-model performance acceptance remain
|
|
open, as does general zero-storage array handling.
|
|
|
|
Primitive submission and task scheduler
|
|
--------------------------------------
|
|
|
|
The fixed indexer tape now checks the original encoder thresholds after a whole
|
|
primitive, never after an individual kernel dispatch. Input/sibling Data and
|
|
backend holds are attached before a possible commit. Counted GPU tasks complete
|
|
from the command callback; failed submissions balance ownership/accounting.
|
|
The single-stream tape also applies the original active-task/memory pressure
|
|
condition, finalizes its stream and waits for progress without inserting sleeps.
|
|
|
|
The Rust scheduler uses stdlib FIFO workers per CPU stream, earliest-error
|
|
preservation, non-consuming cross-stream event error propagation and draining
|
|
shutdown. CPU event waits/signals use the existing Metal shared-event bridge.
|
|
Explicit tile/final fixture synchronizations are checked separately from
|
|
automatic commits, with independent expectations for the two full-prefill
|
|
indexer cases that cross the pinned Max data-size threshold.
|
|
|
|
CPU dispatch now counts every tenth operation, with completion as a separate
|
|
FIFO task so failed work still completes its activity accounting. The CPU
|
|
primitive cleanup task participates in that count and retains complete backend
|
|
temporary descriptors until earlier work has run. CPU and GPU now share the
|
|
input/sibling Data-selection function, excluding donated primary output Data.
|
|
The private CPU temporary wrapper is Send only for drop-only worker ownership;
|
|
Buffer itself remains !Send/!Sync. Five scheduler tests and the existing GPU
|
|
ownership/connected-indexer checks pass, including unretained indexer execution.
|
|
|
|
An explicit runtime-owned stream registry now connects CPU/GPU encoders for the
|
|
installed single-CPU/single-Metal backend. Defaults and template resolution are
|
|
per thread/device. Local encoders are destroyed at thread exit; global streams
|
|
allow sequential cross-thread use. Explicit clear preserves the reference's
|
|
metadata/stale default handles and global CPU/GPU cleanup distinction.
|
|
Registry locks do not cover encoding or waits. GPU selection reuses the same
|
|
Rc/TLS encoder and allocator; exclusive ownership is checked before returning
|
|
an encoder to storage. CPU/GPU events and finalize-all pressure handling use
|
|
the existing scheduler and native bridge. Two new checks include actual
|
|
two-queue copies, eleven blocked CPU tasks, thread cleanup and error unwinding.
|
|
The 200 ongoing indexer cases now use a registered GPU stream in the independent
|
|
path; the full model-free collection passes 57/57 normal and unretained.
|
|
|
|
Graph events now preserve per-copy values/origin streams while sharing native
|
|
events and errors. Inter-stream fences use either the reference SharedEvent
|
|
path or its opt-in Metal3/macOS15 fast path. Fast synchronization remains off
|
|
by default. The existing pinned metallib supplies input_coherent, fence_update
|
|
and fence_wait unchanged. Rust preserves array output registration, raw timestamp
|
|
bindings, explicit update barriers, cross-device coherence and CPU SeqCst
|
|
timestamp operations. Shared fence counts and per-dispatch snapshots are
|
|
separate; completion/task ownership retains timestamp storage until work ends.
|
|
The bridge now accepts empty dispatch grids, including the original zero-work
|
|
coherence dispatch. Three new checks cover events/errors, partial-word/empty
|
|
coherence and CPU/GPU/GPU/CPU transfer in both modes with a test-only deadlock
|
|
rescue. All 60 model-free tests pass normal and unretained; no rescue fired.
|
|
No shader body, metallib, inference default or production routing was changed.
|
|
|
|
This is still test-bound. Full array/evaluator cross-stream dependency construction, actual
|
|
CPU model primitives, compile-cache cleanup integration and the complete model
|
|
graph remain open. Production Qwen and performance acceptance remain unchanged;
|
|
stream/operator checks do not establish whole-model parity.
|
|
|
|
Canonical dispatch now transfers deduplicated Rust root-allocation ownership
|
|
to its existing Metal completion callback. This replaces the native resource
|
|
set in that path and prevents physical release without adding Data aliases
|
|
that would disable donation. Typed bindings also retain their descriptor/scalar
|
|
borrow until dispatch. Early failures keep ownership with Rust; registration
|
|
transfers it even when a submitted standalone command later reports failure.
|
|
No shader, flush, commit, wait or additional completion-handler change.
|
|
Normal and unretained collections pass 45/45 tests including native allocation,
|
|
heap exhaustion, limits, residency and in-flight cache exclusion. This is not model parity.
|
|
Binding input/output roles, barrier epochs, concurrent contexts, inter-encoder
|
|
fences and reference commit thresholds still require the full encoder port.
|
|
|
|
Runtime-generated indexing shader
|
|
--------------------------------
|
|
|
|
The same pinned runtime JIT-compiles gather_front instead of using the
|
|
precompiled library. tools/mtplx-kernel-source.py resolves its two headers
|
|
into metal/mtplx_qwen.metal without editing shader code and supplies the
|
|
BF16/U32/FP32 template instantiations. Original notices and MIT attribution
|
|
are retained. Header identities:
|
|
|
|
indexing/indexing.h:
|
|
e820b8ee2b5132a97122780c12433ebb5100d8078d31e211d0429400a11415bb
|
|
indexing/gather_front.h:
|
|
64aacebf6576dfcd389383564fa1214bc87f2a091dd33cc64c598c5367ecab96
|
|
|
|
The generator requires the pinned runtime source checkout alongside the
|
|
MTPLX reference checkout, named mtplx-runtime-0.32.2. The product requires
|
|
only the generated shader resource, not this reference source checkout.
|
|
|
|
Runtime-generated SiLU shader
|
|
----------------------------
|
|
|
|
tools/mtplx-jit-reference.py observes original runtime compilation without
|
|
changing it. tests/fixtures/mtplx-silu-jit.json pins the generated19variants;
|
|
full observed source SHA256:
|
|
76cafb45db55a91efba66503dde59b37628ea360f220f35dd860f4ac3c3d0111
|
|
|
|
The shader exporter retains the generated computation and its original
|
|
BF16 math, Sigmoid, Multiply, cast and stride helpers. Only host-name aliases
|
|
change. All supporting header identities are enforced by the exporter and
|
|
the emitted unit hashes by the focused Rust test. Copyright Apple Inc.; MIT
|
|
as reproduced in MLX-LM-LICENSE.txt. This does not link a host runtime.
|
|
|
|
Runtime-generated GatherAxis shader
|
|
-----------------------------------
|
|
|
|
The pinned GatherAxis source and generic elem_to_loc helper are retained
|
|
unchanged, with BF16/U32 index instantiations for contiguous/strided inputs
|
|
and int/int64 offsets. The router retains the strided last-ten-column view;
|
|
no replacement top-k kernel is used. Header identities:
|
|
|
|
indexing/gather_axis.h:
|
|
e1a745391ff4990f3f1ad75c5687c3b102dcdc4833d8fbbac38e10f54af29af4
|
|
utils.h:
|
|
5e1568e9edde9d05dbf86f68fa0d6c6240f2c32b973c7c6a76166b9c0d91543d
|
|
|
|
Copyright Apple Inc.; MIT as reproduced in MLX-LM-LICENSE.txt. Softmax,
|
|
reduction, binary operations and index copies use the pinned metallib.
|
|
|
|
Runtime-generated SwiGLU shader
|
|
------------------------------
|
|
|
|
The original compiled activations.swiglu used by non-sanitize-fused SwitchGLU
|
|
and Qwen3NextMLP is captured separately from nn.silu. Full observed source SHA:
|
|
bf78eee5cf96ea7c112c4e61546c12bcacf57fe512e0572182604cb94137510b.
|
|
tests/fixtures/mtplx-swiglu-jit.json preserves all 19 original generated variants.
|
|
The exporter changes only host aliases and reuses the already pinned BF16,
|
|
Sigmoid, Multiply and cast/stride dependencies. Copyright Apple Inc.; MIT.
|
|
|
|
Runtime-generated compute_g shader and staged GDN
|
|
------------------------------------------------
|
|
|
|
The original compiled gated_delta.compute_g is captured with the same observer:
|
|
tests/fixtures/mtplx-compute_g-jit.json. Full observed source SHA256:
|
|
34143a98046f8af5538767734fc169a5cab22a4920c26f9ba7ea45b8097152de.
|
|
Receipt SHA256:
|
|
701e2f54b7cb8bf97616f83256657e6c5e8cc8b46f4b65c559ccc030ab111dbf.
|
|
All 19 variants retain their original BF16 Add/LogAddExp intermediates and
|
|
FP32 final exponential. Only host aliases change. The exporter pins the
|
|
additional Exp, Negative, Add, LogAddExp, Limits and log1p shader dependencies.
|
|
|
|
complex.h SHA256:
|
|
16e8a815b2cbdb6070e0824e64fe33fccb6e918f1b84ea5c792bd89d33e57bf1.
|
|
cexpf.h SHA256:
|
|
88b6e15a52a5800d98d9bc6da840ca5cf70bf572fda136409580c1f17b1e0aab.
|
|
The complex overload dependencies are retained unchanged, not used to add a
|
|
complex-valued Qwen path. complex.h is Apple MIT. cexpf.h is Apache-2.0,
|
|
Copyright Apple 2025, NVIDIA 2008-2013 and Filipe RNC Maia 2013. Its full original
|
|
copyright/license notice remains embedded in the generated shader; the Apache
|
|
license text is included in MTPLX-LICENSE.txt.
|
|
|
|
Stock depthwise Conv1D, copies, casts, reductions and elementary operations
|
|
use the unchanged runtime metallib. Cache valid-length GatherAxis additionally
|
|
instantiates the original signed INT32-index template; router indices remain
|
|
UINT32. No shader body is replaced by a hand-written equivalent.
|
|
|
|
Original QSA indexer preparation
|
|
-------------------------------
|
|
|
|
qsa_indexer_prepare.py SHA256:
|
|
a77f6ca5ae805e729519c4629ae88b455a6dbf473a457a6e1c8219174eb59091.
|
|
The exporter reads _prepare_queries_kernel and _pool_keys_kernel as AST data;
|
|
it does not execute the model or kernel module. Both original source strings
|
|
are unchanged. Header substitutions match the installed geometry: four query
|
|
heads, width128, rotary64, ratio4, epsilon1e-6, attention scaling1. Includes are
|
|
resolved at translation-unit scope; separate namespaces avoid collisions among
|
|
the original header constants. Only entry-point declarations, host aliases and
|
|
template instantiations are adapted. Stride metadata retains the original
|
|
constant int64_t address space. Original Metal math and BF16 rounding remain.
|
|
Copyright MTPLX; Apache-2.0, see MTPLX-LICENSE.txt and MTPLX-NOTICE.txt.
|
|
|
|
This is the preparation portion, not the full QSA indexer, selection,
|
|
attention graph or production integration. Runtime frequencies are input buffers,
|
|
not host replacements for the model's frequency construction.
|
|
|
|
QSACache/KVCache host lifecycle now uses the original scalar/vector/general
|
|
copy and BF16/FP32 cast entries from this runtime, including positional writes,
|
|
growth, strided restored state and the derived mirror. Rust distinguishes array
|
|
object identity (__setitem__ overwrites its descriptor) from shared slice storage.
|
|
Retained state aliases are checked against actual MTPLX cache operations, not
|
|
assumed immutable. No additional shader bodies or runtime host library are used.
|
|
The connected canonical cache remains test-only until product graph integration.
|
|
|
|
Original dynamic QSA selector
|
|
-----------------------------
|
|
|
|
qsa_indexer_select.py SHA256:
|
|
a3c74af27a7045c12f2893a8b7a91724c00d8a4148315c3165f3480c83016cf3.
|
|
metal/mtplx-qsa-select.json preserves the original header, common body and all
|
|
three epilogues (blocks, dense_mask, row_tokens), extracted without importing
|
|
the model. Rust substitutes the original literal header parameters and supplies
|
|
only the entry-point ABI. Tests additionally compare full generated header/body
|
|
hashes against the actual MTPLX factory. H4/D128/ratio4 match the installed model;
|
|
BF16/FP32 operands, backing capacity, top-k and TF32 remain specializations.
|
|
Native compilation follows runtime 0.32.2 CustomKernel defaults: Safe math and
|
|
its platform-selected Metal language version. No runtime host library is linked.
|
|
The original 32MiB score-scratch chunk planner and typed output concatenation
|
|
are connected to the cache/preparation port. General submission/concurrency,
|
|
the complete eager indexer and production integration remain open.
|
|
Copyright MTPLX; Apache-2.0, see MTPLX-LICENSE.txt and MTPLX-NOTICE.txt.
|
|
|
|
Original vectorized QSA prefill
|
|
------------------------------
|
|
|
|
qsa_indexer_prefill.py SHA256:
|
|
4d6fd428243c001746f69f8aed45991356772c2bd4a45586eb3c6813c91998d3.
|
|
The same JSON export retains _MPP_SCORE_HEADER/_MPP_SCORE_SOURCE, the original
|
|
top-k body and literal f-string header segments. Rust resolves only their named
|
|
constants and provides entry-point ABI/type aliases. TensorOps tile layout,
|
|
ordered per-head ReLU reduction, adaptive radix/insertion and all epilogues are
|
|
unchanged. The original required General FP32 copy is used for non-contiguous
|
|
score views; MPP input views keep their strides without added copies.
|
|
The 128MiB producer-aware planner and score -> top-k -> concat chain are connected
|
|
for the installed BF16/M5 geometry, including a 2K continuation from live cache.
|
|
Full indexer branch routing, compiled graph bank and production integration
|
|
remain open. Copyright MTPLX; Apache-2.0.
|
|
|
|
The general FP32 score expression now shares that prefill entry point. Rust
|
|
ports runtime matmul.cpp's H4/D128 M5 Max routing: AsType Vector/General layout,
|
|
check_transpose and broadcast copies, batch collapse, GEMV, regular Steel/NAX
|
|
and both Split-K variants, original per-head Maximum, row/column Sum and Divide.
|
|
All shader entries come from the unchanged pinned metallib; no shader body or
|
|
host runtime library was added. The pooled cast is retained once across chunks;
|
|
producer selection and the H4+1 workspace budget follow the reference.
|
|
384 score cases and 96 connected selection cases are exact with real runtime
|
|
MLX_ENABLE_TF32=0/1 in separate processes. These remain canonical correctness
|
|
fixtures, not production integration or performance-parity evidence.
|
|
|
|
Original eager QSA selection
|
|
---------------------------
|
|
|
|
The untiled QSAIndexer._select_eager score/top-k path uses the original
|
|
runtime Arange, Add, integer Divide, Less, casts, Select, Subtract and
|
|
ArgPartition (implemented by the pinned runtime as argsort). The chronological
|
|
flash_prefill block epilogue adds original int32 Sort, int64 index conversion,
|
|
bool GatherAxis and Select. The exporter adds only the required
|
|
gather_axis<bool,int64_t,int,true,true> instantiation of the already preserved
|
|
GatherAxis body; no body is changed. Its original file/unit hashes are unchanged.
|
|
All untiled output epilogues are connected: dense mask (original bool
|
|
ScatterAxis, repeat/concatenate and causal/tail mask), rows-gather (argsort-order
|
|
tokens and validity), decode flash (chronological blocks, host tail bound) and
|
|
decode gather (chronological tokens and variable-length tail). The flash branch
|
|
retains precedence; neither decode branch evaluates the dead selected-mask DAG.
|
|
Shared original cast/sort/vector dispatch helpers do not alter the shader bodies.
|
|
|
|
ScatterAxis adds these unchanged pinned Apple MIT runtime source units:
|
|
- atomic.h, full-file SHA256:
|
|
4c35ea2798a2335502865247aee878149fc9ada0d7e84c05d771baef0c7fcc60
|
|
- reduction/ops.h None operation, full-file SHA256:
|
|
78d06730fc9564a73944e7f1fe3897d25c8789b28a939bf418e1968db311da41
|
|
- indexing/scatter_axis.h, full-file SHA256:
|
|
43eabd0216101f8e32f5cdd19ce40b7f954564be27fad98a5e0fe345e7b94ce5
|
|
Only include/pragma-once placement, namespace and the two required
|
|
scatter_axis<bool,int64_t,int,None,false/true,true> instantiations are added
|
|
outside the preserved bodies. The exporter guards full-file and body hashes.
|
|
No host C/C++ runtime implementation is linked.
|
|
|
|
The 408 eager receipts tap actual QSAIndexer calls: 60 score/top-k, 24 prefill
|
|
blocks, 144 dense masks, 108 rows-gather and 72 decode outputs. They include 2K
|
|
queries, 65,536 blocks, tails 0/1/3 and separate real TF32-on/off processes.
|
|
The tiled path shares the same score/rank functions, pooled FP32 input and tie
|
|
vector. Each original mx.eval(top_t) is a synchronous command completion before
|
|
the next tile, not an asynchronous flush. Only evaluated index views/backings
|
|
are retained through the original GeneralGeneral uint32 concatenate. Index
|
|
stride changes N -> K, independently of the N-strided validity. No new shader
|
|
source or specialization is needed. Rust shares the original output-branch
|
|
priority, including the tiled rows-gather exclusion and decode flash precedence.
|
|
132 further actual-call receipts (108 tiled, 24 tile-off boundaries) bring the
|
|
eager total to 540. They include observed reference eval row counts, 2K queries,
|
|
65,536 blocks, tail 0/1, partial tiles and stride-2 FP32 query views.
|
|
The existing GPU busy counters additionally verify one completed command buffer
|
|
per observed reference tile eval, plus the final output batch.
|
|
Full indexer routing, the general scheduling tape/allocator and production
|
|
integration are not established by these checks.
|
|
|
|
Original eager QSA preparation
|
|
------------------------------
|
|
|
|
The installed BF16 H4/D128 query and H1/D128 pool paths now use the original
|
|
eager preparation expression as well as the fused custom-kernel branch.
|
|
RMSNorm uses the pinned runtime kernel and its required General-Copy for sliced
|
|
projection inputs. Pool mean is FP32 sum multiplied by 0.25 and cast to BF16
|
|
before weighted RMSNorm. RoPE preserves all Arange, casts, concatenations,
|
|
Cos/Sin, BF16 Negative, FP32 Multiply/Add and final BF16/pass-through stages.
|
|
The installed rotary64/ratio4/eps1e-6/scaling1 contract is unchanged.
|
|
All entries come from the unchanged pinned metallib; no shader body was added.
|
|
|
|
The existing projection and cache-extension entry points select either branch
|
|
and retain the eager intermediates through their consuming operations. 105
|
|
additional actual QSAIndexer receipts cover bare and quantized-projection
|
|
preparation, including 2K rows, padded/stride-2 inputs and high positions. Another
|
|
44 real QSACache/KVCache transitions cover eager pooling, capacity growth,
|
|
reservation, trim, state aliases/restore and FP32 mirror rebuilding. These are
|
|
not a complete indexer, production-integration or performance-parity receipt.
|
|
|
|
Connected non-compiled indexer entry
|
|
----------------------------------
|
|
|
|
The Rust entry after compiled-route rejection now connects projection/supplied
|
|
QK views, query preparation, raw/pool state and the original large-prefill,
|
|
legacy-fused and eager selection order. All existing original shader dispatches
|
|
are reused. Query preparation is dead when dense==sparse; KV.offset advances
|
|
only in the subsequent Attention step. Shared return variants preserve the
|
|
model-visible outputs while retaining other encoded kernel outputs.
|
|
92 actual MTPLX indexer calls in 24 ongoing sequences verify lane choice, 82
|
|
selection hashes, 268 raw/pool/mirror hashes, capacities/frontiers and command
|
|
completion counts. They cover 2K rows, 32K history, supplied 704-stride QK views,
|
|
prefill crossover, gather/flash priority and tiling. No compiled path is silently
|
|
replaced. Compiled eligibility/core, attention, graph scheduling and production
|
|
integration are still open; these are correctness, not performance receipts.
|