Skip to content

parametrize Bidiagonal on wrapped vector type#22925

Merged
tkelman merged 1 commit into
JuliaLang:masterfrom
fredrikekre:fe/bidiagonal
Aug 3, 2017
Merged

parametrize Bidiagonal on wrapped vector type#22925
tkelman merged 1 commit into
JuliaLang:masterfrom
fredrikekre:fe/bidiagonal

Conversation

@fredrikekre

Copy link
Copy Markdown
Member

Same as #22718 but for Bidiagonal.

@fredrikekre fredrikekre added breaking This change will break code linear algebra Linear algebra labels Jul 23, 2017
Comment thread test/linalg/bidiag.jl
end

@testset "triu and tril" begin
bidiagcopy(dv, ev, uplo) = Bidiagonal(copy(dv), copy(ev), uplo)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

hm, so was this previously writing zeros through to these?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No but previously the constructor always made a copy of the vectors, ref e0d75d7#commitcomment-22968553

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

were Tridiagonal or SymTridiagonal behaving like that too, or was Bidiagonal the only case of it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

e0d75d7 only changed the behaviour of Bidiagonal. The other ones still have constructors that don't copy: Diagonal, Tridiagonal and SymTridiagonal.

@Sacha0 Sacha0 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

generally lgtm! :)

@fredrikekre

Copy link
Copy Markdown
Member Author

Restarting Travis, I saved the logs if anyone is interested, but:
Timeout on i686.
The following on x86_64:

The command "du -sk /tmp/julia/*" exited with 1.

0.02s$ if [ `uname` = "Darwin" ]; then for name in suitesparseconfig spqr umfpack colamd cholmod amd suitesparse_wrapper; do install -pm755 usr/lib/lib${name}*.dylib* /tmp/julia/lib/julia/; done; fi 

and some (spurious?) distributed failure on macOS.

@fredrikekre
fredrikekre force-pushed the fe/bidiagonal branch 2 times, most recently from 6177b3b to 1a13b38 Compare July 28, 2017 23:58
@fredrikekre

Copy link
Copy Markdown
Member Author

Added some more constructors which promotes more properly, and tests.

Comment thread base/linalg/bidiag.jl Outdated
function Bidiagonal(dv::AbstractVector{Td}, ev::AbstractVector{Te}, uplo::Symbol) where {Td,Te}
T = promote_type(Td,Te)
function Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{T}, uplo::Symbol) where T
Bidiagonal(convert(Vector{T}, dv), convert(Vector{T}, ev), uplo)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isn't this conversion to Vector what you're trying to make unnecessary?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is just a fallback for cases like Bidiagonal(::Vector{T}, ::GenericVector{T}), but perhaps the constructor on line 62 should be generalized to promote to the same container type as well, and not just promote the element type? That would make this constructor obsolete.
Currently the promotion is as follows:

Bidiagonal(::Vector{T}, ::GenericVector{S}) ->
Bidiagonal(::Vector{R}, ::GenericVector{R}) ->
Bidiagonal(::Vector{R}, ::Vector{R})

The problem with generalizing the method above was this:

julia> A = rand(3); B = GenericArray(rand(3)); a, b = promote(A,B);

julia> typeof(a)
Array{Float64,1}

julia> typeof(b)
Base.Test.GenericArray{Float64,1}

i.e. they don't promote to the same container type. Hence the current scheme.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thinking about this a bit more, perhaps we should not promote anything in the constructor here, and instead let the user promote to appropriate types. In that case this:

function Bidiagonal(dv::V, ev::V, uplo::Symbol) where {T,V<:AbstractVector{T}}
    Bidiagonal{T}(dv, ev, char_uplo(uplo))
end

would be the only constructor. The good thing about this is that we don't try to "figure out" what the user wants; instead the user have to be explicit about this. The other good thing with this method is that the vectors in the Bidiagonal will always alias the vectors sent to the constructor. This would then be consistent with the new Diagonal type from #22718 . As this PR currently stands, the vectors will sometimes alias and sometimes not.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We would also have to deprecate methods that did convert, but I still like this better. It is probably not very often you supply two different vector types anyway; and it would be consistent that the vectors always alias, so I will update the PR like that later, unless other people think that’s a bad idea.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

or promote in a way consistent with what concatenation would do, since this is sort of like a diagonal concatenation

