mlx-bun 0.4.0 → 1.0.0
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 +1453 -88
- package/THIRD_PARTY_NOTICES.md +882 -0
- package/bin/mlx-bun.convert.mjs +4 -0
- package/bin/mlx-bun.fuse.mjs +4 -0
- package/bin/mlx-bun.generate.mjs +4 -0
- package/bin/mlx-bun.lora.mjs +4 -0
- package/bin/mlx-bun.mjs +13 -21
- package/bin/mlx-bun.server.mjs +4 -0
- package/bin/mlx-bun.upload.mjs +4 -0
- package/dist/web/app.js +9584 -0
- package/package.json +50 -53
- package/src/cli/ane-install.ts +76 -0
- package/src/cli/args.ts +179 -0
- package/src/cli/engine-entry.ts +68 -0
- package/src/cli/inference.ts +214 -0
- package/src/cli/job-entry.ts +97 -0
- package/src/cli/library-host.ts +117 -0
- package/src/cli/main.ts +57 -0
- package/src/cli/memory-engine.ts +163 -0
- package/src/cli/memory.ts +36 -0
- package/src/cli/mlx-lm-aliases.ts +309 -0
- package/src/cli/model-choice.ts +33 -0
- package/src/cli/model-selection.ts +84 -0
- package/src/cli/module-host.ts +11 -0
- package/src/cli/module-verbs.ts +50 -0
- package/src/cli/numerical-policy.ts +12 -0
- package/src/cli/perplexity.ts +89 -0
- package/src/cli/serve-host.ts +423 -0
- package/src/cli/serve-isolated.ts +217 -0
- package/src/cli/serve-options.ts +106 -0
- package/src/cli/serve-state.ts +205 -0
- package/src/cli/serve.ts +500 -0
- package/src/cli/served-model-host.ts +102 -0
- package/src/cli/server-entry.ts +148 -0
- package/src/cli/serving-unit.ts +177 -0
- package/src/{tui.ts → cli/terminal.ts} +13 -8
- package/src/cli/worker-adapters.ts +34 -0
- package/src/cli/worker-entry.ts +272 -0
- package/src/cli/worker-unit.ts +179 -0
- package/src/engine/adapter-operation.ts +26 -0
- package/src/engine/cache-services.ts +114 -0
- package/src/engine/completion.ts +39 -0
- package/src/engine/generation-gateway.ts +358 -0
- package/src/engine/index.ts +59 -0
- package/src/engine/kv-budget.ts +120 -0
- package/src/engine/media-preparation.ts +232 -0
- package/src/engine/model-binding.ts +24 -0
- package/src/engine/model-host.ts +513 -0
- package/src/engine/model-serving.ts +89 -0
- package/src/{serve → engine}/preparation.ts +10 -8
- package/src/{serve → engine}/session-completion-engine.ts +6 -6
- package/src/engine/telemetry.ts +109 -0
- package/src/hub/downloads.ts +116 -0
- package/src/jobs/db.ts +16 -7
- package/src/jobs/events.ts +29 -0
- package/src/jobs/executable.ts +5 -0
- package/src/jobs/host.ts +51 -0
- package/src/jobs/in-process.ts +55 -0
- package/src/{contracts/jobs.ts → jobs/protocol.ts} +7 -9
- package/src/jobs/runner.ts +150 -231
- package/src/jobs/service.ts +75 -0
- package/src/jobs/sse.ts +59 -23
- package/src/jobs/worker-memory.ts +46 -0
- package/src/jobs/worker-process.ts +163 -0
- package/src/jobs/worker-supervisor.ts +258 -0
- package/src/modules.ts +58 -0
- package/src/publishing/catalog-hub.ts +18 -0
- package/src/publishing/credentials.ts +31 -0
- package/src/publishing/upload.ts +37 -0
- package/src/residency/leased-adapters.ts +21 -0
- package/src/residency/local-records.ts +16 -0
- package/src/residency/model-residency.ts +405 -0
- package/src/residency/record-index.ts +28 -0
- package/src/residency/resident-estimate.ts +50 -0
- package/src/{anthropic.ts → server/anthropic.ts} +3 -81
- package/src/server/cache-routes.ts +36 -0
- package/src/{serve → server}/chat-request.ts +12 -10
- package/src/{serve → server}/chat-stage.ts +27 -22
- package/src/{client.ts → server/client.ts} +28 -2
- package/src/{serve → server}/completion-executor.ts +42 -42
- package/src/server/decision-body.ts +55 -0
- package/src/server/decision-routes.ts +134 -0
- package/src/server/decision-wire.ts +228 -0
- package/src/{serve → server}/discovery-routes.ts +42 -83
- package/src/server/generated-token-history.ts +57 -0
- package/src/{serve → server}/http.ts +25 -13
- package/src/{serve → server}/inference-request.ts +5 -5
- package/src/server/job-routes.ts +20 -0
- package/src/server/media-prompt.ts +63 -0
- package/src/server/memory-completion-client.ts +46 -0
- package/src/server/model-routes.ts +192 -0
- package/src/{serve → server}/openai-wire.ts +3 -2
- package/src/{serve → server}/pipeline.ts +1 -1
- package/src/server/prompt-builder.ts +13 -0
- package/src/server/prompt-contracts.ts +17 -0
- package/src/server/proxy-routes.ts +187 -0
- package/src/server/publishing-routes.ts +41 -0
- package/src/{serve → server}/request-plan.ts +8 -8
- package/src/{serve → server}/request-prep.ts +82 -68
- package/src/{serve → server}/responses-client.ts +30 -13
- package/src/{responses.ts → server/responses.ts} +12 -93
- package/src/server/routes.ts +205 -0
- package/src/server/start.ts +72 -0
- package/src/server/status-routes.ts +108 -0
- package/src/{serve → server}/text-completion-stage.ts +25 -4
- package/src/server/text-prompt.ts +12 -0
- package/src/{serve → server}/token-streams.ts +36 -38
- package/src/server/worker-routes.ts +311 -0
- package/src/storage/paths.ts +61 -0
- package/src/web/assets.ts +37 -0
- package/src/web/{src → browser}/api.ts +5 -23
- package/src/web/browser/chat-host.ts +17 -0
- package/src/web/browser/installed-panels.ts +6 -0
- package/src/web/browser/main.ts +55 -0
- package/src/web/browser/markdown.ts +279 -0
- package/src/web/browser/memory-panel.ts +9 -0
- package/src/web/browser/palette.ts +64 -0
- package/src/web/browser/protocol.ts +13 -0
- package/src/web/browser/shell.ts +467 -0
- package/src/web/{src → browser}/status.ts +32 -36
- package/src/web/build.ts +51 -0
- package/src/web/public/app.html +1054 -0
- package/src/web/{sw.js → public/sw.js} +4 -3
- package/src/web/{vendor → public/vendor}/hljs-theme.css +2 -2
- package/src/web/{vendor → public/vendor}/hljs.js +2 -2
- package/THIRD_PARTY_LICENSES.md +0 -51
- package/docs/README.md +0 -94
- package/docs/archive/hlg-sampling.md +0 -350
- package/docs/archive/investigations/audio-input-plan.md +0 -356
- package/docs/archive/investigations/chunk-finetune-experiment.md +0 -84
- package/docs/archive/investigations/colibri-glm52-port.md +0 -1486
- package/docs/archive/investigations/colibri-oracle-pin.md +0 -1284
- package/docs/archive/investigations/curve-bisector-routing.md +0 -123
- package/docs/archive/investigations/decode-roofline-lookagain.md +0 -348
- package/docs/archive/investigations/diffusion-gemma-port.md +0 -602
- package/docs/archive/investigations/dspark-handoff.md +0 -224
- package/docs/archive/investigations/expert-offload-single-user-moe.md +0 -292
- package/docs/archive/investigations/faithful-l1-consolidation.md +0 -310
- package/docs/archive/investigations/hlg-sampling-investigation.md +0 -970
- package/docs/archive/investigations/indexshare-performance-spike.md +0 -357
- package/docs/archive/investigations/kernel-perf-review-2026-07.md +0 -171
- package/docs/archive/investigations/lab-build-journal.md +0 -157
- package/docs/archive/investigations/minicpm5-decode-megakernel.md +0 -489
- package/docs/archive/investigations/openjarvis-fit.md +0 -198
- package/docs/archive/investigations/openwiki-evaluation.md +0 -249
- package/docs/archive/investigations/optimization_plan.md +0 -346
- package/docs/archive/investigations/orpo-base-uf-experiment-and-directions.md +0 -120
- package/docs/archive/investigations/orpo-flash-cce-pin-leak.md +0 -167
- package/docs/archive/investigations/orpo-uf-testing-handoff.md +0 -126
- package/docs/archive/investigations/pareto-specialized-runtime-findings.md +0 -92
- package/docs/archive/investigations/pi-builtin-investigation.md +0 -308
- package/docs/archive/investigations/pre-colibri-stabilization.md +0 -329
- package/docs/archive/investigations/qwen38-27b-campaign-log.md +0 -1092
- package/docs/archive/investigations/segmented-backward-handoff.md +0 -148
- package/docs/archive/investigations/starter-model-port-handoff.md +0 -342
- package/docs/archive/investigations/steel-flash-cce-handoff.md +0 -489
- package/docs/archive/investigations/the-dreaming-handoff.md +0 -141
- package/docs/archive/investigations/trainer-validation-experiment.md +0 -173
- package/docs/archive/planning/chat-ui-vision-memory-first.md +0 -199
- package/docs/archive/planning/chat-ui-vision.md +0 -50
- package/docs/archive/planning/chunk-task-roadmap.md +0 -77
- package/docs/archive/planning/curve-sampler-research-plan.md +0 -331
- package/docs/archive/planning/journal.md +0 -316
- package/docs/archive/planning/memory-docs-and-dag-plan.md +0 -194
- package/docs/archive/planning/pi-integration-review.md +0 -178
- package/docs/archive/planning/release-notes-v0.0.10.md +0 -57
- package/docs/archive/planning/release-notes-v0.0.11.md +0 -239
- package/docs/archive/planning/release-notes-v0.0.12.md +0 -80
- package/docs/archive/planning/release-notes-v0.0.13.md +0 -77
- package/docs/archive/planning/release-notes-v0.0.9.md +0 -122
- package/docs/archive/planning/release-notes-v0.2.0.md +0 -49
- package/docs/archive/planning/release-notes-v0.3.0.md +0 -35
- package/docs/archive/planning/web-ui-pass-plan.md +0 -213
- package/docs/archive/planning/website-readme-pass-plan.md +0 -224
- package/docs/design/batching.md +0 -1841
- package/docs/design/decode-speed-program.md +0 -2349
- package/docs/design/dreaming-nightly-pipeline.md +0 -684
- package/docs/design/generic-model-support.md +0 -705
- package/docs/design/kv-cache.md +0 -824
- package/docs/design/orpo-training.md +0 -680
- package/docs/design/speculative-decoding.md +0 -1990
- package/docs/design/turboquant.md +0 -2212
- package/docs/design/unified-engine-frontier-plan.md +0 -1880
- package/docs/design/web-chat-redesign.md +0 -695
- package/docs/planning/PRODUCT_ROADMAP.md +0 -594
- package/docs/planning/ResearchTopics.md +0 -119
- package/docs/planning/release-notes-v0.4.0.md +0 -45
- package/docs/planning/video-series.md +0 -421
- package/docs/reference/benchmarks.md +0 -3613
- package/docs/reference/cli.md +0 -585
- package/docs/reference/distribution.md +0 -355
- package/docs/reference/environment.md +0 -398
- package/docs/reference/glossary.md +0 -39
- package/docs/reference/library-api.md +0 -674
- package/docs/reference/memory.md +0 -260
- package/docs/reference/models.md +0 -334
- package/docs/reference/server-api.md +0 -1775
- package/docs/reference/server-config.md +0 -846
- package/docs/reference/training.md +0 -462
- package/docs/reference/troubleshooting.md +0 -158
- package/src/admission-plan.ts +0 -18
- package/src/audio/conformer.ts +0 -647
- package/src/audio/decode.ts +0 -133
- package/src/audio/features.ts +0 -202
- package/src/audio/transcode.ts +0 -67
- package/src/backends/mlx/assistant-target.ts +0 -46
- package/src/backends/mlx/autoregressive-draft-rows.ts +0 -120
- package/src/backends/mlx/autoregressive.ts +0 -108
- package/src/backends/mlx/batch-group.ts +0 -1790
- package/src/backends/mlx/cache-attachment.ts +0 -67
- package/src/backends/mlx/cache-layout.ts +0 -31
- package/src/backends/mlx/checkpoint-state.ts +0 -53
- package/src/backends/mlx/continuation-persistence.ts +0 -106
- package/src/backends/mlx/continuation-request.ts +0 -43
- package/src/backends/mlx/continuation.ts +0 -77
- package/src/backends/mlx/diffusion.ts +0 -39
- package/src/backends/mlx/draft-target.ts +0 -32
- package/src/backends/mlx/evaluation.ts +0 -105
- package/src/backends/mlx/fill-append.ts +0 -45
- package/src/backends/mlx/full-kv-row-append.ts +0 -32
- package/src/backends/mlx/full-kv-row-donor.ts +0 -54
- package/src/backends/mlx/full-transitioning-kv-rows.ts +0 -65
- package/src/backends/mlx/gateway-binding.ts +0 -130
- package/src/backends/mlx/graph.ts +0 -38
- package/src/backends/mlx/kv-codec.ts +0 -9
- package/src/backends/mlx/kv-maintenance.ts +0 -133
- package/src/backends/mlx/kv-tensor-rows.ts +0 -212
- package/src/backends/mlx/memory-client.ts +0 -189
- package/src/backends/mlx/methods.ts +0 -90
- package/src/backends/mlx/model-prompt.ts +0 -164
- package/src/backends/mlx/model-serving.ts +0 -79
- package/src/backends/mlx/prefill-cohort.ts +0 -89
- package/src/backends/mlx/prefill-rows.ts +0 -200
- package/src/backends/mlx/prefill.ts +0 -33
- package/src/backends/mlx/projected-context-rows.ts +0 -72
- package/src/backends/mlx/request-policy.ts +0 -20
- package/src/backends/mlx/request-state-policy.ts +0 -41
- package/src/backends/mlx/rollback.ts +0 -89
- package/src/backends/mlx/row-sampling.ts +0 -49
- package/src/backends/mlx/serial-executor.ts +0 -242
- package/src/backends/mlx/speculative-group.ts +0 -359
- package/src/backends/mlx/speculative-round.ts +0 -161
- package/src/backends/mlx/speculative.ts +0 -114
- package/src/backends/mlx/state-rows.ts +0 -104
- package/src/backends/mlx/state-views.ts +0 -46
- package/src/backends/mlx/target-layout-capability.ts +0 -35
- package/src/backends/mlx/text-engine.ts +0 -73
- package/src/backends/mlx/transitioning-kv-rows.ts +0 -165
- package/src/chat-template.ts +0 -382
- package/src/cli.ts +0 -3168
- package/src/config.ts +0 -399
- package/src/contracts/completion.ts +0 -16
- package/src/contracts/execution.ts +0 -60
- package/src/contracts/generation.ts +0 -103
- package/src/contracts/host.ts +0 -7
- package/src/contracts/pi-provider.ts +0 -30
- package/src/contracts/pi.ts +0 -259
- package/src/contracts/prefix-cache.ts +0 -23
- package/src/contracts/resources.ts +0 -25
- package/src/contracts/sampling.ts +0 -23
- package/src/contracts/scheduling.ts +0 -45
- package/src/contracts/tsconfig.json +0 -14
- package/src/dataset/generators.ts +0 -1087
- package/src/dataset/index.ts +0 -12
- package/src/dataset/job.ts +0 -81
- package/src/dataset/llm.ts +0 -71
- package/src/dataset/registry.ts +0 -528
- package/src/diffusion/diffusion-generate.ts +0 -507
- package/src/download.ts +0 -505
- package/src/embed.ts +0 -77
- package/src/engine/admission.ts +0 -59
- package/src/engine/cancellation.ts +0 -38
- package/src/engine/engine.ts +0 -56
- package/src/engine/execution-coordinator.ts +0 -70
- package/src/engine/execution-plan.ts +0 -53
- package/src/engine/resources.ts +0 -53
- package/src/engine/scheduler.ts +0 -72
- package/src/engine/session.ts +0 -247
- package/src/eval/README.md +0 -130
- package/src/eval/ifeval.ts +0 -81
- package/src/eval/kl-prompts.ts +0 -29
- package/src/eval/kl.ts +0 -590
- package/src/eval/perplexity.ts +0 -164
- package/src/eval/quality-db.ts +0 -92
- package/src/eval/reference-logits.ts +0 -207
- package/src/eval/runner.ts +0 -124
- package/src/eval/score.ts +0 -49
- package/src/eval/tasks/bfcl.ts +0 -535
- package/src/eval/tasks/gsm8k.ts +0 -98
- package/src/eval/tasks/hashhop.ts +0 -139
- package/src/eval/tasks/humaneval.ts +0 -275
- package/src/eval/tasks/ifeval.ts +0 -525
- package/src/eval/tasks/mmlu.ts +0 -157
- package/src/eval/ultrafeedback.ts +0 -60
- package/src/evaldb.ts +0 -199
- package/src/expert-io.ts +0 -393
- package/src/expert-offload-build.ts +0 -77
- package/src/expert-offload.ts +0 -76
- package/src/expert-residency.ts +0 -1134
- package/src/expert-usage.ts +0 -415
- package/src/fill/echo-index.ts +0 -188
- package/src/fill/fill-session.ts +0 -452
- package/src/fill/proposal.ts +0 -68
- package/src/fill/schema-rows.ts +0 -506
- package/src/fill/tool-boundary.ts +0 -103
- package/src/fit.ts +0 -249
- package/src/generate.ts +0 -1346
- package/src/grammar.ts +0 -591
- package/src/harness-pi.ts +0 -184
- package/src/hf-push.ts +0 -628
- package/src/hub-rest.ts +0 -242
- package/src/index.ts +0 -63
- package/src/inference/denoising.ts +0 -17
- package/src/inference/draft-acceptance.ts +0 -41
- package/src/inference/draft-output.ts +0 -49
- package/src/inference/graph.ts +0 -33
- package/src/inference/prefill.ts +0 -39
- package/src/inference/rollback.ts +0 -7
- package/src/jobs/index.ts +0 -31
- package/src/jobs/job-entry.ts +0 -107
- package/src/jobs/task-client.ts +0 -19
- package/src/jobs/types.ts +0 -2
- package/src/kv-scheme.ts +0 -257
- package/src/kv-store.ts +0 -1099
- package/src/lab/README.md +0 -18
- package/src/lab/curve/curve-designer.html +0 -303
- package/src/lab/curve/curve-sampler.ts +0 -122
- package/src/lab/expert-trace/expert-trace.ts +0 -69
- package/src/lab/paged-kv/paged-kv-rows.ts +0 -83
- package/src/lab/paged-kv/paged-kv.ts +0 -270
- package/src/library.ts +0 -40
- package/src/lora.ts +0 -408
- package/src/md-modules.d.ts +0 -49
- package/src/media-fetch.ts +0 -442
- package/src/memory/article.ts +0 -558
- package/src/memory/chunk-validation.ts +0 -150
- package/src/memory/chunk.ts +0 -318
- package/src/memory/cluster.ts +0 -351
- package/src/memory/coverage.ts +0 -134
- package/src/memory/crosslink.ts +0 -0
- package/src/memory/db.ts +0 -253
- package/src/memory/entity.ts +0 -203
- package/src/memory/gate.ts +0 -187
- package/src/memory/history.ts +0 -152
- package/src/memory/ingest.ts +0 -335
- package/src/memory/model.ts +0 -183
- package/src/memory/normalize.ts +0 -671
- package/src/memory/parse.ts +0 -22
- package/src/memory/pipeline.ts +0 -275
- package/src/memory/prompts.ts +0 -65
- package/src/memory/query.ts +0 -334
- package/src/memory/reconcile.ts +0 -734
- package/src/memory/redirect.ts +0 -108
- package/src/memory/reindex.ts +0 -325
- package/src/memory/resolve.ts +0 -307
- package/src/memory/rest.ts +0 -245
- package/src/memory/route.ts +0 -272
- package/src/memory/schedule.ts +0 -165
- package/src/memory/stages.ts +0 -777
- package/src/memory/synthesize.ts +0 -1638
- package/src/memory/tools.ts +0 -749
- package/src/memory/vault.ts +0 -1194
- package/src/memory/wikify.ts +0 -1064
- package/src/mlx/array.ts +0 -388
- package/src/mlx/autograd.ts +0 -304
- package/src/mlx/checkpoint.ts +0 -149
- package/src/mlx/compile.ts +0 -168
- package/src/mlx/custom-vjp.ts +0 -188
- package/src/mlx/ffi.ts +0 -512
- package/src/mlx/materialize.ts +0 -23
- package/src/mlx/metal-kernel.ts +0 -159
- package/src/mlx/ops.ts +0 -1021
- package/src/mlx/quantized-rows.ts +0 -36
- package/src/mlx/token-bitmask.ts +0 -52
- package/src/mlx/turboquant-kv-decode.ts +0 -82
- package/src/mlx/turboquant-kv-inverse.ts +0 -122
- package/src/mlx/turboquant-ops.ts +0 -861
- package/src/mlx/turboquant-tables.ts +0 -237
- package/src/mmap.ts +0 -90
- package/src/model/artifact-identity.ts +0 -73
- package/src/model/batched-kv.ts +0 -235
- package/src/model/batched-mask.ts +0 -279
- package/src/model/batched-quant.ts +0 -212
- package/src/model/batched-quantized-kv.ts +0 -144
- package/src/model/batched-rotating-quant.ts +0 -353
- package/src/model/batched-rotating-state.ts +0 -149
- package/src/model/batched-rotating.ts +0 -338
- package/src/model/batched-row-storage.ts +0 -179
- package/src/model/batched-ssm.ts +0 -52
- package/src/model/batched-turboquant-kv.ts +0 -93
- package/src/model/compiled-decode.ts +0 -712
- package/src/model/decoded-kv-donor.ts +0 -12
- package/src/model/delayed-quantized-kv.ts +0 -72
- package/src/model/delayed-rotating-quantized-kv.ts +0 -93
- package/src/model/delayed-turboquant-kv.ts +0 -55
- package/src/model/diffusion-gemma.ts +0 -1026
- package/src/model/factory.ts +0 -189
- package/src/model/fingerprint.ts +0 -33
- package/src/model/flash-attention.ts +0 -694
- package/src/model/full-prefill-padding.ts +0 -56
- package/src/model/full-prefill-row.ts +0 -105
- package/src/model/gemma4-base.ts +0 -2351
- package/src/model/gemma4.ts +0 -1315
- package/src/model/generated/gemma4-12b.ts +0 -429
- package/src/model/generated/gemma4-26b.ts +0 -448
- package/src/model/generated/gemma4-e4b.ts +0 -717
- package/src/model/generated/index.ts +0 -18
- package/src/model/glm52-atlas.ts +0 -511
- package/src/model/glm52-cache.ts +0 -792
- package/src/model/glm52-config.ts +0 -262
- package/src/model/glm52-container.ts +0 -305
- package/src/model/glm52-coupling.ts +0 -388
- package/src/model/glm52-dsa.ts +0 -606
- package/src/model/glm52-expert-layout.ts +0 -253
- package/src/model/glm52-layout.ts +0 -152
- package/src/model/glm52-memory.ts +0 -500
- package/src/model/glm52-mla.ts +0 -792
- package/src/model/glm52-moe.ts +0 -223
- package/src/model/glm52-pilot.ts +0 -537
- package/src/model/glm52-reference.ts +0 -445
- package/src/model/glm52-residency.ts +0 -557
- package/src/model/glm52-resident-weights.ts +0 -135
- package/src/model/glm52-streamed-experts.ts +0 -453
- package/src/model/glm52-streamed-metal.ts +0 -610
- package/src/model/glm52-weights.ts +0 -503
- package/src/model/glm52.ts +0 -1132
- package/src/model/implementation.ts +0 -69
- package/src/model/kv-attention-view.ts +0 -67
- package/src/model/minicpm5.ts +0 -376
- package/src/model/profile.ts +0 -443
- package/src/model/qwen-append.ts +0 -12
- package/src/model/qwen-conv.ts +0 -52
- package/src/model/qwen3-delta-state.ts +0 -74
- package/src/model/qwen3-delta.ts +0 -451
- package/src/model/qwen3-moe.ts +0 -404
- package/src/model/qwen3-mrope.ts +0 -252
- package/src/model/qwen3.ts +0 -277
- package/src/model/qwen3_5-checkpoint.ts +0 -164
- package/src/model/qwen3_5.ts +0 -819
- package/src/model/rotating-kv-donor.ts +0 -35
- package/src/model/rotating-kv-layout.ts +0 -262
- package/src/model/rotating-row-transaction.ts +0 -35
- package/src/model/speculative-rotating-kv.ts +0 -101
- package/src/model/ssm-prefill-padding.ts +0 -39
- package/src/model/support.ts +0 -102
- package/src/model/trellis-balanced-scatter.ts +0 -51
- package/src/model/trellis-linear.ts +0 -672
- package/src/model/trellis-shared-m.ts +0 -151
- package/src/model/trellis-shared-scatter.ts +0 -144
- package/src/model/trellis-splitk-prefill.ts +0 -158
- package/src/model/trellis-tiled-prefill.ts +0 -136
- package/src/model/trellis-vector-expand.ts +0 -62
- package/src/model/trellis-wide-prefill.ts +0 -94
- package/src/model/turboquant-codec.ts +0 -83
- package/src/model/universal/archs.ts +0 -332
- package/src/model/universal/dense.ts +0 -612
- package/src/model/universal/modules.ts +0 -170
- package/src/model/universal/rope.ts +0 -381
- package/src/native/expert_io.c +0 -523
- package/src/native/frame_extract.swift +0 -140
- package/src/native-pack.ts +0 -162
- package/src/pi-provider.ts +0 -53
- package/src/pi-session.ts +0 -81
- package/src/pi-terminal.ts +0 -274
- package/src/pi-web.ts +0 -1932
- package/src/preflight.ts +0 -158
- package/src/prompt-cache.ts +0 -460
- package/src/quantize/allocator.ts +0 -627
- package/src/quantize/atomic-output.ts +0 -38
- package/src/quantize/calibration.ts +0 -181
- package/src/quantize/config-writer.ts +0 -145
- package/src/quantize/index.ts +0 -84
- package/src/quantize/job.ts +0 -162
- package/src/quantize/quantizer.ts +0 -666
- package/src/quantize/rotate.ts +0 -603
- package/src/quantize/safetensors-writer.ts +0 -249
- package/src/quantize/sensitivity.ts +0 -216
- package/src/quantize/trellis.ts +0 -586
- package/src/quantize/weight-transform.ts +0 -292
- package/src/registry.ts +0 -602
- package/src/runtime-config.ts +0 -81
- package/src/safetensors.ts +0 -158
- package/src/sampler.ts +0 -1011
- package/src/serve/admin-routes.ts +0 -184
- package/src/serve/assets/curve-terrain.html +0 -105
- package/src/serve/assets/training-inference-map.html +0 -575
- package/src/serve/aux-routes.ts +0 -132
- package/src/serve/batch-scheduler.ts +0 -8
- package/src/serve/checkpoint-identity.ts +0 -64
- package/src/serve/generation-gateway.ts +0 -496
- package/src/serve/isolate.ts +0 -609
- package/src/serve/kv-budget.ts +0 -14
- package/src/serve/lab-routes.ts +0 -341
- package/src/serve/lane-registry.ts +0 -45
- package/src/serve/model-admin-routes.ts +0 -155
- package/src/serve/model-binding.ts +0 -43
- package/src/serve/model-host.ts +0 -511
- package/src/serve/parent-application.ts +0 -56
- package/src/serve/prompt-response-trace.ts +0 -147
- package/src/serve/response-lease.ts +0 -24
- package/src/serve/session-search.ts +0 -326
- package/src/serve/static-routes.ts +0 -101
- package/src/server.ts +0 -1314
- package/src/spec/assistant-rows.ts +0 -92
- package/src/spec/assistant-source.ts +0 -126
- package/src/spec/cache-identity.ts +0 -22
- package/src/spec/deepspec-rows.ts +0 -29
- package/src/spec/deepspec-source.ts +0 -145
- package/src/spec/dflash-source.ts +0 -149
- package/src/spec/drafter.ts +0 -304
- package/src/spec/dspark/ab-stats.ts +0 -136
- package/src/spec/dspark/calibration.ts +0 -112
- package/src/spec/dspark/data-dflash.ts +0 -156
- package/src/spec/dspark/data.ts +0 -201
- package/src/spec/dspark/deepspec-module.ts +0 -776
- package/src/spec/dspark/generate-dflash.ts +0 -245
- package/src/spec/dspark/generate.ts +0 -290
- package/src/spec/dspark/loader.ts +0 -23
- package/src/spec/dspark/loss.ts +0 -213
- package/src/spec/dspark/module-dflash.ts +0 -560
- package/src/spec/dspark/module.ts +0 -540
- package/src/spec/dspark/quantize-drafter.ts +0 -91
- package/src/spec/dspark/sample.ts +0 -112
- package/src/spec/generate.ts +0 -276
- package/src/spec/glm52-mtp-graph.ts +0 -29
- package/src/spec/glm52-mtp-rows.ts +0 -132
- package/src/spec/glm52-mtp-source.ts +0 -317
- package/src/spec/glm52-mtp-state.ts +0 -33
- package/src/spec/ngram-source.ts +0 -204
- package/src/spec/projected-draft-rows.ts +0 -73
- package/src/spec/qwen-mtp-module.ts +0 -171
- package/src/spec/qwen-mtp-rows.ts +0 -219
- package/src/spec/qwen-mtp-source.ts +0 -383
- package/src/spec/qwen-mtp-state.ts +0 -30
- package/src/spec/serve-loop.ts +0 -585
- package/src/spec/source.ts +0 -215
- package/src/spec/two-model-rows.ts +0 -61
- package/src/spec/two-model.ts +0 -113
- package/src/ssd-cache.ts +0 -372
- package/src/ssd-durability.ts +0 -211
- package/src/tokenizer.ts +0 -335
- package/src/tool-approvals.ts +0 -131
- package/src/tool-call.ts +0 -695
- package/src/train/dataset.ts +0 -484
- package/src/train/diffusion-lora.ts +0 -216
- package/src/train/export.ts +0 -32
- package/src/train/flash-cce.ts +0 -1234
- package/src/train/forward.ts +0 -266
- package/src/train/fuse.ts +0 -243
- package/src/train/index.ts +0 -46
- package/src/train/job.ts +0 -205
- package/src/train/lora-params.ts +0 -254
- package/src/train/loss.ts +0 -1591
- package/src/train/merge.ts +0 -195
- package/src/train/optimizer.ts +0 -183
- package/src/train/prefix-shared.ts +0 -490
- package/src/train/rank.ts +0 -137
- package/src/train/segmented.ts +0 -1828
- package/src/train/steel-qmm-header.ts +0 -1461
- package/src/train/trainer.ts +0 -1221
- package/src/train/watch.ts +0 -542
- package/src/vision/diffusion-vision.ts +0 -620
- package/src/vision/embedder.ts +0 -168
- package/src/vision/preprocess.ts +0 -247
- package/src/vision/prompt.ts +0 -373
- package/src/vision/qwen3vl-preprocess.ts +0 -409
- package/src/vision/qwen3vl-prompt.ts +0 -196
- package/src/vision/qwen3vl-tower.ts +0 -555
- package/src/vision/siglip.ts +0 -599
- package/src/vision/video-frames.ts +0 -148
- package/src/web/app.html +0 -2143
- package/src/web/app.js +0 -5703
- package/src/web/skills/memory/SKILL.md +0 -120
- package/src/web/skills/web-research/SKILL.md +0 -46
- package/src/web/skills.ts +0 -97
- package/src/web/src/adapters-panel.ts +0 -288
- package/src/web/src/assistant.ts +0 -451
- package/src/web/src/chat.ts +0 -1057
- package/src/web/src/composer.ts +0 -959
- package/src/web/src/dataset.ts +0 -132
- package/src/web/src/finetune.ts +0 -267
- package/src/web/src/hub.ts +0 -428
- package/src/web/src/main.ts +0 -98
- package/src/web/src/markdown.ts +0 -0
- package/src/web/src/memory-panel.ts +0 -572
- package/src/web/src/model-picker.ts +0 -159
- package/src/web/src/palette.ts +0 -346
- package/src/web/src/protocol.ts +0 -26
- package/src/web/src/quantize.ts +0 -167
- package/src/web/src/rag.ts +0 -274
- package/src/web/src/sessions.ts +0 -469
- package/src/web/src/shell.ts +0 -804
- package/src/web/src/ui-catalog.ts +0 -78
- package/src/web/vendor/README.md +0 -61
- package/src/web-assets.ts +0 -47
- package/src/web-tools.ts +0 -478
- package/src/weights.ts +0 -255
- /package/src/{serve → server}/completion-sink.ts +0 -0
- /package/src/web/{icon.svg → public/icon.svg} +0 -0
- /package/src/web/{manifest.webmanifest → public/manifest.webmanifest} +0 -0
- /package/src/web/{vendor → public/vendor}/hljs-LICENSE +0 -0
package/src/mlx/ops.ts
DELETED
|
@@ -1,1021 +0,0 @@
|
|
|
1
|
-
// Functional op layer over MlxArray. Parity-critical conventions:
|
|
2
|
-
// - Python-float scalars in mlx promote weakly (bf16 array × float →
|
|
3
|
-
// bf16, scalar cast to bf16 first). `scalarLike` replicates that.
|
|
4
|
-
// - Op composition order mirrors mlx-lm exactly; see model/gemma4.ts.
|
|
5
|
-
|
|
6
|
-
import { ptr, read } from "bun:ffi";
|
|
7
|
-
import { C, Dtype, type MlxHandle, optFloat, optInt, outArray, takeMlxError } from "./ffi";
|
|
8
|
-
import { MlxArray, gpuStream } from "./array";
|
|
9
|
-
|
|
10
|
-
const cstrCache = new Map<string, Buffer>();
|
|
11
|
-
function cstr(s: string): Buffer {
|
|
12
|
-
let b = cstrCache.get(s);
|
|
13
|
-
if (!b) {
|
|
14
|
-
b = Buffer.from(s + "\0", "utf8");
|
|
15
|
-
cstrCache.set(s, b);
|
|
16
|
-
}
|
|
17
|
-
return b;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type S = MlxHandle;
|
|
21
|
-
|
|
22
|
-
export function add(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
23
|
-
return new MlxArray(outArray("add", (o) => C.mlx_add(o, a.handle, b.handle, s)));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function sub(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
27
|
-
return new MlxArray(outArray("subtract", (o) => C.mlx_subtract(o, a.handle, b.handle, s)));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function mul(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
31
|
-
return new MlxArray(outArray("multiply", (o) => C.mlx_multiply(o, a.handle, b.handle, s)));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function div(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
35
|
-
return new MlxArray(outArray("divide", (o) => C.mlx_divide(o, a.handle, b.handle, s)));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function tanh(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
39
|
-
return new MlxArray(outArray("tanh", (o) => C.mlx_tanh(o, a.handle, s)));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function sigmoid(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
43
|
-
return new MlxArray(outArray("sigmoid", (o) => C.mlx_sigmoid(o, a.handle, s)));
|
|
44
|
-
}
|
|
45
|
-
|
|
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. */
|
|
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).
|
|
78
|
-
const f = MlxArray.fromFloat32(new Float32Array([value]), []);
|
|
79
|
-
const cast = f.astype(like.dtype);
|
|
80
|
-
f.dispose();
|
|
81
|
-
return cast;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function mulScalar(a: MlxArray, value: number, s: S = gpuStream): MlxArray {
|
|
85
|
-
const k = scalarLike(value, a);
|
|
86
|
-
const r = mul(a, k, s);
|
|
87
|
-
k.dispose();
|
|
88
|
-
return r;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function rmsNorm(
|
|
92
|
-
x: MlxArray, weight: MlxArray | null, eps: number, s: S = gpuStream,
|
|
93
|
-
): MlxArray {
|
|
94
|
-
return new MlxArray(
|
|
95
|
-
outArray("fast_rms_norm", (o) =>
|
|
96
|
-
C.mlx_fast_rms_norm(o, x.handle, weight?.handle ?? 0n, eps, s),
|
|
97
|
-
),
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export function layerNorm(
|
|
102
|
-
x: MlxArray, weight: MlxArray | null, bias: MlxArray | null, eps: number,
|
|
103
|
-
s: S = gpuStream,
|
|
104
|
-
): MlxArray {
|
|
105
|
-
return new MlxArray(
|
|
106
|
-
outArray("fast_layer_norm", (o) =>
|
|
107
|
-
C.mlx_fast_layer_norm(o, x.handle, weight?.handle ?? 0n, bias?.handle ?? 0n, eps, s),
|
|
108
|
-
),
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function matmul(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
113
|
-
return new MlxArray(outArray("matmul", (o) => C.mlx_matmul(o, a.handle, b.handle, s)));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/** Bit-identical copy through a FRESH primitive node (mx.copy). Unlike
|
|
117
|
-
* `contiguous`, this always creates a new graph node even for an already-
|
|
118
|
-
* contiguous input — the tool for DETACHING an array from a multi-output
|
|
119
|
-
* primitive's sibling set (a retained sibling output pins every co-output's
|
|
120
|
-
* buffer natively; see gatedDeltaUpdate's state detach, 2026-08-20). */
|
|
121
|
-
export function copyOf(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
122
|
-
return new MlxArray(outArray("copy", (o) => C.mlx_copy(o, a.handle, s)));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/** Materialize a row-major contiguous copy (needed before rawBytes on views). */
|
|
126
|
-
export function contiguous(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
127
|
-
return new MlxArray(
|
|
128
|
-
outArray("contiguous", (o) => C.mlx_contiguous(o, a.handle, false, s)),
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export function logicalOr(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
133
|
-
return new MlxArray(
|
|
134
|
-
outArray("logical_or", (o) => C.mlx_logical_or(o, a.handle, b.handle, s)),
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export function rope(
|
|
139
|
-
x: MlxArray, dims: number, base: number | null, offset: number,
|
|
140
|
-
freqs: MlxArray | null, s: S = gpuStream,
|
|
141
|
-
): MlxArray {
|
|
142
|
-
return new MlxArray(
|
|
143
|
-
outArray("fast_rope", (o) =>
|
|
144
|
-
C.mlx_fast_rope(
|
|
145
|
-
o, x.handle, dims, false, optFloat(base), 1.0, offset,
|
|
146
|
-
freqs?.handle ?? 0n, s,
|
|
147
|
-
),
|
|
148
|
-
),
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/** fast::rope with every knob exposed (traditional + scale), for the
|
|
153
|
-
* universal rope factory (rope_utils.initialize_rope port). The plain
|
|
154
|
-
* `rope` above stays byte-identical for existing call sites. */
|
|
155
|
-
export function ropeScaled(
|
|
156
|
-
x: MlxArray, dims: number, traditional: boolean, base: number | null,
|
|
157
|
-
scale: number, offset: number, freqs: MlxArray | null, s: S = gpuStream,
|
|
158
|
-
): MlxArray {
|
|
159
|
-
return new MlxArray(
|
|
160
|
-
outArray("fast_rope", (o) =>
|
|
161
|
-
C.mlx_fast_rope(
|
|
162
|
-
o, x.handle, dims, traditional, optFloat(base), scale, offset,
|
|
163
|
-
freqs?.handle ?? 0n, s,
|
|
164
|
-
),
|
|
165
|
-
),
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** fast::rope with the position offset as an ARRAY (int32 scalar) instead
|
|
170
|
-
* of a baked int — required inside compiled decode graphs, where the
|
|
171
|
-
* offset changes every step but the graph must not. Same kernel as
|
|
172
|
-
* `rope`; bit-exactness vs the static form is asserted in
|
|
173
|
-
* tests/unit/compile.test.ts. */
|
|
174
|
-
export function ropeDynamic(
|
|
175
|
-
x: MlxArray, dims: number, base: number | null, offset: MlxArray,
|
|
176
|
-
freqs: MlxArray | null, s: S = gpuStream,
|
|
177
|
-
): MlxArray {
|
|
178
|
-
return new MlxArray(
|
|
179
|
-
outArray("fast_rope_dynamic", (o) =>
|
|
180
|
-
C.mlx_fast_rope_dynamic(
|
|
181
|
-
o, x.handle, dims, false, optFloat(base), 1.0, offset.handle,
|
|
182
|
-
freqs?.handle ?? 0n, s,
|
|
183
|
-
),
|
|
184
|
-
),
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/** Array-offset fast::rope with every knob exposed (traditional + scale) —
|
|
189
|
-
* the dynamic twin of `ropeScaled`, for the universal rope factory's
|
|
190
|
-
* batched-decode path (per-row [B] offsets under left-padding). Same
|
|
191
|
-
* kernel as `ropeDynamic`; static/dynamic bit-exactness is asserted in
|
|
192
|
-
* tests/unit/compile.test.ts. */
|
|
193
|
-
export function ropeScaledDynamic(
|
|
194
|
-
x: MlxArray, dims: number, traditional: boolean, base: number | null,
|
|
195
|
-
scale: number, offset: MlxArray, freqs: MlxArray | null, s: S = gpuStream,
|
|
196
|
-
): MlxArray {
|
|
197
|
-
return new MlxArray(
|
|
198
|
-
outArray("fast_rope_dynamic", (o) =>
|
|
199
|
-
C.mlx_fast_rope_dynamic(
|
|
200
|
-
o, x.handle, dims, traditional, optFloat(base), scale, offset.handle,
|
|
201
|
-
freqs?.handle ?? 0n, s,
|
|
202
|
-
),
|
|
203
|
-
),
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export function sdpa(
|
|
208
|
-
q: MlxArray, k: MlxArray, v: MlxArray, scale: number,
|
|
209
|
-
maskMode: "" | "causal" | "array", maskArr: MlxArray | null = null,
|
|
210
|
-
s: S = gpuStream,
|
|
211
|
-
): MlxArray {
|
|
212
|
-
return new MlxArray(
|
|
213
|
-
outArray("fast_sdpa", (o) =>
|
|
214
|
-
C.mlx_fast_scaled_dot_product_attention(
|
|
215
|
-
o, q.handle, k.handle, v.handle, scale, ptr(cstr(maskMode)),
|
|
216
|
-
maskArr?.handle ?? 0n, 0n, false, s,
|
|
217
|
-
),
|
|
218
|
-
),
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
export interface QuantSpec {
|
|
223
|
-
bits: number;
|
|
224
|
-
groupSize: number;
|
|
225
|
-
mode: string;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
export function quantizedMatmul(
|
|
229
|
-
x: MlxArray, w: MlxArray, scales: MlxArray, biases: MlxArray | null,
|
|
230
|
-
spec: QuantSpec, transpose = true, s: S = gpuStream,
|
|
231
|
-
): MlxArray {
|
|
232
|
-
// UPSTREAM MLX BUG WORKAROUND (found 2026-07-02, reproduced on stock mlx
|
|
233
|
-
// 0.31.2): quantized_matmul with transpose=false returns WRONG VALUES when
|
|
234
|
-
// the row count is 2 or 3 (relnorm ~0.3-1.1 vs the dequantized matmul);
|
|
235
|
-
// M=1 and M>=4 are correct, transpose=true is correct at every M. Pad the
|
|
236
|
-
// row axis to 4 with zeros and slice the result back. NOTE this wrapper
|
|
237
|
-
// cannot protect mlx's INTERNAL vjp of a transpose=true qmm (C++ calls the
|
|
238
|
-
// primitive directly) — training heads pad the span through the head
|
|
239
|
-
// instead (loss.ts logitsFromHiddenPadM).
|
|
240
|
-
const rowAxis = x.shape.length - 2;
|
|
241
|
-
const rows = x.shape[rowAxis]!;
|
|
242
|
-
if (!transpose && (rows === 2 || rows === 3)) {
|
|
243
|
-
const padShape = [...x.shape];
|
|
244
|
-
padShape[rowAxis] = 4 - rows;
|
|
245
|
-
const pad = zeros(padShape, x.dtype, s);
|
|
246
|
-
const xPad = concatAxis([x, pad], rowAxis, s);
|
|
247
|
-
pad.dispose();
|
|
248
|
-
const yPad = quantizedMatmul(xPad, w, scales, biases, spec, transpose, s);
|
|
249
|
-
xPad.dispose();
|
|
250
|
-
const start = MlxArray.fromInt32(new Int32Array([0]), [1]);
|
|
251
|
-
const outShape = [...yPad.shape];
|
|
252
|
-
outShape[rowAxis] = rows;
|
|
253
|
-
const y = sliceDynamic(yPad, start, [rowAxis], outShape, s);
|
|
254
|
-
start.dispose();
|
|
255
|
-
yPad.dispose();
|
|
256
|
-
return y;
|
|
257
|
-
}
|
|
258
|
-
return new MlxArray(
|
|
259
|
-
outArray("quantized_matmul", (o) =>
|
|
260
|
-
C.mlx_quantized_matmul(
|
|
261
|
-
o, x.handle, w.handle, scales.handle, biases?.handle ?? 0n,
|
|
262
|
-
transpose, optInt(spec.groupSize), optInt(spec.bits),
|
|
263
|
-
ptr(cstr(spec.mode)), s,
|
|
264
|
-
),
|
|
265
|
-
),
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/** Gathered quantized matmul over stacked expert weights (MoE).
|
|
270
|
-
* x [..., 1, K] with rhs_indices [...] selecting the expert per row;
|
|
271
|
-
* port of mx.gather_qmm as QuantizedSwitchLinear uses it. */
|
|
272
|
-
export function gatherQmm(
|
|
273
|
-
x: MlxArray, w: MlxArray, scales: MlxArray, biases: MlxArray | null,
|
|
274
|
-
rhsIndices: MlxArray, spec: QuantSpec, sortedIndices: boolean,
|
|
275
|
-
transpose = true, s: S = gpuStream,
|
|
276
|
-
): MlxArray {
|
|
277
|
-
return new MlxArray(
|
|
278
|
-
outArray("gather_qmm", (o) =>
|
|
279
|
-
C.mlx_gather_qmm(
|
|
280
|
-
o, x.handle, w.handle, scales.handle, biases?.handle ?? 0n,
|
|
281
|
-
0n /* lhs_indices */, rhsIndices.handle, transpose,
|
|
282
|
-
optInt(spec.groupSize), optInt(spec.bits), ptr(cstr(spec.mode)),
|
|
283
|
-
sortedIndices, s,
|
|
284
|
-
),
|
|
285
|
-
),
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export function floorDivide(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
290
|
-
return new MlxArray(
|
|
291
|
-
outArray("floor_divide", (o) => C.mlx_floor_divide(o, a.handle, b.handle, s)),
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
export function dequantize(
|
|
296
|
-
w: MlxArray, scales: MlxArray, biases: MlxArray | null, spec: QuantSpec,
|
|
297
|
-
s: S = gpuStream,
|
|
298
|
-
): MlxArray {
|
|
299
|
-
return new MlxArray(
|
|
300
|
-
outArray("dequantize", (o) =>
|
|
301
|
-
C.mlx_dequantize(
|
|
302
|
-
o, w.handle, scales.handle, biases?.handle ?? 0n,
|
|
303
|
-
optInt(spec.groupSize), optInt(spec.bits), ptr(cstr(spec.mode)),
|
|
304
|
-
0n, optInt(null), s,
|
|
305
|
-
),
|
|
306
|
-
),
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
export function takeAxis(a: MlxArray, indices: MlxArray, axis: number, s: S = gpuStream): MlxArray {
|
|
311
|
-
return new MlxArray(
|
|
312
|
-
outArray("take_axis", (o) => C.mlx_take_axis(o, a.handle, indices.handle, axis, s)),
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
export function reshape(a: MlxArray, shape: number[], s: S = gpuStream): MlxArray {
|
|
317
|
-
// bun:ffi cannot take a pointer to an empty view; ndim=0 ignores the dummy.
|
|
318
|
-
const buf = new Int32Array(shape.length ? shape : [0]);
|
|
319
|
-
return new MlxArray(
|
|
320
|
-
outArray("reshape", (o) => C.mlx_reshape(o, a.handle, ptr(buf), BigInt(shape.length), s)),
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
export function transposeAxes(a: MlxArray, axes: number[], s: S = gpuStream): MlxArray {
|
|
325
|
-
const buf = new Int32Array(axes);
|
|
326
|
-
return new MlxArray(
|
|
327
|
-
outArray("transpose", (o) => C.mlx_transpose_axes(o, a.handle, ptr(buf), BigInt(axes.length), s)),
|
|
328
|
-
);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
export function argmaxAxis(a: MlxArray, axis: number, s: S = gpuStream): MlxArray {
|
|
332
|
-
return new MlxArray(
|
|
333
|
-
outArray("argmax_axis", (o) => C.mlx_argmax_axis(o, a.handle, axis, false, s)),
|
|
334
|
-
);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
export function concatAxis(arrays: MlxArray[], axis: number, s: S = gpuStream): MlxArray {
|
|
338
|
-
const handles = new BigUint64Array(arrays.map((a) => a.handle));
|
|
339
|
-
const vec = C.mlx_vector_array_new_data(ptr(handles), BigInt(arrays.length));
|
|
340
|
-
try {
|
|
341
|
-
return new MlxArray(
|
|
342
|
-
outArray("concatenate", (o) => C.mlx_concatenate_axis(o, vec, axis, s)),
|
|
343
|
-
);
|
|
344
|
-
} finally {
|
|
345
|
-
C.mlx_vector_array_free(vec);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
export function pow(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
350
|
-
return new MlxArray(outArray("power", (o) => C.mlx_power(o, a.handle, b.handle, s)));
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/** nn.gelu_approx: 0.5 * x * (1 + tanh(√(2/π) * (x + 0.044715 * x³))) — composed
|
|
354
|
-
* exactly as mlx's python source, INCLUDING operand order: x**3 is mx.power
|
|
355
|
-
* (NOT x·x·x — they round differently in bf16), and every scalar·array product
|
|
356
|
-
* puts the SCALAR FIRST (`0.5 * x`, not `x * 0.5`). Multiply is commutative so
|
|
357
|
-
* this is bit-identical, but it makes the compiled geglu graph's operand string
|
|
358
|
-
* (`Multiply(C, V)`) match the oracle's fused kernel exactly. Scalars promote
|
|
359
|
-
* weakly to x's dtype. */
|
|
360
|
-
export function geluApprox(x: MlxArray, s: S = gpuStream): MlxArray {
|
|
361
|
-
// EXACT copy of mlx's graph for
|
|
362
|
-
// 0.5 * x * (1 + tanh(√(2/π) * (x + 0.044715 * x**3)))
|
|
363
|
-
// as dumped via mx.export_to_dot. mlx's `__rmul__`/`__radd__` canonicalize
|
|
364
|
-
// every `scalar OP array` to `array OP scalar`, so every commutative product/
|
|
365
|
-
// sum below is ARRAY-FIRST, constant-second (NOT scalar-first). Build order
|
|
366
|
-
// follows Python left-to-right (`0.5 * x` first). Same libmlx compiles this to
|
|
367
|
-
// the identical fused kernel.
|
|
368
|
-
const cHalf = scalarLike(0.5, x);
|
|
369
|
-
const halfx = mul(x, cHalf, s); // Multiply(x, 0.5)
|
|
370
|
-
const cThree = scalarLike(3, x);
|
|
371
|
-
const x3 = pow(x, cThree, s); // Power(x, 3)
|
|
372
|
-
const cCoef = scalarLike(0.044715, x);
|
|
373
|
-
const cx3 = mul(x3, cCoef, s); // Multiply(x**3, 0.044715)
|
|
374
|
-
const inner = add(x, cx3, s); // Add(x, cx3)
|
|
375
|
-
const cSqrt = scalarLike(Math.sqrt(2 / Math.PI), x);
|
|
376
|
-
const scaled = mul(inner, cSqrt, s); // Multiply(inner, √(2/π))
|
|
377
|
-
const t = tanh(scaled, s);
|
|
378
|
-
const cOne = scalarLike(1, x);
|
|
379
|
-
const t1 = add(t, cOne, s); // Add(tanh, 1)
|
|
380
|
-
const out = mul(halfx, t1, s); // Multiply(halfx, 1+tanh)
|
|
381
|
-
for (const a of [cHalf, halfx, cThree, x3, cCoef, cx3, inner, cSqrt, scaled, t, cOne, t1]) a.dispose();
|
|
382
|
-
return out;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
export function erf(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
386
|
-
return new MlxArray(outArray("erf", (o) => C.mlx_erf(o, a.handle, s)));
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/** nn.gelu (PRECISE, erf-based): x · (1 + erf(x/√2)) / 2 — composed exactly
|
|
390
|
-
* as mlx's python source (weak scalars promote to x's dtype). Used by the
|
|
391
|
-
* gemma-1 gated MLP and starcoder2's plain MLP; distinct from geluApprox
|
|
392
|
-
* (gelu_pytorch_tanh). */
|
|
393
|
-
export function geluPrecise(x: MlxArray, s: S = gpuStream): MlxArray {
|
|
394
|
-
const sqrt2 = scalarLike(Math.sqrt(2), x);
|
|
395
|
-
const xs = div(x, sqrt2, s); // x / math.sqrt(2) — division, not mul-by-reciprocal
|
|
396
|
-
const e = erf(xs, s);
|
|
397
|
-
const one = scalarLike(1, x);
|
|
398
|
-
const e1 = add(one, e, s);
|
|
399
|
-
const xe = mul(x, e1, s);
|
|
400
|
-
const two = scalarLike(2, x);
|
|
401
|
-
const out = div(xe, two, s); // (...) / 2
|
|
402
|
-
for (const a of [sqrt2, xs, e, one, e1, xe, two]) a.dispose();
|
|
403
|
-
return out;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/** mx.addmm(c, a, b): a@b + c fused (α=β=1) — nn.Linear's bias path
|
|
407
|
-
* (`mx.addmm(bias, x, weight.T)`). */
|
|
408
|
-
export function addmm(c: MlxArray, a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
409
|
-
return new MlxArray(
|
|
410
|
-
outArray("addmm", (o) => C.mlx_addmm(o, c.handle, a.handle, b.handle, 1.0, 1.0, s)),
|
|
411
|
-
);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
export function exp(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
415
|
-
return new MlxArray(outArray("exp", (o) => C.mlx_exp(o, a.handle, s)));
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
export function cos(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
419
|
-
return new MlxArray(outArray("cos", (o) => C.mlx_cos(o, a.handle, s)));
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
export function sin(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
423
|
-
return new MlxArray(outArray("sin", (o) => C.mlx_sin(o, a.handle, s)));
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
export function neg(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
427
|
-
return new MlxArray(outArray("negative", (o) => C.mlx_negative(o, a.handle, s)));
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
export function argsortAxis(a: MlxArray, axis: number, s: S = gpuStream): MlxArray {
|
|
431
|
-
return new MlxArray(outArray("argsort", (o) => C.mlx_argsort_axis(o, a.handle, axis, s)));
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
export function argpartitionAxis(a: MlxArray, kth: number, axis: number, s: S = gpuStream): MlxArray {
|
|
435
|
-
return new MlxArray(
|
|
436
|
-
outArray("argpartition", (o) => C.mlx_argpartition_axis(o, a.handle, kth, axis, s)),
|
|
437
|
-
);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
export function takeAlongAxis(a: MlxArray, idx: MlxArray, axis: number, s: S = gpuStream): MlxArray {
|
|
441
|
-
return new MlxArray(
|
|
442
|
-
outArray("take_along_axis", (o) => C.mlx_take_along_axis(o, a.handle, idx.handle, axis, s)),
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
export function putAlongAxis(
|
|
447
|
-
a: MlxArray, idx: MlxArray, values: MlxArray, axis: number, s: S = gpuStream,
|
|
448
|
-
): MlxArray {
|
|
449
|
-
return new MlxArray(
|
|
450
|
-
outArray("put_along_axis", (o) =>
|
|
451
|
-
C.mlx_put_along_axis(o, a.handle, idx.handle, values.handle, axis, s),
|
|
452
|
-
),
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
export function cumsum(a: MlxArray, axis: number, s: S = gpuStream): MlxArray {
|
|
457
|
-
return new MlxArray(
|
|
458
|
-
outArray("cumsum", (o) => C.mlx_cumsum_axis(o, a.handle, axis, false, true, 0n, s)),
|
|
459
|
-
);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
/** Cumulative maximum along `axis` (inclusive, forward) — mlx.core.cummax. */
|
|
463
|
-
export function cummax(a: MlxArray, axis: number, s: S = gpuStream): MlxArray {
|
|
464
|
-
return new MlxArray(
|
|
465
|
-
outArray("cummax", (o) => C.mlx_cummax_axis(o, a.handle, axis, false, true, s)),
|
|
466
|
-
);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
export function where(cond: MlxArray, x: MlxArray, y: MlxArray, s: S = gpuStream): MlxArray {
|
|
470
|
-
return new MlxArray(
|
|
471
|
-
outArray("where", (o) => C.mlx_where(o, cond.handle, x.handle, y.handle, s)),
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// arange is built host-side and uploaded. The original mlx_arange binding
|
|
476
|
-
// broke once the calling path got JIT-optimized; a standalone repro
|
|
477
|
-
// (lab/repro/bun-ffi-f64/) traced the root cause to a Bun bug: after DFG
|
|
478
|
-
// tier-up, typed-array reads following a bun:ffi call return stale values
|
|
479
|
-
// (the JIT eliminates the load across the native call). Not f64 marshaling
|
|
480
|
-
// — args reach C intact. See PLAN.md Phase 4 findings. Reuse large ranges
|
|
481
|
-
// across attention layers and sampling, but bound their retained storage:
|
|
482
|
-
// causal masks request a new range on every round once context exceeds 64K.
|
|
483
|
-
const arangeCache = new Map<string, { array: MlxArray; bytes: number }>();
|
|
484
|
-
const ARANGE_CACHE_MIN = 65536;
|
|
485
|
-
const ARANGE_CACHE_BYTES = 8 * 1024 * 1024;
|
|
486
|
-
let arangeCacheBytes = 0;
|
|
487
|
-
|
|
488
|
-
export function arange(start: number, stop: number, step: number, dtype: Dtype, s: S = gpuStream): MlxArray {
|
|
489
|
-
if (!Number.isInteger(start) || !Number.isInteger(step) || step === 0)
|
|
490
|
-
throw new Error(`arange: integer start/step required (${start}, ${stop}, ${step})`);
|
|
491
|
-
const n = Math.max(0, Math.ceil((stop - start) / step));
|
|
492
|
-
const key = `${start}|${step}|${n}|${dtype}`;
|
|
493
|
-
const cached = arangeCache.get(key);
|
|
494
|
-
if (cached) {
|
|
495
|
-
arangeCache.delete(key);
|
|
496
|
-
arangeCache.set(key, cached);
|
|
497
|
-
return cached.array.slice([0], [n], s);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
let arr: MlxArray;
|
|
501
|
-
if (dtype === Dtype.int32) {
|
|
502
|
-
// host-built int32 leaf (the Bun-f64-FFI-safe path — see note above).
|
|
503
|
-
const data = new Int32Array(n);
|
|
504
|
-
for (let i = 0; i < n; i++) data[i] = start + i * step;
|
|
505
|
-
arr = MlxArray.fromInt32(data, [n]);
|
|
506
|
-
} else {
|
|
507
|
-
// Native mlx Arange in the target dtype — matches mlx's `Arange` op exactly.
|
|
508
|
-
// The old `fromInt32 → .astype(dtype)` emitted a phantom int32→float Copy
|
|
509
|
-
// (an AsType the oracle never dispatches — e.g. the proportional-RoPE freq
|
|
510
|
-
// exponents). Integer start/step passed as doubles are exact.
|
|
511
|
-
arr = new MlxArray(outArray("arange", (o) => C.mlx_arange(o, start, stop, step, dtype, s)));
|
|
512
|
-
}
|
|
513
|
-
if (n >= ARANGE_CACHE_MIN) {
|
|
514
|
-
const bytes = arr.nbytes;
|
|
515
|
-
if (bytes <= ARANGE_CACHE_BYTES) {
|
|
516
|
-
while (arangeCacheBytes + bytes > ARANGE_CACHE_BYTES) {
|
|
517
|
-
const [oldKey, old] = arangeCache.entries().next().value!;
|
|
518
|
-
arangeCache.delete(oldKey);
|
|
519
|
-
arangeCacheBytes -= old.bytes;
|
|
520
|
-
// Returned slices retain their own native reference, including lazy
|
|
521
|
-
// views that have not been evaluated when this owner is evicted.
|
|
522
|
-
old.array.dispose();
|
|
523
|
-
}
|
|
524
|
-
arangeCache.set(key, { array: arr, bytes });
|
|
525
|
-
arangeCacheBytes += bytes;
|
|
526
|
-
return arr.slice([0], [n], s);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
return arr;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
export function logsumexpAxis(a: MlxArray, axis: number, keepdims: boolean, s: S = gpuStream): MlxArray {
|
|
533
|
-
return new MlxArray(
|
|
534
|
-
outArray("logsumexp", (o) => C.mlx_logsumexp_axis(o, a.handle, axis, keepdims, s)),
|
|
535
|
-
);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
export function greaterEqual(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
539
|
-
return new MlxArray(
|
|
540
|
-
outArray("greater_equal", (o) => C.mlx_greater_equal(o, a.handle, b.handle, s)),
|
|
541
|
-
);
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
export function less(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
545
|
-
return new MlxArray(outArray("less", (o) => C.mlx_less(o, a.handle, b.handle, s)));
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
export function lessEqual(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
549
|
-
return new MlxArray(outArray("less_equal", (o) => C.mlx_less_equal(o, a.handle, b.handle, s)));
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
export function logicalNot(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
553
|
-
return new MlxArray(outArray("logical_not", (o) => C.mlx_logical_not(o, a.handle, s)));
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
export function equal(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
557
|
-
return new MlxArray(outArray("equal", (o) => C.mlx_equal(o, a.handle, b.handle, s)));
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
/** Reduce-all to a scalar (mlx.core.all). */
|
|
561
|
-
export function allReduce(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
562
|
-
return new MlxArray(outArray("all", (o) => C.mlx_all(o, a.handle, false, s)));
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
/** any along one axis (mlx.core.any). */
|
|
566
|
-
export function anyAxis(a: MlxArray, axis: number, keepdims: boolean, s: S = gpuStream): MlxArray {
|
|
567
|
-
return new MlxArray(outArray("any_axis", (o) => C.mlx_any_axis(o, a.handle, axis, keepdims, s)));
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/** Read a 0-d/1-elem boolean array to host (forces eval). */
|
|
571
|
-
export function itemBool(a: MlxArray): boolean {
|
|
572
|
-
const u = a.astype(Dtype.uint32);
|
|
573
|
-
try {
|
|
574
|
-
return itemUint32(u) !== 0;
|
|
575
|
-
} finally {
|
|
576
|
-
u.dispose();
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
export function logicalAnd(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
581
|
-
return new MlxArray(
|
|
582
|
-
outArray("logical_and", (o) => C.mlx_logical_and(o, a.handle, b.handle, s)),
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
export function zeros(shape: number[], dtype: Dtype, s: S = gpuStream): MlxArray {
|
|
587
|
-
const buf = new Int32Array(shape);
|
|
588
|
-
return new MlxArray(
|
|
589
|
-
outArray("zeros", (o) => C.mlx_zeros(o, ptr(buf), BigInt(shape.length), dtype, s)),
|
|
590
|
-
);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
export function sliceUpdate(
|
|
594
|
-
src: MlxArray, update: MlxArray, start: number[], stop: number[], s: S = gpuStream,
|
|
595
|
-
): MlxArray {
|
|
596
|
-
const st = new Int32Array(start);
|
|
597
|
-
const sp = new Int32Array(stop);
|
|
598
|
-
const strides = new Int32Array(start.map(() => 1));
|
|
599
|
-
return new MlxArray(
|
|
600
|
-
outArray("slice_update", (o) =>
|
|
601
|
-
C.mlx_slice_update(
|
|
602
|
-
o, src.handle, update.handle,
|
|
603
|
-
ptr(st), BigInt(st.length), ptr(sp), BigInt(sp.length),
|
|
604
|
-
ptr(strides), BigInt(strides.length), s,
|
|
605
|
-
),
|
|
606
|
-
),
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
/** mx.slice with start as an ARRAY and the output shape as constants —
|
|
611
|
-
* the shapeless-compile-safe slice (mlx's Slice primitive cannot infer
|
|
612
|
-
* output shapes; DynamicSlice's output shape IS sliceSize). Used only
|
|
613
|
-
* inside compiled-decode traces for subrange slices whose bounds are
|
|
614
|
-
* per-layer constants (full-range slices get simplified away and need
|
|
615
|
-
* no substitute). Values identical to `slice`. */
|
|
616
|
-
export function sliceDynamic(
|
|
617
|
-
a: MlxArray, start: MlxArray, axes: number[], sliceSize: number[], s: S = gpuStream,
|
|
618
|
-
): MlxArray {
|
|
619
|
-
const ax = new Int32Array(axes);
|
|
620
|
-
const sz = new Int32Array(sliceSize);
|
|
621
|
-
return new MlxArray(
|
|
622
|
-
outArray("slice_dynamic", (o) =>
|
|
623
|
-
C.mlx_slice_dynamic(
|
|
624
|
-
o, a.handle, start.handle,
|
|
625
|
-
ptr(ax), BigInt(ax.length), ptr(sz), BigInt(sz.length), s,
|
|
626
|
-
),
|
|
627
|
-
),
|
|
628
|
-
);
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
/** slice_update with the start index as an ARRAY (one int32 per entry in
|
|
632
|
-
* `axes`) — the compiled-decode form of the per-step cache write. Same
|
|
633
|
-
* write as `sliceUpdate`; bit-exactness vs the static form is asserted
|
|
634
|
-
* in tests/unit/compile.test.ts. */
|
|
635
|
-
export function sliceUpdateDynamic(
|
|
636
|
-
src: MlxArray, update: MlxArray, start: MlxArray, axes: number[], s: S = gpuStream,
|
|
637
|
-
): MlxArray {
|
|
638
|
-
const ax = new Int32Array(axes);
|
|
639
|
-
return new MlxArray(
|
|
640
|
-
outArray("slice_update_dynamic", (o) =>
|
|
641
|
-
C.mlx_slice_update_dynamic(
|
|
642
|
-
o, src.handle, update.handle, start.handle,
|
|
643
|
-
ptr(ax), BigInt(ax.length), s,
|
|
644
|
-
),
|
|
645
|
-
),
|
|
646
|
-
);
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
export function randomKey(seed: bigint): MlxArray {
|
|
650
|
-
return new MlxArray(outArray("random_key", (o) => C.mlx_random_key(o, seed)));
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
/** Set the GLOBAL mlx PRNG seed (mlx.core.random.seed). Calls to randint/etc
|
|
654
|
-
* with a null key thread the global key, so seeding then calling in the same
|
|
655
|
-
* order as the reference reproduces its draws bit-for-bit. */
|
|
656
|
-
export function randomSeed(seed: bigint): void {
|
|
657
|
-
if (C.mlx_random_seed(seed) !== 0) throw new Error(`mlx_random_seed failed: ${takeMlxError() ?? ""}`);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
/** Uniform integers in [low, high) — mlx.core.random.randint. With key=null it
|
|
661
|
-
* uses (and advances) the global key, matching mx.random.randint exactly. */
|
|
662
|
-
export function randint(
|
|
663
|
-
low: number, high: number, shape: number[], dtype: Dtype,
|
|
664
|
-
key: MlxArray | null = null, s: S = gpuStream,
|
|
665
|
-
): MlxArray {
|
|
666
|
-
const buf = new Int32Array(shape);
|
|
667
|
-
const lo = MlxArray.fromInt32(new Int32Array([low]), []);
|
|
668
|
-
const hi = MlxArray.fromInt32(new Int32Array([high]), []);
|
|
669
|
-
try {
|
|
670
|
-
return new MlxArray(
|
|
671
|
-
outArray("random_randint", (o) =>
|
|
672
|
-
C.mlx_random_randint(o, lo.handle, hi.handle, ptr(buf), BigInt(shape.length), dtype, key?.handle ?? 0n, s),
|
|
673
|
-
),
|
|
674
|
-
);
|
|
675
|
-
} finally {
|
|
676
|
-
lo.dispose();
|
|
677
|
-
hi.dispose();
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
export function randomCategorical(logits: MlxArray, key: MlxArray | null, s: S = gpuStream): MlxArray {
|
|
682
|
-
return new MlxArray(
|
|
683
|
-
outArray("categorical", (o) =>
|
|
684
|
-
C.mlx_random_categorical(o, logits.handle, -1, key?.handle ?? 0n, s),
|
|
685
|
-
),
|
|
686
|
-
);
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
/** Eval several arrays in one call (e.g. cache state after a prefill chunk). */
|
|
690
|
-
export function evalAll(arrays: MlxArray[]): void {
|
|
691
|
-
const handles = new BigUint64Array(arrays.map((a) => a.handle));
|
|
692
|
-
const vec = C.mlx_vector_array_new_data(ptr(handles), BigInt(arrays.length));
|
|
693
|
-
try {
|
|
694
|
-
if (C.mlx_eval(vec) !== 0) throw new Error(`mlx_eval failed: ${takeMlxError() ?? ""}`);
|
|
695
|
-
} finally {
|
|
696
|
-
C.mlx_vector_array_free(vec);
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
/** Kick off async evaluation (decode pipelining). */
|
|
701
|
-
export function asyncEvalAll(arrays: MlxArray[]): void {
|
|
702
|
-
const handles = new BigUint64Array(arrays.map((a) => a.handle));
|
|
703
|
-
const vec = C.mlx_vector_array_new_data(ptr(handles), BigInt(arrays.length));
|
|
704
|
-
try {
|
|
705
|
-
if (C.mlx_async_eval(vec) !== 0) throw new Error(`mlx_async_eval failed: ${takeMlxError() ?? ""}`);
|
|
706
|
-
} finally {
|
|
707
|
-
C.mlx_vector_array_free(vec);
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
/** Read a scalar uint32 (forces eval). Hot per-token path: the out-param
|
|
712
|
-
* is read back via read.u32, never out[0] (DFG stale-read bug — see
|
|
713
|
-
* outArray in ffi.ts). */
|
|
714
|
-
export function itemUint32(a: MlxArray): number {
|
|
715
|
-
a.eval();
|
|
716
|
-
const out = new Uint32Array(1);
|
|
717
|
-
const p = ptr(out);
|
|
718
|
-
if (C.mlx_array_item_uint32(p, a.handle) !== 0)
|
|
719
|
-
throw new Error("mlx_array_item_uint32 failed");
|
|
720
|
-
return read.u32(p, 0);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
export function fromInt32(data: number[], shape: number[]): MlxArray {
|
|
724
|
-
return MlxArray.fromInt32(new Int32Array(data), shape);
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// --- quantized KV support (Phase 6) ---------------------------------------
|
|
728
|
-
|
|
729
|
-
export interface QuantizedTensor {
|
|
730
|
-
packed: MlxArray;
|
|
731
|
-
scales: MlxArray;
|
|
732
|
-
biases: MlxArray;
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
/** mx.quantize: w → (packed u32, scales, biases). `mode` defaults to the
|
|
736
|
-
* mlx-standard "affine" scheme; the quantizer seam may pass others. */
|
|
737
|
-
export function quantize(
|
|
738
|
-
w: MlxArray, groupSize: number, bits: number, mode = "affine", s: S = gpuStream,
|
|
739
|
-
): QuantizedTensor {
|
|
740
|
-
const slot = new BigUint64Array([C.mlx_vector_array_new()]);
|
|
741
|
-
const slotPtr = ptr(slot);
|
|
742
|
-
const status = C.mlx_quantize(
|
|
743
|
-
slotPtr, w.handle, optInt(groupSize), optInt(bits), ptr(cstr(mode)), 0n, s,
|
|
744
|
-
);
|
|
745
|
-
if (status !== 0) throw new Error(`quantize failed: ${takeMlxError() ?? ""}`);
|
|
746
|
-
const vec = read.u64(slotPtr, 0);
|
|
747
|
-
const get = (i: number): MlxArray => {
|
|
748
|
-
const aSlot = new BigUint64Array([C.mlx_array_new()]);
|
|
749
|
-
const aPtr = ptr(aSlot);
|
|
750
|
-
if (C.mlx_vector_array_get(aPtr, vec, BigInt(i)) !== 0)
|
|
751
|
-
throw new Error("vector_array_get failed");
|
|
752
|
-
return new MlxArray(read.u64(aPtr, 0));
|
|
753
|
-
};
|
|
754
|
-
try {
|
|
755
|
-
return { packed: get(0), scales: get(1), biases: get(2) };
|
|
756
|
-
} finally {
|
|
757
|
-
C.mlx_vector_array_free(vec);
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
// --- training: elementwise / reductions / random ------------------------
|
|
762
|
-
|
|
763
|
-
/** Stops gradient flow through `a` (identity forward; ∂=0). DPO reference
|
|
764
|
-
* logprobs are stop_gradient'd before the policy forward. */
|
|
765
|
-
export function stopGradient(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
766
|
-
return new MlxArray(outArray("stop_gradient", (o) => C.mlx_stop_gradient(o, a.handle, s)));
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
export function log(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
770
|
-
return new MlxArray(outArray("log", (o) => C.mlx_log(o, a.handle, s)));
|
|
771
|
-
}
|
|
772
|
-
|
|
773
|
-
export function logaddexp(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
774
|
-
return new MlxArray(outArray("logaddexp", (o) => C.mlx_logaddexp(o, a.handle, b.handle, s)));
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
export function sqrt(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
778
|
-
return new MlxArray(outArray("sqrt", (o) => C.mlx_sqrt(o, a.handle, s)));
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
export function rsqrt(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
782
|
-
return new MlxArray(outArray("rsqrt", (o) => C.mlx_rsqrt(o, a.handle, s)));
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
export function square(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
786
|
-
return new MlxArray(outArray("square", (o) => C.mlx_square(o, a.handle, s)));
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
export function abs(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
790
|
-
return new MlxArray(outArray("abs", (o) => C.mlx_abs(o, a.handle, s)));
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
/** Reduce-mean over all elements → scalar (keepdims=false) or [1,…]. */
|
|
794
|
-
export function meanAll(a: MlxArray, keepdims = false, s: S = gpuStream): MlxArray {
|
|
795
|
-
return new MlxArray(outArray("mean", (o) => C.mlx_mean(o, a.handle, keepdims, s)));
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
export function meanAxis(a: MlxArray, axis: number, keepdims: boolean, s: S = gpuStream): MlxArray {
|
|
799
|
-
return new MlxArray(outArray("mean_axis", (o) => C.mlx_mean_axis(o, a.handle, axis, keepdims, s)));
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
export function clip(a: MlxArray, lo: MlxArray | null, hi: MlxArray | null, s: S = gpuStream): MlxArray {
|
|
803
|
-
return new MlxArray(
|
|
804
|
-
outArray("clip", (o) => C.mlx_clip(o, a.handle, lo?.handle ?? 0n, hi?.handle ?? 0n, s)),
|
|
805
|
-
);
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
/** mx.random.normal(shape, dtype, loc, scale, key). key may be null. */
|
|
809
|
-
export function randomNormal(
|
|
810
|
-
shape: number[], dtype: Dtype, loc: number, scale: number,
|
|
811
|
-
key: MlxArray | null, s: S = gpuStream,
|
|
812
|
-
): MlxArray {
|
|
813
|
-
const buf = new Int32Array(shape);
|
|
814
|
-
return new MlxArray(
|
|
815
|
-
outArray("random_normal", (o) =>
|
|
816
|
-
C.mlx_random_normal(o, ptr(buf), BigInt(shape.length), dtype, loc, scale, key?.handle ?? 0n, s),
|
|
817
|
-
),
|
|
818
|
-
);
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
/** mx.random.uniform(low, high, shape, dtype, key). low/high are scalars.
|
|
822
|
-
* Matches mlx-lm LoRALinear A init: uniform(-1/√in, +1/√in). */
|
|
823
|
-
export function randomUniform(
|
|
824
|
-
shape: number[], dtype: Dtype, low: number, high: number,
|
|
825
|
-
key: MlxArray | null, s: S = gpuStream,
|
|
826
|
-
): MlxArray {
|
|
827
|
-
const buf = new Int32Array(shape);
|
|
828
|
-
const lo = MlxArray.fromFloat32(new Float32Array([low]), []);
|
|
829
|
-
const hi = MlxArray.fromFloat32(new Float32Array([high]), []);
|
|
830
|
-
try {
|
|
831
|
-
return new MlxArray(
|
|
832
|
-
outArray("random_uniform", (o) =>
|
|
833
|
-
C.mlx_random_uniform(o, lo.handle, hi.handle, ptr(buf), BigInt(shape.length), dtype, key?.handle ?? 0n, s),
|
|
834
|
-
),
|
|
835
|
-
);
|
|
836
|
-
} finally {
|
|
837
|
-
lo.dispose();
|
|
838
|
-
hi.dispose();
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
/** mx.random.split(key, num) → [num, 2] uint32 subkeys. */
|
|
843
|
-
export function randomSplitNum(key: MlxArray, num: number, s: S = gpuStream): MlxArray {
|
|
844
|
-
return new MlxArray(
|
|
845
|
-
outArray("random_split", (o) => C.mlx_random_split_num(o, key.handle, num, s)),
|
|
846
|
-
);
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
export function softmaxAxis(a: MlxArray, axis: number, precise: boolean, s: S = gpuStream): MlxArray {
|
|
850
|
-
return new MlxArray(
|
|
851
|
-
outArray("softmax", (o) => C.mlx_softmax_axis(o, a.handle, axis, precise, s)),
|
|
852
|
-
);
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
export function maxAxis(a: MlxArray, axis: number, keepdims: boolean, s: S = gpuStream): MlxArray {
|
|
856
|
-
return new MlxArray(
|
|
857
|
-
outArray("max_axis", (o) => C.mlx_max_axis(o, a.handle, axis, keepdims, s)),
|
|
858
|
-
);
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
export function sumAxis(a: MlxArray, axis: number, keepdims: boolean, s: S = gpuStream): MlxArray {
|
|
862
|
-
return new MlxArray(
|
|
863
|
-
outArray("sum_axis", (o) => C.mlx_sum_axis(o, a.handle, axis, keepdims, s)),
|
|
864
|
-
);
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
/** View-preserving expand_dims (reshape on a non-contiguous view copies —
|
|
868
|
-
* different kernel path, different reduction rounding; see Phase 6). */
|
|
869
|
-
export function expandDims(a: MlxArray, axis: number, s: S = gpuStream): MlxArray {
|
|
870
|
-
return new MlxArray(
|
|
871
|
-
outArray("expand_dims", (o) => C.mlx_expand_dims(o, a.handle, axis, s)),
|
|
872
|
-
);
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
export function maximum(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
876
|
-
return new MlxArray(
|
|
877
|
-
outArray("maximum", (o) => C.mlx_maximum(o, a.handle, b.handle, s)),
|
|
878
|
-
);
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
/** quantized_matmul against a quantized tensor (x @ qt^T or x @ qt). */
|
|
882
|
-
export function quantizedMatmulQT(
|
|
883
|
-
x: MlxArray, qt: QuantizedTensor, transpose: boolean,
|
|
884
|
-
groupSize: number, bits: number, s: S = gpuStream,
|
|
885
|
-
): MlxArray {
|
|
886
|
-
return new MlxArray(
|
|
887
|
-
outArray("quantized_matmul", (o) =>
|
|
888
|
-
C.mlx_quantized_matmul(
|
|
889
|
-
o, x.handle, qt.packed.handle, qt.scales.handle, qt.biases.handle,
|
|
890
|
-
transpose, optInt(groupSize), optInt(bits), ptr(cstr("affine")), s,
|
|
891
|
-
),
|
|
892
|
-
),
|
|
893
|
-
);
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
/** nn.Conv1d: input [B, L, C_in], weight [C_out, K, C_in/groups] → [B, L', C_out].
|
|
897
|
-
* Depthwise (groups == channels) for the gated-DeltaNet causal conv; the model
|
|
898
|
-
* left-pads with the conv-state cache, so padding is 0 here. */
|
|
899
|
-
export function conv1d(
|
|
900
|
-
input: MlxArray, weight: MlxArray, stride = 1, padding = 0, dilation = 1,
|
|
901
|
-
groups = 1, s: S = gpuStream,
|
|
902
|
-
): MlxArray {
|
|
903
|
-
return new MlxArray(
|
|
904
|
-
outArray("conv1d", (o) =>
|
|
905
|
-
C.mlx_conv1d(o, input.handle, weight.handle, stride, padding, dilation, groups, s),
|
|
906
|
-
),
|
|
907
|
-
);
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
/** nn.Conv2d: input [B, H, W, C_in] (NHWC), weight [C_out, kH, kW, C_in/groups]
|
|
911
|
-
* → [B, H', W', C_out]. mlx weight layout — the oracle transposes PyTorch's
|
|
912
|
-
* [C_out, C_in, kH, kW] at load. For the gemma-4 audio SSCP subsampler. */
|
|
913
|
-
export function conv2d(
|
|
914
|
-
input: MlxArray, weight: MlxArray, stride: [number, number] = [1, 1],
|
|
915
|
-
padding: [number, number] = [0, 0], dilation: [number, number] = [1, 1],
|
|
916
|
-
groups = 1, s: S = gpuStream,
|
|
917
|
-
): MlxArray {
|
|
918
|
-
return new MlxArray(
|
|
919
|
-
outArray("conv2d", (o) =>
|
|
920
|
-
C.mlx_conv2d(o, input.handle, weight.handle, stride[0], stride[1],
|
|
921
|
-
padding[0], padding[1], dilation[0], dilation[1], groups, s),
|
|
922
|
-
),
|
|
923
|
-
);
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
/** nn.Conv3d: input [B, D, H, W, C_in] (NDHWC), weight [C_out, kD, kH, kW,
|
|
927
|
-
* C_in/groups] → [B, D', H', W', C_out]. The Qwen3-VL vision patch embed
|
|
928
|
-
* (kernel == stride) — the conv KERNEL's accumulation order is the parity-
|
|
929
|
-
* relevant arithmetic; a value-equivalent GEMM differs by bf16 ulp. */
|
|
930
|
-
export function conv3d(
|
|
931
|
-
input: MlxArray, weight: MlxArray,
|
|
932
|
-
stride: [number, number, number] = [1, 1, 1],
|
|
933
|
-
padding: [number, number, number] = [0, 0, 0],
|
|
934
|
-
dilation: [number, number, number] = [1, 1, 1],
|
|
935
|
-
groups = 1, s: S = gpuStream,
|
|
936
|
-
): MlxArray {
|
|
937
|
-
return new MlxArray(
|
|
938
|
-
outArray("conv3d", (o) =>
|
|
939
|
-
C.mlx_conv3d(o, input.handle, weight.handle, stride[0], stride[1],
|
|
940
|
-
stride[2], padding[0], padding[1], padding[2], dilation[0],
|
|
941
|
-
dilation[1], dilation[2], groups, s),
|
|
942
|
-
),
|
|
943
|
-
);
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
/** mx.split(a, indices, axis): split at the given boundary offsets along `axis`
|
|
947
|
-
* into N+1 contiguous slices (mirrors numpy/mlx split-by-indices). */
|
|
948
|
-
export function split(a: MlxArray, indices: number[], axis: number): MlxArray[] {
|
|
949
|
-
const shape = a.shape;
|
|
950
|
-
const ax = axis < 0 ? shape.length + axis : axis;
|
|
951
|
-
const dim = shape[ax]!;
|
|
952
|
-
const bounds = [0, ...indices, dim];
|
|
953
|
-
const out: MlxArray[] = [];
|
|
954
|
-
for (let i = 0; i < bounds.length - 1; i++) {
|
|
955
|
-
const start = shape.map(() => 0);
|
|
956
|
-
const stop = [...shape];
|
|
957
|
-
start[ax] = bounds[i]!;
|
|
958
|
-
stop[ax] = bounds[i + 1]!;
|
|
959
|
-
out.push(a.slice(start, stop));
|
|
960
|
-
}
|
|
961
|
-
return out;
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
/** nn.softplus: log(1 + exp(x)) == logaddexp(x, 0). */
|
|
965
|
-
export function softplus(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
966
|
-
const zero = scalarLike(0, a);
|
|
967
|
-
const r = logaddexp(a, zero, s);
|
|
968
|
-
zero.dispose();
|
|
969
|
-
return r;
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
/** nn.silu: x * sigmoid(x). */
|
|
973
|
-
export function silu(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
974
|
-
const sig = sigmoid(a, s);
|
|
975
|
-
const r = mul(a, sig, s);
|
|
976
|
-
sig.dispose();
|
|
977
|
-
return r;
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
/** fast::hadamard_transform over the last axis. `scale` defaults to
|
|
981
|
-
* 1/sqrt(dim) (mlx's own default when unset) — pass it explicitly to
|
|
982
|
-
* match a reference that always states its normalization, per
|
|
983
|
-
* turboquant-ops.ts's fwht(). */
|
|
984
|
-
export function hadamardTransform(x: MlxArray, scale: number | null = null, s: S = gpuStream): MlxArray {
|
|
985
|
-
return new MlxArray(
|
|
986
|
-
outArray("hadamard_transform", (o) =>
|
|
987
|
-
C.mlx_hadamard_transform(o, x.handle, optFloat(scale), s),
|
|
988
|
-
),
|
|
989
|
-
);
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
export function minAxis(a: MlxArray, axis: number, keepdims: boolean, s: S = gpuStream): MlxArray {
|
|
993
|
-
return new MlxArray(
|
|
994
|
-
outArray("min_axis", (o) => C.mlx_min_axis(o, a.handle, axis, keepdims, s)),
|
|
995
|
-
);
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
/** mx.round(x, decimals=0) — round-half-to-even at the ULP grid mlx uses. */
|
|
999
|
-
export function round(a: MlxArray, s: S = gpuStream): MlxArray {
|
|
1000
|
-
return new MlxArray(outArray("round", (o) => C.mlx_round(o, a.handle, 0, s)));
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
export function greater(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
1004
|
-
return new MlxArray(outArray("greater", (o) => C.mlx_greater(o, a.handle, b.handle, s)));
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
export function bitwiseAnd(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
1008
|
-
return new MlxArray(outArray("bitwise_and", (o) => C.mlx_bitwise_and(o, a.handle, b.handle, s)));
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
export function bitwiseOr(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
1012
|
-
return new MlxArray(outArray("bitwise_or", (o) => C.mlx_bitwise_or(o, a.handle, b.handle, s)));
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
export function leftShift(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
1016
|
-
return new MlxArray(outArray("left_shift", (o) => C.mlx_left_shift(o, a.handle, b.handle, s)));
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
export function rightShift(a: MlxArray, b: MlxArray, s: S = gpuStream): MlxArray {
|
|
1020
|
-
return new MlxArray(outArray("right_shift", (o) => C.mlx_right_shift(o, a.handle, b.handle, s)));
|
|
1021
|
-
}
|