@@ -25,11 +25,6 @@ BroadcastStyle(::BlockStyle{M}, ::PseudoBlockStyle{N}) where {M,N} = BlockStyle(
25
25
BroadcastStyle (:: PseudoBlockStyle{M} , :: BlockStyle{N} ) where {M,N} = BlockStyle (Val (max (M,N)))
26
26
27
27
28
- # ###
29
- # Default to standard Array broadcast
30
- # ###
31
-
32
-
33
28
# following code modified from julia/base/broadcast.jl
34
29
broadcast_cumulsizes (:: Number ) = ()
35
30
broadcast_cumulsizes (A:: AbstractArray ) = cumulsizes (blocksizes (A))
@@ -48,11 +43,84 @@ blocksizes(A::Broadcasted{<:AbstractArrayStyle{N}}) where N =
48
43
BlockSizes (combine_cumulsizes (broadcast_cumulsizes .(A. args)... ))
49
44
50
45
51
- copyto! (dest:: AbstractArray , bc:: Broadcasted{<:AbstractBlockStyle{N}} ) where N =
52
- copyto! (dest, Broadcasted {DefaultArrayStyle{N}} (bc. f, bc. args, bc. axes))
53
-
54
46
similar (bc:: Broadcasted{<:AbstractBlockStyle{N}} , :: Type{T} ) where {T,N} =
55
47
BlockArray {T,N} (undef, blocksizes (bc))
56
48
57
49
similar (bc:: Broadcasted{PseudoBlockStyle{N}} , :: Type{T} ) where {T,N} =
58
50
PseudoBlockArray {T,N} (undef, blocksizes (bc))
51
+
52
+
53
+ subblocks (:: Any , bs:: BlockSizes , dim:: Integer ) =
54
+ (nothing for _ in 1 : nblocks (bs, dim))
55
+
56
+ function subblocks (arr:: AbstractArray , bs:: BlockSizes , dim:: Integer )
57
+ if size (arr, dim) == 1
58
+ return (BlockIndexRange (Block (1 ), 1 : 1 ) for _ in 1 : nblocks (bs, dim))
59
+ end
60
+ j = 1
61
+ next = 1
62
+ arrstops = cumulsizes (arr, dim)
63
+ return (
64
+ let n = blocksize (bs, dim, i)
65
+ start = next
66
+ next = start + n
67
+ j0 = j
68
+ if arrstops[j + 1 ] == next
69
+ j += 1
70
+ end
71
+ BlockIndexRange (Block (j0), (start: next - 1 ) .- (arrstops[j0] - 1 ))
72
+ end
73
+ for i in 1 : nblocks (bs, dim))
74
+ end
75
+
76
+ @inline _bview (arg, :: Vararg ) = arg
77
+ @inline _bview (A:: AbstractArray , I... ) = view (A, I... )
78
+
79
+ @generated function copyto! (
80
+ dest:: AbstractArray ,
81
+ bc:: Broadcasted{<:AbstractBlockStyle{NDims}, <:Any, <:Any, Args} ,
82
+ ) where {NDims, Args <: Tuple }
83
+
84
+ NArgs = length (Args. parameters)
85
+
86
+ # `bvar(0, dim)` is a variable for BlockIndexRange of `dim`-th dimension
87
+ # of `dest` array. `bvar(i, dim)` is a similar variable of `i`-th
88
+ # argument in `bc.args`.
89
+ bvar (i, dim) = Symbol (" blockindexrange_" , i, " _" , dim)
90
+
91
+ function forloop (dim)
92
+ if dim > 0
93
+ quote
94
+ for ($ (bvar (0 , dim)), $ (bvar .(1 : NArgs, dim)... ),) in zip (
95
+ subblocks (dest, bs, $ dim),
96
+ subblocks .(bc. args, Ref (bs), Ref ($ dim))... )
97
+ $ (forloop (dim - 1 ))
98
+ end
99
+ end
100
+ else
101
+ bview (a, i) = :(_bview ($ a, $ ([bvar (i, d) for d in 1 : NDims]. .. )))
102
+ destview = bview (:dest , 0 )
103
+ argblocks = [bview (:(bc. args[$ i]), i) for i in 1 : NArgs]
104
+ quote
105
+ broadcast! (bc. f, $ destview, $ (argblocks... ))
106
+ end
107
+ end
108
+ end
109
+
110
+ quote
111
+ bs = blocksizes (bc)
112
+ if blocksizes (dest) ≠ bs
113
+ copyto! (PseudoBlockArray (dest, bs), bc)
114
+ return dest
115
+ end
116
+
117
+ $ (forloop (NDims))
118
+ return dest
119
+ end
120
+ end
121
+
122
+ @inline function Broadcast. instantiate (
123
+ bc:: Broadcasted{Style} ) where {Style <: AbstractBlockStyle }
124
+ bcf = Broadcast. flatten (Broadcasted {Nothing} (bc. f, bc. args, bc. axes))
125
+ return Broadcasted {Style} (bcf. f, bcf. args, bcf. axes)
126
+ end
0 commit comments