@@ -18,6 +18,38 @@ function union_eachblockstoredindex(as::AbstractArray...)
18
18
return ∪ (map (eachblockstoredindex, as)... )
19
19
end
20
20
21
+ # Get a view of a block assuming it is stored.
22
+ function viewblock_stored (a:: AbstractArray{<:Any,N} , I:: Vararg{Block{1},N} ) where {N}
23
+ return blocks (a)[Int .(I)... ]
24
+ end
25
+ function viewblock_stored (a:: AbstractArray{<:Any,N} , I:: Block{N} ) where {N}
26
+ return viewblock_stored (a, Tuple (I)... )
27
+ end
28
+
29
+ using FillArrays: Zeros
30
+ # Get a view of a block if it is stored, otherwise return a lazy zeros.
31
+ function viewblock_or_zeros (a:: AbstractArray{<:Any,N} , I:: Vararg{Block{1},N} ) where {N}
32
+ if isstored (a, I... )
33
+ return viewblock_stored (a, I... )
34
+ else
35
+ block_ax = map ((ax, i) -> eachblockaxis (ax)[Int (i)], axes (a), I)
36
+ return Zeros {eltype(a)} (block_ax)
37
+ end
38
+ end
39
+ function viewblock_or_zeros (a:: AbstractArray{<:Any,N} , I:: Block{N} ) where {N}
40
+ return viewblock_or_zeros (a, Tuple (I)... )
41
+ end
42
+
43
+ function map_block! (f, a_dest:: AbstractArray , I:: Block , a_srcs:: AbstractArray... )
44
+ a_srcs_I = map (a_src -> viewblock_or_zeros (a_src, I), a_srcs)
45
+ if isstored (a_dest, I)
46
+ a_dest[I] .= f .(a_srcs_I... )
47
+ else
48
+ a_dest[I] = Broadcast. broadcast_preserving_zero_d (f, a_srcs_I... )
49
+ end
50
+ return a_dest
51
+ end
52
+
21
53
function map_blockwise! (f, a_dest:: AbstractArray , a_srcs:: AbstractArray... )
22
54
# TODO : This assumes element types are numbers, generalize this logic.
23
55
f_preserves_zeros = f (zero .(eltype .(a_srcs))... ) == zero (eltype (a_dest))
@@ -27,22 +59,7 @@ function map_blockwise!(f, a_dest::AbstractArray, a_srcs::AbstractArray...)
27
59
BlockRange (a_dest)
28
60
end
29
61
for I in Is
30
- # TODO : Use:
31
- # block_dest = @view a_dest[I]
32
- # or:
33
- # block_dest = @view! a_dest[I]
34
- block_dest = blocks_maybe_single (a_dest)[Int .(Tuple (I))... ]
35
- # TODO : Use:
36
- # block_srcs = map(a_src -> @view(a_src[I]), a_srcs)
37
- block_srcs = map (a_srcs) do a_src
38
- return blocks_maybe_single (a_src)[Int .(Tuple (I))... ]
39
- end
40
- # TODO : Use `map!!` to handle immutable blocks.
41
- map! (f, block_dest, block_srcs... )
42
- # Replace the entire block, handles initializing new blocks
43
- # or if blocks are immutable.
44
- # TODO : Use `a_dest[I] = block_dest`.
45
- blocks (a_dest)[Int .(Tuple (I))... ] = block_dest
62
+ map_block! (f, a_dest, I, a_srcs... )
46
63
end
47
64
return a_dest
48
65
end
0 commit comments