Skip to content

Add compiled CopyPlan for prepared strided copies (stage 1 of #139)#142

Merged
shinaoka merged 3 commits into
tensor4all:mainfrom
Ryo-wtnb11:feat/139-copy-plan
Jul 16, 2026
Merged

Add compiled CopyPlan for prepared strided copies (stage 1 of #139)#142
shinaoka merged 3 commits into
tensor4all:mainfrom
Ryo-wtnb11:feat/139-copy-plan

Conversation

@Ryo-wtnb11

Copy link
Copy Markdown
Contributor

Add compiled CopyPlan for prepared strided copies

Summary

Stage 1 of #139: a prepared, reusable copy plan over the raw borrowed-layout kernels from #140. CopyPlan::compile runs the layout planning once (validation + fused-pair layout); execute / execute_scale / execute_conj replay it against RawStridedRef / RawStridedMut with zero heap allocations for rank ≤ 8.

let plan = CopyPlan::compile(dims, dst_strides, src_strides)?; // plan once
plan.execute(dst_raw, src_raw)?;                               // zero-alloc, repeatable
plan.execute_scale(dst_raw, src_raw, alpha)?;

Design

  • Layering: execute is exactly "Add allocation-free raw copy/axpy kernels #140 minus the per-call planning" — it reuses the same pub(crate) fused-pair machinery (fuse_pair_layout / apply_fused_pair), so there is no second copy-kernel implementation. Rank > 8 falls back to the view kernels (the explicit-fallback rule; this is the only allocating path).
  • Validation split: compile proves layout compatibility (rank agreement, extent-product overflow, destination injectivity via the existing is_injective_layout); execute* re-checks only the per-call facts (the supplied views must carry exactly the compiled layout — PlanLayoutMismatch otherwise). Buffer bounds are already proven by RawStridedRef/Mut construction.
  • Public surface kept minimal: only CopyPlan + its methods and the new StridedError::PlanLayoutMismatch variant become public; all planning internals stay pub(crate).

MapPlan / ReducePlan (stages 2–3 of #139) are deliberately not included; this PR proves the API shape on the smallest reviewable slice.

Tests

  • Differential plan-vs-direct (byte-identical against the Add allocation-free raw copy/axpy kernels #140 raw kernels): rank 0/1/2/4/8, zero-size dims, identity layout (asserts single fused axis), transposed and negative-stride layouts, rank-9 fallback, f32/f64/c32/c64, scale and conj semantics.
  • Compile rejections (length mismatch, extent overflow, non-injective destination; broadcast source allowed) and execute-time layout-drift rejection (dims / dst strides / src strides).
  • Zero-allocation contract: a counting global allocator asserts execute / execute_scale / execute_conj perform no heap allocations at rank 8, on both the default and parallel features.

cargo test --workspace green (incl. --features parallel), cargo fmt --check clean, cargo doc --no-deps warning-free, per-file coverage ≥ 80% (copy_plan.rs 99.3%).

Ryo-wtnb11 and others added 3 commits July 16, 2026 08:19
Make fuse_pair_layout / apply_fused_pair / FusedPairLayout and
is_injective_layout pub(crate) so a compiled CopyPlan can reuse the
exact traversal the per-call raw kernels build, and add the
PlanLayoutMismatch error variant for the plan's per-call layout check.
No public API change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CopyPlan::compile validates the layout pair once (rank agreement,
extent overflow, destination injectivity) and builds the fused loop
nest; execute / execute_scale / execute_conj re-check only the
per-call facts (that the supplied raw views carry the compiled
layout) and replay it with no planning and no heap allocation for
ranks at most RAW_FUSED_RANK_LIMIT. Higher ranks fall back to the
view-based kernels. Prepared-replay consumers issuing many small
fixed-layout copies avoid the per-call fusion cost measured in tensor4all#139.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Counting-global-allocator integration test asserting that
execute/execute_scale/execute_conj perform no heap allocations for
rank <= RAW_FUSED_RANK_LIMIT layouts. Kept in its own test binary so
concurrent sibling tests cannot leak setup allocations into the
counted window.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants