20
20
# iteration (see, e.g., CUDA.jl#145)
21
21
@inline function Broadcast. copy (bc:: Broadcasted{<:AbstractGPUArrayStyle} )
22
22
ElType = Broadcast. combine_eltypes (bc. f, bc. args)
23
- if ElType == Union{}
24
- # using a Union{} eltype would fail early, during GPU array construction,
25
- # so use Nothing instead to give the error a chance to be thrown dynamically.
26
- ElType = Nothing
23
+ if ElType == Union{} || ! Base. allocatedinline (ElType)
24
+ # a Union{} or non-isbits eltype would fail early, during GPU array construction,
25
+ # so use a special marker to give the error a chance to be thrown during compilation
26
+ # or even dynamically, and pick that marker up afterwards to throw an error.
27
+ ElType = BrokenBroadcast{ElType}
27
28
end
28
29
copyto! (similar (bc, ElType), bc)
29
30
end
30
31
32
+ struct BrokenBroadcast{T} end
33
+ Base. convert (:: Type{BrokenBroadcast{T}} , x) where T = BrokenBroadcast {T} ()
34
+ Base. convert (:: Type{BrokenBroadcast{T}} , x:: BrokenBroadcast{T} ) where T = x
35
+ Base. eltype (:: Type{BrokenBroadcast{T}} ) where T = T
36
+
31
37
@inline function Base. materialize! (:: Style , dest, bc:: Broadcasted ) where {Style<: AbstractGPUArrayStyle }
32
38
return _copyto! (dest, instantiate (Broadcasted {Style} (bc. f, bc. args, axes (dest))))
33
39
end
76
82
gpu_call (broadcast_kernel, dest, bc, config. elements_per_thread;
77
83
threads= config. threads, blocks= config. blocks)
78
84
85
+ if eltype (dest) <: BrokenBroadcast
86
+ throw (ArgumentError (" Broadcast operation resulting in $(eltype (eltype (dest))) is not GPU compatible" ))
87
+ end
88
+
79
89
return dest
80
90
end
81
91
92
+
82
93
# # map
83
94
84
95
allequal (x) = true
@@ -97,7 +108,10 @@ function Base.map(f, x::AnyGPUArray, xs::AbstractArray...)
97
108
98
109
# construct a broadcast to figure out the destination container
99
110
ElType = Broadcast. combine_eltypes (f, xs)
100
- isbitstype (ElType) || error (" Cannot map function returning non-isbits $ElType ." )
111
+ if ElType == Union{} || ! Base. allocatedinline (ElType)
112
+ # see `broadcast`
113
+ ElType = BrokenBroadcast{ElType}
114
+ end
101
115
dest = similar (x, ElType, common_length)
102
116
103
117
return map! (f, dest, xs... )
@@ -138,5 +152,9 @@ function Base.map!(f, dest::AnyGPUArray, xs::AbstractArray...)
138
152
gpu_call (map_kernel, dest, bc, config. elements_per_thread;
139
153
threads= config. threads, blocks= config. blocks)
140
154
155
+ if eltype (dest) <: BrokenBroadcast
156
+ throw (ArgumentError (" Map operation resulting in $(eltype (eltype (dest))) is not GPU compatible" ))
157
+ end
158
+
141
159
return dest
142
160
end
0 commit comments