Skip to content

Commit 7e7d2c0

Browse files
authored
Merge pull request #141 from JuliaGPU/tb/move_tests
Improving tests
2 parents 0ed6336 + 2a84ed5 commit 7e7d2c0

22 files changed

+296
-353
lines changed

src/GPUArrays.jl

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
module GPUArrays
22

3+
export GPUArray, gpu_call, thread_blocks_heuristic, global_size, synchronize_threads
4+
export linear_index, @linearidx, @cartesianidx, convolution!, device, synchronize
5+
export JLArray
6+
37
using Serialization
48
using Random
59
using LinearAlgebra
610
using Printf
711

8-
import Random: rand, rand!
912
using LinearAlgebra.BLAS
10-
import Base: pointer, similar, size, convert
11-
using Base: @propagate_inbounds, @pure, RefValue
1213
using Base.Cartesian
1314

1415
using FFTW
15-
import FFTW: *, plan_ifft!, plan_fft!, plan_fft, plan_ifft, size, plan_bfft, plan_bfft!
1616

1717
include("abstractarray.jl")
1818
include("abstract_gpu_interface.jl")
@@ -34,8 +34,4 @@ include("array.jl")
3434

3535
include("testsuite.jl")
3636

37-
export GPUArray, gpu_call, thread_blocks_heuristic, global_size, synchronize_threads
38-
export linear_index, @linearidx, @cartesianidx, convolution!, device, synchronize
39-
export JLArray
40-
4137
end # module

src/abstractarray.jl

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import Base: similar, convert, _reshape, map!, copyto!, map, copy, deepcopy
2-
31
# Dense GPU Array
42
abstract type GPUArray{T, N} <: DenseArray{T, N} end
53

@@ -16,8 +14,11 @@ struct LocalMemory{T} <: GPUArray{T, 1}
1614
LocalMemory{T}(x::Integer) where T = new{T}(x)
1715
end
1816

19-
############################################
20-
# serialization
17+
18+
# input/output
19+
20+
## serialization
21+
2122
import Serialization: AbstractSerializer, serialize, deserialize, serialize_type
2223

2324
function serialize(s::AbstractSerializer, t::T) where T <: GPUArray
@@ -53,6 +54,14 @@ function to_cartesian(A, indices::Tuple)
5354
CartesianIndices(start, stop)
5455
end
5556

57+
## showing
58+
59+
Base.print_array(io::IO, x::GPUArray) = Base.print_array(io, collect(x))
60+
Base.print_array(io::IO, x::LinearAlgebra.Adjoint{<:Any,<:GPUArray}) = Base.print_array(io, LinearAlgebra.adjoint(collect(x.parent)))
61+
Base.print_array(io::IO, x::LinearAlgebra.Transpose{<:Any,<:GPUArray}) = Base.print_array(io, LinearAlgebra.transpose(collect(x.parent)))
62+
63+
64+
# memory operations
5665

5766
## basic copy methods that dispatch to unsafe_copyto! for linear copies
5867

