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

eltype of A' for abstractly typed A breaks after loading package #52729

Open
oxinabox opened this issue Jan 4, 2024 · 1 comment
Open

eltype of A' for abstractly typed A breaks after loading package #52729

oxinabox opened this issue Jan 4, 2024 · 1 comment
Labels
compiler:inference Type inference types and dispatch Types, subtyping and method dispatch

Comments

@oxinabox
Copy link
Contributor

oxinabox commented Jan 4, 2024

This is an attempt to isolate what is happening in JuliaDiff/ChainRulesCore.jl#649
as I don't think that one is ChainRulesCore's fault

Basically what we see is:

julia> eltype(ones(Complex,100,100)')
Complex

julia> using ChainRulesCore

julia> eltype(ones(Complex,100,100)')
Any

This does not occur with concretely typed Matrix{ComplexF64}

I am pretty sure this is because Adjoint{Matrix{Complex}} actually makes an invalid use of promote_op here
according to its the promote_op doc sting
and this is what fails

julia> Base.promote_op(adjoint, Matrix{Complex})
LinearAlgebra.Adjoint{Complex, Matrix{Complex}}

julia> using ChainRulesCore

julia> Base.promote_op(adjoint, Matrix{Complex})
LinearAlgebra.Adjoint{Any, Matrix{Complex}}
@martinholters
Copy link
Member

Yep, loading ChainRulesCore makes inference of Complex(::Any, ::Any) go from Complex to Any:

julia> code_typed(Complex, Tuple{Any,Any})
2-element Vector{Any}:
 CodeInfo(
1%1 = $(Expr(:static_parameter, 1))::Type{T} where T<:Real%2 = Core.apply_type(Base.Complex, %1)::Type{Complex{T}} where T<:Real%3 = %new(%2, re, im)::Complex
└──      return %3
) => Complex
                    CodeInfo(
1%1 = Base.promote(x, y)::Tuple{Any, Any}%2 = Core.getfield(%1, 1)::Any%3 = Core.getfield(%1, 2)::Any%4 = Base.Complex(%2, %3)::Complex
└──      return %4
) => Complex

julia> using ChainRulesCore

julia> code_typed(Complex, Tuple{Any,Any})
5-element Vector{Any}:
 CodeInfo(
1%1 = (isa)(x, Bool)::Bool
└──      goto #3 if not %1
2%3 = π (x, Bool)
│   %4 = %new(Complex{Bool}, %3, false)::Complex{Bool}
└──      goto #4
3%6 = ChainRulesCore.Complex(x, false)::Any
└──      goto #4
4%8 = φ (#2 => %4, #3 => %6)::Any
└──      return %8
) => Any
                                                                           CodeInfo(
1%1 = $(Expr(:static_parameter, 1))::Type{T} where T<:Real%2 = Core.apply_type(Base.Complex, %1)::Type{Complex{T}} where T<:Real%3 = %new(%2, re, im)::Complex
└──      return %3
) => Complex
                                                                                                  CodeInfo(
1%1 = Base.promote(x, y)::Tuple{Any, Any}%2 = Core.getfield(%1, 1)::Any%3 = Core.getfield(%1, 2)::Any%4 = Base.Complex(%2, %3)::Any
└──      return %4
) => Any
                                                                                                                          CodeInfo(
1%1 = ChainRulesCore.unthunk(a)::Any%2 = ChainRulesCore.unthunk(b)::Any%3 = ChainRulesCore.Complex(%1, %2)::Any
└──      return %3
) => Any
 CodeInfo(
1%1 = (isa)(y, Bool)::Bool
└──      goto #3 if not %1
2%3 = π (y, Bool)
│   %4 = %new(Complex{Bool}, false, %3)::Complex{Bool}
└──      goto #4
3%6 = ChainRulesCore.Complex(false, y)::Any
└──      goto #4
4%8 = φ (#2 => %4, #3 => %6)::Any
└──      return %8
) => Any

Note that even if the new methods successfully inferred as Complex, there would still be too many of them.

But even if this effect of loading ChainRulesCore on inference is somewhat unfortunate, having adjoint use promote_op in this way is quite problematic. However, our options are limited: We don't want to compute adjoint of every element here, but need to determine the type(s) resulting from doing so.

@nsajko nsajko added types and dispatch Types, subtyping and method dispatch compiler:inference Type inference labels Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:inference Type inference types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

3 participants