diff --git a/src/host/construction.jl b/src/host/construction.jl index bb3da24e..4bf230d3 100644 --- a/src/host/construction.jl +++ b/src/host/construction.jl @@ -1,5 +1,14 @@ # convenience and indirect construction +# conversions from CPU arrays rely on constructors +Base.convert(::Type{T}, a::AbstractArray) where {T<:AbstractGPUArray} = a isa T ? a : T(a) +# TODO: can we implement constructors to and from ::AbstractArray here? by calling the undef +# constructor and doing a `copyto!`. this is tricky, due to ambiguities, and no easy +# way to go from <:AbstractGPUArray{T,N} to e.g. CuArray{S,N} + + +## convenience constructors + function Base.fill!(A::AnyGPUArray{T}, x) where T length(A) == 0 && return A gpu_call(A, convert(T, x)) do ctx, a, val @@ -49,61 +58,3 @@ end Base.one(x::AbstractGPUMatrix{T}) where {T} = _one(one(T), x) Base.oneunit(x::AbstractGPUMatrix{T}) where {T} = _one(oneunit(T), x) - - -## collect & convert - -function indexstyle(x::T) where T - style = try - Base.IndexStyle(x) - catch - nothing - end - style -end - -function collect_kernel(ctx::AbstractKernelContext, A, iter, ::IndexCartesian) - idx = @cartesianidx(A) - @inbounds A[idx...] = iter[idx...] - return -end - -function collect_kernel(ctx::AbstractKernelContext, A, iter, ::IndexLinear) - idx = linear_index(ctx) - @inbounds A[idx] = iter[idx] - return -end - -eltype_or(::Type{<: AbstractGPUArray}, or) = or -eltype_or(::Type{<: AbstractGPUArray{T}}, or) where T = T -eltype_or(::Type{<: AbstractGPUArray{T, N}}, or) where {T, N} = T - -function Base.convert(AT::Type{<: AbstractGPUArray}, iter) - isize = Base.IteratorSize(iter) - style = indexstyle(iter) - ettrait = Base.IteratorEltype(iter) - if isbits(iter) && isa(isize, Base.HasShape) && style != nothing && isa(ettrait, Base.HasEltype) - # We can collect on the GPU - A = similar(AT, eltype_or(AT, eltype(iter)), size(iter)) - gpu_call(collect_kernel, A, iter, style) - A - else - convert(AT, collect(iter)) - end -end - -function Base.convert(AT::Type{<: AbstractGPUArray{T, N}}, A::DenseArray{T, N}) where {T, N} - copyto!(AT(undef, size(A)), A) -end - -function Base.convert(AT::Type{<: AbstractGPUArray{T1}}, A::DenseArray{T2, N}) where {T1, T2, N} - copyto!(similar(AT, size(A)), convert(Array{T1, N}, A)) -end - -function Base.convert(AT::Type{<: AbstractGPUArray}, A::DenseArray{T2, N}) where {T2, N} - copyto!(similar(AT{T2}, size(A)), A) -end - -function Base.convert(AT::Type{Array{T, N}}, A::AbstractGPUArray{CT, CN}) where {T, N, CT, CN} - convert(AT, copyto!(Array{CT, CN}(undef, size(A)), A)) -end