@@ -161,8 +170,8 @@ function Base.copyto!(
161170
dest
162171
end
163172

164-
copy(x::GPUArray) = identity.(x)
165-
deepcopy(x::GPUArray) = copy(x)
173+
Base.copy(x::GPUArray) = identity.(x)
174+
Base.deepcopy(x::GPUArray) = copy(x)
166175

167176
#=
168177
reinterpret taken from julia base/array.jl
@@ -211,13 +220,13 @@ function reinterpret(::Type{T}, a::GPUArray{S}, dims::NTuple{N, Integer}) where
211220
unsafe_reinterpret(T, a, dims)
212221
end
213222

214-
function _reshape(A::GPUArray{T}, dims::Dims) where T
223+
function Base._reshape(A::GPUArray{T}, dims::Dims) where T
215224
n = length(A)
216225
prod(dims) == n || throw(DimensionMismatch("parent has $n elements, which is incompatible with size $dims"))
217226
return unsafe_reinterpret(T, A, dims)
218227
end
219228
#ambig
220-
function _reshape(A::GPUArray{T, 1}, dims::Tuple{Integer}) where T
229+
function Base._reshape(A::GPUArray{T, 1}, dims::Tuple{Integer}) where T
221230
n = Base._length(A)
222231
prod(dims) == n || throw(DimensionMismatch("parent has $n elements, which is incompatible with size $dims"))
223232
return unsafe_reinterpret(T, A, dims)

src/array.jl

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,11 @@ end
2424

2525
## getters
2626

27-
size(x::JLArray) = x.size
27+
Base.size(x::JLArray) = x.size
2828

29-
pointer(x::JLArray) = pointer(x.data)
29+
Base.pointer(x::JLArray) = pointer(x.data)
3030

3131

32-
## I/O
33-
Base.print_array(io::IO, x::GPUArray) = Base.print_array(io, collect(x))B
34-
Base.print_array(io::IO, x::LinearAlgebra.Adjoint{<:Any,<:GPUArray}) = Base.print_array(io, LinearAlgebra.adjoint(collect(x.parent)))
35-
Base.print_array(io::IO, x::LinearAlgebra.Transpose{<:Any,<:GPUArray}) = Base.print_array(io, LinearAlgebra.transpose(collect(x.parent)))
36-
3732
## other
3833

3934
"""
@@ -45,7 +40,7 @@ end
4540

4641
to_device(state, x::JLArray) = x.data
4742
to_device(state, x::Tuple) = to_device.(Ref(state), x)
48-
to_device(state, x::RefValue{<: JLArray}) = RefValue(to_device(state, x[]))
43+
to_device(state, x::Base.RefValue{<: JLArray}) = Base.RefValue(to_device(state, x[]))
4944
to_device(state, x) = x
5045
# creates a `local` vector for each thread group
5146
to_device(state, x::LocalMemory{T}) where T = LocalMem(ntuple(i-> Vector{T}(x.size), blockdim_x(state)))
@@ -54,11 +49,10 @@ to_blocks(state, x) = x
5449
# unpacks local memory for each block
5550
to_blocks(state, x::LocalMem) = x.x[blockidx_x(state)]
5651

57-
similar(::Type{<: JLArray}, ::Type{T}, size::Base.Dims{N}) where {T, N} = JLArray{T, N}(size)
52+
Base.similar(::Type{<: JLArray}, ::Type{T}, size::Base.Dims{N}) where {T, N} = JLArray{T, N}(size)
5853

59-
function unsafe_reinterpret(::Type{T}, A::JLArray{ET}, size::NTuple{N, Integer}) where {T, ET, N}
60-
JLArray(Array(reshape(reinterpret(T, A.data), size)), size)
61-
end
54+
unsafe_reinterpret(::Type{T}, A::JLArray, size::Tuple) where T =
55+
reshape(reinterpret(T, A.data), size)
6256

6357
function Base.unsafe_copyto!(dest::Array{T}, d_offset::Integer,
6458
source::JLArray{T}, s_offset::Integer,
@@ -126,7 +120,6 @@ function AbstractDeviceArray(ptr::Array, shape::Vararg{Integer, N}) where N
126120
reshape(ptr, shape)
127121
end
128122

129-
130123
function _gpu_call(f, A::JLArray, args::Tuple, blocks_threads::Tuple{T, T}) where T <: NTuple{N, Integer} where N
131124
blocks, threads = blocks_threads
132125
idx = ntuple(i-> 1, length(blocks))
@@ -176,32 +169,21 @@ end
176169
blas_module(::JLArray) = LinearAlgebra.BLAS
177170
blasbuffer(A::JLArray) = A.data
178171

179-
# defining our own plan type is the easiest way to pass around the plans in Base interface
172+
# defining our own plan type is the easiest way to pass around the plans in FFTW interface
180173
# without ambiguities
181174

182175
struct FFTPlan{T}
183176
p::T
184177
end
185-
function plan_fft(A::JLArray; kw_args...)
186-
FFTPlan(plan_fft(A.data; kw_args...))
187-
end
188-
function plan_fft!(A::JLArray; kw_args...)
189-
FFTPlan(plan_fft!(A.data; kw_args...))
190-
end
191-
function plan_bfft!(A::JLArray; kw_args...)
192-
FFTPlan(plan_bfft!(A.data; kw_args...))
193-
end
194-
function plan_bfft(A::JLArray; kw_args...)
195-
FFTPlan(plan_bfft(A.data; kw_args...))
196-
end
197-
function plan_ifft!(A::JLArray; kw_args...)
198-
FFTPlan(plan_ifft!(A.data; kw_args...))
199-
end
200-
function plan_ifft(A::JLArray; kw_args...)
201-
FFTPlan(plan_ifft(A.data; kw_args...))
202-
end
203178

204-
function *(plan::FFTPlan, A::JLArray)
179+
FFTW.plan_fft(A::JLArray; kw_args...) = FFTPlan(plan_fft(A.data; kw_args...))
180+
FFTW.plan_fft!(A::JLArray; kw_args...) = FFTPlan(plan_fft!(A.data; kw_args...))
181+
FFTW.plan_bfft!(A::JLArray; kw_args...) = FFTPlan(plan_bfft!(A.data; kw_args...))
182+
FFTW.plan_bfft(A::JLArray; kw_args...) = FFTPlan(plan_bfft(A.data; kw_args...))
183+
FFTW.plan_ifft!(A::JLArray; kw_args...) = FFTPlan(plan_ifft!(A.data; kw_args...))
184+
FFTW.plan_ifft(A::JLArray; kw_args...) = FFTPlan(plan_ifft(A.data; kw_args...))
185+
186+
function Base.:(*)(plan::FFTPlan, A::JLArray)
205187
x = plan.p * A.data
206188
JLArray(x)
207189
end

src/base.jl

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
import Base: count, map!, permutedims!, cat_t, vcat, hcat
2-
using Base: @pure
3-
41
allequal(x) = true
52
allequal(x, y, z...) = x == y && allequal(y, z...)
6-
function map!(f, y::GPUArray, xs::GPUArray...)
3+
function Base.map!(f, y::GPUArray, xs::GPUArray...)
74
@assert allequal(size.((y, xs...))...)
85
return y .= f.(xs...)
96
end
10-
function map(f, y::GPUArray, xs::GPUArray...)
7+
function Base.map(f, y::GPUArray, xs::GPUArray...)
118
@assert allequal(size.((y, xs...))...)
129
return f.(y, xs...)
1310
end
1411

1512
# Break ambiguities with base
16-
map!(f, y::GPUArray) =
13+
Base.map!(f, y::GPUArray) =
1714
invoke(map!, Tuple{Any,GPUArray,Vararg{GPUArray}}, f, y)
18-
map!(f, y::GPUArray, x::GPUArray) =
15+
Base.map!(f, y::GPUArray, x::GPUArray) =
1916
invoke(map!, Tuple{Any,GPUArray, Vararg{GPUArray}}, f, y, x)
20-
map!(f, y::GPUArray, x1::GPUArray, x2::GPUArray) =
17+
Base.map!(f, y::GPUArray, x1::GPUArray, x2::GPUArray) =
2118
invoke(map!, Tuple{Any,GPUArray, Vararg{GPUArray}}, f, y, x1, x2)
2219

2320

@@ -49,36 +46,36 @@ map!(f, y::GPUArray, x1::GPUArray, x2::GPUArray) =
4946
# return dest
5047
# end
5148
#
52-
# function cat_t(dims::Integer, T::Type, x::GPUArray, xs::GPUArray...)
49+
# function Base.cat_t(dims::Integer, T::Type, x::GPUArray, xs::GPUArray...)
5350
# catdims = Base.dims2cat(dims)
5451
# shape = Base.cat_shape(catdims, (), size.((x, xs...))...)
5552
# dest = Base.cat_similar(x, T, shape)
5653
# _cat(dims, dest, x, xs...)
5754
# end
5855
#
59-
# vcat(xs::GPUArray...) = cat(1, xs...)
60-
# hcat(xs::GPUArray...) = cat(2, xs...)
56+
# Base.vcat(xs::GPUArray...) = cat(1, xs...)
57+
# Base.hcat(xs::GPUArray...) = cat(2, xs...)
6158

6259

6360
# Base functions that are sadly not fit for the the GPU yet (they only work for Int64)
64-
@pure @inline function gpu_ind2sub(A::AbstractArray, ind::T) where T
61+
Base.@pure @inline function gpu_ind2sub(A::AbstractArray, ind::T) where T
6562
_ind2sub(size(A), ind - T(1))
6663
end
67-
@pure @inline function gpu_ind2sub(dims::NTuple{N}, ind::T) where {N, T}
64+
Base.@pure @inline function gpu_ind2sub(dims::NTuple{N}, ind::T) where {N, T}
6865
_ind2sub(NTuple{N, T}(dims), ind - T(1))
6966
end
70-
@pure @inline _ind2sub(::Tuple{}, ind::T) where {T} = (ind + T(1),)
71-
@pure @inline function _ind2sub(indslast::NTuple{1}, ind::T) where T
67+
Base.@pure @inline _ind2sub(::Tuple{}, ind::T) where {T} = (ind + T(1),)
68+
Base.@pure @inline function _ind2sub(indslast::NTuple{1}, ind::T) where T
7269
((ind + T(1)),)
7370
end
74-
@pure @inline function _ind2sub(inds, ind::T) where T
71+
Base.@pure @inline function _ind2sub(inds, ind::T) where T
7572
r1 = inds[1]
7673
indnext = div(ind, r1)
7774
f = T(1); l = r1
7875
(ind-l*indnext+f, _ind2sub(Base.tail(inds), indnext)...)
7976
end
8077

81-
@pure function gpu_sub2ind(dims::NTuple{N}, I::NTuple{N2, T}) where {N, N2, T}
78+
Base.@pure function gpu_sub2ind(dims::NTuple{N}, I::NTuple{N2, T}) where {N, N2, T}
8279
Base.@_inline_meta
8380
_sub2ind(NTuple{N, T}(dims), T(1), T(1), I...)
8481
end

src/construction.jl

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
import Base: fill!, similar, zeros, ones, fill
2-
3-
4-
5-
function fill(X::Type{<: GPUArray}, val::T, dims::NTuple{N, Integer}) where {T, N}
1+
function Base.fill(X::Type{<: GPUArray}, val::T, dims::NTuple{N, Integer}) where {T, N}
62
res = similar(X, T, dims)
73
fill!(res, val)
84
end
9-
function fill(X::Type{<: GPUArray{T}}, val, dims::NTuple{N, Integer}) where {T, N}
5+
function Base.fill(X::Type{<: GPUArray{T}}, val, dims::NTuple{N, Integer}) where {T, N}
106
res = similar(X, T, dims)
117
fill!(res, convert(T, val))
128
end
13-
function fill!(A::GPUArray{T}, x) where T
9+
function Base.fill!(A::GPUArray{T}, x) where T
1410
gpu_call(A, (A, convert(T, x))) do state, a, val
1511
idx = @linearidx(a, state)
1612
@inbounds a[idx] = val
@@ -19,8 +15,8 @@ function fill!(A::GPUArray{T}, x) where T
1915
A
2016
end
2117

22-
zeros(T::Type{<: GPUArray}, dims::NTuple{N, Integer}) where N = fill(T, zero(eltype(T)), dims)
23-
ones(T::Type{<: GPUArray}, dims::NTuple{N, Integer}) where N = fill(T, one(eltype(T)), dims)
18+
Base.zeros(T::Type{<: GPUArray}, dims::NTuple{N, Integer}) where N = fill(T, zero(eltype(T)), dims)
19+
Base.ones(T::Type{<: GPUArray}, dims::NTuple{N, Integer}) where N = fill(T, one(eltype(T)), dims)
2420

2521
function uniformscaling_kernel(state, res::AbstractArray{T}, stride, s::UniformScaling) where T
2622
i = linear_index(state)
@@ -43,10 +39,10 @@ end
4339
(T::Type{<: GPUArray{X} where X})(dims::NTuple{N, Integer}) where N = similar(T, eltype(T), dims)
4440
(T::Type{<: GPUArray{X} where X})(::UndefInitializer, dims::NTuple{N, Integer}) where N = similar(T, eltype(T), dims)
4541

46-
similar(x::X, ::Type{T}, size::Base.Dims{N}) where {X <: GPUArray, T, N} = similar(X, T, size)
47-
similar(::Type{X}, ::Type{T}, size::NTuple{N, Base.OneTo{Int}}) where {X <: GPUArray, T, N} = similar(X, T, length.(size))
42+
Base.similar(x::X, ::Type{T}, size::Base.Dims{N}) where {X <: GPUArray, T, N} = similar(X, T, size)
43+
Base.similar(::Type{X}, ::Type{T}, size::NTuple{N, Base.OneTo{Int}}) where {X <: GPUArray, T, N} = similar(X, T, length.(size))
4844

49-
convert(AT::Type{<: GPUArray{T, N}}, A::GPUArray{T, N}) where {T, N} = A
45+
Base.convert(AT::Type{<: GPUArray{T, N}}, A::GPUArray{T, N}) where {T, N} = A
5046

5147
function indexstyle(x::T) where T
5248
style = try
@@ -73,7 +69,7 @@ eltype_or(::Type{<: GPUArray}, or) = or
7369
eltype_or(::Type{<: GPUArray{T}}, or) where T = T
7470
eltype_or(::Type{<: GPUArray{T, N}}, or) where {T, N} = T
7571

76-
function convert(AT::Type{<: GPUArray}, iter)
72+
function Base.convert(AT::Type{<: GPUArray}, iter)
7773
isize = Base.IteratorSize(iter)
7874
style = indexstyle(iter)
7975
ettrait = Base.IteratorEltype(iter)
@@ -87,17 +83,18 @@ function convert(AT::Type{<: GPUArray}, iter)
8783
end
8884
end
8985

90-
function convert(AT::Type{<: GPUArray{T, N}}, A::DenseArray{T, N}) where {T, N}
86+
function Base.convert(AT::Type{<: GPUArray{T, N}}, A::DenseArray{T, N}) where {T, N}
9187
copyto!(AT(Base.size(A)), A)
9288
end
9389

94-
function convert(AT::Type{<: GPUArray{T1}}, A::DenseArray{T2, N}) where {T1, T2, N}
90+
function Base.convert(AT::Type{<: GPUArray{T1}}, A::DenseArray{T2, N}) where {T1, T2, N}
9591
copyto!(similar(AT, T1, size(A)), convert(Array{T1, N}, A))
9692
end
97-
function convert(AT::Type{<: GPUArray}, A::DenseArray{T2, N}) where {T2, N}
93+
94+
function Base.convert(AT::Type{<: GPUArray}, A::DenseArray{T2, N}) where {T2, N}
9895
copyto!(similar(AT, T2, size(A)), A)
9996
end
10097

101-
function convert(AT::Type{Array{T, N}}, A::GPUArray{CT, CN}) where {T, N, CT, CN}
98+
function Base.convert(AT::Type{Array{T, N}}, A::GPUArray{CT, CN}) where {T, N, CT, CN}
10299
convert(AT, copyto!(Array{CT, CN}(undef, size(A)), A))
103100
end

src/linalg.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ function LinearAlgebra.permutedims!(dest::GPUArray, src::GPUArray, perm::NTuple{
9090
end
9191

9292

93-
function copyto!(A::AbstractArray, B::Adjoint{T, <: GPUArray}) where T
93+
function Base.copyto!(A::AbstractArray, B::Adjoint{T, <: GPUArray}) where T
9494
copyto!(A, Adjoint(Array(B.parent)))
9595
end
96-
function copyto!(A::GPUArray, B::Adjoint{T, <: GPUArray}) where T
96+
function Base.copyto!(A::GPUArray, B::Adjoint{T, <: GPUArray}) where T
9797
transpose!(A, B.parent)
9898
end

src/random.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ let rand_state_dict = Dict()
5555
end
5656
end
5757
end
58-
function rand!(A::GPUArray{T}) where T <: Number
58+
function Random.rand!(A::GPUArray{T}) where T <: Number
5959
rstates = cached_state(A)
6060
gpu_call(A, (rstates, A,)) do state, randstates, a
6161
idx = linear_index(state)
@@ -66,14 +66,14 @@ function rand!(A::GPUArray{T}) where T <: Number
6666
A
6767
end
6868

69-
rand(X::Type{<: GPUArray}, i::Integer...) = rand(X, Float32, i...)
70-
rand(X::Type{<: GPUArray}, size::NTuple{N, Int}) where N = rand(X, Float32, size...)
71-
rand(X::Type{<: GPUArray{T}}, i::Integer...) where T = rand(X, T, i...)
72-
rand(X::Type{<: GPUArray{T}}, size::NTuple{N, Int}) where {T, N} = rand(X, T, size...)
73-
rand(X::Type{<: GPUArray{T, N}}, size::NTuple{N, Integer}) where {T, N} = rand(X, T, size...)
74-
rand(X::Type{<: GPUArray{T, N}}, size::NTuple{N, Int}) where {T, N} = rand(X, T, size...)
69+
Random.rand(X::Type{<: GPUArray}, i::Integer...) = rand(X, Float32, i...)
70+
Random.rand(X::Type{<: GPUArray}, size::NTuple{N, Int}) where N = rand(X, Float32, size...)
71+
Random.rand(X::Type{<: GPUArray{T}}, i::Integer...) where T = rand(X, T, i...)
72+
Random.rand(X::Type{<: GPUArray{T}}, size::NTuple{N, Int}) where {T, N} = rand(X, T, size...)
73+
Random.rand(X::Type{<: GPUArray{T, N}}, size::NTuple{N, Integer}) where {T, N} = rand(X, T, size...)
74+
Random.rand(X::Type{<: GPUArray{T, N}}, size::NTuple{N, Int}) where {T, N} = rand(X, T, size...)
7575

76-
function rand(X::Type{<: GPUArray}, ::Type{ET}, size::Integer...) where ET
76+
function Random.rand(X::Type{<: GPUArray}, ::Type{ET}, size::Integer...) where ET
7777
A = similar(X, ET, size)
7878
rand!(A)
7979
end

0 commit comments

Comments
 (0)