Skip to content

Commit 6ad62c4

Browse files
Sacha0tkelman
authored andcommitted
Deprecate Base.SparseArrays.broadcast_zpreserving[!]. (#19720)
Generic sparse broadcast[!] now provides most of Base.SparseArrays.broadcast_zpreserving[!]'s functionality.
1 parent b143301 commit 6ad62c4

File tree

2 files changed

+123
-111
lines changed

2 files changed

+123
-111
lines changed

base/deprecated.jl

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,129 @@ for (dep, f, op) in [(:sumabs!, :sum!, :abs),
11461146
end
11471147
end
11481148

1149+
## Deprecate broadcast_zpreserving[!] (wasn't exported, but might as well be friendly)
1150+
function gen_broadcast_function_sparse(genbody::Function, f::Function, is_first_sparse::Bool)
1151+
body = genbody(f, is_first_sparse)
1152+
@eval let
1153+
local _F_
1154+
function _F_{Tv,Ti}(B::SparseMatrixCSC{Tv,Ti}, A_1, A_2)
1155+
$body
1156+
end
1157+
_F_
1158+
end
1159+
end
1160+
function gen_broadcast_body_zpreserving(f::Function, is_first_sparse::Bool)
1161+
F = Expr(:quote, f)
1162+
if is_first_sparse
1163+
A1 = :(A_1)
1164+
A2 = :(A_2)
1165+
op1 = :(val1)
1166+
op2 = :(val2)
1167+
else
1168+
A1 = :(A_2)
1169+
A2 = :(A_1)
1170+
op1 = :(val2)
1171+
op2 = :(val1)
1172+
end
1173+
quote
1174+
Base.Broadcast.check_broadcast_indices(indices(B), $A1)
1175+
Base.Broadcast.check_broadcast_indices(indices(B), $A2)
1176+
1177+
nnzB = isempty(B) ? 0 :
1178+
nnz($A1) * div(B.n, ($A1).n) * div(B.m, ($A1).m)
1179+
if length(B.rowval) < nnzB
1180+
resize!(B.rowval, nnzB)
1181+
end
1182+
if length(B.nzval) < nnzB
1183+
resize!(B.nzval, nnzB)
1184+
end
1185+
z = zero(Tv)
1186+
1187+
ptrB = 1
1188+
B.colptr[1] = 1
1189+
1190+
@inbounds for col = 1:B.n
1191+
ptr1::Int = ($A1).n == 1 ? ($A1).colptr[1] : ($A1).colptr[col]
1192+
stop1::Int = ($A1).n == 1 ? ($A1).colptr[2] : ($A1).colptr[col+1]
1193+
col2 = size($A2, 2) == 1 ? 1 : col
1194+
row = 1
1195+
while ptr1 < stop1 && row <= B.m
1196+
if ($A1).m != 1
1197+
row = ($A1).rowval[ptr1]
1198+
end
1199+
row2 = size($A2, 1) == 1 ? 1 : row
1200+
val1 = ($A1).nzval[ptr1]
1201+
val2 = ($A2)[row2,col2]
1202+
res = ($F)($op1, $op2)
1203+
if res != z
1204+
B.rowval[ptrB] = row
1205+
B.nzval[ptrB] = res
1206+
ptrB += 1
1207+
end
1208+
if ($A1).m != 1
1209+
ptr1 += 1
1210+
else
1211+
row += 1
1212+
end
1213+
end
1214+
B.colptr[col+1] = ptrB
1215+
end
1216+
deleteat!(B.rowval, B.colptr[end]:length(B.rowval))
1217+
deleteat!(B.nzval, B.colptr[end]:length(B.nzval))
1218+
nothing
1219+
end
1220+
end
1221+
for (Bsig, A1sig, A2sig, gbb, funcname) in
1222+
(
1223+
(SparseMatrixCSC , SparseMatrixCSC , Array, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1224+
(SparseMatrixCSC , Array , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1225+
(SparseMatrixCSC , Number , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1226+
(SparseMatrixCSC , SparseMatrixCSC , Number, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1227+
(SparseMatrixCSC , BitArray , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1228+
(SparseMatrixCSC , SparseMatrixCSC , BitArray, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1229+
)
1230+
@eval let cache = Dict{Function,Function}()
1231+
global $funcname
1232+
function $funcname(f::Function, B::$Bsig, A1::$A1sig, A2::$A2sig)
1233+
func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC)
1234+
# need eval because func was just created by gen_broadcast_function_sparse
1235+
# TODO: convert this to a generated function
1236+
eval(current_module(), Expr(:body, Expr(:return, Expr(:call, QuoteNode(func), QuoteNode(B), QuoteNode(A1), QuoteNode(A2)))))
1237+
return B
1238+
end
1239+
end # let broadcast_cache
1240+
end
1241+
_broadcast_zpreserving!(args...) = broadcast!(args...)
1242+
_broadcast_zpreserving(args...) = Base.Broadcast.broadcast_elwise_op(args...)
1243+
_broadcast_zpreserving{Tv1,Ti1,Tv2,Ti2}(f::Function, A_1::SparseMatrixCSC{Tv1,Ti1}, A_2::SparseMatrixCSC{Tv2,Ti2}) =
1244+
_broadcast_zpreserving!(f, spzeros(promote_type(Tv1, Tv2), promote_type(Ti1, Ti2), Base.to_shape(Base.Broadcast.broadcast_indices(A_1, A_2))), A_1, A_2)
1245+
_broadcast_zpreserving{Tv,Ti}(f::Function, A_1::SparseMatrixCSC{Tv,Ti}, A_2::Union{Array,BitArray,Number}) =
1246+
_broadcast_zpreserving!(f, spzeros(promote_eltype(A_1, A_2), Ti, Base.to_shape(Base.Broadcast.broadcast_indices(A_1, A_2))), A_1, A_2)
1247+
_broadcast_zpreserving{Tv,Ti}(f::Function, A_1::Union{Array,BitArray,Number}, A_2::SparseMatrixCSC{Tv,Ti}) =
1248+
_broadcast_zpreserving!(f, spzeros(promote_eltype(A_1, A_2), Ti, Base.to_shape(Base.Broadcast.broadcast_indices(A_1, A_2))), A_1, A_2)
1249+
1250+
function _depstring_bczpres()
1251+
return string("broadcast_zpreserving[!] is deprecated. Generic sparse broadcast[!] ",
1252+
"provides most of broadcast_zpreserving[!]'s functionality. If you have a use case ",
1253+
"that generic sparse broadcast[!] does not cover, please describe your use case in ",
1254+
" issue #19533 (https://github.com/JuliaLang/julia/issues/19533).")
1255+
end
1256+
function _depwarn_bczpres(f, args...)
1257+
depwarn(_depstring_bczpres(), :broadcast_zpreserving)
1258+
return _broadcast_zpreserving(f, args...)
1259+
end
1260+
function _depwarn_bczpres!(f, args...)
1261+
depwarn(_depstring_bczpres(), :broadcast_zpreserving!)
1262+
return _broadcast_zpreserving!(f, args...)
1263+
end
1264+
eval(SparseArrays, :(broadcast_zpreserving(f, args...) = Base._depwarn_bczpres(f, args...)))
1265+
eval(SparseArrays, :(broadcast_zpreserving(f, A::SparseMatrixCSC, B::SparseMatrixCSC) = Base._depwarn_bczpres(f, A, B)))
1266+
eval(SparseArrays, :(broadcast_zpreserving(f, A::SparseMatrixCSC, B::Union{Array,BitArray,Number}) = Base._depwarn_bczpres(f, A, B)))
1267+
eval(SparseArrays, :(broadcast_zpreserving(f, A::Union{Array,BitArray,Number}, B::SparseMatrixCSC) = Base._depwarn_bczpres(f, A, B)))
1268+
eval(SparseArrays, :(broadcast_zpreserving!(f, args...) = Base._depwarn_bczpres!(f, args...)))
1269+
eval(SparseArrays, :(broadcast_zpreserving!(f, C::SparseMatrixCSC, A::SparseMatrixCSC, B::Union{Array,BitArray,Number}) = Base._depwarn_bczpres!(f, C, A, B)))
1270+
eval(SparseArrays, :(broadcast_zpreserving!(f, C::SparseMatrixCSC, A::Union{Array,BitArray,Number}, B::SparseMatrixCSC) = Base._depwarn_bczpres!(f, C, A, B)))
1271+
11491272
# #19719
11501273
@deprecate getindex(t::Tuple, r::AbstractArray) getindex(t, vec(r))
11511274
@deprecate getindex(t::Tuple, b::AbstractArray{Bool}) getindex(t, vec(b))

base/sparse/sparsematrix.jl

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,117 +2160,6 @@ broadcast{Tf,T}(f::Tf, ::Type{T}, A::SparseMatrixCSC) = broadcast(y -> f(T, y),
21602160
broadcast{Tf,T}(f::Tf, A::SparseMatrixCSC, ::Type{T}) = broadcast(x -> f(x, T), A)
21612161

21622162

2163-
## Define unexported broadcast_zpreserving[!] methods
2164-
# TODO: Sort out what to do with broadcast_zpreserving and dependencies
2165-
2166-
function gen_broadcast_function_sparse(genbody::Function, f::Function, is_first_sparse::Bool)
2167-
body = genbody(f, is_first_sparse)
2168-
@eval let
2169-
local _F_
2170-
function _F_{Tv,Ti}(B::SparseMatrixCSC{Tv,Ti}, A_1, A_2)
2171-
$body
2172-
end
2173-
_F_
2174-
end
2175-
end
2176-
2177-
# Operations with zero result if any operand is zero
2178-
# A_1 or A_2 (or both) are sparse.
2179-
# is_first_sparse == true => A_1 is sparse
2180-
# is_first_sparse == false => A_2 is sparse
2181-
function gen_broadcast_body_zpreserving(f::Function, is_first_sparse::Bool)
2182-
F = Expr(:quote, f)
2183-
if is_first_sparse
2184-
A1 = :(A_1)
2185-
A2 = :(A_2)
2186-
op1 = :(val1)
2187-
op2 = :(val2)
2188-
else
2189-
A1 = :(A_2)
2190-
A2 = :(A_1)
2191-
op1 = :(val2)
2192-
op2 = :(val1)
2193-
end
2194-
quote
2195-
Base.Broadcast.check_broadcast_indices(indices(B), $A1)
2196-
Base.Broadcast.check_broadcast_indices(indices(B), $A2)
2197-
2198-
nnzB = isempty(B) ? 0 :
2199-
nnz($A1) * div(B.n, ($A1).n) * div(B.m, ($A1).m)
2200-
if length(B.rowval) < nnzB
2201-
resize!(B.rowval, nnzB)
2202-
end
2203-
if length(B.nzval) < nnzB
2204-
resize!(B.nzval, nnzB)
2205-
end
2206-
z = zero(Tv)
2207-
2208-
ptrB = 1
2209-
B.colptr[1] = 1
2210-
2211-
@inbounds for col = 1:B.n
2212-
ptr1::Int = ($A1).n == 1 ? ($A1).colptr[1] : ($A1).colptr[col]
2213-
stop1::Int = ($A1).n == 1 ? ($A1).colptr[2] : ($A1).colptr[col+1]
2214-
col2 = size($A2, 2) == 1 ? 1 : col
2215-
row = 1
2216-
while ptr1 < stop1 && row <= B.m
2217-
if ($A1).m != 1
2218-
row = ($A1).rowval[ptr1]
2219-
end
2220-
row2 = size($A2, 1) == 1 ? 1 : row
2221-
val1 = ($A1).nzval[ptr1]
2222-
val2 = ($A2)[row2,col2]
2223-
res = ($F)($op1, $op2)
2224-
if res != z
2225-
B.rowval[ptrB] = row
2226-
B.nzval[ptrB] = res
2227-
ptrB += 1
2228-
end
2229-
if ($A1).m != 1
2230-
ptr1 += 1
2231-
else
2232-
row += 1
2233-
end
2234-
end
2235-
B.colptr[col+1] = ptrB
2236-
end
2237-
deleteat!(B.rowval, B.colptr[end]:length(B.rowval))
2238-
deleteat!(B.nzval, B.colptr[end]:length(B.nzval))
2239-
nothing
2240-
end
2241-
end
2242-
2243-
for (Bsig, A1sig, A2sig, gbb, funcname) in
2244-
(
2245-
(SparseMatrixCSC , SparseMatrixCSC , Array, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
2246-
(SparseMatrixCSC , Array , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
2247-
(SparseMatrixCSC , Number , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
2248-
(SparseMatrixCSC , SparseMatrixCSC , Number, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
2249-
(SparseMatrixCSC , BitArray , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
2250-
(SparseMatrixCSC , SparseMatrixCSC , BitArray, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
2251-
)
2252-
@eval let cache = Dict{Function,Function}()
2253-
global $funcname
2254-
function $funcname(f::Function, B::$Bsig, A1::$A1sig, A2::$A2sig)
2255-
func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC)
2256-
# need eval because func was just created by gen_broadcast_function_sparse
2257-
# TODO: convert this to a generated function
2258-
eval(current_module(), Expr(:body, Expr(:return, Expr(:call, QuoteNode(func), QuoteNode(B), QuoteNode(A1), QuoteNode(A2)))))
2259-
return B
2260-
end
2261-
end # let broadcast_cache
2262-
end
2263-
2264-
@inline broadcast_zpreserving!(args...) = broadcast!(args...)
2265-
@inline broadcast_zpreserving(args...) = Base.Broadcast.broadcast_elwise_op(args...)
2266-
broadcast_zpreserving{Tv1,Ti1,Tv2,Ti2}(f::Function, A_1::SparseMatrixCSC{Tv1,Ti1}, A_2::SparseMatrixCSC{Tv2,Ti2}) =
2267-
broadcast_zpreserving!(f, spzeros(promote_type(Tv1, Tv2), promote_type(Ti1, Ti2), to_shape(broadcast_indices(A_1, A_2))), A_1, A_2)
2268-
broadcast_zpreserving{Tv,Ti}(f::Function, A_1::SparseMatrixCSC{Tv,Ti}, A_2::Union{Array,BitArray,Number}) =
2269-
broadcast_zpreserving!(f, spzeros(promote_eltype(A_1, A_2), Ti, to_shape(broadcast_indices(A_1, A_2))), A_1, A_2)
2270-
broadcast_zpreserving{Tv,Ti}(f::Function, A_1::Union{Array,BitArray,Number}, A_2::SparseMatrixCSC{Tv,Ti}) =
2271-
broadcast_zpreserving!(f, spzeros(promote_eltype(A_1, A_2), Ti, to_shape(broadcast_indices(A_1, A_2))), A_1, A_2)
2272-
2273-
22742163
# TODO: More appropriate location?
22752164
conj!(A::SparseMatrixCSC) = (broadcast!(conj, A.nzval, A.nzval); A)
22762165
(-)(A::SparseMatrixCSC) = SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), map(-, A.nzval))

0 commit comments

Comments
 (0)