-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
using SparseArrays makes vcat'ing adjoint vectors memory hog, regression in Julia 1.10 beta #51011
using SparseArrays makes vcat'ing adjoint vectors memory hog, regression in Julia 1.10 beta #51011
Comments
Can reproduce, and also that performance is fine on both versions without the The stack overflow on splatting seems potentially serious enough to consider a bug as well as a performance regression. I'll add to the 1.10 milestone given that, but others feel free to undo.. |
The issue is perhaps |
This is a duplicate of a larger problem, namely that
May be considered a duplicate of #50473, #30796 and several other issues Honestly I don't think doing regression whack-a-mole on basically unsupported behaviour is a good long-term strategy. Something like what is suggested by @StefanKarpinski in #50473 (comment) is the only real fix (or, alternatively, combing through Julia internals to guarantee handling of large splats, but I think this will be too hard) |
The large number of elements leading to a stack overflow is a red herring, as there's a performance regression in julia> using SparseArrays
julia> a=[rand(2) for i=1:30];
julia> @btime vcat($a'...);
5.382 μs (125 allocations: 4.25 KiB) # v1.9.2
81.229 μs (1449 allocations: 35.75 KiB) # v1.10.0-beta2 |
Note that BenchmarkTools pulls in Statistics that pulls in SparseArrays. |
The issue here seems to be more the type piracy in SparseArrays. |
Bisect points to 8fd5f27 (as far as the behavior change) sparsevector.jl:1229 is the method called now. Could maybe be fixed by making |
This patch to SparseArrays mostly fixes it:
On the benchmark above, I get: Not all the way there unfortunately. |
Helps to short-circuit calls to large splat calls, since those have all the same type elements. Fixes #51011
The generic `cat` does more shape analysis, that typed_cat does not always do (before either may then dispatch to _cat_t), so we can make this faster by calling it instead. Secondly, we can make `issparse` non-recursive once it hits a base case where all trailing elements are the same. This makes it much better at handling large splat, since we do not need to check each recursively smaller type down to the base case using generic code, and just generate one const method specialized on the full length instead. Fix JuliaLang/julia#51011
The generic `cat` does more shape analysis, that typed_cat does not always do (before either may then dispatch to _cat_t), so we can make this faster by calling it instead. Secondly, we can make `issparse` non-recursive once it hits a base case where all trailing elements are the same. This makes it much better at handling large splat, since we do not need to check each recursively smaller type down to the base case using generic code, and just generate one const method specialized on the full length instead. Fix JuliaLang/julia#51011
Helps to short-circuit calls to large splat calls, since those have all the same type elements. Fixes #51011
The generic `cat` does more shape analysis, that typed_cat does not always do (before either may then dispatch to _cat_t), so we can make this faster by calling it instead. Secondly, we can make `issparse` non-recursive once it hits a base case where all trailing elements are the same. This makes it much better at handling large splat, since we do not need to check each recursively smaller type down to the base case using generic code, and just generate one const method specialized on the full length instead. Fix JuliaLang/julia#51011
The generic `cat` does more shape analysis, that typed_cat does not always do (before either may then dispatch to _cat_t), so we can make this faster by calling it instead. Secondly, we can make `issparse` non-recursive once it hits a base case where all trailing elements are the same. This makes it much better at handling large splat, since we do not need to check each recursively smaller type down to the base case using generic code, and just generate one const method specialized on the full length instead. Fix JuliaLang/julia#51011 (cherry picked from commit 4e6776a)
EDIT:
using SparseArrays
that gets loaded byusing Statistics
gives
The example works on Julia 1.9.
On Julia 1.10 both
collect(hcat(a...)')
andstack(a, dims=1)
work ok, latter requires Julia ≥ 1.9.Julia from juliaup, started with
julia +beta --startup-file=no
The text was updated successfully, but these errors were encountered: