One named densification chokepoint and a dispatch table for CSR-backed expressions
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 35/100
Direzione di ricerca
Start with linopy/expressions.py, especially _densify, the .data property, and the listed CSR branches; read the dispatch-table notes in issues #971 and #1011 for context. Review the partial fallbacks in linopy/constraints.py as well, then run the proposed parametrized tests in test/test_csr.py. Done means dispatch entries preserve CSR backing under no_densify(), fallbacks warn with the operation name without densifying the receiver, and the existing twin-build tests pass.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
[!NOTE]
The following content was generated by AI.
Describe the feature you'd like to see
Child of #1019 (step 1). Blocked on legacy semantics removal (#845, #846): the methods this touches carry the is_v1() gates, and the dispatch table should be built once, against the v1-only code. Internal refactor of linopy/expressions.py; no change to results or to the public API. Code links point to master at 69dd5c97.
Problem
A CSR-backed LinearExpression falls back to dense in two ways. Explicit overrides call self._densify(reason) with a hand-written string. Every method without an override reads self.data (linopy/expressions.py:2443), which converts the receiver in place and for good through _densify_all (:3698) with the generic reason ".data read". There are 34 explicit branch points on _csr / is_sparse / _try_csr_* / _sparse_* (:2443-3100, groupby :485-669, _try_csr_merge :3740), and the implicit set (shift, diff, coeffs, vars, to_quadexpr, simplify, loc, densify_terms, the const setter, ...) is nowhere listed.
import warnings
import numpy as np, pandas as pd, linopy
linopy.options["semantics"] = "v1"
linopy.options["warn_on_densify"] = True
i, t = pd.RangeIndex(20, name="i"), pd.RangeIndex(5, name="t")
m = linopy.Model(sparse=True)
x = m.add_variables(0, 1, coords=[i, t], name="x")
g = pd.Series(np.arange(20) % 3, index=i, name="g")
for op in ["shift(t=1)", "diff('t')", "coeffs", "to_quadexpr()", "isnull()"]:
s = x.groupby(g).sum()
assert s.is_sparse
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
eval(f"s.{op}")
msgs = [str(x.message) for x in w if "dens" in str(x.message).lower()]
print(f"{op:16} sparse after: {s.is_sparse!s:5} warning: {msgs}")
Output on master (69dd5c97):
shift(t=1) sparse after: False warning: ['Sparse (CSR) backing densified: `.data` read, e.g. by an operation without a sparse path.']
diff('t') sparse after: False warning: ['Sparse (CSR) backing densified: `.data` read, e.g. by an operation without a sparse path.']
coeffs sparse after: False warning: ['Sparse (CSR) backing densified: `.data` read, e.g. by an operation without a sparse path.']
to_quadexpr() sparse after: False warning: ['Sparse (CSR) backing densified: `.data` read, e.g. by an operation without a sparse path.']
isnull() sparse after: True warning: []
Proposed direction
- One chokepoint
_delegate(name, ...)onLinearExpression. Ifnamehas a sparse implementation, call it. Otherwise convert withreason=nameand call the dense implementation on the converted copy. The receiver keeps its backing. - The 34
if self._csrblocks become a dispatch table mapping frontend methods toCSRLinearExpressioncounterparts (sumtosummed,__neg__/__mul__toscaled,sel/isel/wheretotaken,reindextoreindexed,fillnatofilled,renametorenamed,@tocontracted, constant arithmetic towith_const, ...). The table is the authoritative list of backing-preserving operations; #971 documents it, #1011 adds rows. .databecomes a plain read through the chokepoint with reason"data". Setters that must mutate (const,dataassignment) go through the chokepoint with their own reason.- Partial fallbacks (
_selected:2582,_sparse_matmul:2904,_try_csr_merge:3740,csr_rhsinlinopy/constraints.py:1689) return a reason string instead of calling_densify_allthemselves. - Expected warning after the change:
Sparse (CSR) backing densified by shift, one name per operation.
Tests
- One parametrized test in
test/test_csr.pyover the dispatch table: each entry keeps the backing underno_densify(); each fallback warns with its own operation name and leaves the receiver sparse. - Existing twin-build tests (
assert_sparse_matches,assert_frozen_equal) pass unchanged.
- Lingua principale
- Python
- Stelle
- 259
- Fork
- 89
- Merge medio
- 1g 18h
- PR unite (30g)
- 26
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di PyPSA/linopy
-
bug solver interface
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno
-
Meta: separate dense and sparse stores from the expression and constraint frontendForse già presa @Rishabhkanhaiya l’ha presa 5 giorni fa. Apertadiscussion refactor sparse
Difficoltà 5/5 Più di una settimana Idoneità per principianti 25/100
PyPSA/linopy#1019 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
refactor sparse
Difficoltà 4/5 3-5 giorni Idoneità per principianti 38/100
I maintainer di solito rispondono entro 1 giorno
-
Xpress missing _license_probe: licensed_solvers includes xpress with an out-of-date licence, breaking local testsForse già presa @FabianHofmann l’ha presa 14 giorni fa. Apertabug solver interface
Difficoltà 4/5 3-5 giorni Idoneità per principianti 58/100
I maintainer di solito rispondono entro 1 giorno
-
discussion math-spec
Difficoltà 5/5 Più di una settimana Idoneità per principianti 30/100
PyPSA/linopy#993 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di PyPSA/linopy
Issue simili
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
gradio-app/gradio#13964 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 93/100
BSData/horus-heresy-3rd-edition#3232 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
jbacalso24/mimry#123 ·
I maintainer di solito rispondono entro 1 giorno
-
p:3-mid pydanty:bug pydanty:is-working
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
pydantic/pydantic-ai#10153 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
good first issue priority: medium size: S testing
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
cubrid-lab/cubrid-cookbook-python#316 ·
I maintainer di solito rispondono entro 1 giorno