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

added new methods to similar_arr_type to deal with SubArray ReshapedA… #18

Merged
merged 8 commits into from
Jun 20, 2024

Conversation

RainerHeintzmann
Copy link
Member

This relates to an issue as discussed here.
The method is using the Type-based constructor to generate an empty array, which is not supported by some nested array types.
Support for SubArray , Base.ReshapedArray and Base.ReinterpretArray was now added. This should potentially also be added to the corresponding similar(Type, axes) call in Base.

Copy link

codecov bot commented Jun 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.21%. Comparing base (3d33774) to head (3c0b3f6).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #18      +/-   ##
==========================================
+ Coverage   89.95%   90.21%   +0.25%     
==========================================
  Files          11       11              
  Lines         229      235       +6     
==========================================
+ Hits          206      212       +6     
  Misses         23       23              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Manifest.toml Outdated
@@ -0,0 +1,73 @@
# This file is machine-generated - editing it directly is not advised
Copy link
Member

Choose a reason for hiding this comment

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

Delete this file.

@roflmaostc
Copy link
Member

I don't like those methods as they are now, because they are error prone and induce type instability issues.

julia> @code_warntype similar_arr_type(typeof(x), dims=2)
MethodInstance for Core.kwcall(::@NamedTuple{dims::Int64}, ::typeof(similar_arr_type), ::Type{Matrix{Float64}})
  from kwcall(::NamedTuple, ::typeof(similar_arr_type), ::Type{TA}) where {T, N, TA<:AbstractArray{T, N}} @ Main REPL[8]:1
Static Parameters
  T = Float64
  N = 2
  TA = Matrix{Float64}
Arguments
  _::Core.Const(Core.kwcall)
  @_2::@NamedTuple{dims::Int64}
  @_3::Core.Const(similar_arr_type)
  @_4::Core.Const(Matrix{Float64})
Locals
  dims::Union{}
  dtype::Union{}
  @_7::Union{Int64, Type{Float64}}
Body::DataType
1 ─       Core.NewvarNode(:(dims))
│         Core.NewvarNode(:(dtype))
│         Core.NewvarNode(:(@_7))
│   %4  = Core.isdefined(@_2, :dims)::Core.Const(true)
└──       goto #3 if not %4
2 ─       (@_7 = Core.getfield(@_2, :dims))
└──       goto #4
3 ─       Core.Const(:(@_7 = $(Expr(:static_parameter, 2))))
4%9  = @_7::Int64%10 = Core.isdefined(@_2, :dtype)::Core.Const(false)
└──       goto #6 if not %10
5 ─       Core.Const(:(@_7 = Core.getfield(@_2, :dtype)))
└──       Core.Const(:(goto %15))
6 ┄       (@_7 = $(Expr(:static_parameter, 1)))
│   %15 = @_7::Core.Const(Float64)
│   %16 = (:dims, :dtype)::Core.Const((:dims, :dtype))
│   %17 = Core.apply_type(Core.NamedTuple, %16)::Core.Const(NamedTuple{(:dims, :dtype)})
│   %18 = Base.structdiff(@_2, %17)::Core.Const(NamedTuple())
│   %19 = Base.pairs(%18)::Core.Const(Base.Pairs{Symbol, Union{}, Tuple{}, @NamedTuple{}}())
│   %20 = Base.isempty(%19)::Core.Const(true)
└──       goto #8 if not %20
7 ─       goto #9
8 ─       Core.Const(:(Base.kwerr(@_2, @_3, @_4)))
9%24 = Main.:(var"#similar_arr_type#1")(%9, %15, @_3, @_4)::DataType
└──       return %24

I think the best template is something like this. Explicit type annotations avoid abuse through the user:

julia> function similar_arr_type(::Type{AA}, ::Val{N2}=Val(N), ::Type{T2}=Type{T}) where {T, N, AA<:AbstractArray{T, N}, N2, T2}
           typeof(similar(AA(undef, ntuple(x->0, Val(N2))), T2, ntuple(x->0, Val(N2))))
       end
similar_arr_type (generic function with 3 methods)

julia> similar_arr_type(typeof(ones(2,2)))
Matrix{Type{Float64}} (alias for Array{Type{Float64}, 2})

julia> @code_warntype similar_arr_type(typeof(ones(2,2)))
MethodInstance for similar_arr_type(::Type{Matrix{Float64}})
  from similar_arr_type(::Type{AA}) where {T, N, AA<:AbstractArray{T, N}} @ Main REPL[1]:1
Static Parameters
  T = Float64
  N = 2
  AA = Matrix{Float64}
Arguments
  #self#::Core.Const(similar_arr_type)
  @_2::Core.Const(Matrix{Float64})
Body::Type{Matrix{Type{Float64}}}
1%1 = Main.Val($(Expr(:static_parameter, 2)))::Core.Const(Val{2}())
│   %2 = (#self#)(@_2, %1)::Core.Const(Matrix{Type{Float64}})
└──      return %2

@roflmaostc
Copy link
Member

Maybe changing the order of element type and dimension, that's more consistent with similar.

Still I think, this method is very error prone and people should just use similar and typeof.
Those kind of methods make Julia very unreadable, and it doesn't save so many characters.

@roflmaostc roflmaostc merged commit 7a6e941 into main Jun 20, 2024
4 checks passed
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.

2 participants