Skip to content

Commit

Permalink
Merge pull request #19639 from pabloferz/pz/inline-broadcast
Browse files Browse the repository at this point in the history
Reduce allocations in broadcast
  • Loading branch information
stevengj authored Dec 20, 2016
2 parents b0a4153 + 4c964d3 commit 99b6a8c
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 10 deletions.
7 changes: 3 additions & 4 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ Base.@propagate_inbounds _broadcast_getindex(::Any, A, I) = A[I]
# of keeps). The first two type parameters are to ensure specialization.
@generated function _broadcast!{K,ID,AT,nargs}(f, B::AbstractArray, keeps::K, Idefaults::ID, As::AT, ::Type{Val{nargs}}, iter)
quote
$(Expr(:meta, :noinline))
$(Expr(:meta, :inline))
# destructure the keeps and As tuples
@nexprs $nargs i->(A_i = As[i])
@nexprs $nargs i->(keep_i = keeps[i])
Expand All @@ -147,7 +147,7 @@ end
# and then copy in chunks into the output
@generated function _broadcast!{K,ID,AT,nargs}(f, B::BitArray, keeps::K, Idefaults::ID, As::AT, ::Type{Val{nargs}}, iter)
quote
$(Expr(:meta, :noinline))
$(Expr(:meta, :inline))
# destructure the keeps and As tuples
@nexprs $nargs i->(A_i = As[i])
@nexprs $nargs i->(keep_i = keeps[i])
Expand Down Expand Up @@ -241,9 +241,8 @@ function broadcast_t(f, ::Type{Any}, shape, iter, As...)
B[I] = val
return _broadcast!(f, B, keeps, Idefaults, As, Val{nargs}, iter, st, 1)
end
@inline function broadcast_t(f, T, shape, iter, As...)
@inline function broadcast_t{nargs}(f, T, shape, iter, As::Vararg{Any,nargs})
B = similar(Array{T}, shape)
nargs = length(As)
keeps, Idefaults = map_newindexer(shape, As)
_broadcast!(f, B, keeps, Idefaults, As, Val{nargs}, iter)
return B
Expand Down
15 changes: 11 additions & 4 deletions base/linalg/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -559,23 +559,30 @@ function eigvecs{T}(M::Bidiagonal{T})
n = length(M.dv)
Q = Array{T}(n, n)
blks = [0; find(x -> x == 0, M.ev); n]
v = zeros(T, n)
if M.isupper
for idx_block = 1:length(blks) - 1, i = blks[idx_block] + 1:blks[idx_block + 1] #index of eigenvector
v=zeros(T, n)
fill!(v, zero(T))
v[blks[idx_block] + 1] = one(T)
for j = blks[idx_block] + 1:i - 1 #Starting from j=i, eigenvector elements will be 0
v[j+1] = (M.dv[i] - M.dv[j])/M.ev[j] * v[j]
end
Q[:, i] = v/norm(v)
c = norm(v)
for j = 1:n
Q[j, i] = v[j] / c
end
end
else
for idx_block = 1:length(blks) - 1, i = blks[idx_block + 1]:-1:blks[idx_block] + 1 #index of eigenvector
v = zeros(T, n)
fill!(v, zero(T))
v[blks[idx_block+1]] = one(T)
for j = (blks[idx_block+1] - 1):-1:max(1, (i - 1)) #Starting from j=i, eigenvector elements will be 0
v[j] = (M.dv[i] - M.dv[j+1])/M.ev[j] * v[j+1]
end
Q[:,i] = v/norm(v)
c = norm(v)
for j = 1:n
Q[j, i] = v[j] / c
end
end
end
Q #Actually Triangular
Expand Down
4 changes: 2 additions & 2 deletions base/linalg/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,9 @@ svdvals(D::Diagonal) = [svdvals(v) for v in D.diag]
function svd{T<:Number}(D::Diagonal{T})
S = abs.(D.diag)
piv = sortperm(S, rev = true)
U = Array(Diagonal(D.diag ./ S))
U = Diagonal(D.diag ./ S)
Up = hcat([U[:,i] for i = 1:length(D.diag)][piv]...)
V = eye(D)
V = Diagonal(ones(D.diag))
Vp = hcat([V[:,i] for i = 1:length(D.diag)][piv]...)
return (Up, S[piv], Vp)
end
Expand Down

0 comments on commit 99b6a8c

Please sign in to comment.