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

Base.LinAlg to LinearAlgebra stdlib #25571

Merged

Conversation

fredrikekre
Copy link
Member

@fredrikekre fredrikekre commented Jan 15, 2018

Move Base.LinAlg to the new LinearAlgebra standard library module.

TODO:

  • Hunt down the last ~10 test failures
  • Fix documentations
  • @deprecate_moved everything

@fredrikekre fredrikekre added domain:linear algebra Linear algebra kind:excision Removal of code from Base or the repository stdlib Julia's standard library labels Jan 15, 2018
@quinnj
Copy link
Member

quinnj commented Jan 15, 2018

very exciting!

@ViralBShah
Copy link
Member

Thank you!

@JeffBezanson JeffBezanson added this to the 1.0 milestone Jan 17, 2018
@fredrikekre
Copy link
Member Author

Test Summary: |     Pass  Broken     Total
  Overall     | 26598697  328325  26927022
    SUCCESS

@fredrikekre fredrikekre force-pushed the so-long-and-thanks-for-all-the-fish branch from 3545b04 to d2dbcce Compare January 17, 2018 11:21
@KristofferC
Copy link
Sponsor Member

Small thing but should remove the linalg test group from test/Makefile.

@KristofferC
Copy link
Sponsor Member

A nice thing Fredrik told me about is the CI time. Before this PR, the linalg tests (on the freebsd builder) took a total of 3580 seconds. WIth all the linalg running on the same worker, it now takes 1842 seconds.

base/exports.jl Outdated
# vecdot,
# vecnorm,
# ⋅,
# ×,
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

All these should just be deleted.

Copy link
Member Author

Choose a reason for hiding this comment

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

Part of the working process, will clean up the PR :)

println(io, " BLAS: ",libblas_name)
end
println(io, " LAPACK: ",liblapack_name)
# if Base.libblas_name == "libopenblas" || BLAS.vendor() == :openblas || BLAS.vendor() == :openblas64
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

If we're going to remove this code, it should also just be deleted.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, will add this as a LinearAlgebra.versioninfo() function for now.

@JeffBezanson
Copy link
Sponsor Member

I think I should wait for this before merging #25421

@KristofferC
Copy link
Sponsor Member

Has there been any thought of about the fact that stdlibs still "affect" Base functions by using method extension and being in the sysimg? For example, it is likely that there is still something in Base using matrix multiplication which now only works because LinearAlgebra is in the sysimg.

@JeffBezanson
Copy link
Sponsor Member

My thought on that is we will try to make them less coupled over time, and a change like this is a step in that direction.

@quinnj
Copy link
Member

quinnj commented Jan 17, 2018

