@@ -67,9 +67,20 @@ using BroadcastMapConversion: map_function, map_args
6767# TODO : Look into `SparseArrays.capturescalars`:
6868# https://github.com/JuliaSparse/SparseArrays.jl/blob/1beb0e4a4618b0399907b0000c43d9f66d34accc/src/higherorderfns.jl#L1092-L1102
6969@interface interface:: AbstractArrayInterface function Base. copyto! (
70- dest :: AbstractArray , bc:: Broadcast.Broadcasted
70+ a_dest :: AbstractArray , bc:: Broadcast.Broadcasted
7171)
72- return @interface interface map! (map_function (bc), dest, map_args (bc)... )
72+ return @interface interface map! (map_function (bc), a_dest, map_args (bc)... )
73+ end
74+
75+ # This captures broadcast expressions such as `a .= 2`.
76+ # Ideally this would be handled by `map!(f, a_dest)` but that isn't defined yet:
77+ # https://github.com/JuliaLang/julia/issues/31677
78+ # https://github.com/JuliaLang/julia/pull/40632
79+ @interface interface:: AbstractArrayInterface function Base. copyto! (
80+ a_dest:: AbstractArray , bc:: Broadcast.Broadcasted{Broadcast.DefaultArrayStyle{0}}
81+ )
82+ isempty (map_args (bc)) || error (" Bad broadcast expression." )
83+ return @interface interface map! (map_function (bc), a_dest, a_dest)
7384end
7485
7586# This is defined in this way so we can rely on the Broadcast logic
8697# `invoke(Base.map!, Tuple{Any,AbstractArray,Vararg{AbstractArray}}, f, dest, as...)`.
8798# TODO : Use `MethodError`?
8899@interface :: AbstractArrayInterface function Base. map! (
89- f, dest :: AbstractArray , as :: AbstractArray...
100+ f, a_dest :: AbstractArray , a_srcs :: AbstractArray...
90101)
91102 return error (" Not implemented." )
92103end
93104
105+ @interface interface:: AbstractArrayInterface function Base. fill! (a:: AbstractArray , value)
106+ @interface interface map! (Returns (value), a, a)
107+ end
108+
109+ using ArrayLayouts: zero!
110+
111+ # `zero!` isn't defined in `Base`, but it is defined in `ArrayLayouts`
112+ # and is useful for sparse array logic, since it can be used to empty
113+ # the sparse array storage.
114+ # We use a single function definition to minimize method ambiguities.
115+ @interface interface:: AbstractArrayInterface function ArrayLayouts. zero! (a:: AbstractArray )
116+ # More generally, the first codepath could be taking if `zero(eltype(a))`
117+ # is defined and the elements are immutable.
118+ f = eltype (a) <: Number ? Returns (zero (eltype (a))) : zero!
119+ return @interface interface map! (f, a, a)
120+ end
121+
122+ # Specialized version of `Base.zero` written in terms of `ArrayLayouts.zero!`.
123+ # This is friendlier for sparse arrays since `ArrayLayouts.zero!` makes it easier
124+ # to handle the logic of dropping all elements of the sparse array when possible.
125+ # We use a single function definition to minimize method ambiguities.
126+ @interface interface:: AbstractArrayInterface function Base. zero (a:: AbstractArray )
127+ # More generally, the first codepath could be taking if `zero(eltype(a))`
128+ # is defined and the elements are immutable.
129+ if eltype (a) <: Number
130+ return @interface interface zero! (similar (a))
131+ end
132+ return @interface interface map (interface (zero), a)
133+ end
134+
94135@interface :: AbstractArrayInterface function Base. mapreduce (
95136 f, op, as:: AbstractArray... ; kwargs...
96137)
0 commit comments