JuliaSIMD / JuliaSIMD/StrideArrays.jl

Type instability for `PtrArray`s with `--check-bounds=no` and StrideArrays.jl (but not with StrideArraysCore.jl)

Open
#93 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Julia
Stars
59
Forks
9
PR merge metrics
No merged PRs in 30d

Description

When using StrideArrays.jl with Julia v1.11 and `--check-bounds=no`, `PtrArray`s will cause a type instability that only manifests when loading StrideArrays.jl, but not when loading StrideArraysCore.jl.

I know all the arguments for and against `--check-bounds=no`, but this seems to me like it _should_ work (or at least be fixable), which would likely mean that `--check-bounds=no` becomes usable again for us in Trixi-land...

### MWE

For this I used Julia v1.11.3 on a Linux machine.

Install packages first with (only needed once)
```shell
julia --project=. --check-bounds=no -e 'using Pkg; Pkg.add(["StrideArrays", "StrideArraysCore"])'
```
This currently install StrideArrays.jl v0.1.29 with StrideArraysCore.jl v0.5.7.

Then, start the Julia REPL with `julia --project=. --check-bounds=no` and execute either
```julia
using StrideArraysCore: PtrArray, StaticInt

_u = zeros(1)
u = PtrArray(pointer(_u), (StaticInt(1),))

@code_warntype u[1]
```
or
```julia
using StrideArrays: PtrArray, StaticInt

_u = zeros(1)
u = PtrArray(pointer(_u), (StaticInt(1),))

@code_warntype u[1]
```

The first one (with StrideArraysCore.jl) will give you
```julia-repl
MethodInstance for getindex(::PtrArray{Float64, 1, (1,), Tuple{StaticInt{1}}, Tuple{Nothing}, Tuple{StaticInt{1}}}, ::Int64)
from getindex(A::PtrArray{T, 1}, i::Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8, StaticInt}) where T @ StrideArraysCore ~/.julia/packages/StrideArraysCore/Yyyvt/src/ptr_array.jl:1035
Static Parameters
T = Float64
Arguments
#self#::Core.Const(getindex)
A::PtrArray{Float64, 1, (1,), Tuple{StaticInt{1}}, Tuple{Nothing}, Tuple{StaticInt{1}}}
i::Int64
Body::Float64
1 ─ nothing
│ %2 = $(Expr(:boundscheck))::Bool
└── goto #3 if not %2
2 ─ %4 = StrideArraysCore.checkbounds::Core.Const(checkbounds)
└── (%4)(A, i)
3 ┄ %6 = StrideArraysCore.unsafe_getindex(A, i)::Float64
└── return %6
```
while the second one will give you
```julia-repl
MethodInstance for getindex(::PtrArray{Float64, 1, (1,), Tuple{StaticInt{1}}, Tuple{Nothing}, Tuple{StaticInt{1}}}, ::Int64)
from getindex(A::PtrArray{T, 1}, i::Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8, StaticInt}) where T @ StrideArraysCore ~/.julia/packages/StrideArraysCore/Yyyvt/src/ptr_array.jl:1035
Static Parameters
T = Float64
Arguments
#self#::Core.Const(getindex)
A::PtrArray{Float64, 1, (1,), Tuple{StaticInt{1}}, Tuple{Nothing}, Tuple{StaticInt{1}}}
i::Int64
Body::Any
1 ─ nothing
│ %2 = $(Expr(:boundscheck))::Bool
└── goto #3 if not %2
2 ─ %4 = StrideArraysCore.checkbounds::Core.Const(checkbounds)
└── (%4)(A, i)
3 ┄ %6 = StrideArraysCore.unsafe_getindex(A, i)::Any
└── return %6
```
That is, in the second version `StrideArraysCore.unsafe_getindex(A, i)::Any` is type unstable.

Note that you need to execute Julia in between, since once you've loaded StrideArrays.jl, there's no going back.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reproducing the two MWE variants with Julia 1.11 and --check-bounds=no, then compare the StrideArrays and StrideArraysCore loading paths. Inspect ptr_array.jl around line 1035 and the unsafe_getindex call shown by @code_warntype. Done means the StrideArrays variant retains a concrete inferred result like the StrideArraysCore variant.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.