Skip to content

Commit 8273529

Browse files
authored
Merge pull request #23750 from JuliaLang/kf/reinterpretarray
Implement ReinterpretArray
2 parents 19b3ca7 + 0054051 commit 8273529

38 files changed

+767
-225
lines changed

NEWS.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,9 @@ This section lists changes that do not have deprecation warnings.
243243
* All command line arguments passed via `-e`, `-E`, and `-L` will be executed in the order
244244
given on the command line ([#23665]).
245245

246+
* The return type of `reinterpret` has changed to `ReinterpretArray`. `reinterpret` on sparse
247+
arrays has been discontinued.
248+
246249
Library improvements
247250
--------------------
248251

@@ -313,6 +316,10 @@ Library improvements
313316
* New function `equalto(x)`, which returns a function that compares its argument to `x`
314317
using `isequal` ([#23812]).
315318

319+
* `reinterpret` now works on any AbstractArray using the new `ReinterpretArray` type.
320+
This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting
321+
arrays with different alignment requirements (removed in 0.6) is once again allowed ([#23750]).
322+
316323
Compiler/Runtime improvements
317324
-----------------------------
318325

@@ -511,6 +518,11 @@ Deprecated or removed
511518
* `find` functions now operate only on booleans by default. To look for non-zeros, use
512519
`x->x!=0` or `!iszero` ([#23120]).
513520

521+
* The ability of `reinterpret` to yield `Array`s of different type than the underlying storage
522+
has been removed. The `reinterpret` function is still available, but now returns a
523+
`ReinterpretArray`. The three argument form of `reinterpret` that implicitly reshapes
524+
has been deprecated ([#23750]).
525+
514526
Command-line option changes
515527
---------------------------
516528

base/array.jl

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -218,33 +218,6 @@ original.
218218
"""
219219
copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)
220220

221-
function reinterpret(::Type{T}, a::Array{S,1}) where T where S
222-
nel = Int(div(length(a) * sizeof(S), sizeof(T)))
223-
# TODO: maybe check that remainder is zero?
224-
return reinterpret(T, a, (nel,))
225-
end
226-
227-
function reinterpret(::Type{T}, a::Array{S}) where T where S
228-
if sizeof(S) != sizeof(T)
229-
throw(ArgumentError("result shape not specified"))
230-
end
231-
reinterpret(T, a, size(a))
232-
end
233-
234-
function reinterpret(::Type{T}, a::Array{S}, dims::NTuple{N,Int}) where T where S where N
235-
function throwbits(::Type{S}, ::Type{T}, ::Type{U}) where {S,T,U}
236-
@_noinline_meta
237-
throw(ArgumentError("cannot reinterpret Array{$(S)} to ::Type{Array{$(T)}}, type $(U) is not a bits type"))
238-
end
239-
isbits(T) || throwbits(S, T, T)
240-
isbits(S) || throwbits(S, T, S)
241-
nel = div(length(a) * sizeof(S), sizeof(T))
242-
if prod(dims) != nel
243-
_throw_dmrsa(dims, nel)
244-
end
245-
ccall(:jl_reshape_array, Array{T,N}, (Any, Any, Any), Array{T,N}, a, dims)
246-
end
247-
248221
# reshaping to same # of dimensions
249222
function reshape(a::Array{T,N}, dims::NTuple{N,Int}) where T where N
250223
if prod(dims) != length(a)

base/deprecated.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,10 @@ end
18551855
# also remove deprecation warnings in find* functions in array.jl, sparse/sparsematrix.jl,
18561856
# and sparse/sparsevector.jl.
18571857

1858+
# issue #22849
1859+
@deprecate reinterpret(::Type{T}, a::Array{S}, dims::NTuple{N,Int}) where {T, S, N} reshape(reinterpret(T, vec(a)), dims)
1860+
@deprecate reinterpret(::Type{T}, a::SparseMatrixCSC{S}, dims::NTuple{N,Int}) where {T, S, N} reinterpret(T, reshape(a, dims))
1861+
18581862
# END 0.7 deprecations
18591863

18601864
# BEGIN 1.0 deprecations

base/essentials.jl

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,20 +321,12 @@ unsafe_convert(::Type{P}, x::Ptr) where {P<:Ptr} = convert(P, x)
321321
reinterpret(type, A)
322322
323323
Change the type-interpretation of a block of memory.
324-
For arrays, this constructs an array with the same binary data as the given
324+
For arrays, this constructs a view of the array with the same binary data as the given
325325
array, but with the specified element type.
326326
For example,
327327
`reinterpret(Float32, UInt32(7))` interprets the 4 bytes corresponding to `UInt32(7)` as a
328328
[`Float32`](@ref).
329329
330-
!!! warning
331-
332-
It is not allowed to `reinterpret` an array to an element type with a larger alignment then
333-
the alignment of the array. For a normal `Array`, this is the alignment of its element type.
334-
For a reinterpreted array, this is the alignment of the `Array` it was reinterpreted from.
335-
For example, `reinterpret(UInt32, UInt8[0, 0, 0, 0])` is not allowed but
336-
`reinterpret(UInt32, reinterpret(UInt8, Float32[1.0]))` is allowed.
337-
338330
# Examples
339331
```jldoctest
340332
julia> reinterpret(Float32, UInt32(7))

base/inference.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,8 @@ add_tfunc(sdiv_int, 2, 2, math_tfunc, 30)
504504
add_tfunc(udiv_int, 2, 2, math_tfunc, 30)
505505
add_tfunc(srem_int, 2, 2, math_tfunc, 30)
506506
add_tfunc(urem_int, 2, 2, math_tfunc, 30)
507+
add_tfunc(add_ptr, 2, 2, math_tfunc, 1)
508+
add_tfunc(sub_ptr, 2, 2, math_tfunc, 1)
507509
add_tfunc(neg_float, 1, 1, math_tfunc, 1)
508510
add_tfunc(add_float, 2, 2, math_tfunc, 1)
509511
add_tfunc(sub_float, 2, 2, math_tfunc, 1)

base/io.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,15 +267,16 @@ readlines(s=STDIN; chomp::Bool=true) = collect(eachline(s, chomp=chomp))
267267

268268
## byte-order mark, ntoh & hton ##
269269

270-
let endian_boms = reinterpret(UInt8, UInt32[0x01020304])
270+
let a = UInt32[0x01020304]
271+
endian_bom = @gc_preserve a unsafe_load(convert(Ptr{UInt8}, pointer(a)))
271272
global ntoh, hton, ltoh, htol
272-
if endian_boms == UInt8[1:4;]
273+
if endian_bom == 0x01
273274
ntoh(x) = x
274275
hton(x) = x
275276
ltoh(x) = bswap(x)
276277
htol(x) = bswap(x)
277278
const global ENDIAN_BOM = 0x01020304
278-
elseif endian_boms == UInt8[4:-1:1;]
279+
elseif endian_bom == 0x04
279280
ntoh(x) = bswap(x)
280281
hton(x) = bswap(x)
281282
ltoh(x) = x

base/linalg/factorization.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ Base.isequal(F::T, G::T) where {T<:Factorization} = all(f -> isequal(getfield(F,
5656
# With a real lhs and complex rhs with the same precision, we can reinterpret
5757
# the complex rhs as a real rhs with twice the number of columns
5858
function (\)(F::Factorization{T}, B::VecOrMat{Complex{T}}) where T<:BlasReal
59-
c2r = reshape(transpose(reinterpret(T, B, (2, length(B)))), size(B, 1), 2*size(B, 2))
59+
c2r = reshape(transpose(reinterpret(T, reshape(B, (1, length(B))))), size(B, 1), 2*size(B, 2))
6060
x = A_ldiv_B!(F, c2r)
61-
return reinterpret(Complex{T}, transpose(reshape(x, div(length(x), 2), 2)), _ret_size(F, B))
61+
return reshape(collect(reinterpret(Complex{T}, transpose(reshape(x, div(length(x), 2), 2)))), _ret_size(F, B))
6262
end
6363

6464
for (f1, f2) in ((:\, :A_ldiv_B!),

base/linalg/lq.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,10 @@ end
267267
# With a real lhs and complex rhs with the same precision, we can reinterpret
268268
# the complex rhs as a real rhs with twice the number of columns
269269
function (\)(F::LQ{T}, B::VecOrMat{Complex{T}}) where T<:BlasReal
270-
c2r = reshape(transpose(reinterpret(T, B, (2, length(B)))), size(B, 1), 2*size(B, 2))
270+
c2r = reshape(transpose(reinterpret(T, reshape(B, (1, length(B))))), size(B, 1), 2*size(B, 2))
271271
x = A_ldiv_B!(F, c2r)
272-
return reinterpret(Complex{T}, transpose(reshape(x, div(length(x), 2), 2)),
273-
isa(B, AbstractVector) ? (size(F,2),) : (size(F,2), size(B,2)))
272+
return reshape(collect(reinterpret(Complex{T}, transpose(reshape(x, div(length(x), 2), 2)))),
273+
isa(B, AbstractVector) ? (size(F,2),) : (size(F,2), size(B,2)))
274274
end
275275

276276

base/linalg/matmul.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ A_mul_B!(y::StridedVector{T}, A::StridedVecOrMat{T}, x::StridedVector{T}) where
9090
for elty in (Float32,Float64)
9191
@eval begin
9292
function A_mul_B!(y::StridedVector{Complex{$elty}}, A::StridedVecOrMat{Complex{$elty}}, x::StridedVector{$elty})
93-
Afl = reinterpret($elty,A,(2size(A,1),size(A,2)))
93+
Afl = reinterpret($elty,A)
9494
yfl = reinterpret($elty,y)
9595
gemv!(yfl,'N',Afl,x)
9696
return y
@@ -148,8 +148,8 @@ A_mul_B!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) wher
148148
for elty in (Float32,Float64)
149149
@eval begin
150150
function A_mul_B!(C::StridedMatrix{Complex{$elty}}, A::StridedVecOrMat{Complex{$elty}}, B::StridedVecOrMat{$elty})
151-
Afl = reinterpret($elty, A, (2size(A,1), size(A,2)))
152-
Cfl = reinterpret($elty, C, (2size(C,1), size(C,2)))
151+
Afl = reinterpret($elty, A)
152+
Cfl = reinterpret($elty, C)
153153
gemm_wrapper!(Cfl, 'N', 'N', Afl, B)
154154
return C
155155
end
@@ -190,8 +190,8 @@ A_mul_Bt!(C::StridedMatrix{T}, A::StridedVecOrMat{T}, B::StridedVecOrMat{T}) whe
190190
for elty in (Float32,Float64)
191191
@eval begin
192192
function A_mul_Bt!(C::StridedMatrix{Complex{$elty}}, A::StridedVecOrMat{Complex{$elty}}, B::StridedVecOrMat{$elty})
193-
Afl = reinterpret($elty, A, (2size(A,1), size(A,2)))
194-
Cfl = reinterpret($elty, C, (2size(C,1), size(C,2)))
193+
Afl = reinterpret($elty, A)
194+
Cfl = reinterpret($elty, C)
195195
gemm_wrapper!(Cfl, 'N', 'T', Afl, B)
196196
return C
197197
end

base/linalg/qr.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,15 +918,15 @@ function (\)(A::Union{QR{T},QRCompactWY{T},QRPivoted{T}}, BIn::VecOrMat{Complex{
918918
# |z2|z4| -> |y1|y2|y3|y4| -> |x2|y2| -> |x2|y2|x4|y4|
919919
# |x3|y3|
920920
# |x4|y4|
921-
B = reshape(transpose(reinterpret(T, BIn, (2, length(BIn)))), size(BIn, 1), 2*size(BIn, 2))
921+
B = reshape(transpose(reinterpret(T, reshape(BIn, (1, length(BIn))))), size(BIn, 1), 2*size(BIn, 2))
922922

923923
X = A_ldiv_B!(A, _append_zeros(B, T, n))
924924

925925
# |z1|z3| reinterpret |x1|x2|x3|x4| transpose |x1|y1| reshape |x1|y1|x3|y3|
926926
# |z2|z4| <- |y1|y2|y3|y4| <- |x2|y2| <- |x2|y2|x4|y4|
927927
# |x3|y3|
928928
# |x4|y4|
929-
XX = reinterpret(Complex{T}, transpose(reshape(X, div(length(X), 2), 2)), _ret_size(A, BIn))
929+
XX = reshape(collect(reinterpret(Complex{T}, transpose(reshape(X, div(length(X), 2), 2)))), _ret_size(A, BIn))
930930
return _cut_B(XX, 1:n)
931931
end
932932

0 commit comments

Comments
 (0)