Eventually it'd be nice to have some kind of compile flag to say --NO_LINALG to avoid including the LinAlg module or any of it's source dependencies. It would then be pretty clear that there are no dependencies in Base (or maybe you'd just get a MethodError).

@StefanKarpinski
Copy link
Sponsor Member

I think that not all linear algebra definitions can be moved out, but that's ok. The line ends up being that we need in-Base implementations when the operation and its argument types all belong to Base – i.e. precisely when LinAlg would be committing type piracy (second degree, not first). Matmul is a good example. But methods on types that don't belong to Base and operations that aren't defined in Base can live entirely in LinAlg. We could even have a pure Julia definition of matmul in Base and then overwrite it with a definition that calls BLAS in LinAlg. So there are definitely options here.

@KristofferC
Copy link
Sponsor Member

KristofferC commented Jan 17, 2018

The line ends up being that we need in-Base implementations when the operation and its argument types all belong to Base – i.e. precisely when LinAlg would be committing type piracy (second degree, not first)

What are first / second degree type piracy?

@StefanKarpinski
Copy link
Sponsor Member

StefanKarpinski commented Jan 17, 2018

What are first / second degree type piracy?

Terms I just made up 😬 ... but which I define as for function and args types you don't own:

  • "first degree type piracy" = redefining existing methods that aren't yours
  • "second degree type piracy" = defining new methods that aren't yours

So first degree is a form of monkey patching and can have non-local effects on program behavior. Second degree is not monkey patching and is far less risky but could still have a non-local effect on behavior if some other code overwrites the same new methods that aren't theirs.

@fredrikekre
Copy link
Member Author

I think stdlibs should have the licence to commit second degree type piracy 😄

@JeffBezanson
Copy link
Sponsor Member

Agreed.

@StefanKarpinski
Copy link
Sponsor Member

sean-connery-james-bond-bw

@fredrikekre fredrikekre force-pushed the so-long-and-thanks-for-all-the-fish branch 2 times, most recently from 8b73a98 to e2fc62b Compare January 17, 2018 23:47
@@ -391,7 +391,12 @@ end
function _one(unit::T, x::AbstractMatrix) where T
m,n = size(x)
m==n || throw(DimensionMismatch("multiplicative identity defined only for square matrices"))
Matrix{T}(I, m, m)
# Matrix{T}(I, m, m)
Copy link
Member Author

Choose a reason for hiding this comment

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

This function should probably be moved too, but can stay for now.

@@ -506,7 +506,7 @@ end

Compute the hypotenuse ``\\sqrt{\\sum x_i^2}`` avoiding overflow and underflow.
"""
hypot(x::Number...) = vecnorm(x)
hypot(x::Number...) = sqrt(sum(abs2(y) for y in x))
Copy link
Member Author

Choose a reason for hiding this comment

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

One of two places which uses a LinearAlgebra owned function... I hope this hack is fine for now.

Copy link
Member

Choose a reason for hiding this comment

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

We should consider deprecating this function or just move it since the raison d'être of hypot is to handle potential overflow which vecnorm does but this implementation doesn't

@@ -328,7 +330,7 @@ unscaled_covzm(x::AbstractVector{<:Number}) = sum(abs2, x)
unscaled_covzm(x::AbstractVector) = sum(t -> t*t', x)
unscaled_covzm(x::AbstractMatrix, vardim::Int) = (vardim == 1 ? _conj(x'x) : x * x')

unscaled_covzm(x::AbstractVector, y::AbstractVector) = dot(y, x)
unscaled_covzm(x::AbstractVector, y::AbstractVector) = sum(conj(y[i])*x[i] for i in eachindex(y, x))
Copy link
Member Author

Choose a reason for hiding this comment

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

The second place where a LinearAlgebra owned function is used. This should be ok for now...

Copy link
Member

Choose a reason for hiding this comment

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

This is not equivalent for all element types. Should we move statistics to stdlib first?

Copy link
Member

Choose a reason for hiding this comment

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

This indeed turned out to be a problem in some cases. See https://github.com/JuliaLang/Statistics.jl/pull/85.

@@ -59,13 +59,13 @@ julia> A = [1 2; 2 3]
2 3

julia> bkfact(A)
Base.LinAlg.BunchKaufman{Float64,Array{Float64,2}}
LinearAlgebra.BunchKaufman{Float64,Array{Float64,2}}
Copy link
Member Author

Choose a reason for hiding this comment

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

This is much prettier IMO, rather awkward with the Base. prefix before 🙂

@fredrikekre fredrikekre changed the title wip linalg stdlib linalg stdlib Jan 17, 2018
@fredrikekre fredrikekre changed the title linalg stdlib Base.LinAlg to LinearAlgebra stdlib Jan 17, 2018
@fredrikekre fredrikekre force-pushed the so-long-and-thanks-for-all-the-fish branch from e2fc62b to b40d312 Compare January 18, 2018 00:04
@fredrikekre fredrikekre force-pushed the so-long-and-thanks-for-all-the-fish branch from 9e37ae2 to a056c2f Compare January 18, 2018 13:57
@JeffBezanson
Copy link
Sponsor Member

Looking good! Ready to merge?

@fredrikekre
Copy link
Member Author

Looking good! Ready to merge?

I think so. Since CI pass it should be fine. Can always fix up stuff in subsequent PRs. @Sacha0 ?

@Sacha0
Copy link
Member

Sacha0 commented Jan 18, 2018

If @fredrikekre is happy, I am happy :). Otherwise I will continue reviewing this over the next few days. Best!

Copy link
Member

@andreasnoack andreasnoack left a comment

Choose a reason for hiding this comment

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

This is a pretty big diff but I think it mostly fine. I only have a few comments.

@@ -70,7 +60,6 @@ export
IOBuffer,
IOStream,
LinSpace,
LowerTriangular,
Irrational,
Matrix,
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we want to define these aliases in LinearAlgebra

@@ -506,7 +506,7 @@ end

Compute the hypotenuse ``\\sqrt{\\sum x_i^2}`` avoiding overflow and underflow.
"""
hypot(x::Number...) = vecnorm(x)
hypot(x::Number...) = sqrt(sum(abs2(y) for y in x))
Copy link
Member

Choose a reason for hiding this comment

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

We should consider deprecating this function or just move it since the raison d'être of hypot is to handle potential overflow which vecnorm does but this implementation doesn't

@@ -59,7 +59,8 @@ julia> mean!([1. 1.], v)
"""
function mean!(R::AbstractArray, A::AbstractArray)
sum!(R, A; init=true)
scale!(R, max(1, _length(R)) // _length(A))
x = max(1, _length(R)) // _length(A)
R .= R .* x
Copy link
Member

Choose a reason for hiding this comment

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

I believe this could R .*= x

@@ -328,7 +330,7 @@ unscaled_covzm(x::AbstractVector{<:Number}) = sum(abs2, x)
unscaled_covzm(x::AbstractVector) = sum(t -> t*t', x)
unscaled_covzm(x::AbstractMatrix, vardim::Int) = (vardim == 1 ? _conj(x'x) : x * x')

unscaled_covzm(x::AbstractVector, y::AbstractVector) = dot(y, x)
unscaled_covzm(x::AbstractVector, y::AbstractVector) = sum(conj(y[i])*x[i] for i in eachindex(y, x))
Copy link
Member

Choose a reason for hiding this comment

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

This is not equivalent for all element types. Should we move statistics to stdlib first?

@Sacha0 Sacha0 merged commit 7deac81 into JuliaLang:master Jan 18, 2018
@JeffBezanson
Copy link
Sponsor Member

🎉

@fredrikekre fredrikekre deleted the so-long-and-thanks-for-all-the-fish branch January 18, 2018 20:59
@Sacha0
Copy link
Member

Sacha0 commented Jan 18, 2018

BOOM

@mbauman
Copy link
Sponsor Member

mbauman commented Jan 20, 2018

This is awesome!

Is the deprecation for I missing?

fredrikekre added a commit that referenced this pull request May 20, 2018
this commit removes cor, cov, median, median!,
middle, quantile, quantile!, std, stdm, var,
varm and linreg and moves them to StatsBase

fix #25571 (comment) (included in StatsBase.jl/#379)
fix #23769 (included in StatsBase.jl/#379)
fix #27140
fredrikekre added a commit that referenced this pull request May 20, 2018
this commit removes cor, cov, median, median!,
middle, quantile, quantile!, std, stdm, var,
varm and linreg and moves them to StatsBase

fix #25571 (comment)
    (included in JuliaStats/StatsBase.jl#379)
fix #23769 (included in JuliaStats/StatsBase.jl#379)
fix #27140
andreasnoack pushed a commit to JuliaLinearAlgebra/SparseLinearAlgebra.jl that referenced this pull request Jun 21, 2018
nalimilan pushed a commit to JuliaStats/Statistics.jl that referenced this pull request Sep 18, 2019
nalimilan pushed a commit to JuliaStats/Statistics.jl that referenced this pull request Sep 18, 2019
KristofferC pushed a commit to JuliaSparse/SparseArrays.jl that referenced this pull request Nov 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:linear algebra Linear algebra kind:excision Removal of code from Base or the repository stdlib Julia's standard library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants