Skip to content
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

Add a work-around on Julia 1.0 for #857 #859

Merged
merged 2 commits into from
Dec 5, 2020
Merged

Add a work-around on Julia 1.0 for #857 #859

merged 2 commits into from
Dec 5, 2020

Conversation

odow
Copy link
Contributor

@odow odow commented Dec 3, 2020

This PR is an attempt at fixing #857.

Briefly, StaticVecOrMatLike is a very large union, and this caused Julia 1.0.x
to use a large amount of memory when compiling StaticArrays in the presence of
other packages that also extend LinearAlgebra.mul! in a similar fashion. As an
example, this led to JuMP using more than 4 GB of RAM when running using JuMP,
causing its CI to crash.

Computing the eltypes within the function, rather than specifying them in the
type arguments greatly improves the issue, with using JuMP going from:

julia> @time using JuMP
[ Info: Precompiling JuMP [4076af6c-e467-56ae-b986-b466b2749572]
Killed

to:

julia> @time using JuMP
[ Info: Precompiling JuMP [4076af6c-e467-56ae-b986-b466b2749572]
97.868305 seconds (12.75 M allocations: 805.413 MiB, 0.30% gc time)

Here's a work-flow of after/before:

(base) parallels@parallels-Parallels-Virtual-Platform:~/.julia/dev/JuMP$ rm -rf ~/.julia/compiled/v1.0/
(base) parallels@parallels-Parallels-Virtual-Platform:~/.julia/dev/JuMP$ julia --project=.
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.0.5 (2019-09-09)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> @time using JuMP
[ Info: Precompiling JuMP [4076af6c-e467-56ae-b986-b466b2749572]
 97.868305 seconds (12.75 M allocations: 805.413 MiB, 0.30% gc time)

(JuMP) pkg> st -m
Project JuMP v0.21.5
    Status `~/.julia/dev/JuMP/Manifest.toml`
  [6e4b80f9] + BenchmarkTools v0.5.0
  [9e28174c] + BinDeps v1.0.2
  [b99e7846] + BinaryProvider v0.5.10
  [49dc2e85] + Calculus v0.5.1
  [523fee87] + CodecBzip2 v0.6.0
  [944b1d66] + CodecZlib v0.6.0
  [bbf7d656] + CommonSubexpressions v0.3.0
  [34da2185] + Compat v3.23.0
  [864edb3b] + DataStructures v0.18.8
  [163ba53b] + DiffResults v1.0.3
  [b552c78f] + DiffRules v1.0.2
  [f6369f11] + ForwardDiff v0.10.14
  [cd3eb016] + HTTP v0.9.0
  [83e8ac13] + IniFile v0.5.0
  [682c06a0] + JSON v0.21.1
  [7d188eb4] + JSONSchema v0.3.3
  [1914dd2f] + MacroTools v0.5.6
  [b8f27783] + MathOptInterface v0.9.19
  [739be429] + MbedTLS v0.6.8
  [d8a4904e] + MutableArithmetics v0.2.12
  [77ba4419] + NaNMath v0.3.5
  [bac558e1] + OrderedCollections v1.3.2
  [69de0a69] + Parsers v1.0.12
  [276daf66] + SpecialFunctions v0.8.0
  [90137ffa] + StaticArrays v0.12.5 [`~/.julia/dev/StaticArrays`]
  [3bb67fe8] + TranscodingStreams v0.9.5
  [30578b45] + URIParser v0.4.1
  [5c2747f8] + URIs v1.1.0
  [a5390f91] + ZipFile v0.8.4
  [2a0f44e3] + Base64 
  [ade2ca70] + Dates 
  [8bb1440f] + DelimitedFiles 
  [8ba89e20] + Distributed 
  [b77e0a4c] + InteractiveUtils 
  [76f85450] + LibGit2 
  [8f399da3] + Libdl 
  [37e2e46d] + LinearAlgebra 
  [56ddb016] + Logging 
  [d6f4376e] + Markdown 
  [a63ad114] + Mmap 
  [44cfe95a] + Pkg 
  [de0858da] + Printf 
  [3fa0cd96] + REPL 
  [9a3f8284] + Random 
  [ea8e919c] + SHA 
  [9e88b42a] + Serialization 
  [1a1011a3] + SharedArrays 
  [6462fe0b] + Sockets 
  [2f01184e] + SparseArrays 
  [10745b16] + Statistics 
  [8dfed614] + Test 
  [cf7118a7] + UUIDs 
  [4ec0a83e] + Unicode 

(JuMP) pkg> free StaticArrays
 Resolving package versions...
  Updating `~/.julia/dev/JuMP/Project.toml`
  [90137ffa] ↑ StaticArrays v0.12.5 [`~/.julia/dev/StaticArrays`] ⇒ v1.0.0
  Updating `~/.julia/dev/JuMP/Manifest.toml`
  [90137ffa] ↑ StaticArrays v0.12.5 [`~/.julia/dev/StaticArrays`] ⇒ v1.0.0

(JuMP) pkg> st -m
Project JuMP v0.21.5
    Status `~/.julia/dev/JuMP/Manifest.toml`
  [6e4b80f9] + BenchmarkTools v0.5.0
  [9e28174c] + BinDeps v1.0.2
  [b99e7846] + BinaryProvider v0.5.10
  [49dc2e85] + Calculus v0.5.1
  [523fee87] + CodecBzip2 v0.6.0
  [944b1d66] + CodecZlib v0.6.0
  [bbf7d656] + CommonSubexpressions v0.3.0
  [34da2185] + Compat v3.23.0
  [864edb3b] + DataStructures v0.18.8
  [163ba53b] + DiffResults v1.0.3
  [b552c78f] + DiffRules v1.0.2
  [f6369f11] + ForwardDiff v0.10.14
  [cd3eb016] + HTTP v0.9.0
  [83e8ac13] + IniFile v0.5.0
  [682c06a0] + JSON v0.21.1
  [7d188eb4] + JSONSchema v0.3.3
  [1914dd2f] + MacroTools v0.5.6
  [b8f27783] + MathOptInterface v0.9.19
  [739be429] + MbedTLS v0.6.8
  [d8a4904e] + MutableArithmetics v0.2.12
  [77ba4419] + NaNMath v0.3.5
  [bac558e1] + OrderedCollections v1.3.2
  [69de0a69] + Parsers v1.0.12
  [276daf66] + SpecialFunctions v0.8.0
  [90137ffa] + StaticArrays v1.0.0
  [3bb67fe8] + TranscodingStreams v0.9.5
  [30578b45] + URIParser v0.4.1
  [5c2747f8] + URIs v1.1.0
  [a5390f91] + ZipFile v0.8.4
  [2a0f44e3] + Base64 
  [ade2ca70] + Dates 
  [8bb1440f] + DelimitedFiles 
  [8ba89e20] + Distributed 
  [b77e0a4c] + InteractiveUtils 
  [76f85450] + LibGit2 
  [8f399da3] + Libdl 
  [37e2e46d] + LinearAlgebra 
  [56ddb016] + Logging 
  [d6f4376e] + Markdown 
  [a63ad114] + Mmap 
  [44cfe95a] + Pkg 
  [de0858da] + Printf 
  [3fa0cd96] + REPL 
  [9a3f8284] + Random 
  [ea8e919c] + SHA 
  [9e88b42a] + Serialization 
  [1a1011a3] + SharedArrays 
  [6462fe0b] + Sockets 
  [2f01184e] + SparseArrays 
  [10745b16] + Statistics 
  [8dfed614] + Test 
  [cf7118a7] + UUIDs 
  [4ec0a83e] + Unicode 

julia> exit()
(base) parallels@parallels-Parallels-Virtual-Platform:~/.julia/dev/JuMP$ rm -rf ~/.julia/compiled/v1.0/
(base) parallels@parallels-Parallels-Virtual-Platform:~/.julia/dev/JuMP$ julia --project=.
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.0.5 (2019-09-09)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> @time using JuMP
[ Info: Precompiling JuMP [4076af6c-e467-56ae-b986-b466b2749572]
Killed
(base) parallels@parallels-Parallels-Virtual-Platform:~/.julia/dev/JuMP$ 

I also checked that allocations were still 0:

julia> using StaticArrays

julia> using LinearAlgebra

julia> A = @SMatrix(rand(2, 2))
2×2 SArray{Tuple{2,2},Float64,2,4}:
 0.566513  0.958625
 0.423874  0.242269

julia> B = LinearAlgebra.Transpose(A)
2×2 Transpose{Float64,SArray{Tuple{2,2},Float64,2,4}}:
 0.566513  0.423874
 0.958625  0.242269

julia> dest = similar(A)
2×2 MArray{Tuple{2,2},Float64,2,4}:
 6.92317e-310  6.92316e-310
 6.92317e-310  6.9232e-310 

julia> @allocated LinearAlgebra.mul!(dest, A, B)
87367114

julia> @allocated LinearAlgebra.mul!(dest, A, B)
0

Closes #857

`StaticVecOrMatLike` is a very large union, and this caused Julia 1.0.x to use a
large amount of memory when compiling StaticArrays in the presence of other
packages that also extend `LinearAlgebra.mul!` in a similar fashion. As an
example, this led to JuMP using more than 4 GB of RAM when running `using JuMP`,
causing its CI to crash.

Computing the eltypes within the function, rather than specifying them in the
type arguments greatly improves the issue, with `using JuMP` going from:
    julia> @time using JuMP
    [ Info: Precompiling JuMP [4076af6c-e467-56ae-b986-b466b2749572]
    Killed
to:
    julia> @time using JuMP
    [ Info: Precompiling JuMP [4076af6c-e467-56ae-b986-b466b2749572]
    97.868305 seconds (12.75 M allocations: 805.413 MiB, 0.30% gc time)
@mateuszbaran
Copy link
Collaborator

I have no idea how did you manage to figure this out but it's a really clean solution 👍 .

@odow
Copy link
Contributor Author

odow commented Dec 3, 2020

I have no idea how did you manage to figure this out

A hunch based on bisecting (jump-dev/JuMP.jl#2390 (comment)) this diff:
1b94778#diff-b899cd68e303f333bd6341af9c63b3717cbd50ae3a20d884de7c1822e2ddcfb3L52-R73

Copy link
Collaborator

@mateuszbaran mateuszbaran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, it looks good. Could you bump the version to 1.0.1?

@c42f could you tag a new version when this PR is merged?

Copy link
Member

@c42f c42f left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A clever workaround! I'm fine to just merge this, though if the type parameters are the problem, I wondered if we can get away with something even simpler.

src/matrix_multiply_add.jl Outdated Show resolved Hide resolved
@c42f
Copy link
Member

c42f commented Dec 4, 2020

@c42f could you tag a new version when this PR is merged?

Sure. By the way @mateuszbaran please feel free to push out low risk patch releases if you feel comfortable doing it. It's always good to get them done promptly.

Anyway, let's see if we can get away with the one-line version of this workaround. If not, I think it's fine to merge what's here.

@mateuszbaran
Copy link
Collaborator

Sure. By the way @mateuszbaran please feel free to push out low risk patch releases if you feel comfortable doing it. It's always good to get them done promptly.

OK, thanks. I didn't even know I have the right permissions.

@c42f
Copy link
Member

c42f commented Dec 4, 2020

I think anyone with write privileges can do it? Just mention @JuliaRegistrator as usual.

@JuliaRegistrator
Copy link

Error while trying to register: Action not recognized: as

@c42f
Copy link
Member

c42f commented Dec 4, 2020

Error while trying to register: Action not recognized: as

Haha oops! Apparently JuliaRegistrator is always listening, even if you quote its name in a code block 😆

@mateuszbaran
Copy link
Collaborator

OK, I'll try tagging 1.0.1 then when this is finished.

@odow
Copy link
Contributor Author

odow commented Dec 5, 2020

Bumped the version and simplified the code to remove the < v"1.1" branch.

Copy link
Member

@c42f c42f left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine to me. In fact, I'd argue that this is an improvement even for Julia > 1.0.

Generally I prefer to remove type parameters where possible (apart from the hack which is https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing which I wish would go away :) ).

At this point we could probably trim down the big comment block to a few lines, as the code doesn't actually look like a hack which needs explaining; it just looks nice.

@mateuszbaran mateuszbaran merged commit bfd1c05 into JuliaArrays:master Dec 5, 2020
@mateuszbaran
Copy link
Collaborator

Now there seems to be a problem with memory consumption in StaticArrays on Julia 1.3/Linux 😕 : https://github.com/JuliaArrays/StaticArrays.jl/runs/1503538242?check_suite_focus=true :

Test Summary:        | Pass  Total
LU singularity check |    2      2
Test Summary:        | Pass  Total
LU singularity check |    2      2
Test Summary:    | Pass  Total
QR decomposition |  496    496
LLVM ERROR: out of memory

signal (6): Aborted
in expression starting at /home/runner/work/StaticArrays.jl/StaticArrays.jl/test/chol.jl:4
__kernel_vsyscall at linux-gate.so.1 (unknown line)

@mateuszbaran
Copy link
Collaborator

That was probably something random, I've re-run the tests and now they all pass.

@odow
Copy link
Contributor Author

odow commented Dec 6, 2020

Thanks for the fast response. Looks like we're back up and running: jump-dev/JuMP.jl#2396

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.

Large union causes large allocations when compiling Julia 1.0.x
4 participants