Skip to content

Commit 08ed837

Browse files
committed
Deprecate Base.SparseArrays.broadcast_zpreserving[!].
Generic sparse broadcast[!] now provides most of Base.SparseArrays.broadcast_zpreserving[!]'s functionality.
1 parent 4793e88 commit 08ed837

File tree

2 files changed

+128
-111
lines changed

2 files changed

+128
-111
lines changed

base/deprecated.jl

+124
Original file line numberDiff line numberDiff line change
@@ -1168,4 +1168,128 @@ for (dep, f, op) in [(:sumabs!, :sum!, :abs),
11681168
end
11691169
end
11701170

1171+
## Deprecate broadcast_zpreserving[!] (wasn't exported, but might as well be friendly)
1172+
function gen_broadcast_function_sparse(genbody::Function, f::Function, is_first_sparse::Bool)
1173+
body = genbody(f, is_first_sparse)
1174+
@eval let
1175+
local _F_
1176+
function _F_{Tv,Ti}(B::SparseMatrixCSC{Tv,Ti}, A_1, A_2)
1177+
$body
1178+
end
1179+
_F_
1180+
end
1181+
end
1182+
function gen_broadcast_body_zpreserving(f::Function, is_first_sparse::Bool)
1183+
F = Expr(:quote, f)
1184+
if is_first_sparse
1185+
A1 = :(A_1)
1186+
A2 = :(A_2)
1187+
op1 = :(val1)
1188+
op2 = :(val2)
1189+
else
1190+
A1 = :(A_2)
1191+
A2 = :(A_1)
1192+
op1 = :(val2)
1193+
op2 = :(val1)
1194+
end
1195+
quote
1196+
Base.Broadcast.check_broadcast_indices(indices(B), $A1)
1197+
Base.Broadcast.check_broadcast_indices(indices(B), $A2)
1198+
1199+
nnzB = isempty(B) ? 0 :
1200+
nnz($A1) * div(B.n, ($A1).n) * div(B.m, ($A1).m)
1201+
if length(B.rowval) < nnzB
1202+
resize!(B.rowval, nnzB)
1203+
end
1204+
if length(B.nzval) < nnzB
1205+
resize!(B.nzval, nnzB)
1206+
end
1207+
z = zero(Tv)
1208+
1209+
ptrB = 1
1210+
B.colptr[1] = 1
1211+
1212+
@inbounds for col = 1:B.n
1213+
ptr1::Int = ($A1).n == 1 ? ($A1).colptr[1] : ($A1).colptr[col]
1214+
stop1::Int = ($A1).n == 1 ? ($A1).colptr[2] : ($A1).colptr[col+1]
1215+
col2 = size($A2, 2) == 1 ? 1 : col
1216+
row = 1
1217+
while ptr1 < stop1 && row <= B.m
1218+
if ($A1).m != 1
1219+
row = ($A1).rowval[ptr1]
1220+
end
1221+
row2 = size($A2, 1) == 1 ? 1 : row
1222+
val1 = ($A1).nzval[ptr1]
1223+
val2 = ($A2)[row2,col2]
1224+
res = ($F)($op1, $op2)
1225+
if res != z
1226+
B.rowval[ptrB] = row
1227+
B.nzval[ptrB] = res
1228+
ptrB += 1
1229+
end
1230+
if ($A1).m != 1
1231+
ptr1 += 1
1232+
else
1233+
row += 1
1234+
end
1235+
end
1236+
B.colptr[col+1] = ptrB
1237+
end
1238+
deleteat!(B.rowval, B.colptr[end]:length(B.rowval))
1239+
deleteat!(B.nzval, B.colptr[end]:length(B.nzval))
1240+
nothing
1241+
end
1242+
end
1243+
for (Bsig, A1sig, A2sig, gbb, funcname) in
1244+
(
1245+
(SparseMatrixCSC , SparseMatrixCSC , Array, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1246+
(SparseMatrixCSC , Array , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1247+
(SparseMatrixCSC , Number , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1248+
(SparseMatrixCSC , SparseMatrixCSC , Number, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1249+
(SparseMatrixCSC , BitArray , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1250+
(SparseMatrixCSC , SparseMatrixCSC , BitArray, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
1251+
)
1252+
@eval let cache = Dict{Function,Function}()
1253+
global $funcname
1254+
function $funcname(f::Function, B::$Bsig, A1::$A1sig, A2::$A2sig)
1255+
func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC)
1256+
# need eval because func was just created by gen_broadcast_function_sparse
1257+
# TODO: convert this to a generated function
1258+
eval(current_module(), Expr(:body, Expr(:return, Expr(:call, QuoteNode(func), QuoteNode(B), QuoteNode(A1), QuoteNode(A2)))))
1259+
return B
1260+
end
1261+
end # let broadcast_cache
1262+
end
1263+
_broadcast_zpreserving!(args...) = broadcast!(args...)
1264+
_broadcast_zpreserving(args...) = Base.Broadcast.broadcast_elwise_op(args...)
1265+
_broadcast_zpreserving{Tv1,Ti1,Tv2,Ti2}(f::Function, A_1::SparseMatrixCSC{Tv1,Ti1}, A_2::SparseMatrixCSC{Tv2,Ti2}) =
1266+
_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)
1267+
_broadcast_zpreserving{Tv,Ti}(f::Function, A_1::SparseMatrixCSC{Tv,Ti}, A_2::Union{Array,BitArray,Number}) =
1268+
_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)
1269+
_broadcast_zpreserving{Tv,Ti}(f::Function, A_1::Union{Array,BitArray,Number}, A_2::SparseMatrixCSC{Tv,Ti}) =
1270+
_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)
1271+
1272+
function _depstring_bczpres()
1273+
return string("broadcast_zpreserving[!] is deprecated. Generic sparse broadcast[!] ",
1274+
"provides most of broadcast_zpreserving[!]'s functionality. If you have a use case ",
1275+
"that generic sparse broadcast[!] does not cover, please describe your use case in ",
1276+
" issue #19533 (https://github.com/JuliaLang/julia/issues/19533).")
1277+
end
1278+
function _depwarn_bczpres(f, args...)
1279+
depwarn(_depstring_bczpres(), :broadcast_zpreserving)
1280+
return _broadcast_zpreserving(f, args...)
1281+
end
1282+
function _depwarn_bczpres!(f, args...)
1283+
depwarn(_depstring_bczpres(), :broadcast_zpreserving!)
1284+
return _broadcast_zpreserving!(f, args...)
1285+
end
1286+
import Base.SparseArrays: broadcast_zpreserving, broadcast_zpreserving!
1287+
broadcast_zpreserving(f, args...) = _depwarn_bczpres(f, args...)
1288+
broadcast_zpreserving(f, A::SparseMatrixCSC, B::SparseMatrixCSC) = _depwarn_bczpres(f, A, B)
1289+
broadcast_zpreserving(f, A::SparseMatrixCSC, B::Union{Array,BitArray,Number}) = _depwarn_bczpres(f, A, B)
1290+
broadcast_zpreserving(f, A::Union{Array,BitArray,Number}, B::SparseMatrixCSC) = _depwarn_bczpres(f, A, B)
1291+
broadcast_zpreserving!(f, args...) = _depwarn_bczpres!(f, args...)
1292+
broadcast_zpreserving!(f, C::SparseMatrixCSC, A::SparseMatrixCSC, B::Union{Array,BitArray,Number}) = _depwarn_bczpres!(f, C, A, B)
1293+
broadcast_zpreserving!(f, C::SparseMatrixCSC, A::Union{Array,BitArray,Number}, B::SparseMatrixCSC) = _depwarn_bczpres!(f, C, A, B)
1294+
11711295
# End deprecations scheduled for 0.6

base/sparse/sparsematrix.jl

+4-111
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))
@@ -2281,6 +2170,10 @@ floor{To}(::Type{To}, A::SparseMatrixCSC) = floor.(To, A)
22812170
trunc{To}(::Type{To}, A::SparseMatrixCSC) = trunc.(To, A)
22822171
round{To}(::Type{To}, A::SparseMatrixCSC) = round.(To, A)
22832172

2173+
# broadcast_zpreserving[!] deprecated in 0.6. Wasn't exported prior, so need these
2174+
# definitions for the deprecation to serve its purpose. Remove after 0.6.
2175+
function broadcast_zpreserving end
2176+
function broadcast_zpreserving! end
22842177

22852178
## Binary arithmetic and boolean operators
22862179
(+)(A::SparseMatrixCSC, B::SparseMatrixCSC) = map(+, A, B)

0 commit comments

Comments
 (0)