Skip to content

Commit a8f9945

Browse files
Merge branch 'master' into csr-dispatch
2 parents 060a742 + a8cf98a commit a8f9945

3 files changed

Lines changed: 85 additions & 10 deletions

File tree

src/array.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,24 @@ const StridedCuVector{T} = StridedCuArray{T,1}
379379
const StridedCuMatrix{T} = StridedCuArray{T,2}
380380
const StridedCuVecOrMat{T} = Union{StridedCuVector{T}, StridedCuMatrix{T}}
381381

382+
"""
383+
pointer(::CuArray, [index=1]; [type=DeviceMemory])
384+
385+
Get the native address of a CUDA array object, optionally at a given location `index`.
386+
387+
The `type` argument indicates what kind of pointer to return, either a GPU-accessible
388+
`CuPtr` when passing `type=DeviceMemory`, or a CPU-accessible `Ptr` when passing
389+
`type=HostMemory`.
390+
391+
!!! note
392+
393+
The `type` argument indicates what kind of pointer to return, i.e., where the data will
394+
be accessed from. This is separate from where the data is stored. For example an array
395+
backed by `HostMemory` may be accessed from both the CPU and GPU, so it is valid to
396+
pass `type=HostMemory` or `type=DeviceMemory` (but note that accessing `HostMemory` from
397+
the GPU is typically slow). That also implies it is not valid to pass
398+
`type=UnifiedMemory`, as this does not indicate where the pointer will be accessed from.
399+
"""
382400
@inline function Base.pointer(x::StridedCuArray{T}, i::Integer=1; type=DeviceMemory) where T
383401
PT = if type == DeviceMemory
384402
CuPtr{T}

src/texture.jl

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,29 +104,65 @@ CuTextureArray(A::AbstractArray{T,N}) where {T,N} = CuTextureArray{T,N}(A)
104104

105105
## memory operations
106106

107-
function Base.copyto!(dst::CuTextureArray{T,1}, src::Union{Array{T,1}, CuArray{T,1}}) where {T}
107+
function Base.copyto!(dst::CuTextureArray{T,1}, src::Union{Array{T,1}, CuTextureArray{T,1}}) where {T}
108108
size(dst) == size(src) || throw(DimensionMismatch("source and destination sizes must match"))
109109
Base.unsafe_copyto!(pointer(dst), pointer(src), length(dst))
110110
return dst
111111
end
112112

113-
function Base.copyto!(dst::CuTextureArray{T,2}, src::Union{Array{T,2}, CuArray{T,2}}) where {T}
113+
function Base.copyto!(dst::CuTextureArray{T,1}, src::CuArray{T,1,M}) where {T, M}
114114
size(dst) == size(src) || throw(DimensionMismatch("source and destination sizes must match"))
115-
unsafe_copy2d!(pointer(dst), ArrayMemory,
116-
pointer(src), isa(src, Array) ? HostMemory : DeviceMemory,
117-
size(dst)...)
115+
if M <: Union{HostMemory, DeviceMemory}
116+
Base.unsafe_copyto!(pointer(dst), pointer(src; type=M), length(dst))
117+
else
118+
Base.unsafe_copyto!(pointer(dst), pointer(src), length(dst))
119+
end
118120
return dst
119121
end
120122

121-
function Base.copyto!(dst::CuTextureArray{T,3}, src::Union{Array{T,3}, CuArray{T,3}}) where {T}
123+
function Base.copyto!(dst::CuTextureArray{T,2}, src::Array{T,2}) where {T}
122124
size(dst) == size(src) || throw(DimensionMismatch("source and destination sizes must match"))
123-
unsafe_copy3d!(pointer(dst), ArrayMemory,
124-
pointer(src), isa(src, Array) ? HostMemory : DeviceMemory,
125-
size(dst)...)
125+
unsafe_copy2d!(pointer(dst), ArrayMemory, pointer(src), HostMemory, size(dst)...)
126126
return dst
127127
end
128128

129+
function Base.copyto!(dst::CuTextureArray{T,2}, src::CuArray{T,2,M}) where {T, M}
130+
size(dst) == size(src) || throw(DimensionMismatch("source and destination sizes must match"))
131+
if M <: Union{HostMemory, DeviceMemory}
132+
unsafe_copy2d!(pointer(dst), ArrayMemory, pointer(src; type=M), M, size(dst)...)
133+
else
134+
unsafe_copy2d!(pointer(dst), ArrayMemory, pointer(src), M, size(dst)...)
135+
end
136+
return dst
137+
end
129138

