Skip to content

Commit

Permalink
Deprecate Base.SparseArrays.broadcast_zpreserving[!]. (#19720)
Browse files Browse the repository at this point in the history
Generic sparse broadcast[!] now provides most of Base.SparseArrays.broadcast_zpreserving[!]'s functionality.
  • Loading branch information
Sacha0 authored and tkelman committed Dec 30, 2016
1 parent b143301 commit 6ad62c4
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 111 deletions.
123 changes: 123 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,129 @@ for (dep, f, op) in [(:sumabs!, :sum!, :abs),
end
end

## Deprecate broadcast_zpreserving[!] (wasn't exported, but might as well be friendly)
function gen_broadcast_function_sparse(genbody::Function, f::Function, is_first_sparse::Bool)
body = genbody(f, is_first_sparse)
@eval let
local _F_
function _F_{Tv,Ti}(B::SparseMatrixCSC{Tv,Ti}, A_1, A_2)
$body
end
_F_
end
end
function gen_broadcast_body_zpreserving(f::Function, is_first_sparse::Bool)
F = Expr(:quote, f)
if is_first_sparse
A1 = :(A_1)
A2 = :(A_2)
op1 = :(val1)
op2 = :(val2)
else
A1 = :(A_2)
A2 = :(A_1)
op1 = :(val2)
op2 = :(val1)
end
quote
Base.Broadcast.check_broadcast_indices(indices(B), $A1)
Base.Broadcast.check_broadcast_indices(indices(B), $A2)

nnzB = isempty(B) ? 0 :
nnz($A1) * div(B.n, ($A1).n) * div(B.m, ($A1).m)
if length(B.rowval) < nnzB
resize!(B.rowval, nnzB)
end
if length(B.nzval) < nnzB
resize!(B.nzval, nnzB)
end
z = zero(Tv)

ptrB = 1
B.colptr[1] = 1

@inbounds for col = 1:B.n
ptr1::Int = ($A1).n == 1 ? ($A1).colptr[1] : ($A1).colptr[col]
stop1::Int = ($A1).n == 1 ? ($A1).colptr[2] : ($A1).colptr[col+1]
col2 = size($A2, 2) == 1 ? 1 : col
row = 1
while ptr1 < stop1 && row <= B.m
if ($A1).m != 1
row = ($A1).rowval[ptr1]
end
row2 = size($A2, 1) == 1 ? 1 : row
val1 = ($A1).nzval[ptr1]
val2 = ($A2)[row2,col2]
res = ($F)($op1, $op2)
if res != z
B.rowval[ptrB] = row
B.nzval[ptrB] = res
ptrB += 1
end
if ($A1).m != 1
ptr1 += 1
else
row += 1
end
end
B.colptr[col+1] = ptrB
end
deleteat!(B.rowval, B.colptr[end]:length(B.rowval))
deleteat!(B.nzval, B.colptr[end]:length(B.nzval))
nothing
end
end
for (Bsig, A1sig, A2sig, gbb, funcname) in
(
(SparseMatrixCSC , SparseMatrixCSC , Array, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
(SparseMatrixCSC , Array , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
(SparseMatrixCSC , Number , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
(SparseMatrixCSC , SparseMatrixCSC , Number, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
(SparseMatrixCSC , BitArray , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
(SparseMatrixCSC , SparseMatrixCSC , BitArray, :gen_broadcast_body_zpreserving, :_broadcast_zpreserving!),
)
@eval let cache = Dict{Function,Function}()
global $funcname
function $funcname(f::Function, B::$Bsig, A1::$A1sig, A2::$A2sig)
func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC)
# need eval because func was just created by gen_broadcast_function_sparse
# TODO: convert this to a generated function
eval(current_module(), Expr(:body, Expr(:return, Expr(:call, QuoteNode(func), QuoteNode(B), QuoteNode(A1), QuoteNode(A2)))))
return B
end
end # let broadcast_cache
end
_broadcast_zpreserving!(args...) = broadcast!(args...)
_broadcast_zpreserving(args...) = Base.Broadcast.broadcast_elwise_op(args...)
_broadcast_zpreserving{Tv1,Ti1,Tv2,Ti2}(f::Function, A_1::SparseMatrixCSC{Tv1,Ti1}, A_2::SparseMatrixCSC{Tv2,Ti2}) =
_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)
_broadcast_zpreserving{Tv,Ti}(f::Function, A_1::SparseMatrixCSC{Tv,Ti}, A_2::Union{Array,BitArray,Number}) =
_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)
_broadcast_zpreserving{Tv,Ti}(f::Function, A_1::Union{Array,BitArray,Number}, A_2::SparseMatrixCSC{Tv,Ti}) =
_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)

function _depstring_bczpres()
return string("broadcast_zpreserving[!] is deprecated. Generic sparse broadcast[!] ",
"provides most of broadcast_zpreserving[!]'s functionality. If you have a use case ",
"that generic sparse broadcast[!] does not cover, please describe your use case in ",
" issue #19533 (https://github.com/JuliaLang/julia/issues/19533).")
end
function _depwarn_bczpres(f, args...)
depwarn(_depstring_bczpres(), :broadcast_zpreserving)
return _broadcast_zpreserving(f, args...)
end
function _depwarn_bczpres!(f, args...)
depwarn(_depstring_bczpres(), :broadcast_zpreserving!)
return _broadcast_zpreserving!(f, args...)
end
eval(SparseArrays, :(broadcast_zpreserving(f, args...) = Base._depwarn_bczpres(f, args...)))
eval(SparseArrays, :(broadcast_zpreserving(f, A::SparseMatrixCSC, B::SparseMatrixCSC) = Base._depwarn_bczpres(f, A, B)))
eval(SparseArrays, :(broadcast_zpreserving(f, A::SparseMatrixCSC, B::Union{Array,BitArray,Number}) = Base._depwarn_bczpres(f, A, B)))
eval(SparseArrays, :(broadcast_zpreserving(f, A::Union{Array,BitArray,Number}, B::SparseMatrixCSC) = Base._depwarn_bczpres(f, A, B)))
eval(SparseArrays, :(broadcast_zpreserving!(f, args...) = Base._depwarn_bczpres!(f, args...)))
eval(SparseArrays, :(broadcast_zpreserving!(f, C::SparseMatrixCSC, A::SparseMatrixCSC, B::Union{Array,BitArray,Number}) = Base._depwarn_bczpres!(f, C, A, B)))
eval(SparseArrays, :(broadcast_zpreserving!(f, C::SparseMatrixCSC, A::Union{Array,BitArray,Number}, B::SparseMatrixCSC) = Base._depwarn_bczpres!(f, C, A, B)))

# #19719
@deprecate getindex(t::Tuple, r::AbstractArray) getindex(t, vec(r))
@deprecate getindex(t::Tuple, b::AbstractArray{Bool}) getindex(t, vec(b))
Expand Down
111 changes: 0 additions & 111 deletions base/sparse/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2160,117 +2160,6 @@ broadcast{Tf,T}(f::Tf, ::Type{T}, A::SparseMatrixCSC) = broadcast(y -> f(T, y),
broadcast{Tf,T}(f::Tf, A::SparseMatrixCSC, ::Type{T}) = broadcast(x -> f(x, T), A)


## Define unexported broadcast_zpreserving[!] methods
# TODO: Sort out what to do with broadcast_zpreserving and dependencies

function gen_broadcast_function_sparse(genbody::Function, f::Function, is_first_sparse::Bool)
body = genbody(f, is_first_sparse)
@eval let
local _F_
function _F_{Tv,Ti}(B::SparseMatrixCSC{Tv,Ti}, A_1, A_2)
$body
end
_F_
end
end

# Operations with zero result if any operand is zero
# A_1 or A_2 (or both) are sparse.
# is_first_sparse == true => A_1 is sparse
# is_first_sparse == false => A_2 is sparse
function gen_broadcast_body_zpreserving(f::Function, is_first_sparse::Bool)
F = Expr(:quote, f)
if is_first_sparse
A1 = :(A_1)
A2 = :(A_2)
op1 = :(val1)
op2 = :(val2)
else
A1 = :(A_2)
A2 = :(A_1)
op1 = :(val2)
op2 = :(val1)
end
quote
Base.Broadcast.check_broadcast_indices(indices(B), $A1)
Base.Broadcast.check_broadcast_indices(indices(B), $A2)

nnzB = isempty(B) ? 0 :
nnz($A1) * div(B.n, ($A1).n) * div(B.m, ($A1).m)
if length(B.rowval) < nnzB
resize!(B.rowval, nnzB)
end
if length(B.nzval) < nnzB
resize!(B.nzval, nnzB)
end
z = zero(Tv)

ptrB = 1
B.colptr[1] = 1

@inbounds for col = 1:B.n
ptr1::Int = ($A1).n == 1 ? ($A1).colptr[1] : ($A1).colptr[col]
stop1::Int = ($A1).n == 1 ? ($A1).colptr[2] : ($A1).colptr[col+1]
col2 = size($A2, 2) == 1 ? 1 : col
row = 1
while ptr1 < stop1 && row <= B.m
if ($A1).m != 1
row = ($A1).rowval[ptr1]
end
row2 = size($A2, 1) == 1 ? 1 : row
val1 = ($A1).nzval[ptr1]
val2 = ($A2)[row2,col2]
res = ($F)($op1, $op2)
if res != z
B.rowval[ptrB] = row
B.nzval[ptrB] = res
ptrB += 1
end
if ($A1).m != 1
ptr1 += 1
else
row += 1
end
end
B.colptr[col+1] = ptrB
end
deleteat!(B.rowval, B.colptr[end]:length(B.rowval))
deleteat!(B.nzval, B.colptr[end]:length(B.nzval))
nothing
end
end

for (Bsig, A1sig, A2sig, gbb, funcname) in
(
(SparseMatrixCSC , SparseMatrixCSC , Array, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
(SparseMatrixCSC , Array , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
(SparseMatrixCSC , Number , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
(SparseMatrixCSC , SparseMatrixCSC , Number, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
(SparseMatrixCSC , BitArray , SparseMatrixCSC, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
(SparseMatrixCSC , SparseMatrixCSC , BitArray, :gen_broadcast_body_zpreserving, :broadcast_zpreserving!),
)
@eval let cache = Dict{Function,Function}()
global $funcname
function $funcname(f::Function, B::$Bsig, A1::$A1sig, A2::$A2sig)
func = @get! cache f gen_broadcast_function_sparse($gbb, f, ($A1sig) <: SparseMatrixCSC)
# need eval because func was just created by gen_broadcast_function_sparse
# TODO: convert this to a generated function
eval(current_module(), Expr(:body, Expr(:return, Expr(:call, QuoteNode(func), QuoteNode(B), QuoteNode(A1), QuoteNode(A2)))))
return B
end
end # let broadcast_cache
end

@inline broadcast_zpreserving!(args...) = broadcast!(args...)
@inline broadcast_zpreserving(args...) = Base.Broadcast.broadcast_elwise_op(args...)
broadcast_zpreserving{Tv1,Ti1,Tv2,Ti2}(f::Function, A_1::SparseMatrixCSC{Tv1,Ti1}, A_2::SparseMatrixCSC{Tv2,Ti2}) =
broadcast_zpreserving!(f, spzeros(promote_type(Tv1, Tv2), promote_type(Ti1, Ti2), to_shape(broadcast_indices(A_1, A_2))), A_1, A_2)
broadcast_zpreserving{Tv,Ti}(f::Function, A_1::SparseMatrixCSC{Tv,Ti}, A_2::Union{Array,BitArray,Number}) =
broadcast_zpreserving!(f, spzeros(promote_eltype(A_1, A_2), Ti, to_shape(broadcast_indices(A_1, A_2))), A_1, A_2)
broadcast_zpreserving{Tv,Ti}(f::Function, A_1::Union{Array,BitArray,Number}, A_2::SparseMatrixCSC{Tv,Ti}) =
broadcast_zpreserving!(f, spzeros(promote_eltype(A_1, A_2), Ti, to_shape(broadcast_indices(A_1, A_2))), A_1, A_2)


# TODO: More appropriate location?
conj!(A::SparseMatrixCSC) = (broadcast!(conj, A.nzval, A.nzval); A)
(-)(A::SparseMatrixCSC) = SparseMatrixCSC(A.m, A.n, copy(A.colptr), copy(A.rowval), map(-, A.nzval))
Expand Down

0 comments on commit 6ad62c4

Please sign in to comment.