Skip to content

fix: a dimensionless parameter is one row, and now has to be - #225

Merged
FBumann merged 1 commit into
polars-enginefrom
fix/dimensionless-parameter-on-polars
Jul 28, 2026
Merged

fix: a dimensionless parameter is one row, and now has to be#225
FBumann merged 1 commit into
polars-enginefrom
fix/dimensionless-parameter-on-polars

Conversation

@FBumann

@FBumann FBumann commented Jul 28, 2026

Copy link
Copy Markdown
Owner

The polars-side half of #166. The other half — plus #197 and #198, which are language-layer — is #223 against main; those files are byte-identical on both branches, so they arrive here on the next rebase and are deliberately not duplicated in this PR.

What was wrong

_check_one_row_per_coordinate returned early when a parameter had no dims, on the reading that there was no coordinate to group by. But a parameter with no dims has exactly one coordinate — the empty one — so the rule it was skipping is the rule that matters most there.

A dimensionless parameter is broadcast by joining on nothing: correct for one row, a silent row multiplication for two. Duplicate cols entries for one variable in a bound, duplicate mask rows in a where.

On this branch it also left keyed asserting at-most-one-row-per-key over a source that had two. That is what turned the duplicate columns into HiGHS refusing the batch, and the engine blaming itself:

before: the solver refused a batch of rows: 'Not Set'. Nothing was loaded [...]
        This is an engine bug rather than a problem with the model — please report it.

after:  parameter 's' is declared with no dims, which means one value broadcast
        everywhere — but its source has 2 rows. Declare the dims it is indexed
        by, or reduce the source to a single row.

A user who gets here has usually passed a column they thought was indexed, so the message says what a dimensionless parameter means rather than only what is wrong with the source. Zero rows is caught by the same count.

Cost is one pl.len() over the source frame, per scalar parameter.

Verification

403 passed, 1 xfailed; ruff check clean; pyrefly 0 errors. Tests cover 2 rows, 0 rows, and the one-row control that must still build.

🤖 Generated with Claude Code

`_check_one_row_per_coordinate` returned early when a parameter had no dims,
on the reading that there was no coordinate to group by. But a parameter with
no dims has exactly one coordinate — the empty one — so the rule it was
skipping is the rule that matters most there.

A dimensionless parameter is broadcast by joining on nothing, which is correct
for one row and a silent row multiplication for two: duplicate `cols` entries
for one variable in a bound, duplicate mask rows in a where. It also left
`keyed` asserting at-most-one-row-per-key over a source that had two, which is
what turned the duplicate columns into HiGHS refusing the batch and the engine
blaming itself in the message.

A user who gets here has usually passed a column they thought was indexed, so
the message says what a dimensionless parameter means rather than only what is
wrong with the source. Zero rows is caught by the same count.

Closes #166

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f9615602-b727-4c13-a3a7-93c261ab450f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/dimensionless-parameter-on-polars

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@FBumann
FBumann merged commit 43b7ab9 into polars-engine Jul 28, 2026
3 checks passed
FBumann added a commit that referenced this pull request Jul 28, 2026
main gained the three duckdb perf PRs (#152, #174, #178), two language-level
fixes (#201, #223) and the bench harness from #205. Resolved by lane:

**Engine files take the polars side.** #152, #174 and #178 are `ROW_NUMBER()
OVER`, `CREATE TYPE ... AS ENUM` and `CREATE TABLE surv_*` against the engine
this branch deletes. Their *ideas* are already here in polars form — #152's as
`_positional`, #174's as #211, #178's as #212 — so taking main's side would
have re-added SQL against a connection that no longer exists.

**Language and validation take main's.** #223's `lowering.py`,
`validation.py` and `linopy/builder.py` changes merged clean and are engine
independent; its executor half and #201's are already here (as #225 and
`_check_one_row_per_coordinate`). `test_objective.py` and `test_validation.py`
arrived whole and pass on this lane unmodified — 404 tests to 414.

**bench takes ours**, which carries #205's two ideas ported rather than
merged (#215): the duckdb commit also brings `--memory-limits`, `--chunk-rows`
and `workdir_bytes`, the budget apparatus this branch removed.

Two tests were combined rather than picked. `test_group_sum`'s docstring says
both true things now — the divergence between lanes, and the aggregate-skip
premise that rests on it. `test_milp` keeps the polars Enum test and gains
main's ragged-chunk test, which is API-level and applies to this sink too.

Main's duckdb label tests are dropped, not ported: they drive `DuckdbExecutor`
and `ex._con` directly. The properties they pin are covered here by
`test_a_mask_that_removes_nothing_labels_exactly_like_no_mask` and
`test_a_factored_mask_labels_exactly_like_the_counted_path`.

Co-Authored-By: Claude Opus 5 (1M context) <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.

1 participant