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

A*v with A SymTridiagonal{Float64,Array{Float64,1}} and v Vector{Real} infers as Array{Any,1} #37960

Closed
Seelengrab opened this issue Oct 9, 2020 · 4 comments

Comments

@Seelengrab
Copy link
Contributor

julia> using LinearAlgebra

julia> A = SymTridiagonal([1., 2., 3.], [4., 5.])
3×3 SymTridiagonal{Float64,Array{Float64,1}}:
 1.0  4.0   ⋅
 4.0  2.0  5.0
  ⋅   5.0  3.0

julia> v = Vector{Real}(undef, 3)
3-element Array{Real,1}:
 #undef
 #undef
 #undef

julia> for n = 1:length(v)
           v[n] = rand(Float64)
       end

julia> A*v |> typeof
Array{Any,1}

julia> versioninfo()
Julia Version 1.5.2
Commit 539f3ce943 (2020-09-23 23:17 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
  JULIA_NUM_THREADS = 4

First found here - I'm not too familiar with the internals, but it feels like it should be possible to at least infer Array{Real,1}.

@dkarrasch
Copy link
Member

This is due to

julia> Base.promote_op(LinearAlgebra.matprod, Real, Float64)
Any

which is the first thing that is executed upon A*v. I guess this is not surprising, given that even

julia> Base.promote_op(*, Real, Float64)
Any

julia> Base.promote_op(*, AbstractFloat, Float64)
Any

where AbstractFloat is the immediate supertype of Float64.

@Seelengrab
Copy link
Contributor Author

Yes, @timholy mentioned something similar in the linked discourse thread. I'm unsure whether the linked PR (#36208) was just a workaround or meant as a final solution, so I won't close this issue myself 🤷‍♂️

@oscardssmith
Copy link
Member

The reason Julia does this is because although any reasonable subtype of Real should have this property hold, nothing technical stops people from defining unreasonable subtypes. If this method existed, it would have to check The invariant any time someone made a new subtype of Real.

@timholy
Copy link
Member

timholy commented Oct 10, 2020

I'm unsure whether the linked PR (#36208) was just a workaround or meant as a final solution, so I won't close this issue myself man_shrugging

It's probably not short term. Inference is subject to the halting problem so will never be perfect, and even when it's "just" a question of checking long lists of methods we have to cut it off somewhere or inference time is potentially unbounded. (I could write a script that would generate N methods for arbitrary N.)

Candidate solutions are things like #36463, but that's pretty speculative and Jeff points out that it could end up in a bad place.

@timholy timholy closed this as completed Oct 10, 2020
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

No branches or pull requests

4 participants