Skip to content

refactor(api): the carry is an argument of the axis rather than of solve_over, so an archive's axis holds its carry - #1980

Merged
FBumann merged 2 commits into
mainfrom
feat/carry-on-axis
Oct 12, 2026
Merged

FBumann merged 2 commits into
mainfrom
feat/carry-on-axis

Conversation

@FBumann

@FBumann FBumann commented Oct 11, 2026

Copy link
Copy Markdown
Collaborator

Prompt: There is a pr that changes the axis classes to include the carry
Maybe we should extract this into main first

Note

The following content was generated by AI.

carry= moves from solve_over onto EachCoordinate and EachWindow, as #1888 has it, for one axis. An archive's axis now holds its carry, so solve_over(spec, sources, archive.axis) runs a sweep again. axis.json is unchanged byte for byte.

What changed
  • EachCoordinate(..., carry=) and EachWindow(..., carry=), a keyword-only {parameter: variable}, empty by default. solve_over loses carry=.
  • A hand-built list carries nothing. It has no axis to hold a carry. No test used one.
  • SweepArchive.carry and ArchivedInputs.carry are gone. The carry is archive.axis.carry.
  • The carry stays out of the hash. It is a mapping, so a frozen axis with one would be unhashable otherwise. Equality still compares it. Axes on main are hashable, and a new test (test_an_axis_that_carries_is_still_hashable) holds that.
  • The executor refusal, the seed check and the line-up checks are unchanged. They read the carry off the axis.
  • Docs: the sweeps reference, the sweep tour, the archiving how-to, the glossary entry and both examples move to carry= on the axis.
Why no layout number rises

On main, the archive wrote the carry as a carry key beside the axis's own keys in axis.json. The axis now writes the same key in the same place. I wrote the same carried rolling horizon with released 0.8.1 and with this branch, and cmp reports the two axis.json files identical:

{"each": "window", "dim": "snapshot", "steps": 4, "lookahead": 2, "into": "t", "carry": {"soc_initial": "soc"}}

So INPUTS_LAYOUT stays at 1, and an 0.8.1 archive reads back with its carry on the axis.

Breaking, and where coverage moved
Mutation table, gates, and what was not done
mutation result tree
axes.py: hash=False dropped from both carry fields caught: test_an_axis_that_carries_is_still_hashable[coordinate] and [window], TypeError: unhashable type: 'dict' clean

I took it by hand: committed tree, git checkout -- restore, __pycache__ dropped. Before the probe existed, the full suite passed with this mutation (5605 passed). That is why the probe was added.

🤖 Generated with Claude Code

https://claude.ai/code/session_01G1TmcQZZCctsVr54HE93qS


Generated by Claude Code

…lve_over, so an archive's axis holds its carry

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G1TmcQZZCctsVr54HE93qS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G1TmcQZZCctsVr54HE93qS
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 specsolve | 🛠️ Build #35079037 | 📁 Comparing 918e5b8 against latest (990de2a)

  🔍 Preview build  

6 files changed · ± 6 modified

± Modified

@codspeed

codspeed Bot commented Oct 11, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 14.76%

⚡ 4 improved benchmarks
❌ 11 regressed benchmarks
✅ 68 untouched benchmarks
🆕 10 new benchmarks
⏩ 307 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ test_window[sector-s-specsolve-highs-shape] 4.1 MB 6.1 MB -33.55%
❌ test_window[sector-s-specsolve-highs-cold] 4.1 MB 6.2 MB -33.21%
❌ test_window[sector-s-specsolve-highs-values] 4.2 MB 6.2 MB -32.41%
❌ test_window[sector-s-specsolve-highs-one] 4.2 MB 6.1 MB -32.25%
❌ test_emit[sector-s-specsolve-highs] 4.2 MB 6.1 MB -32.21%
❌ test_window[sector-s-specsolve-highs-coefficient] 4.2 MB 6.1 MB -31.77%
❌ test_emit[sector-s-specsolve-lp] 4.6 MB 6.1 MB -24.53%
❌ test_window[transport-s-specsolve-highs-values] 11.3 MB 13.1 MB -13.71%
❌ test_window[transport-s-specsolve-highs-one] 11.3 MB 13.1 MB -13.71%
❌ test_window[storage-s-specsolve-highs-values] 9.3 MB 10.5 MB -11.52%
❌ test_window[storage-s-specsolve-highs-one] 9.3 MB 10.5 MB -11.52%
⚡ test_window[dispatch-s-specsolve-highs-one] 9.1 MB 6.8 MB +34.11%
⚡ test_window[dispatch-s-specsolve-highs-values] 9.1 MB 6.8 MB +34.08%
⚡ test_read[profiled-s-specsolve-parquet] 6.6 MB 5.7 MB +15.62%
⚡ test_window[fleet-s-specsolve-highs-values] 12 MB 11.3 MB +6.02%
🆕 test_emit[milp-s-specsolve-highs] N/A 29.5 MB N/A
🆕 test_emit[milp-s-specsolve-in-memory-highs] N/A 29.5 MB N/A
🆕 test_emit[milp-s-specsolve-in-memory-lp] N/A 47.7 MB N/A
🆕 test_emit[milp-s-specsolve-lp] N/A 47.7 MB N/A
🆕 test_read[milp-s-specsolve-frames] N/A 1.5 MB N/A
... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing feat/carry-on-axis (918e5b8) with main (89306c6)2

Open in CodSpeed

Footnotes

  1. 307 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

  2. No successful run was found on main (990de2a) during the generation of this report, so 89306c6 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

@FBumann
FBumann added this pull request to stack #1986 October 12, 2026 06:36
@FBumann
FBumann merged commit 02b0ae4 into main Oct 12, 2026
13 checks passed
@FBumann
FBumann deleted the feat/carry-on-axis branch October 12, 2026 06:36
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