@tkelman tkelman Jul 30, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the aliasing predictability benefits of not promoting at all and making the user pick could also have advantages though - as long as the old methods were deprecated, and the restriction is documented, I think that would also be fine and not trip up too many people

@fredrikekre

Copy link
Copy Markdown
Member Author

Alright, updated the PR.

Comment thread base/deprecated.jl Outdated
# PR #22925
# also uncomment constructor tests in test/linalg/bidiag.jl
function Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}, uplo::Symbol) where {T,S}
depwarn(string("Bidiagonal(dv::AbstractVector{T}, ev::AbstractVector{S}, uplo::Symbol) ",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

add a bullet for this deprecation in NEWS

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Right, updated.

Comment thread base/linalg/bidiag.jl
"""
Bidiagonal(A::AbstractMatrix, uplo::Symbol) = Bidiagonal(diag(A), diag(A, uplo == :U ? 1 : -1), uplo)
function Bidiagonal(A::AbstractMatrix, uplo::Symbol)
Bidiagonal(diag(A, 0), diag(A, uplo == :U ? 1 : -1), uplo)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I didn't actually realize diag(A, k) would already give a SparseVector

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, as long as the two arg form is inferable this should be "more correct" since diag(A) in some cases give something else.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

which isn't very consistent with it acting like a default argument, but that's a discussion for a different issue

@fredrikekre

Copy link
Copy Markdown
Member Author

Added NEWS for the deprecations. Would like to merge this first and then fix up #23035 afterwards.

Comment thread NEWS.md Outdated
`AbstractVector`s ([#22718], [#22925]).

* `Bidiagonal` constructors that automatically converted the input vectors to
the same type are deprecated in favor of explicit conversion ([#22925]).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was thinking this would go in the Deprecated or removed section since the library functionality part of the change is mentioned earlier

@tkelman

tkelman commented Aug 2, 2017

Copy link
Copy Markdown
Contributor

I'd also add to the docstring what restrictions on the two inputs there are - in Bidiagonal(dv, ev, uplo::Symbol) is it now that dv and ev could have different element types but must otherwise be the same subtype of AbstractVector, or do they have to be the same type including eltype?

deprecate Bidiagonal constructor that automatically convert the vectors
@fredrikekre

Copy link
Copy Markdown
Member Author

Updated the docstring for the constructor. There are some Bidiagonal benchmarks in BaseBenchmarks.jl, so before merging:
@nanosoldier runbenchmarks("linalg", vs = ":master")

@tkelman

tkelman commented Aug 3, 2017

Copy link
Copy Markdown
Contributor

I'm not seeing a docstring change?

@fredrikekre

Copy link
Copy Markdown
Member Author

I only added the constraint to the signature, you want me to mention it in the text too?

@tkelman

tkelman commented Aug 3, 2017

Copy link
Copy Markdown
Contributor

no, I just missed that, probably good enough

@nanosoldier

Copy link
Copy Markdown
Collaborator

Your benchmark job has completed - no performance regressions were detected. A full report can be found here. cc @ararslan

@tkelman
tkelman merged commit 8832208 into JuliaLang:master Aug 3, 2017
@tkelman

tkelman commented Aug 3, 2017

Copy link
Copy Markdown
Contributor

win32 appveyor failure in distributed is a bit alarming, but highly doubt it's related

@fredrikekre
fredrikekre deleted the fe/bidiagonal branch August 3, 2017 23:17
@fredrikekre

Copy link
Copy Markdown
Member Author

win32 appveyor failure in distributed is a bit alarming, but highly doubt it's related

It happens from time to time

@StefanKarpinski

Copy link
Copy Markdown
Member

Good lord 😠. Getting our CI rock solid has got to be a top priority post 1.0 if not sooner.

@amitmurthy

Copy link
Copy Markdown
Contributor

The randomly occurring distributed failure is a segfault . Stack shows gf.c, but then the corruption could have happened elsewhere too.

The distributed module does not have any ccalls - consequently I don't know how to track it down especially since it does not occur locally.

Long term CI plans should include a valgrind / memcheck run if possible.

@StefanKarpinski

Copy link
Copy Markdown
Member

I'm not complaining about this particular issue really, just the general flakiness of our CI lately. A bunch of it is that Travis keeps giving us less resources so now many runs just time out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking This change will break code linear algebra Linear algebra

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants