fix: correctness & safety improvements for training - #9
Closed
alvgeppetto wants to merge 1 commit into
Closed
Conversation
- Validate all fread() return values in model_load_weights (model.h) - Check ane_eval() return values in ane_conv_eval (forward.h) and ane_eval_k (tiny_train.m) - Log error details on ANE eval failure (ane_runtime.h) - Thread-safe RMSNorm: replace global g_rms_tmp with local allocation (stories_cpu_ops.h) - Bounds-check token indices in cross_entropy_loss, embed_lookup, embed_backward - Atomic checkpoint writes via tmp+rename pattern (tiny_train.m) - Non-destructive recompile: compile new kernels first, swap only on success (model.h) - Validate fread() in load_checkpoint (tiny_train.m)
ebowwa
pushed a commit
to ebowwa/ANE
that referenced
this pull request
Aug 4, 2026
… hardening #1 /models bypassed safety: now uses services.safe_compile (lint → validate → passes → compile) instead of calling bridge.compile directly. The shared compile service enforces all /raw/kernels safety rules (MIL lint, positive tensor-size validation, tensor-count limits, compiler passes, weight-name validation, bridge-error mapping). #2 Model leases leaked: register_model now does atomic replace (free old lease before installing new). unregister_model calls bridge.free(kernel_id) before removing the dictionary entry. maderix#3 Async eval bypassed admission: now calls admit_eval BEFORE dispatching the background task, and finish_eval in _bg's finally block. max_pending backpressure applies to async work. maderix#4 Cancellation resurrection: _bg checks sub.state == CANCELLED before transitioning to EXECUTING. A cancelled submission is not resurrected. maderix#5 Submission memory leak: SubmissionRegistry now has max_retained=100 + ttl_s=300. _prune() evicts terminal submissions by TTL and count on every create(). maderix#6 Batch-eval bypassed admission: each item now goes through admit_eval/finish_eval. Endpoint honestly named "serial batch" (NOT parallel without kernel replication). 138 tests. Co-Authored-By: Claude <noreply@anthropic.com>
ebowwa
pushed a commit
to ebowwa/ANE
that referenced
this pull request
Aug 4, 2026
maderix#9 GraphDescriptor: operation entries now include op.args (graph dependencies). Constants use their BLOBFILE/file attr as digest instead of placeholder "const". maderix#10 IR pipeline: rejects unparseable MIL at the tensor-IR level (rejected_at_tensor_ir) before reaching ANE-IR lint — previously reported "validated" for meaningless input. maderix#11 ExecutionPlan + PlanSegment: frozen=True (immutable as documented). __post_init__ uses object.__setattr__ for the auto-generated id. maderix#12 Communication: recv() now verifies consumer_exec_id + checksum before returning data. maderix#13 Transforms: docstring honestly states these are VariantIntents (metadata), not transformed graphs — quantize() labels int8, doesn't produce int8 MIL. maderix#14 Autotuner: select_and_benchmark now passes weights to bridge.bench (previously discarded). Evidence keyed by real mil-hash fingerprint + shape, not "auto"/"default". All-failed case returns best_variant=None instead of picking an infinite-latency variant. bridge.bench now accepts a weights param (for constant-weight autotuning). 138 tests. Co-Authored-By: Claude <noreply@anthropic.com>
ebowwa
pushed a commit
to ebowwa/ANE
that referenced
this pull request
Aug 4, 2026
…, capability-aware tests, byte-bounded retention, artifact manifests maderix#5 MLX backend: load() now stores the operation spec (executable_id → spec dict). execute() uses the stored spec, not the input's layout field. Respects per-input dtype/shape/byte_offset (no longer assumes contiguous fp16). Produces correct output descriptors with actual output shape (no longer reuses input descriptor). maderix#9 Capability-aware tests: MLX tests skip when mlx unavailable or on non-Darwin-arm64 platforms. TestClient-based tests don't assert MLX availability universally. maderix#10 Byte-bounded submissions: SubmissionRegistry now has max_result_bytes (256 MiB default). _prune() evicts terminal submissions by total result byte size, not just count. maderix#11 Artifact manifests: LocalArtifactBackend.put_artifact() stores each file as a tensor + a manifest linking all files. resolve_artifact() returns the full manifest. Multi-file artifacts (compiled ANE programs with multiple BLOBFILEs) can now be reconstructed. 149 tests. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes 7 correctness & safety issues identified during M3 Ultra benchmarking and code review.
Changes
Testing
Both
make trainandmake train_largecompile cleanly with-Wallon macOS (Apple clang).