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

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

Open
sloede opened this issue Feb 14, 2025 · 3 comments

Comments

@sloede
Copy link

sloede commented Feb 14, 2025

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.

@ranocha
Copy link
Member

ranocha commented Feb 16, 2025

This seems to be basically JuliaLang/julia#50985

@ranocha
Copy link
Member

ranocha commented Feb 16, 2025

Loading StrideArrays.jl makes the final pointer arithmetic in StrideArraysCore.unsafe_getindex(u, 1) type unstable - I guess since some new methods are added and heuristics drop inferring further.

@sloede
Copy link
Author

sloede commented Feb 16, 2025

This seems to be basically JuliaLang/julia#50985

🤦 I guess it would have been sensible to check that first. However, given that I posted this already 1.5 years ago, I really didn't have it on the radar anymore :-/

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

No branches or pull requests

2 participants