Skip to content

Commit 9e2f77b

Browse files
maleadtclaude
andcommitted
Store JLArray offset in bytes instead of elements
The element-based offset was lossy when materializing reinterpret on views with non-aligned offsets (e.g., reinterpreting a view of Float32 as Float64). The byte offset would get truncated by integer division when converting to the new element count. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b6d1f98 commit 9e2f77b

2 files changed

Lines changed: 11 additions & 4 deletions

File tree

lib/JLArrays/src/JLArrays.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Adapt.adapt_structure(to::Adaptor, r::Base.RefValue) = JlRefValue(adapt(to, r[])
6565
Base.sizeof(x::JLDeviceArray) = Base.elsize(x) * length(x)
6666

6767
Base.unsafe_convert(::Type{Ptr{T}}, x::JLDeviceArray{T}) where {T} =
68-
convert(Ptr{T}, pointer(x.data)) + x.offset*Base.elsize(x)
68+
convert(Ptr{T}, pointer(x.data)) + x.offset
6969

7070
# conversion of untyped data to a typed Array
7171
function typed_data(x::JLDeviceArray{T}) where {T}
@@ -92,7 +92,7 @@ end
9292
mutable struct JLArray{T, N} <: AbstractGPUArray{T, N}
9393
data::DataRef{Vector{UInt8}}
9494

95-
offset::Int # offset of the data in the buffer, in number of elements
95+
offset::Int # offset of the data in the buffer, in bytes
9696

9797
dims::Dims{N}
9898

@@ -266,7 +266,7 @@ end
266266

267267
function GPUArrays.derive(::Type{T}, a::JLArray, dims::Dims{N}, offset::Int) where {T,N}
268268
ref = copy(a.data)
269-
offset = (a.offset * Base.elsize(a)) ÷ sizeof(T) + offset
269+
offset = a.offset + offset * sizeof(T)
270270
JLArray{T,N}(ref, dims; offset)
271271
end
272272

@@ -343,7 +343,7 @@ Base.size(x::JLArray) = x.dims
343343
Base.sizeof(x::JLArray) = Base.elsize(x) * length(x)
344344

345345
Base.unsafe_convert(::Type{Ptr{T}}, x::JLArray{T}) where {T} =
346-
convert(Ptr{T}, pointer(x.data[])) + x.offset*Base.elsize(x)
346+
convert(Ptr{T}, pointer(x.data[])) + x.offset
347347

348348

349349
## interop with Julia arrays

test/testsuite/base.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,13 @@ end
442442

443443
@test collect(reinterpret(Int32, AT(fill(1f0))))[] == reinterpret(Int32, 1f0)
444444

445+
@testset "reinterpret of view with non-aligned offset" begin
446+
a = AT(Float16[1,2,3,4,5,6,7,8,9])
447+
v = view(a, 2:7) # offset of 1 Float16 = 2 bytes
448+
r = reinterpret(Float32, v) # Float32 = 4 bytes; 2 is not a multiple of 4
449+
@test Array(r) == reinterpret(Float32, @view Array(a)[2:7])
450+
end
451+
445452
@testset "reinterpret(reshape)" begin
446453
a = AT(ComplexF32[1.0f0+2.0f0*im, 2.0f0im, 3.0f0im])
447454
b = reinterpret(reshape, Float32, a)

0 commit comments

Comments
 (0)