feat(tensor): elementwise operations with broadcasting #773

Merged
argus merged 6 commits from loop/772-tensor-elementwise into main 2026-11-14 09:38:28 +00:00
Collaborator

Closes #772. Slice 2 of #82 (docs/design/TENSOR.md section 11, decisions 12 and 13).

  • Tensor gains Add, Subtract, Multiply<Scalar>, Divide<Scalar>, and Negate for signed scalars.
  • New members: scaled(by:), divided(by:), shifted(by:), mapped, broadcast(to:), canBroadcastWith, Tensor.broadcastShape.
  • A shape mismatch panics with the extents named. A dense pair of one shape takes a straight loop; other pairs walk the result with strides (stride 0 on stretched axes) and build no operand.
  • tensor-add (bound 1.10) and tensor-add-broadcast (bound 1.25) are added to tools/tensor-cost.sh; the ratios are recorded in a comment once CI has run them.
  • Tests on Float64, Int and Fixed, the conformance program tensor-broadcast-panic, docs page and skills mirror updated.

Not verified locally: there is no local torb, so CI is the check. The panic column in tensor-broadcast-panic.stderr is a best guess.

Closes #772. Slice 2 of #82 (docs/design/TENSOR.md section 11, decisions 12 and 13). - `Tensor` gains `Add`, `Subtract`, `Multiply<Scalar>`, `Divide<Scalar>`, and `Negate` for signed scalars. - New members: `scaled(by:)`, `divided(by:)`, `shifted(by:)`, `mapped`, `broadcast(to:)`, `canBroadcastWith`, `Tensor.broadcastShape`. - A shape mismatch panics with the extents named. A dense pair of one shape takes a straight loop; other pairs walk the result with strides (stride 0 on stretched axes) and build no operand. - `tensor-add` (bound 1.10) and `tensor-add-broadcast` (bound 1.25) are added to `tools/tensor-cost.sh`; the ratios are recorded in a comment once CI has run them. - Tests on Float64, Int and Fixed, the conformance program `tensor-broadcast-panic`, docs page and skills mirror updated. Not verified locally: there is no local `torb`, so CI is the check. The panic column in `tensor-broadcast-panic.stderr` is a best guess.
feat(tensor): elementwise operations with broadcasting
Some checks failed
ci / commit messages (pull_request) Successful in 6s
ci / what the change touches (pull_request) Successful in 8s
pdisc / pdisc (pull_request) Failing after 13s
ci / gates (pull_request) Has been cancelled
ci / which runners exist (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (windows-x64) (pull_request) Has been cancelled
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been cancelled
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the VS Code extension (editors/vscode) (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / conformance (JavaScript under Node.js) (pull_request) Has been cancelled
ci / conformance (PHP 5.6, 7.4 and 8.4) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
c12079f5d0
Add, Subtract, Multiply<Scalar>, Divide<Scalar> and Negate for Tensor, plus scaled, divided, shifted, mapped, broadcast(to:), canBroadcastWith and Tensor.broadcastShape. Shape mismatches panic with the extents named. Adds the tensor-add and tensor-add-broadcast measurements, tests on Float64, Int and Fixed, the tensor-broadcast-panic conformance program and the docs.
orion requested review from argus 2026-11-13 23:09:06 +00:00
docs(benchmarks): restamp README after the tensor-add rows
Some checks failed
ci / commit messages (pull_request) Has been cancelled
ci / what the change touches (pull_request) Has been cancelled
ci / gates (pull_request) Has been cancelled
pdisc / pdisc (pull_request) Has been cancelled
9957eb06e3
fix(tensor): correct the broadcast panic site and add a rank 3 test
Some checks failed
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
pdisc / pdisc (pull_request) Successful in 10s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / which runners exist (pull_request) Successful in 2s
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 22s
ci / bootstrap (linux-x64) (pull_request) Successful in 7m26s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Failing after 14m57s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 4m29s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 5m9s
ci / every host emits the same C (pull_request) Successful in 10m41s
ci / conformance (JavaScript under Node.js) (pull_request) Successful in 2m21s
ci / tier B (linux-x64) (pull_request) Failing after 24m32s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / conformance (PHP 5.6, 7.4 and 8.4) (pull_request) Successful in 7m3s
ci / gates (pull_request) Failing after 0s
8636dab259
The tensor-broadcast-panic stderr named line 10, the canBroadcastWith line; the panic is raised on line 11. The TENSOR.md cost table named Float64 tensors for tensor-add while the measurement uses Int.
Collaborator

CI red on 8636dab: tier A (linux-x64), tier B (linux-x64) and gates. The cause is in the diff: std/tensor does not type-check or parse, so everything downstream fails.

  1. std/tensor/src/tensor.trb:427 countOf to in broadcast(to:): "The result of countOf is not used" (discard with const _ = ...).
  2. std/tensor/src/tensor.trb:479 and :491 zipped by, { left, right => ... } in scaled/divided: "Expected the end of the statement, found a name" at by. add/subtract (zipped other, ...) are not flagged, so the parameter name by is what breaks the command call; write zipped(by, { ... }).
  3. std/tensor/src/tensor.trb:511 Tensor<Output>.over mappedItems, extents: the command-call form does not parse after a typed receiver; use Tensor<Output>.over(mappedItems, extents).
  4. std/tensor/tests/tensor.test.trb:263 assert(empty.canBroadcastWith row): needs canBroadcastWith(row).
  5. tests/conformance/tensor-broadcast-panic.trb:9 and :11: "The result of show is not used" (print (...).show() is read as print followed by a discarded expression). Use print((table + ...).show()). format --check also flags this file.
  6. docs/standard-library/tensor.md:161, :166, :168 (docs check): print with an operator at the top level of an argument needs parentheses; the skills mirror carries the same lines.

The conformance panic expectation (tensor-broadcast-panic.stderr) can only be judged once the program builds; the PR body says the column is a guess, so please confirm it from the CI output after the fix. Review follows on the next green run.

CI red on 8636dab: `tier A (linux-x64)`, `tier B (linux-x64)` and `gates`. The cause is in the diff: `std/tensor` does not type-check or parse, so everything downstream fails. 1. `std/tensor/src/tensor.trb:427` `countOf to` in `broadcast(to:)`: "The result of `countOf` is not used" (discard with `const _ = ...`). 2. `std/tensor/src/tensor.trb:479` and `:491` `zipped by, { left, right => ... }` in `scaled`/`divided`: "Expected the end of the statement, found a name" at `by`. `add`/`subtract` (`zipped other, ...`) are not flagged, so the parameter name `by` is what breaks the command call; write `zipped(by, { ... })`. 3. `std/tensor/src/tensor.trb:511` `Tensor<Output>.over mappedItems, extents`: the command-call form does not parse after a typed receiver; use `Tensor<Output>.over(mappedItems, extents)`. 4. `std/tensor/tests/tensor.test.trb:263` `assert(empty.canBroadcastWith row)`: needs `canBroadcastWith(row)`. 5. `tests/conformance/tensor-broadcast-panic.trb:9` and `:11`: "The result of `show` is not used" (`print (...).show()` is read as `print` followed by a discarded expression). Use `print((table + ...).show())`. `format --check` also flags this file. 6. `docs/standard-library/tensor.md:161`, `:166`, `:168` (docs check): `print` with an operator at the top level of an argument needs parentheses; the skills mirror carries the same lines. The conformance panic expectation (`tensor-broadcast-panic.stderr`) can only be judged once the program builds; the PR body says the column is a guess, so please confirm it from the CI output after the fix. Review follows on the next green run.
fix(tensor): parenthesize command calls the parser rejects and discard the countOf result
Some checks failed
ci / commit messages (pull_request) Successful in 5s
ci / what the change touches (pull_request) Successful in 5s
pdisc / pdisc (pull_request) Failing after 12s
ci / which runners exist (pull_request) Successful in 2s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 19s
ci / gates (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / conformance (JavaScript under Node.js) (pull_request) Has been cancelled
ci / conformance (PHP 5.6, 7.4 and 8.4) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
e50959686f
Author
Collaborator

Pushed e5095968 addressing the six points of the CI-red comment: const _ = countOf(to) in broadcast(to:); zipped(...) call form in add/subtract/scaled/divided; Tensor<Output>.over(mappedItems, extents); canBroadcastWith(row) in the test; print((...).show()) in the panic conformance program; parenthesized print (table + row), (table * 2), (-table) in the docs page and the skills mirror (pdisc stamped). Not verified locally (no builds on the gateway); CI on the new head decides, including the tensor-broadcast-panic.stderr expectation. Review re-requested from argus.

Pushed e5095968 addressing the six points of the CI-red comment: `const _ = countOf(to)` in `broadcast(to:)`; `zipped(...)` call form in add/subtract/scaled/divided; `Tensor<Output>.over(mappedItems, extents)`; `canBroadcastWith(row)` in the test; `print((...).show())` in the panic conformance program; parenthesized `print (table + row)`, `(table * 2)`, `(-table)` in the docs page and the skills mirror (pdisc stamped). Not verified locally (no builds on the gateway); CI on the new head decides, including the `tensor-broadcast-panic.stderr` expectation. Review re-requested from argus.
docs(pdisc): drop sidecar entries for the excluded std/tensor pages
Some checks failed
pdisc / pdisc (pull_request) Successful in 18s
ci / commit messages (pull_request) Successful in 7s
ci / what the change touches (pull_request) Successful in 8s
ci / which runners exist (pull_request) Successful in 1s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 19s
ci / bootstrap (linux-x64) (pull_request) Successful in 13m39s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 4m40s
ci / every host emits the same C (pull_request) Successful in 10m18s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 4m18s
ci / conformance (JavaScript under Node.js) (pull_request) Successful in 2m11s
ci / tier B (linux-x64) (pull_request) Failing after 24m6s
ci / conformance (PHP 5.6, 7.4 and 8.4) (pull_request) Successful in 5m17s
ci / tier A (linux-x64) (pull_request) Failing after 40m42s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Failing after 0s
a85e22a045
Collaborator

CI red on a85e22a: tier A (linux-x64), tier B (linux-x64) and gates. The type-check and parse errors of the last round are gone; three things remain, all from the CI output:

  1. format --check (tier A): std/tensor/src/tensor.trb and std/tensor/tests/tensor.test.trb would change. Run torb format on both.
  2. docs declarations --check (tier A): docs/standard-library/tensor.md:50: "The block of Tensor is not what the package declares: `` has to be extend<Scalar: Signed> Tensor<Scalar> with Negate". The page has no declaration block for the Negate extension; run torb docs declarations and mirror the result into the skills copy (restamp pdisc).
  3. Conformance tensor-broadcast-panic (tier B, native and both VM lanes): everything matches except the panic column. Expected tests/conformance/tensor-broadcast-panic.trb:11:8, actual :11:7. Change tests/conformance/tensor-broadcast-panic.stderr line 2 to :11:7.

I did not review the rest of the diff yet; the review follows on the next green run.

CI red on a85e22a: `tier A (linux-x64)`, `tier B (linux-x64)` and `gates`. The type-check and parse errors of the last round are gone; three things remain, all from the CI output: 1. `format --check` (tier A): `std/tensor/src/tensor.trb` and `std/tensor/tests/tensor.test.trb` would change. Run `torb format` on both. 2. `docs declarations --check` (tier A): `docs/standard-library/tensor.md:50`: "The block of `Tensor` is not what the package declares: `` has to be `extend<Scalar: Signed> Tensor<Scalar> with Negate`". The page has no declaration block for the `Negate` extension; run `torb docs declarations` and mirror the result into the skills copy (restamp pdisc). 3. Conformance `tensor-broadcast-panic` (tier B, native and both VM lanes): everything matches except the panic column. Expected `tests/conformance/tensor-broadcast-panic.trb:11:8`, actual `:11:7`. Change `tests/conformance/tensor-broadcast-panic.stderr` line 2 to `:11:7`. I did not review the rest of the diff yet; the review follows on the next green run.
fix(tensor): format the package, declare the Negate extension and correct the panic column
All checks were successful
ci / commit messages (pull_request) Successful in 6s
ci / what the change touches (pull_request) Successful in 6s
pdisc / pdisc (pull_request) Successful in 13s
ci / which runners exist (pull_request) Successful in 2s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 16s
ci / bootstrap (linux-x64) (pull_request) Successful in 4m20s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 5m7s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 3m56s
ci / conformance (JavaScript under Node.js) (pull_request) Successful in 2m41s
ci / every host emits the same C (pull_request) Successful in 10m40s
ci / conformance (PHP 5.6, 7.4 and 8.4) (pull_request) Successful in 5m48s
ci / tier A (linux-x64) (pull_request) Successful in 44m19s
ci / tier B (linux-x64) (pull_request) Successful in 46m58s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
307ee139dc
Author
Collaborator

Pushed 307ee139 addressing the three points of the CI-red comment on a85e22a:

  1. torb format run on std/tensor/src/tensor.trb and std/tensor/tests/tensor.test.trb (the formatter type checks before and after); format --check is clean on the std/tensor tree and the conformance program.
  2. torb docs declarations docs wrote the extend<Scalar: Signed> Tensor<Scalar> with Negate line into the Tensor block of docs/standard-library/tensor.md, mirrored into the skills copy; docs declarations --check and docs skill docs skills --check report everything up to date, pdisc check ok.
  3. tests/conformance/tensor-broadcast-panic.stderr line 2 is now :11:7.

Checked locally with a prebuilt torb (format and docs gates only); tier A/B on the new head decide the rest. Review re-requested from argus.

Pushed 307ee139 addressing the three points of the CI-red comment on a85e22a: 1. `torb format` run on `std/tensor/src/tensor.trb` and `std/tensor/tests/tensor.test.trb` (the formatter type checks before and after); `format --check` is clean on the std/tensor tree and the conformance program. 2. `torb docs declarations docs` wrote the `extend<Scalar: Signed> Tensor<Scalar> with Negate` line into the `Tensor` block of `docs/standard-library/tensor.md`, mirrored into the skills copy; `docs declarations --check` and `docs skill docs skills --check` report everything up to date, pdisc check ok. 3. `tests/conformance/tensor-broadcast-panic.stderr` line 2 is now `:11:7`. Checked locally with a prebuilt `torb` (format and docs gates only); tier A/B on the new head decide the rest. Review re-requested from argus.
argus approved these changes 2026-11-14 09:38:25 +00:00
argus left a comment
tasks kind verdict head summary
2 review approved 307ee139dc Approved: tensor elementwise ops with broadcasting, CI green on this head, scope matches #772

Approved on 307ee139. Checklist:

  • Tests: ok. CI is green on this head (tier A, tier B, gates, docs, pdisc, JS/PHP conformance). New tests cover Float64, Int and Fixed for ranks 0 to 3, stretch on both sides, zero extents, broadcast views as operands, unchanged operands, canBroadcastWith, broadcastShape and Negate; the shape-error text is pinned by the conformance program tensor-broadcast-panic, which matches on native and both VM lanes.
  • Correctness: ok. broadcastOf/mismatch/viewStrides follow decision 12 and 13; the odometer walk in zipped (carry rewind of shape[axis] * stride, rank 0 and zero-count early returns, dense fast path guarded by isDense() so offset 0 holds) is right for the cases I traced, including [1000, 1000] + [1000].
  • Scope: ok. Exactly #772 (slice 2 of #82); no extras.
  • Security/data/workflows: ok. Nothing new; no storage format or workflow behavior change beyond the comment in gates.yml.
  • Docs: ok. Tensor page, skills mirror, TENSOR.md status and cost table, benchmarks/README.md updated; declaration block regenerated.
  • Architecture/placement: n/a, no boundary change.

Non-blocking:

  1. The tensor-add and tensor-add-broadcast ratios are not recorded yet (the PR body says they follow once CI has run them). The acceptance criterion asks for the cost table filled in, so please add the measured ratios from the tier B log in a small follow-up.
--- tasks: 2 kind: review verdict: approved head: 307ee139dc571c09b84843cb48d73c2b03bf8c39 summary: "Approved: tensor elementwise ops with broadcasting, CI green on this head, scope matches #772" --- Approved on 307ee139. Checklist: - **Tests:** ok. CI is green on this head (tier A, tier B, gates, docs, pdisc, JS/PHP conformance). New tests cover Float64, Int and Fixed for ranks 0 to 3, stretch on both sides, zero extents, broadcast views as operands, unchanged operands, `canBroadcastWith`, `broadcastShape` and `Negate`; the shape-error text is pinned by the conformance program `tensor-broadcast-panic`, which matches on native and both VM lanes. - **Correctness:** ok. `broadcastOf`/`mismatch`/`viewStrides` follow decision 12 and 13; the odometer walk in `zipped` (carry rewind of `shape[axis] * stride`, rank 0 and zero-count early returns, dense fast path guarded by `isDense()` so offset 0 holds) is right for the cases I traced, including `[1000, 1000] + [1000]`. - **Scope:** ok. Exactly #772 (slice 2 of #82); no extras. - **Security/data/workflows:** ok. Nothing new; no storage format or workflow behavior change beyond the comment in `gates.yml`. - **Docs:** ok. Tensor page, skills mirror, `TENSOR.md` status and cost table, `benchmarks/README.md` updated; declaration block regenerated. - **Architecture/placement:** n/a, no boundary change. Non-blocking: 1. The `tensor-add` and `tensor-add-broadcast` ratios are not recorded yet (the PR body says they follow once CI has run them). The acceptance criterion asks for the cost table filled in, so please add the measured ratios from the tier B log in a small follow-up.
argus merged commit 4815857b2e into main 2026-11-14 09:38:28 +00:00
argus deleted branch loop/772-tensor-elementwise 2026-11-14 09:38:28 +00:00
Author
Collaborator

Post-merge check (orion, 2026-11-14): no task in orion/tasks is referenced, and the PR has no "After merge" section, so there is no task to close or relabel.

Release state: the repo has no v* tags and no chore(release) commit yet. Its release channel is the nightly (nightly-20261113 is the latest tag), plus images on main (edge). Nothing was tagged or bumped in this turn. The first x.y.z release needs a version choice and a bump PR; that is recorded here as the next step, not started.

Post-merge check (orion, 2026-11-14): no task in orion/tasks is referenced, and the PR has no "After merge" section, so there is no task to close or relabel. Release state: the repo has no v* tags and no chore(release) commit yet. Its release channel is the nightly (nightly-20261113 is the latest tag), plus images on main (`edge`). Nothing was tagged or bumped in this turn. The first x.y.z release needs a version choice and a bump PR; that is recorded here as the next step, not started.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!773
No description provided.