Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
c854b5d
docs: add arithmetic-convention goals
FBumann May 21, 2026
1e336a4
docs: add convention.md placeholder
FBumann May 21, 2026
93193d7
docs: write the v1 arithmetic convention spec
FBumann May 21, 2026
5e40c56
docs: drop the narrow "arithmetic" framing from the spec
FBumann May 21, 2026
edb8edd
feat: add semantics option and convention test harness
FBumann May 22, 2026
1a3f2be
feat: v1 §5 and §8 on expression-OP-constant path
FBumann May 23, 2026
9b52ebd
feat: v1 §8 on the expr+expr / var+var merge path
FBumann May 23, 2026
e1a2390
feat: v1 §6 absence propagation through every operator
FBumann May 23, 2026
15b87e9
feat: Variable.reindex / .reindex_like (§4 absence creation)
FBumann May 23, 2026
4d87a05
fix: enforce v1 dead-term invariant in merge
FBumann May 23, 2026
602dbdd
feat: v1 §10 named-method join + §12 constraint RHS
FBumann May 23, 2026
317e57f
feat: make piecewise and SOS2 reformulation v1-aware
FBumann May 23, 2026
786d126
test: pin v1 §13 reductions skip absent
FBumann May 23, 2026
0ebccc1
feat: v1 §11 raises on auxiliary-coordinate conflicts
FBumann May 23, 2026
c7e9099
test: pin aux-coord propagation guarantees (§11)
FBumann May 23, 2026
e2cb24f
test: pin v1 dead-term invariant, == constraints, §11 ops, end-to-end…
FBumann May 23, 2026
e8d7b6b
refactor: extract v1 semantics helpers into linopy/semantics.py
FBumann May 23, 2026
6093f66
test: parameterize the three operator-uniform v1 test groups
FBumann May 23, 2026
f0bced4
refactor: split _add_constant / _apply_constant_op for clean 1.0 removal
FBumann May 23, 2026
4a6e8e4
fix(ci): defer linopy import in conftest + add missing type annotations
FBumann May 23, 2026
4dc67bf
feat: self-describing v1 error messages
FBumann May 23, 2026
56ad5bf
test: round out v1 coverage gaps + fix Variable.unstack absence sentinel
FBumann May 23, 2026
e21b144
test: pin upstream catches for objective and constraint-LHS NaN
FBumann May 23, 2026
9455683
feat: site-specific, actionable legacy warnings (goal #2)
FBumann May 24, 2026
7a44e62
feat: full-text warning assertions + stdlib stacklevel + docs-plan
FBumann May 24, 2026
72ddd99
fix: §11 aux-coord check fires on every join, not just join=None
FBumann May 24, 2026
a38a50d
fix: §6 absence propagates through quadratic factor product
FBumann May 24, 2026
71e0fd2
test: parametrize §6 quadratic propagation across entry points
FBumann May 24, 2026
df34c72
fix: §5 user-NaN check on Variable.to_linexpr(coefficient)
FBumann May 24, 2026
1c77a74
fix: §10 join='override' rejects shared-dim size mismatch
FBumann May 24, 2026
a4c7f06
fix: split legacy RHS warnings — coord-mismatch vs user-NaN
FBumann May 24, 2026
578c6f4
fix: structural §8 pre-check, drop brittle xarray exception parse
FBumann May 24, 2026
7498cc3
docs: lock §5 — user NaN raises, close #627 alternative
FBumann May 24, 2026
1517a11
perf: hoist semantics imports out of Variable.to_linexpr hot path
FBumann May 24, 2026
79b89b1
refactor: thread op_kind explicitly through _apply_constant_op
FBumann May 24, 2026
99c87cf
fix: §11 aux-coord — document asymmetric presence, split shape vs val…
FBumann May 24, 2026
32edfaf
fix(types): sort with key=str so override gate is Hashable-safe
FBumann May 24, 2026
d32be12
docs: trim docs-plan to an early-stage outline
FBumann May 24, 2026
b6d38bf
refactor: dedupe v1-semantics helpers
FBumann May 24, 2026
55d9e0c
docs: define object scope and the unlabeled-operand pairing rule
FBumann Jun 1, 2026
a91b901
docs: link unlabeled-pairing TODO to tracking issue #736
FBumann Jun 1, 2026
04c7cb4
Merge master into feat/arithmetic-convention
FBumann Jun 3, 2026
f036c24
feat(alignment): make implicit MI projection semantics-aware (#738, s…
FBumann Jun 3, 2026
4598d94
docs(convention): spec the stacked-MultiIndex rule (scenario B)
FBumann Jun 3, 2026
a644ad3
fix(expressions): close merge gap — _add_constant_v1 must broadcast i…
FBumann Jun 3, 2026
11cbbca
feat: unlabeled-operand pairing by size (#736)
FBumann Jun 4, 2026
ff0b691
Merge remote-tracking branch 'origin/master' into feat/arithmetic-con…
FBumann Jun 4, 2026
1b83bd8
Merge branch 'master' into feat/arithmetic-convention
FBumann Jun 4, 2026
e7d1217
fix: align reordered shared-dim coords by label in merge (#550) (#758)
FBumann Jun 4, 2026
a4c6dde
test: pin legacy side of §13 reductions-over-absent divergence
FBumann Jun 4, 2026
1e8944a
test: pin legacy side of remaining v1/legacy result divergences
FBumann Jun 4, 2026
7f5d8d8
test: unmark equal-behaviour tests so they run under both semantics
FBumann Jun 4, 2026
f06908f
test: re-mark reordered-merge tests v1 and pin the legacy pairing
FBumann Jun 5, 2026
a81f00c
test: re-mark fillna-on-masked tests v1 (strict-equality bar)
FBumann Jun 5, 2026
8b2fd9f
test: add strict v1/legacy equivalence guard
FBumann Jun 5, 2026
f101343
Merge remote-tracking branch 'origin/master' into feat/arithmetic-con…
FBumann Jun 24, 2026
4beedda
fix(types): drop now-unused rhs-setter type-ignores and cast test hel…
FBumann Jun 24, 2026
83abcc6
Merge branch 'master' into feat/arithmetic-convention
FBumann Jun 29, 2026
51841fe
ci(benchmarks): v1-vs-legacy build report + v1 benchmark coverage
FBumann Jun 29, 2026
71bd655
docs(arithmetics): track open-items.md rollout checklist (#744)
FBumann Jul 1, 2026
6b8d65e
docs(convention): scope §13 to implemented reductions; defer rest to …
FBumann Jul 1, 2026
562d528
docs(convention): note §13's future reductions are v1-only (#703)
FBumann Jul 1, 2026
825e90a
perf: fix v1 build-memory regressions (exact-join reindex + Variable×…
FBumann Jul 1, 2026
d88689f
docs(convention): §10 — override is size-guarded; assign_coords is un…
FBumann Jul 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions .github/workflows/benchmark-smoke.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Benchmark smoke

# Builds every spec and fires every phase once (--benchmark-disable):
# a "did a refactor break a spec?" check, not timing.
# Builds every spec and fires every phase once (--benchmark-disable) under both
# arithmetic conventions: a "did a refactor break a spec?" check, not timing.

on:
push:
Expand All @@ -15,8 +15,14 @@ concurrency:

jobs:
smoke:
name: Benchmark smoke (quick)
name: Benchmark smoke (${{ matrix.semantics }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
semantics: [legacy, v1]
env:
LINOPY_BENCH_SEMANTICS: ${{ matrix.semantics }}

steps:
- uses: actions/checkout@v7
Expand Down
121 changes: 121 additions & 0 deletions .github/workflows/semantics-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: Semantics report (v1 vs legacy)

on:
push:
branches: [ master ]
pull_request:
branches: [ '*' ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
report:
name: Build cost — v1 vs legacy
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Set up Python 3.13
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install package and benchmark dependencies
run: |
python -m pip install uv
uv pip install --system -e ".[dev,benchmarks]"
- name: Build under each semantics (memray peak + time)
run: |
pytest benchmarks/drivers/test_build.py \
--benchmark-only --benchmark-memory --benchmark-json=legacy.json
LINOPY_BENCH_SEMANTICS=v1 pytest benchmarks/drivers/test_build.py \
--benchmark-only --benchmark-memory --benchmark-json=v1.json
- name: Render plots + table
run: |
mkdir -p semantics-report
benchmem plot legacy.json v1.json --columns peak --view scatter -o semantics-report/peak-relative.html
benchmem plot legacy.json v1.json --columns peak --view compare -o semantics-report/peak-absolute.html
benchmem plot legacy.json v1.json --columns time --view scatter -o semantics-report/time-relative.html
benchmem plot legacy.json v1.json --columns peak --view scatter -o semantics-report/peak-relative.svg
benchmem plot legacy.json v1.json --columns time --view scatter -o semantics-report/time-relative.svg
benchmem compare legacy.json v1.json --columns time,peak --stat mean --sort change \
--csv semantics-report/comparison.csv \
| sed 's/\x1b\[[0-9;]*m//g' > semantics-report/comparison.txt
run_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
{
echo '## Build cost — v1 vs legacy (peak + time, mean)'
echo ''
echo '_v1 build cost relative to legacy on this commit — not a comparison against master (that is CodSpeed)._'
echo ''
echo '```'
cat semantics-report/comparison.txt
echo '```'
echo ''
echo "📊 Plots + CSV: the **semantics-report-v1-vs-legacy** artifact on [this run]($run_url)."
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload report
uses: actions/upload-artifact@v4
with:
name: semantics-report-v1-vs-legacy
path: semantics-report/
- name: Publish plot image + compose comment
if: >-
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository
env:
GH_TOKEN: ${{ github.token }}
PR: ${{ github.event.pull_request.number }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
ASSETS_BRANCH: ci-assets-semantics-report-v1-vs-legacy-plot-images
run: |
remote="https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
tmp="$(mktemp -d)"
git clone --depth=1 --branch "$ASSETS_BRANCH" "$remote" "$tmp" 2>/dev/null || {
git clone --depth=1 "$remote" "$tmp"
git -C "$tmp" checkout --orphan "$ASSETS_BRANCH"
git -C "$tmp" rm -rf . >/dev/null 2>&1 || true
}
mkdir -p "$tmp/pr-$PR"
cp semantics-report/peak-relative.svg semantics-report/time-relative.svg "$tmp/pr-$PR/"
git -C "$tmp" config user.name "github-actions[bot]"
git -C "$tmp" config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git -C "$tmp" add "pr-$PR"
git -C "$tmp" commit -m "semantics-report plot for pr-$PR" || echo "no image change"
git -C "$tmp" push origin "$ASSETS_BRANCH"
base="https://raw.githubusercontent.com/${GITHUB_REPOSITORY}/${ASSETS_BRANCH}/pr-$PR"
peak_img="$base/peak-relative.svg?$HEAD_SHA"
time_img="$base/time-relative.svg?$HEAD_SHA"
run_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
{
echo '## Build cost — v1 vs legacy'
echo ''
echo '_v1 build peak & time relative to legacy, on this commit — not a comparison against master (that is CodSpeed)._'
echo ''
echo '| peak — v1 / legacy | time — v1 / legacy |'
echo '| :---: | :---: |'
echo "| <img src=\"$peak_img\" width=\"100%\" alt=\"peak v1/legacy\"> | <img src=\"$time_img\" width=\"100%\" alt=\"time v1/legacy\"> |"
echo ''
echo '<details><summary>Full table (time + peak, mean)</summary>'
echo ''
echo '```'
cat semantics-report/comparison.txt
echo '```'
echo '</details>'
echo ''
echo "📊 Interactive plots + CSV: download the **semantics-report-v1-vs-legacy** artifact from [this run]($run_url)."
echo ''
echo '<sub>Report-only · not a gate · refreshed on every push · obsolete once legacy is dropped.</sub>'
} > report.md
- name: Sticky PR comment
if: >-
github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository
uses: marocchino/sticky-pull-request-comment@0ea0beb66eb9baf113663a64ec522f60e49231c0
with:
header: semantics-report
path: report.md
Loading
Loading