3
3
module Broadcast
4
4
5
5
using Base. Cartesian
6
- using Base: promote_op, promote_eltype, promote_eltype_op, @get! , _msk_end, unsafe_bitgetindex, shape, linearindices, allocate_for , tail, dimlength
6
+ using Base: promote_op, promote_eltype, promote_eltype_op, @get! , _msk_end, unsafe_bitgetindex, linearindices, to_shape , tail, dimlength, OneTo
7
7
import Base: .+ , .- , .* , ./ , .\ , .// , .== , .< , .!= , .<= , .÷ , .% , .<< , .>> , .^
8
8
export broadcast, broadcast!, bitbroadcast
9
9
export broadcast_getindex, broadcast_setindex!
@@ -13,8 +13,8 @@ export broadcast_getindex, broadcast_setindex!
13
13
# # Calculate the broadcast shape of the arguments, or error if incompatible
14
14
# array inputs
15
15
broadcast_shape () = ()
16
- broadcast_shape (A) = shape (A)
17
- @inline broadcast_shape (A, B... ) = broadcast_shape ((), shape (A), map (shape , B)... )
16
+ broadcast_shape (A) = indices (A)
17
+ @inline broadcast_shape (A, B... ) = broadcast_shape ((), indices (A), map (indices , B)... )
18
18
# shape inputs
19
19
broadcast_shape (shape:: Tuple ) = shape
20
20
@inline broadcast_shape (shape:: Tuple , shape1:: Tuple , shapes:: Tuple... ) = broadcast_shape (_bcs ((), shape, shape1), shapes... )
@@ -39,8 +39,10 @@ _bcsm(a::Number, b::Number) = a == b || b == 1
39
39
# # Check that all arguments are broadcast compatible with shape
40
40
# # Check that all arguments are broadcast compatible with shape
41
41
# comparing one input against a shape
42
+ check_broadcast_shape (:: Tuple{} ) = nothing
43
+ check_broadcast_shape (:: Tuple{} , A:: Union{AbstractArray,Number} ) = check_broadcast_shape ((), indices (A))
42
44
check_broadcast_shape (shp) = nothing
43
- check_broadcast_shape (shp, A) = check_broadcast_shape (shp, shape (A))
45
+ check_broadcast_shape (shp, A) = check_broadcast_shape (shp, indices (A))
44
46
check_broadcast_shape (:: Tuple{} , :: Tuple{} ) = nothing
45
47
check_broadcast_shape (shp, :: Tuple{} ) = nothing
46
48
check_broadcast_shape (:: Tuple{} , Ashp:: Tuple ) = throw (DimensionMismatch (" cannot broadcast array to have fewer dimensions" ))
133
135
end
134
136
135
137
@inline function broadcast! {nargs} (f, B:: AbstractArray , As:: Vararg{Any,nargs} )
136
- check_broadcast_shape (shape (B), As... )
138
+ check_broadcast_shape (indices (B), As... )
137
139
sz = size (B)
138
140
mapindex = map (x-> newindexer (sz, x), As)
139
141
_broadcast! (f, B, mapindex, As, Val{nargs})
@@ -179,20 +181,20 @@ function broadcast_t(f, ::Type{Any}, As...)
179
181
shp = broadcast_shape (As... )
180
182
iter = CartesianRange (shp)
181
183
if isempty (iter)
182
- return allocate_for (Array{Union{}}, As , shp)
184
+ return similar (Array{Union{}}, shp)
183
185
end
184
186
nargs = length (As)
185
187
sz = size (iter)
186
188
indexmaps = map (x-> newindexer (sz, x), As)
187
189
st = start (iter)
188
190
I, st = next (iter, st)
189
191
val = f ([ As[i][newindex (I, indexmaps[i])] for i= 1 : nargs ]. .. )
190
- B = allocate_for (Array{typeof (val)}, As , shp)
192
+ B = similar (Array{typeof (val)}, shp)
191
193
B[I] = val
192
194
return _broadcast! (f, B, indexmaps, As, Val{nargs}, iter, st, 1 )
193
195
end
194
196
195
- @inline broadcast_t (f, T, As... ) = broadcast! (f, allocate_for (Array{T}, As , broadcast_shape (As... )), As... )
197
+ @inline broadcast_t (f, T, As... ) = broadcast! (f, similar (Array{T}, broadcast_shape (As... )), As... )
196
198
197
199
@inline broadcast (f, As... ) = broadcast_t (f, promote_eltype_op (f, As... ), As... )
198
200
@@ -215,15 +217,15 @@ function broadcast(f, As...)
215
217
end
216
218
=#
217
219
218
- @inline bitbroadcast (f, As... ) = broadcast! (f, allocate_for (BitArray, As , broadcast_shape (As... )), As... )
220
+ @inline bitbroadcast (f, As... ) = broadcast! (f, similar (BitArray, broadcast_shape (As... )), As... )
219
221
220
- broadcast_getindex (src:: AbstractArray , I:: AbstractArray... ) = broadcast_getindex! (Array {eltype(src)} (broadcast_shape (I... )), src, I... )
222
+ broadcast_getindex (src:: AbstractArray , I:: AbstractArray... ) = broadcast_getindex! (Array {eltype(src)} (to_shape ( broadcast_shape (I... ) )), src, I... )
221
223
@generated function broadcast_getindex! (dest:: AbstractArray , src:: AbstractArray , I:: AbstractArray... )
222
224
N = length (I)
223
225
Isplat = Expr[:(I[$ d]) for d = 1 : N]
224
226
quote
225
227
@nexprs $ N d-> (I_d = I[d])
226
- check_broadcast_shape (size (dest), $ (Isplat... )) # unnecessary if this function is never called directly
228
+ check_broadcast_shape (indices (dest), $ (Isplat... )) # unnecessary if this function is never called directly
227
229
checkbounds (src, $ (Isplat... ))
228
230
@nloops $ N i dest d-> (@nexprs $ N k-> (j_d_k = size (I_k, d) == 1 ? 1 : i_d)) begin
229
231
@nexprs $ N k-> (@inbounds J_k = @nref $ N I_k d-> j_d_k)
@@ -240,22 +242,22 @@ end
240
242
@nexprs $ N d-> (I_d = I[d])
241
243
checkbounds (A, $ (Isplat... ))
242
244
shape = broadcast_shape ($ (Isplat... ))
243
- @nextract $ N shape d-> (length (shape) < d ? 1 : shape[d])
245
+ @nextract $ N shape d-> (length (shape) < d ? OneTo ( 1 ) : shape[d])
244
246
if ! isa (x, AbstractArray)
245
- @nloops $ N i d-> (1 : shape_d) d-> (@nexprs $ N k-> (j_d_k = size (I_k, d) == 1 ? 1 : i_d)) begin
247
+ xA = convert (eltype (A), x)
248
+ @nloops $ N i d-> shape_d d-> (@nexprs $ N k-> (j_d_k = size (I_k, d) == 1 ? 1 : i_d)) begin
246
249
@nexprs $ N k-> (@inbounds J_k = @nref $ N I_k d-> j_d_k)
247
- @inbounds (@nref $ N A J) = x
250
+ @inbounds (@nref $ N A J) = xA
248
251
end
249
252
else
250
253
X = x
251
- # To call setindex_shape_check, we need to create fake 1-d indexes of the proper size
252
- @nexprs $ N d-> (fakeI_d = 1 : shape_d)
253
- @ncall $ N Base. setindex_shape_check X shape
254
- k = 1
255
- @nloops $ N i d-> (1 : shape_d) d-> (@nexprs $ N k-> (j_d_k = size (I_k, d) == 1 ? 1 : i_d)) begin
256
- @nexprs $ N k-> (@inbounds J_k = @nref $ N I_k d-> j_d_k)
257
- @inbounds (@nref $ N A J) = X[k]
258
- k += 1
254
+ @nexprs $ N d-> (shapelen_d = dimlength (shape_d))
255
+ @ncall $ N Base. setindex_shape_check X shapelen
256
+ Xstate = start (X)
257
+ @inbounds @nloops $ N i d-> shape_d d-> (@nexprs $ N k-> (j_d_k = size (I_k, d) == 1 ? 1 : i_d)) begin
258
+ @nexprs $ N k-> (J_k = @nref $ N I_k d-> j_d_k)
259
+ x_el, Xstate = next (X, Xstate)
260
+ (@nref $ N A J) = x_el
259
261
end
260
262
end
261
263
A
@@ -271,22 +273,22 @@ end
271
273
272
274
eltype_plus (As:: AbstractArray... ) = promote_eltype_op (+ , As... )
273
275
274
- .+ (As:: AbstractArray... ) = broadcast! (+ , Array {eltype_plus(As...)} (broadcast_shape (As... )), As... )
276
+ .+ (As:: AbstractArray... ) = broadcast! (+ , Array {eltype_plus(As...)} (to_shape ( broadcast_shape (As... ) )), As... )
275
277
276
278
function .- (A:: AbstractArray , B:: AbstractArray )
277
- broadcast! (- , Array {promote_op(-, eltype(A), eltype(B))} (broadcast_shape (A,B)), A, B)
279
+ broadcast! (- , Array {promote_op(-, eltype(A), eltype(B))} (to_shape ( broadcast_shape (A,B) )), A, B)
278
280
end
279
281
280
282
eltype_mul (As:: AbstractArray... ) = promote_eltype_op (* , As... )
281
283
282
- .* (As:: AbstractArray... ) = broadcast! (* , Array {eltype_mul(As...)} (broadcast_shape (As... )), As... )
284
+ .* (As:: AbstractArray... ) = broadcast! (* , Array {eltype_mul(As...)} (to_shape ( broadcast_shape (As... ) )), As... )
283
285
284
286
function ./ (A:: AbstractArray , B:: AbstractArray )
285
- broadcast! (/ , Array {promote_op(/, eltype(A), eltype(B))} (broadcast_shape (A, B)), A, B)
287
+ broadcast! (/ , Array {promote_op(/, eltype(A), eltype(B))} (to_shape ( broadcast_shape (A, B) )), A, B)
286
288
end
287
289
288
290
function .\ (A:: AbstractArray , B:: AbstractArray )
289
- broadcast! (\ , Array {promote_op(\, eltype(A), eltype(B))} (broadcast_shape (A, B)), A, B)
291
+ broadcast! (\ , Array {promote_op(\, eltype(A), eltype(B))} (to_shape ( broadcast_shape (A, B) )), A, B)
290
292
end
291
293
292
294
typealias RatIntT{T<: Integer } Union{Type{Rational{T}},Type{T}}
@@ -296,11 +298,11 @@ type_rdiv{T<:Integer,S<:Integer}(::RatIntT{T}, ::RatIntT{S}) =
296
298
type_rdiv {T<:Integer,S<:Integer} (:: CRatIntT{T} , :: CRatIntT{S} ) =
297
299
Complex{Rational{promote_type (T,S)}}
298
300
function .// (A:: AbstractArray , B:: AbstractArray )
299
- broadcast! (// , Array {type_rdiv(eltype(A), eltype(B))} (broadcast_shape (A, B)), A, B)
301
+ broadcast! (// , Array {type_rdiv(eltype(A), eltype(B))} (to_shape ( broadcast_shape (A, B) )), A, B)
300
302
end
301
303
302
304
function .^ (A:: AbstractArray , B:: AbstractArray )
303
- broadcast! (^ , Array {promote_op(^, eltype(A), eltype(B))} (broadcast_shape (A, B)), A, B)
305
+ broadcast! (^ , Array {promote_op(^, eltype(A), eltype(B))} (to_shape ( broadcast_shape (A, B) )), A, B)
304
306
end
305
307
306
308
# ## element-wise comparison operators returning BitArray ##
@@ -363,10 +365,10 @@ for (f, scalarf) in ((:.==, :(==)),
363
365
:((A,ind)-> A), :((B,ind)-> B[ind])),
364
366
(:AbstractArray , :Any , :A ,
365
367
:((A,ind)-> A[ind]), :((B,ind)-> B)))
366
- shape = :(shape ($ active))
368
+ shape = :(indices ($ active))
367
369
@eval begin
368
370
function ($ f)(A:: $sigA , B:: $sigB )
369
- P = allocate_for (BitArray, $ active , $ shape)
371
+ P = similar (BitArray, $ shape)
370
372
F = parent (P)
371
373
l = length (F)
372
374
l == 0 && return F
0 commit comments