JuliaArrays / JuliaArrays/OffsetArrays.jl
Preserving static size information in `no_offset_view`
Nobody has claimed this yet.
- Dominant language
- Julia
- Stars
- 212
- Forks
- 45
- PR merge metrics
- No merged PRs in 30d
Description
Currently, no_offst_view has special methods defined for Bsae.OneTo, but nothing for SOneTo axes that a StaticArray has. As a consequence, OffsetArrays doesn't realize that a SOneTo is 1-based. This leads to
julia> OffsetArrays.no_offset_view(SOneTo(4)) |> typeof
UnitRange{Int64}
that is, it loses the static size information. As a consequence,
julia> A = Float64.(reshape(1:16, 4, 4));
julia> B = @view A[SOneTo(4)];
julia> @code_warntype size(B) # size is constant-propagated
MethodInstance for size(::SubArray{Float64, 1, Vector{Float64}, Tuple{SOneTo{4}}, true})
from size(V::SubArray) in Base at subarray.jl:63
Arguments
#self#::Core.Const(size)
V::SubArray{Float64, 1, Vector{Float64}, Tuple{SOneTo{4}}, true}
Body::Tuple{Int64}
1 ─ nothing
│ %2 = Base.axes(V)::Core.Const((SOneTo(4),))
│ %3 = Base.map(Base.length, %2)::Core.Const((4,))
└── return %3
julia> @code_warntype size(OffsetArrays.no_offset_view(B)) # static size information is lost
MethodInstance for size(::SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true})
from size(V::SubArray) in Base at subarray.jl:63
Arguments
#self#::Core.Const(size)
V::SubArray{Float64, 1, Vector{Float64}, Tuple{UnitRange{Int64}}, true}
Body::Tuple{Int64}
1 ─ nothing
│ %2 = Base.axes(V)::Tuple{Base.OneTo{Int64}}
│ %3 = Base.map(Base.length, %2)::Tuple{Int64}
└── return %3
julia> B = @view A[SOneTo(4)];
julia> C = OffsetArrays.no_offset_view(B);
julia> @btime sum($B);
3.356 ns (0 allocations: 0 bytes)
julia> @btime sum($C);
5.870 ns (0 allocations: 0 bytes)
One way to resolve this is to simply define _no_offset_view for Union{Base.OneTo, StaticArrays.SOneTo} over here, but this will require us to explicitly depend on StaticArrays. The second way might be something like https://github.com/JuliaLang/julia/issues/41946, where Base defines OneTo <: AbstractOneTo, and we define methods for AbstractOneTo in this package. However, it doesn't appear that there's a clear direction to this in Base at the moment. I wonder if there's another way to preserve the size, without one package explicitly depending on the other.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the _no_offset_view methods and compare their handling of Base.OneTo with StaticArrays.SOneTo; review the design discussed in Julia issue 41946 before choosing an approach. Reproduce the SOneTo examples with @code_warntype and @btime; done means no_offset_view preserves static size information without introducing an inappropriate dependency.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 32/100