139+
function Base.copyto!(dst::CuTextureArray{T,2}, src::CuTextureArray{T,2}) where {T}
140+
size(dst) == size(src) || throw(DimensionMismatch("source and destination sizes must match"))
141+
unsafe_copy2d!(pointer(dst), ArrayMemory, pointer(src), ArrayMemory, size(dst)...)
142+
return dst
143+
end
144+
145+
function Base.copyto!(dst::CuTextureArray{T,3}, src::Array{T,3}) where {T}
146+
size(dst) == size(src) || throw(DimensionMismatch("source and destination sizes must match"))
147+
unsafe_copy3d!(pointer(dst), ArrayMemory, pointer(src), HostMemory, size(dst)...)
148+
return dst
149+
end
150+
151+
function Base.copyto!(dst::CuTextureArray{T,3}, src::CuArray{T,3,M}) where {T, M}
152+
size(dst) == size(src) || throw(DimensionMismatch("source and destination sizes must match"))
153+
if M <: Union{HostMemory, DeviceMemory}
154+
unsafe_copy3d!(pointer(dst), ArrayMemory, pointer(src; type=M), M, size(dst)...)
155+
else
156+
unsafe_copy3d!(pointer(dst), ArrayMemory, pointer(src), M, size(dst)...)
157+
end
158+
return dst
159+
end
160+
161+
function Base.copyto!(dst::CuTextureArray{T,3}, src::CuTextureArray{T,3}) where {T}
162+
size(dst) == size(src) || throw(DimensionMismatch("source and destination sizes must match"))
163+
unsafe_copy3d!(pointer(dst), ArrayMemory, pointer(src), ArrayMemory, size(dst)...)
164+
return dst
165+
end
130166

131167
#
132168
# Texture objects

test/base/texture.jl

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,29 @@ end
8282
copyto!(texarr1D, a1D)
8383
tex1D = CuTexture(texarr1D)
8484
@test Array(fetch_all(tex1D)) == a1D
85+
@test sizeof(texarr1D) == sizeof(a1D)
86+
@test eltype(texarr1D) == Float32
87+
h_arr_1D = zeros(Float32, length(a1D))
88+
Base.unsafe_copyto!(pointer(h_arr_1D), pointer(texarr1D), length(h_arr_1D))
89+
@test h_arr_1D == a1D
90+
cu_arr_1D = CUDA.zeros(Float32, length(a1D))
91+
Base.unsafe_copyto!(pointer(cu_arr_1D), pointer(texarr1D), length(cu_arr_1D))
92+
@test Array(cu_arr_1D) == a1D
8593

8694
texarr2D = CuTextureArray(a2D)
8795
tex2D = CuTexture(texarr2D)
8896
@test Array(fetch_all(tex2D)) == a2D
8997
texarr2D_2 = CuTextureArray(texarr2D)
9098
tex2D_2 = CuTexture(texarr2D_2)
9199
@test Array(fetch_all(tex2D_2)) == a2D
92-
100+
texarr2D_3 = CuTextureArray{Float32, 2}(texarr2D)
101+
tex2D_2 = CuTexture(texarr2D_3)
102+
@test Array(fetch_all(tex2D_2)) == a2D
103+
copyto!(texarr2D_3, texarr2D_2)
104+
tex2D_2 = CuTexture(texarr2D_3)
105+
@test Array(fetch_all(tex2D_2)) == a2D
106+
@test sizeof(texarr2D) == sizeof(a2D)
107+
@test eltype(texarr2D) == Float32
93108

94109
tex2D_dir = CuTexture(CuTextureArray(a2D))
95110
@test Array(fetch_all(tex2D_dir)) == a2D
@@ -100,6 +115,12 @@ end
100115
texarr3D_2 = CuTextureArray(texarr3D)
101116
tex3D_2 = CuTexture(texarr3D_2)
102117
@test Array(fetch_all(tex3D_2)) == a3D
118+
texarr3D_3 = CuTextureArray{Float32, 3}(texarr3D)
119+
copyto!(texarr2D_3, texarr2D_2)
120+
tex3D_3 = CuTexture(texarr3D_3)
121+
@test Array(fetch_all(tex3D_3)) == a3D
122+
@test sizeof(texarr3D) == sizeof(a3D)
123+
@test eltype(texarr3D) == Float32
103124
end
104125

105126
@testset "CuTexture(::CuArray)" begin

0 commit comments

Comments
 (0)