mlx-bun 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -21
- package/THIRD_PARTY_LICENSES.md +1 -0
- package/docs/archive/mlx-bun-lab-report.html +275 -0
- package/docs/archive/wwdc-mlx-bun.html +848 -0
- package/docs/design/audio-input-plan.md +356 -0
- package/docs/design/batching-perf-path.md +255 -0
- package/docs/design/batching-v2-plan.md +23 -9
- package/docs/design/bucketing-stage.md +2 -1
- package/docs/design/compat-cli-surface-design.md +4 -3
- package/docs/design/decode-speed-program.md +172 -0
- package/docs/design/docs-reorg-plan.md +1 -1
- package/docs/design/dspark-serving-program.md +371 -0
- package/docs/design/dspark-speculative-decoding.md +167 -5
- package/docs/design/faithful-l1-consolidation.md +310 -0
- package/docs/design/generic-model-support.md +8 -5
- package/docs/design/grammar-spec-batching-integration.md +301 -0
- package/docs/design/minicpm5-decode-megakernel.md +16 -11
- package/docs/design/mlx-lm-tool-parity-plan.md +11 -1
- package/docs/design/omlx-adoption-map.md +98 -0
- package/docs/design/orpo-training.md +34 -30
- package/docs/design/paged-kv-cache.md +214 -0
- package/docs/design/parallel-slots.md +82 -49
- package/docs/design/parity-tier-dag.md +43 -33
- package/docs/design/repo-cleanup-plan.md +189 -0
- package/docs/design/runtime-isolation.md +19 -3
- package/docs/design/segmented-backward-training.md +18 -2
- package/docs/design/ssd-kv-cold-tier.md +288 -0
- package/docs/design/structured-output.md +484 -0
- package/docs/design/the-dreaming-master-plan.md +2 -3
- package/docs/design/turboquant-kv.md +235 -0
- package/docs/design/unified-engine-frontier-plan.md +774 -0
- package/docs/design/web-chat-beat-matrix.md +315 -0
- package/docs/design/web-chat-redesign.md +1112 -0
- package/docs/investigations/decode-roofline-lookagain.md +92 -6
- package/docs/investigations/dspark-handoff.md +182 -16
- package/docs/investigations/kernel-perf-review-2026-07.md +105 -26
- package/docs/investigations/lab-build-journal.md +2 -2
- package/docs/investigations/openwiki-evaluation.md +249 -0
- package/docs/planning/IDEAS.md +14 -0
- package/docs/planning/PRODUCT_ROADMAP.md +2 -3
- package/docs/planning/chat-ui-vision-memory-first.md +199 -0
- package/docs/planning/chat-ui-vision.md +50 -0
- package/docs/planning/memory-docs-and-dag-plan.md +15 -6
- package/docs/planning/release-notes-v0.0.10.md +57 -0
- package/docs/planning/release-notes-v0.0.11.md +239 -0
- package/docs/reference/cli.md +35 -16
- package/docs/reference/distribution.md +13 -6
- package/docs/reference/embedding.md +35 -14
- package/docs/reference/features-matrix.md +97 -0
- package/docs/reference/library-api.md +30 -9
- package/docs/reference/memory.md +26 -6
- package/docs/reference/models.md +11 -1
- package/docs/reference/orpo-quickstart.md +3 -4
- package/docs/reference/server-api.md +634 -22
- package/docs/reference/server-config.md +251 -119
- package/docs/reference/training.md +20 -16
- package/package.json +5 -3
- package/src/anthropic.ts +13 -0
- package/src/audio/conformer.ts +647 -0
- package/src/audio/decode.ts +133 -0
- package/src/audio/features.ts +202 -0
- package/src/audio/transcode.ts +67 -0
- package/src/cli.ts +402 -107
- package/src/config.ts +49 -2
- package/src/download.ts +40 -0
- package/src/eval/README.md +7 -6
- package/src/eval/kl.ts +59 -3
- package/src/eval/quality-db.ts +2 -2
- package/src/eval/runner.ts +3 -3
- package/src/expert-offload.ts +15 -2
- package/src/flags.ts +13 -0
- package/src/generate.ts +330 -16
- package/src/grammar.ts +585 -0
- package/src/hub-rest.ts +242 -0
- package/src/kv-store.ts +618 -122
- package/src/lora.ts +8 -0
- package/src/md-modules.d.ts +42 -0
- package/src/media-fetch.ts +284 -0
- package/src/memory/rest.ts +245 -0
- package/src/memory/vault.ts +74 -0
- package/src/mlx/array.ts +127 -19
- package/src/mlx/autograd.ts +2 -2
- package/src/mlx/ffi.ts +27 -3
- package/src/mlx/metal-kernel.ts +7 -4
- package/src/mlx/ops.ts +179 -23
- package/src/mlx/turboquant-ops.ts +831 -0
- package/src/mlx/turboquant-tables.ts +237 -0
- package/src/model/batched-mask.ts +62 -1
- package/src/model/batched-quant.ts +206 -0
- package/src/model/batched-rotating-quant.ts +346 -0
- package/src/model/batched-rotating.ts +46 -1
- package/src/model/compiled-decode.ts +4 -15
- package/src/model/factory.ts +10 -4
- package/src/model/gemma4-base.ts +391 -34
- package/src/model/gemma4.ts +122 -33
- package/src/model/generated/gemma4-12b.ts +9 -13
- package/src/model/generated/gemma4-26b.ts +10 -5
- package/src/model/generated/gemma4-e4b.ts +14 -9
- package/src/model/minicpm5.ts +58 -102
- package/src/model/paged-kv.ts +253 -0
- package/src/model/qwen3-delta.ts +123 -15
- package/src/model/qwen3-moe.ts +404 -0
- package/src/model/qwen3.ts +9 -8
- package/src/model/qwen3_5.ts +99 -25
- package/src/model/support.ts +12 -1
- package/src/model/universal/dense.ts +40 -5
- package/src/model/universal/rope.ts +36 -21
- package/src/pi-web.ts +1299 -82
- package/src/preflight.ts +27 -8
- package/src/prompt-cache.ts +338 -32
- package/src/quantize/quantizer.ts +16 -1
- package/src/registry.ts +61 -3
- package/src/serve/batch-scheduler.ts +1001 -76
- package/src/serve/generation-gateway.ts +292 -30
- package/src/serve/isolate.ts +417 -0
- package/src/serve/lane-registry.ts +44 -0
- package/src/serve/session-search.ts +326 -0
- package/src/server.ts +1460 -105
- package/src/spec/assistant-source.ts +150 -0
- package/src/spec/deepspec-source.ts +143 -0
- package/src/spec/dflash-source.ts +124 -0
- package/src/spec/dspark/ab-stats.ts +136 -0
- package/src/spec/dspark/calibration.ts +112 -0
- package/src/spec/dspark/deepspec-module.ts +801 -0
- package/src/spec/dspark/generate-dflash.ts +72 -20
- package/src/spec/dspark/loader.ts +23 -0
- package/src/spec/dspark/module-dflash.ts +278 -36
- package/src/spec/dspark/quantize-drafter.ts +91 -0
- package/src/spec/generate.ts +59 -25
- package/src/spec/ngram-source.ts +132 -0
- package/src/spec/serve-loop.ts +536 -0
- package/src/spec/source.ts +93 -0
- package/src/spec/two-model.ts +171 -0
- package/src/ssd-cache.ts +285 -0
- package/src/tokenizer.ts +288 -2
- package/src/tool-approvals.ts +131 -0
- package/src/tool-call.ts +408 -20
- package/src/train/flash-cce.ts +29 -26
- package/src/train/job.ts +0 -2
- package/src/train/loss.ts +53 -11
- package/src/train/prefix-shared.ts +30 -7
- package/src/train/segmented.ts +150 -46
- package/src/train/trainer.ts +22 -15
- package/src/vision/prompt.ts +217 -48
- package/src/web/app.html +1184 -1789
- package/src/web/app.js +5667 -0
- package/src/web/icon.svg +13 -0
- package/src/web/manifest.webmanifest +24 -0
- package/src/web/src/adapters-panel.ts +288 -0
- package/src/web/src/api.ts +57 -0
- package/src/web/src/assistant.ts +485 -0
- package/src/web/src/chat.ts +1050 -0
- package/src/web/src/composer.ts +959 -0
- package/src/web/src/dataset.ts +132 -0
- package/src/web/src/finetune.ts +267 -0
- package/src/web/src/hub.ts +428 -0
- package/src/web/src/main.ts +98 -0
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +572 -0
- package/src/web/src/model-picker.ts +159 -0
- package/src/web/src/palette.ts +346 -0
- package/src/web/src/protocol.ts +62 -0
- package/src/web/src/quantize.ts +167 -0
- package/src/web/src/rag.ts +274 -0
- package/src/web/src/sessions.ts +469 -0
- package/src/web/src/shell.ts +804 -0
- package/src/web/src/status.ts +252 -0
- package/src/web/src/ui-catalog.ts +92 -0
- package/src/web/sw.js +71 -0
- package/src/web/vendor/README.md +61 -0
- package/src/web/vendor/hljs-LICENSE +29 -0
- package/src/web/vendor/hljs-theme.css +59 -0
- package/src/web/vendor/hljs.js +26 -0
- package/src/model/fused-decode-kernel.ts +0 -312
- package/src/model/fused-geglu-kernel.ts +0 -198
- package/src/model/fused-mlp-kernel.ts +0 -169
- package/src/model/fused-swiglu-kernel.ts +0 -240
- package/src/model/steel-linear-kernel.ts +0 -96
- package/src/status-page.html +0 -497
package/src/mlx/ops.ts
CHANGED
|
@@ -43,10 +43,39 @@ export function sigmoid(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
|
43
43
|
return new MlxArray(outArray("sigmoid", (o) => C.mlx_sigmoid(o, a.handle, s)));
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
/**
|
|
46
|
+
/** f32 → bf16 truncation with round-to-nearest-even, returning the 2
|
|
47
|
+
* little-endian bytes of the bf16 value. Matches mlx's
|
|
48
|
+
* `static_cast<bfloat16_t>(float)` bit-for-bit so a host-built bf16 scalar is
|
|
49
|
+
* numerically identical to `f32_scalar.astype(bf16)` — just without the GPU
|
|
50
|
+
* Copy (astype) kernel. */
|
|
51
|
+
function bf16Bytes(value: number): Uint8Array {
|
|
52
|
+
const fb = new Float32Array([value]);
|
|
53
|
+
const bits = new Uint32Array(fb.buffer)[0]!;
|
|
54
|
+
let hi16: number;
|
|
55
|
+
if (((bits >>> 23) & 0xff) === 0xff) {
|
|
56
|
+
// inf / nan: keep the high 16 bits, and keep a NaN a (quiet) NaN.
|
|
57
|
+
hi16 = (bits >>> 16) & 0xffff;
|
|
58
|
+
if ((bits & 0x7fffff) !== 0) hi16 |= 0x40;
|
|
59
|
+
} else {
|
|
60
|
+
const roundingBias = 0x7fff + ((bits >>> 16) & 1); // round to nearest even
|
|
61
|
+
hi16 = ((bits + roundingBias) >>> 16) & 0xffff;
|
|
62
|
+
}
|
|
63
|
+
return new Uint8Array([hi16 & 0xff, (hi16 >>> 8) & 0xff]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Scalar constant with the same dtype as `like` (python weak-scalar semantics).
|
|
67
|
+
* Built HOST-SIDE at the target dtype — mlx's own scalar→array path constructs
|
|
68
|
+
* a bf16/f32 constant directly, so `scalar * bf16_array` is a single multiply.
|
|
69
|
+
* Going through an f32 leaf + GPU `.astype(bf16)` (the old path) emits a
|
|
70
|
+
* separate Copy kernel (`v_copy…`) that the reference never dispatches. */
|
|
47
71
|
export function scalarLike(value: number, like: MlxArray): MlxArray {
|
|
72
|
+
if (like.dtype === Dtype.float32)
|
|
73
|
+
return MlxArray.fromFloat32(new Float32Array([value]), []);
|
|
74
|
+
if (like.dtype === Dtype.bfloat16)
|
|
75
|
+
return MlxArray.fromBytesCopy(bf16Bytes(value), [], Dtype.bfloat16);
|
|
76
|
+
// f16 / other float dtypes: keep the astype path (rare here; no bit-exact JS
|
|
77
|
+
// converter written for them yet).
|
|
48
78
|
const f = MlxArray.fromFloat32(new Float32Array([value]), []);
|
|
49
|
-
if (like.dtype === Dtype.float32) return f;
|
|
50
79
|
const cast = f.astype(like.dtype);
|
|
51
80
|
f.dispose();
|
|
52
81
|
return cast;
|
|
@@ -147,6 +176,25 @@ export function ropeDynamic(
|
|
|
147
176
|
);
|
|
148
177
|
}
|
|
149
178
|
|
|
179
|
+
/** Array-offset fast::rope with every knob exposed (traditional + scale) —
|
|
180
|
+
* the dynamic twin of `ropeScaled`, for the universal rope factory's
|
|
181
|
+
* batched-decode path (per-row [B] offsets under left-padding). Same
|
|
182
|
+
* kernel as `ropeDynamic`; static/dynamic bit-exactness is asserted in
|
|
183
|
+
* tests/compile.test.ts. */
|
|
184
|
+
export function ropeScaledDynamic(
|
|
185
|
+
x: MlxArray, dims: number, traditional: boolean, base: number | null,
|
|
186
|
+
scale: number, offset: MlxArray, freqs: MlxArray | null, s: S = gpuStream,
|
|
187
|
+
): MlxArray {
|
|
188
|
+
return new MlxArray(
|
|
189
|
+
outArray("fast_rope_dynamic", (o) =>
|
|
190
|
+
C.mlx_fast_rope_dynamic(
|
|
191
|
+
o, x.handle, dims, traditional, optFloat(base), scale, offset.handle,
|
|
192
|
+
freqs?.handle ?? 0n, s,
|
|
193
|
+
),
|
|
194
|
+
),
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
150
198
|
export function sdpa(
|
|
151
199
|
q: MlxArray, k: MlxArray, v: MlxArray, scale: number,
|
|
152
200
|
maskMode: "" | "causal" | "array", maskArr: MlxArray | null = null,
|
|
@@ -172,6 +220,32 @@ export function quantizedMatmul(
|
|
|
172
220
|
x: MlxArray, w: MlxArray, scales: MlxArray, biases: MlxArray | null,
|
|
173
221
|
spec: QuantSpec, transpose = true, s: S = gpuStream,
|
|
174
222
|
): MlxArray {
|
|
223
|
+
// UPSTREAM MLX BUG WORKAROUND (found 2026-07-02, reproduced on stock mlx
|
|
224
|
+
// 0.31.2): quantized_matmul with transpose=false returns WRONG VALUES when
|
|
225
|
+
// the row count is 2 or 3 (relnorm ~0.3-1.1 vs the dequantized matmul);
|
|
226
|
+
// M=1 and M>=4 are correct, transpose=true is correct at every M. Pad the
|
|
227
|
+
// row axis to 4 with zeros and slice the result back. NOTE this wrapper
|
|
228
|
+
// cannot protect mlx's INTERNAL vjp of a transpose=true qmm (C++ calls the
|
|
229
|
+
// primitive directly) — training heads pad the span through the head
|
|
230
|
+
// instead (loss.ts logitsFromHiddenPadM).
|
|
231
|
+
const rowAxis = x.shape.length - 2;
|
|
232
|
+
const rows = x.shape[rowAxis]!;
|
|
233
|
+
if (!transpose && (rows === 2 || rows === 3)) {
|
|
234
|
+
const padShape = [...x.shape];
|
|
235
|
+
padShape[rowAxis] = 4 - rows;
|
|
236
|
+
const pad = zeros(padShape, x.dtype, s);
|
|
237
|
+
const xPad = concatAxis([x, pad], rowAxis, s);
|
|
238
|
+
pad.dispose();
|
|
239
|
+
const yPad = quantizedMatmul(xPad, w, scales, biases, spec, transpose, s);
|
|
240
|
+
xPad.dispose();
|
|
241
|
+
const start = MlxArray.fromInt32(new Int32Array([0]), [1]);
|
|
242
|
+
const outShape = [...yPad.shape];
|
|
243
|
+
outShape[rowAxis] = rows;
|
|
244
|
+
const y = sliceDynamic(yPad, start, [rowAxis], outShape, s);
|
|
245
|
+
start.dispose();
|
|
246
|
+
yPad.dispose();
|
|
247
|
+
return y;
|
|
248
|
+
}
|
|
175
249
|
return new MlxArray(
|
|
176
250
|
outArray("quantized_matmul", (o) =>
|
|
177
251
|
C.mlx_quantized_matmul(
|
|
@@ -266,21 +340,35 @@ export function pow(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
|
266
340
|
return new MlxArray(outArray("power", (o) => C.mlx_power(o, a.handle, b.handle, s)));
|
|
267
341
|
}
|
|
268
342
|
|
|
269
|
-
/** nn.gelu_approx: 0.5 x (1 + tanh(√(2/π) (x + 0.044715 x³))) — composed
|
|
270
|
-
* exactly as mlx's python source: x**3 is mx.power
|
|
271
|
-
* round differently in bf16),
|
|
343
|
+
/** nn.gelu_approx: 0.5 * x * (1 + tanh(√(2/π) * (x + 0.044715 * x³))) — composed
|
|
344
|
+
* exactly as mlx's python source, INCLUDING operand order: x**3 is mx.power
|
|
345
|
+
* (NOT x·x·x — they round differently in bf16), and every scalar·array product
|
|
346
|
+
* puts the SCALAR FIRST (`0.5 * x`, not `x * 0.5`). Multiply is commutative so
|
|
347
|
+
* this is bit-identical, but it makes the compiled geglu graph's operand string
|
|
348
|
+
* (`Multiply(C, V)`) match the oracle's fused kernel exactly. Scalars promote
|
|
349
|
+
* weakly to x's dtype. */
|
|
272
350
|
export function geluApprox(x: MlxArray, s: S = gpuStream): MlxArray {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
351
|
+
// EXACT copy of mlx's graph for
|
|
352
|
+
// 0.5 * x * (1 + tanh(√(2/π) * (x + 0.044715 * x**3)))
|
|
353
|
+
// as dumped via mx.export_to_dot. mlx's `__rmul__`/`__radd__` canonicalize
|
|
354
|
+
// every `scalar OP array` to `array OP scalar`, so every commutative product/
|
|
355
|
+
// sum below is ARRAY-FIRST, constant-second (NOT scalar-first). Build order
|
|
356
|
+
// follows Python left-to-right (`0.5 * x` first). Same libmlx compiles this to
|
|
357
|
+
// the identical fused kernel.
|
|
358
|
+
const cHalf = scalarLike(0.5, x);
|
|
359
|
+
const halfx = mul(x, cHalf, s); // Multiply(x, 0.5)
|
|
360
|
+
const cThree = scalarLike(3, x);
|
|
361
|
+
const x3 = pow(x, cThree, s); // Power(x, 3)
|
|
362
|
+
const cCoef = scalarLike(0.044715, x);
|
|
363
|
+
const cx3 = mul(x3, cCoef, s); // Multiply(x**3, 0.044715)
|
|
364
|
+
const inner = add(x, cx3, s); // Add(x, cx3)
|
|
365
|
+
const cSqrt = scalarLike(Math.sqrt(2 / Math.PI), x);
|
|
366
|
+
const scaled = mul(inner, cSqrt, s); // Multiply(inner, √(2/π))
|
|
278
367
|
const t = tanh(scaled, s);
|
|
279
|
-
const
|
|
280
|
-
const t1 = add(
|
|
281
|
-
const
|
|
282
|
-
const
|
|
283
|
-
for (const a of [three, x3, cx3, inner, scaled, t, one, t1, halfx]) a.dispose();
|
|
368
|
+
const cOne = scalarLike(1, x);
|
|
369
|
+
const t1 = add(t, cOne, s); // Add(tanh, 1)
|
|
370
|
+
const out = mul(halfx, t1, s); // Multiply(halfx, 1+tanh)
|
|
371
|
+
for (const a of [cHalf, halfx, cThree, x3, cCoef, cx3, inner, cSqrt, scaled, t, cOne, t1]) a.dispose();
|
|
284
372
|
return out;
|
|
285
373
|
}
|
|
286
374
|
|
|
@@ -376,7 +464,7 @@ export function where(cond: MlxArray, x: MlxArray, y: MlxArray, s: S = gpuStream
|
|
|
376
464
|
|
|
377
465
|
// arange is built host-side and uploaded. The original mlx_arange binding
|
|
378
466
|
// broke once the calling path got JIT-optimized; a standalone repro
|
|
379
|
-
// (repro/bun-ffi-f64/) traced the root cause to a Bun bug: after DFG
|
|
467
|
+
// (lab/repro/bun-ffi-f64/) traced the root cause to a Bun bug: after DFG
|
|
380
468
|
// tier-up, typed-array reads following a bun:ffi call return stale values
|
|
381
469
|
// (the JIT eliminates the load across the native call). Not f64 marshaling
|
|
382
470
|
// — args reach C intact. See PLAN.md Phase 4 findings. Large constant
|
|
@@ -392,13 +480,18 @@ export function arange(start: number, stop: number, step: number, dtype: Dtype,
|
|
|
392
480
|
const cached = arangeCache.get(key);
|
|
393
481
|
if (cached) return cached.slice([0], [n], s);
|
|
394
482
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
arr.
|
|
401
|
-
|
|
483
|
+
let arr: MlxArray;
|
|
484
|
+
if (dtype === Dtype.int32) {
|
|
485
|
+
// host-built int32 leaf (the Bun-f64-FFI-safe path — see note above).
|
|
486
|
+
const data = new Int32Array(n);
|
|
487
|
+
for (let i = 0; i < n; i++) data[i] = start + i * step;
|
|
488
|
+
arr = MlxArray.fromInt32(data, [n]);
|
|
489
|
+
} else {
|
|
490
|
+
// Native mlx Arange in the target dtype — matches mlx's `Arange` op exactly.
|
|
491
|
+
// The old `fromInt32 → .astype(dtype)` emitted a phantom int32→float Copy
|
|
492
|
+
// (an AsType the oracle never dispatches — e.g. the proportional-RoPE freq
|
|
493
|
+
// exponents). Integer start/step passed as doubles are exact.
|
|
494
|
+
arr = new MlxArray(outArray("arange", (o) => C.mlx_arange(o, start, stop, step, dtype, s)));
|
|
402
495
|
}
|
|
403
496
|
if (n >= ARANGE_CACHE_MIN) {
|
|
404
497
|
arangeCache.set(key, arr);
|
|
@@ -785,6 +878,26 @@ export function conv1d(
|
|
|
785
878
|
);
|
|
786
879
|
}
|
|
787
880
|
|
|
881
|
+
/** nn.Conv2d: input [B, H, W, C_in] (NHWC), weight [C_out, kH, kW, C_in/groups]
|
|
882
|
+
* → [B, H', W', C_out]. mlx weight layout — the oracle transposes PyTorch's
|
|
883
|
+
* [C_out, C_in, kH, kW] at load. For the gemma-4 audio SSCP subsampler.
|
|
884
|
+
* dilation_1 and groups ride in one packed u64 — see the mlx_conv2d hazard
|
|
885
|
+
* note in ffi.ts (bun:ffi stack-arg ABI bug). */
|
|
886
|
+
export function conv2d(
|
|
887
|
+
input: MlxArray, weight: MlxArray, stride: [number, number] = [1, 1],
|
|
888
|
+
padding: [number, number] = [0, 0], dilation: [number, number] = [1, 1],
|
|
889
|
+
groups = 1, s: S = gpuStream,
|
|
890
|
+
): MlxArray {
|
|
891
|
+
const dilation1AndGroups =
|
|
892
|
+
(BigInt(dilation[1] >>> 0) & 0xffffffffn) | (BigInt(groups >>> 0) << 32n);
|
|
893
|
+
return new MlxArray(
|
|
894
|
+
outArray("conv2d", (o) =>
|
|
895
|
+
C.mlx_conv2d(o, input.handle, weight.handle, stride[0], stride[1],
|
|
896
|
+
padding[0], padding[1], dilation[0], dilation1AndGroups, s),
|
|
897
|
+
),
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
|
|
788
901
|
/** mx.split(a, indices, axis): split at the given boundary offsets along `axis`
|
|
789
902
|
* into N+1 contiguous slices (mirrors numpy/mlx split-by-indices). */
|
|
790
903
|
export function split(a: MlxArray, indices: number[], axis: number): MlxArray[] {
|
|
@@ -818,3 +931,46 @@ export function silu(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
|
818
931
|
sig.dispose();
|
|
819
932
|
return r;
|
|
820
933
|
}
|
|
934
|
+
|
|
935
|
+
/** fast::hadamard_transform over the last axis. `scale` defaults to
|
|
936
|
+
* 1/sqrt(dim) (mlx's own default when unset) — pass it explicitly to
|
|
937
|
+
* match a reference that always states its normalization, per
|
|
938
|
+
* turboquant-ops.ts's fwht(). */
|
|
939
|
+
export function hadamardTransform(x: MlxArray, scale: number | null = null, s: S = gpuStream): MlxArray {
|
|
940
|
+
return new MlxArray(
|
|
941
|
+
outArray("hadamard_transform", (o) =>
|
|
942
|
+
C.mlx_hadamard_transform(o, x.handle, optFloat(scale), s),
|
|
943
|
+
),
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
export function minAxis(a: MlxArray, axis: number, keepdims: boolean, s: S = gpuStream): MlxArray {
|
|
948
|
+
return new MlxArray(
|
|
949
|
+
outArray("min_axis", (o) => C.mlx_min_axis(o, a.handle, axis, keepdims, s)),
|
|
950
|
+
);
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
/** mx.round(x, decimals=0) — round-half-to-even at the ULP grid mlx uses. */
|
|
954
|
+
export function round(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
955
|
+
return new MlxArray(outArray("round", (o) => C.mlx_round(o, a.handle, 0, s)));
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
export function greater(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
959
|
+
return new MlxArray(outArray("greater", (o) => C.mlx_greater(o, a.handle, b.handle, s)));
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
export function bitwiseAnd(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
963
|
+
return new MlxArray(outArray("bitwise_and", (o) => C.mlx_bitwise_and(o, a.handle, b.handle, s)));
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
export function bitwiseOr(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
967
|
+
return new MlxArray(outArray("bitwise_or", (o) => C.mlx_bitwise_or(o, a.handle, b.handle, s)));
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
export function leftShift(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
971
|
+
return new MlxArray(outArray("left_shift", (o) => C.mlx_left_shift(o, a.handle, b.handle, s)));
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
export function rightShift(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
975
|
+
return new MlxArray(outArray("right_shift", (o) => C.mlx_right_shift(o, a.handle, b.handle, s)));
|
|
976
|
+
}
|