1
1
using ArrayLayouts: LayoutArray
2
- using BlockArrays: blockisequal
3
- using DerivableInterfaces: @interface , AbstractArrayInterface, interface
4
- using GPUArraysCore: @allowscalar
2
+ using BlockArrays: AbstractBlockVector, Block
5
3
using LinearAlgebra: Adjoint, Transpose
6
- using SparseArraysBase: SparseArraysBase, SparseArrayStyle
7
-
8
- # Returns `Vector{<:CartesianIndices}`
9
- function union_stored_blocked_cartesianindices (as:: Vararg{AbstractArray} )
10
- combined_axes = combine_axes (axes .(as)... )
11
- stored_blocked_cartesianindices_as = map (as) do a
12
- return blocked_cartesianindices (axes (a), combined_axes, eachblockstoredindex (a))
13
- end
14
- return ∪ (stored_blocked_cartesianindices_as... )
15
- end
16
-
17
- # This is used by `map` to get the output axes.
18
- # This is type piracy, try to avoid this, maybe requires defining `map`.
19
- # # Base.promote_shape(a1::Tuple{Vararg{BlockedUnitRange}}, a2::Tuple{Vararg{BlockedUnitRange}}) = combine_axes(a1, a2)
20
-
21
- reblock (a) = a
22
4
5
+ # TODO : Make this more general, independent of `AbstractBlockSparseArray`.
23
6
# If the blocking of the slice doesn't match the blocking of the
24
7
# parent array, reblock according to the blocking of the parent array.
25
8
function reblock (
@@ -32,12 +15,14 @@ function reblock(
32
15
return @view parent (a)[UnitRange {Int} .(parentindices (a))... ]
33
16
end
34
17
18
+ # TODO : Make this more general, independent of `AbstractBlockSparseArray`.
35
19
function reblock (
36
20
a:: SubArray{<:Any,<:Any,<:AbstractBlockSparseArray,<:Tuple{Vararg{NonBlockedArray}}}
37
21
)
38
22
return @view parent (a)[map (I -> I. array, parentindices (a))... ]
39
23
end
40
24
25
+ # TODO : Make this more general, independent of `AbstractBlockSparseArray`.
41
26
function reblock (
42
27
a:: SubArray {
43
28
<: Any ,
@@ -50,77 +35,18 @@ function reblock(
50
35
return @view parent (a)[map (I -> Vector (I. blocks), parentindices (a))... ]
51
36
end
52
37
53
- # `map!` specialized to zero-dimensional inputs.
54
- function map_zero_dim! end
55
-
56
- @interface :: AbstractArrayInterface function map_zero_dim! (
57
- f, a_dest:: AbstractArray , a_srcs:: AbstractArray...
58
- )
59
- @allowscalar a_dest[] = f .(map (a_src -> a_src[], a_srcs)... )
38
+ function Base. map! (f, a_dest:: AbstractArray , a_srcs:: AnyAbstractBlockSparseArray... )
39
+ @interface interface (a_dest, a_srcs... ) map! (f, a_dest, a_srcs... )
60
40
return a_dest
61
41
end
62
-
63
- # TODO : Move to `blocksparsearrayinterface/map.jl`.
64
- # TODO : Rewrite this so that it takes the blocking structure
65
- # made by combining the blocking of the axes (i.e. the blocking that
66
- # is used to determine `union_stored_blocked_cartesianindices(...)`).
67
- # `reblock` is a partial solution to that, but a bit ad-hoc.
68
- # # TODO : Make this an `@interface AbstractBlockSparseArrayInterface` function.
69
- @interface interface:: AbstractBlockSparseArrayInterface function Base. map! (
70
- f, a_dest:: AbstractArray , a_srcs:: AbstractArray...
71
- )
72
- if iszero (ndims (a_dest))
73
- @interface interface map_zero_dim! (f, a_dest, a_srcs... )
74
- return a_dest
75
- end
76
-
77
- a_dest, a_srcs = reblock (a_dest), reblock .(a_srcs)
78
- for I in union_stored_blocked_cartesianindices (a_dest, a_srcs... )
79
- BI_dest = blockindexrange (a_dest, I)
80
- BI_srcs = map (a_src -> blockindexrange (a_src, I), a_srcs)
81
- # TODO : Investigate why this doesn't work:
82
- # block_dest = @view a_dest[_block(BI_dest)]
83
- block_dest = blocks_maybe_single (a_dest)[Int .(Tuple (_block (BI_dest)))... ]
84
- # TODO : Investigate why this doesn't work:
85
- # block_srcs = ntuple(i -> @view(a_srcs[i][_block(BI_srcs[i])]), length(a_srcs))
86
- block_srcs = ntuple (length (a_srcs)) do i
87
- return blocks_maybe_single (a_srcs[i])[Int .(Tuple (_block (BI_srcs[i])))... ]
88
- end
89
- subblock_dest = @view block_dest[BI_dest. indices... ]
90
- subblock_srcs = ntuple (i -> @view (block_srcs[i][BI_srcs[i]. indices... ]), length (a_srcs))
91
- # TODO : Use `map!!` to handle immutable blocks.
92
- map! (f, subblock_dest, subblock_srcs... )
93
- # Replace the entire block, handles initializing new blocks
94
- # or if blocks are immutable.
95
- blocks (a_dest)[Int .(Tuple (_block (BI_dest)))... ] = block_dest
96
- end
42
+ function Base. map! (f, a_dest:: AnyAbstractBlockSparseArray , a_srcs:: AbstractArray... )
43
+ @interface interface (a_dest, a_srcs... ) map! (f, a_dest, a_srcs... )
97
44
return a_dest
98
45
end
99
-
100
- # TODO : Move to `blocksparsearrayinterface/map.jl`.
101
- @interface :: AbstractBlockSparseArrayInterface function Base. mapreduce (
102
- f, op, as:: AbstractArray... ; kwargs...
46
+ function Base. map! (
47
+ f, a_dest:: AnyAbstractBlockSparseArray , a_srcs:: AnyAbstractBlockSparseArray...
103
48
)
104
- # TODO : Define an `init` value based on the element type.
105
- return @interface interface (blocks .(as)... ) mapreduce (
106
- block -> mapreduce (f, op, block), op, blocks .(as)... ; kwargs...
107
- )
108
- end
109
-
110
- # TODO : Move to `blocksparsearrayinterface/map.jl`.
111
- @interface :: AbstractBlockSparseArrayInterface function Base. iszero (a:: AbstractArray )
112
- # TODO : Just call `iszero(blocks(a))`?
113
- return @interface interface (blocks (a)) iszero (blocks (a))
114
- end
115
-
116
- # TODO : Move to `blocksparsearrayinterface/map.jl`.
117
- @interface :: AbstractBlockSparseArrayInterface function Base. isreal (a:: AbstractArray )
118
- # TODO : Just call `isreal(blocks(a))`?
119
- return @interface interface (blocks (a)) isreal (blocks (a))
120
- end
121
-
122
- function Base. map! (f, a_dest:: AbstractArray , a_srcs:: AnyAbstractBlockSparseArray... )
123
- @interface interface (a_srcs... ) map! (f, a_dest, a_srcs... )
49
+ @interface interface (a_dest, a_srcs... ) map! (f, a_dest, a_srcs... )
124
50
return a_dest
125
51
end
126
52
0 commit comments