Skip to content

feat: block tensor literal syntax [ta; tb], (ta, tb), [|ta; tb|] in %op#10

Open
lukstafi wants to merge 4 commits intomasterfrom
ludics/task-fe1c593d-s4/root
Open

feat: block tensor literal syntax [ta; tb], (ta, tb), [|ta; tb|] in %op#10
lukstafi wants to merge 4 commits intomasterfrom
ludics/task-fe1c593d-s4/root

Conversation

@lukstafi
Copy link
Copy Markdown
Owner

@lukstafi lukstafi commented Apr 20, 2026

Summary

  • Add block tensor literal syntax to %op PPX: [ta; tb] (output axis), (ta, tb) (input axis), [|ta; tb|] (batch axis)
  • Support nesting: [[ta; tb]; [tc; td]] constructs 2x2 block matrices
  • Disambiguation via first-leaf heuristic: numeric literal leaves -> ndarray constant, tensor expression leaves -> block tensor
  • Add regression tests for ndarray constants, tuple-in-apply preservation, and gradient flow
  • Fix stale "upcoming"/"planned" wording in 4 doc files

Test plan

  • dune build @check passes
  • dune runtest passes (only pre-existing unrelated failures)
  • 12 tests in test_block_tensor.ml covering: list/array/tuple block tensors, 3-way, nesting, single-element, 2-way and 3-way gradient flow, ndarray constant regressions, tuple-in-apply preservation
  • Existing test_concat_graph, test_concat_ppx, small_literal_tensor pass unchanged

🤖 Generated with Claude Code

lukstafi and others added 3 commits April 15, 2026 10:23
Add syntactic sugar for constructing block tensors from component tensors
using OCaml list/tuple/array notation inside %op blocks. Lists stack along
a new leading output axis, tuples along input axis (top-level only), and
arrays along batch axis.

Implementation: first-leaf disambiguation (numeric → ndarray constant,
non-numeric → block tensor), two-step unsqueeze via einsum1 + concat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Concat-Concat element-wise unification case to row.ml's unify_dim,
allowing the shape solver to equate structurally-matching Concat dimensions
from inner block tensor results when used in outer block tensors.

Update test and docs to demonstrate direct nesting (2x2 block matrix).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ndarray constant regressions (tuple, list, array) to pin the
first-leaf disambiguation heuristic, and a tuple-in-apply test to
lock Pexp_apply tuple preservation. Remove "upcoming"/"planned"
wording from syntax_extensions.md, migration_guide.md, and
slides-shapes_and_einsum.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lukstafi lukstafi changed the title feat: ludics/task-fe1c593d-s4/root feat: block tensor literal syntax [ta; tb], (ta, tb), [|ta; tb|] in %op Apr 20, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ba7d3bd6b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tensor/ppx_op.ml Outdated
Comment on lines +107 to +109
| `Output ->
String.concat ~sep:"; " (List.map labels ~f:(fun l -> l ^ ",..."))
^ " => " ^ concat_parts ^ ",..."
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve batch/input rows in output-axis block concat

Update the output-axis branch in translate_block_tensor to generate a full shape spec, not just an output-row spec. The current string (bt0,...; bt1,... => bt0^bt1,...) drops |...->..., so %op [ta; tb] only works when components are output-only tensors; if ta/tb have input or batch axes, shape inference compares them against empty default rows and fails (or cannot preserve those axes). This makes list block tensors unusable for nontrivial tensor shapes.

Useful? React with 👍 / 👎.

The output-axis concat spec "bt0,...; bt1,..." dropped batch and input
rows, causing shape errors when list block tensor components had input
or batch axes. Use the full spec "...|...-> bt0,...; ..." to broadcast
batch/input rows through concatenation.

Add test 13 exercising list block tensors with input-dim components.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@lukstafi
Copy link
Copy Markdown
Owner Author

Forwarded to upstream: ahrefs#450

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.

1 participant