PRF Don't force X to C-order for LogisticRegression's lbfgs solver - #34903
Draft
cakedev0 wants to merge 2 commits into
Draft
PRF Don't force X to C-order for LogisticRegression's lbfgs solver#34903cakedev0 wants to merge 2 commits into
cakedev0 wants to merge 2 commits into
Conversation
X is only read (never mutated) across all L-BFGS iterations, so forcing a C-order copy discards any layout the caller already had. If X is already Fortran-contiguous, the backward-pass GEMV in the loss/gradient (X.T @ grad) lands on OpenBLAS's better-parallelizing kernel, and the forced copy (which doubles peak memory and costs real time) is avoided entirely. C-order input, the common case, is unaffected.
cakedev0
commented
Sep 7, 2026
| ), | ||
| accept_large_sparse=solver not in ("liblinear", "newton-cd", "sag", "saga"), | ||
| ) | ||
| n_samples, n_features = X.shape |
Contributor
Author
There was a problem hiding this comment.
Both n_samples and n_features are unused...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reference Issues/PRs
Related to #32162 (that one's about OpenMP threads in the loss kernel; this is about BLAS threads in the GEMV calls around it).
What does this implement/fix? Explain your changes.
While investigating why
LogisticRegression(solver="lbfgs")doesn't benefit from (and sometimes gets hurt by) multithreaded OpenBLAS, I traced it down to the backward-pass gradient computation (X.T @ grad_pointwiseinLinearModelLoss.loss_gradient). Forn_samples >> n_features(the common shape), that GEMV parallelizes much better for the F-order (for the C-order, on my machine, parallelization is usually neutral / slightly counter-productive)Turns out
LogisticRegression.fit()unconditionally forcesXto C-order forsolver="lbfgs", even thoughXis only read (never mutated) throughout all L-BFGS iterations. So if a caller already had F-orderX, we were silently paying for a full copy and throwing away the layout that would've made BLAS threading actually work.This PR just changes that to
order=None(preserve caller's layout) forsolver="lbfgs". This gives a nice speed-up and saves memory for users passing a F-orderedX.AI usage disclosure
Benchmarks
LogisticRegression(max_iter=200).fit(X, y)on synthetic binary data, 9 fits, median, 14 BLAS threads (this machine's core count).For X already Fortran-ordered:
Peak memory (1M x 200 float64, X is ~1.6GB):