Skip to content

Type instability for PtrArrays with --check-bounds=no and StrideArrays.jl (but not with StrideArraysCore.jl) #93

@sloede

Description

@sloede

When using StrideArrays.jl with Julia v1.11 and --check-bounds=no, PtrArrays 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)

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

using StrideArraysCore: PtrArray, StaticInt

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

@code_warntype u[1]

or

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

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

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions