Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
* upstream/master:
  fix type-inference bug for tupleref((..),0)
  Rename profile C functions
  Add sparse triangular solver. Make A_ldiv_B a polyalgorithm, some reorganization and some tests.
  • Loading branch information
Michael Fox committed Dec 3, 2013
2 parents b830fa1 + 915a43a commit 54ddd9d
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 66 deletions.
2 changes: 2 additions & 0 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ const tupleref_tfunc = function (A, t, i)
end
elseif i == n && vararg
return last.parameters[1]
elseif i <= 0
return None
else
return tupleref(t,i)
end
Expand Down
10 changes: 8 additions & 2 deletions base/linalg/factorization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ macro assertnonsingular(A, info)
:(($info)==0 ? $A : throw(SingularException($info)))
end

\(F::Factorization, b::Union(AbstractVector, AbstractMatrix)) = A_ldiv_B!(F, copy(b))
A_ldiv_B!(C::Factorization, B::StridedVecOrMat) = A_ldiv_B!(C, float(B))
typealias AbstractVecOrMat Union(AbstractVector, AbstractMatrix)

\(F::Factorization, B::AbstractVecOrMat) = A_ldiv_B!(F, copy(B))
Ac_ldiv_B(F::Factorization, B::AbstractVecOrMat) = Ac_ldiv_B!(F, copy(B))
At_ldiv_B(F::Factorization, B::AbstractVecOrMat) = At_ldiv_B!(F, copy(B))
A_ldiv_B!(F::Factorization, B::StridedVecOrMat) = A_ldiv_B!(F, float(B))
Ac_ldiv_B!(F::Factorization, B::StridedVecOrMat) = Ac_ldiv_B!(F, float(B))
At_ldiv_B!(F::Factorization, B::StridedVecOrMat) = At_ldiv_B!(F, float(B))

type Cholesky{T<:BlasFloat} <: Factorization{T}
UL::Matrix{T}
Expand Down
56 changes: 56 additions & 0 deletions base/linalg/sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,62 @@ function *{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti})
Ctt = Base.SparseMatrix.transpose!(Ct, SparseMatrixCSC(mA, nB, colptrC, rowvalC, nzvalC))
end

## solvers
function A_ldiv_B!(A::SparseMatrixCSC, b::AbstractVector)
if istril(A)
if istriu(A) return A_ldiv_B!(Diagonal(A.nzval), b) end
return fwdTriSolve!(A, b)
end
if istriu(A) return bwdTriSolve!(A, b) end
return A_ldiv_B!(lufact(A),b)
end

function fwdTriSolve!(A::SparseMatrixCSC, b::AbstractVector)
# forward substitution for CSC matrices
n = length(b)
ncol = chksquare(A)
if n != ncol throw(DimensionMismatch("A is $(ncol)X$(ncol) and b has length $(n)")) end

aa = A.nzval
ja = A.rowval
ia = A.colptr

for j = 1:n - 1
i1 = ia[j]
i2 = ia[j+1]-1
b[j] /= aa[i1]
bj = b[j]
for i = i1+1:i2
b[ja[i]] -= bj*aa[i]
end
end
b[end] /= aa[end]
return b
end

function bwdTriSolve!(A::SparseMatrixCSC, b::AbstractVector)
# backward substitution for CSC matrices
n = length(b)
ncol = chksquare(A)
if n != ncol throw(DimensionMismatch("A is $(ncol)X$(ncol) and b has length $(n)")) end

aa = A.nzval
ja = A.rowval
ia = A.colptr

for j = n:-1:2
i1 = ia[j]
i2 = ia[j+1]-1
b[j] /= aa[i2]
bj = b[j]
for i = i2-1:-1:i1
b[ja[i]] -= bj*aa[i]
end
end
b[1] /= aa[1]
return b
end

## triu, tril

function triu{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, k::Integer)
Expand Down
55 changes: 21 additions & 34 deletions base/linalg/umfpack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export UmfpackLU,

import Base: (\), Ac_ldiv_B, At_ldiv_B, findnz, getindex, nnz, show, size

import ..LinAlg: Factorization, det, lufact, lufact!, solve
import ..LinAlg: A_ldiv_B!, Ac_ldiv_B!, At_ldiv_B!, Factorization, det, lufact, lufact!, solve

include("umfpack_h.jl")
type MatrixIllConditionedException <: Exception
Expand Down Expand Up @@ -278,42 +278,29 @@ for (sym_r,sym_c,num_r,num_c,sol_r,sol_c,det_r,det_z,lunz,get_num_r,get_num_z,it
end

### Solve with Factorization

(\){T<:UMFVTypes}(fact::UmfpackLU{T}, b::Vector{T}) = solve(fact, b)
(\){Ts<:UMFVTypes,Tb<:Number}(fact::UmfpackLU{Ts}, b::Vector{Tb}) = fact\convert(Vector{Ts},b)
function (\){Tb<:Complex}(fact::UmfpackLU{Float64}, b::Vector{Tb})
r = fact\[convert(Float64,real(be)) for be in b]
i = fact\[convert(Float64,imag(be)) for be in b]
Complex128[r[k]+im*i[k] for k = 1:length(r)]
end
At_ldiv_B{T<:UMFVTypes}(fact::UmfpackLU{T}, b::Vector{T}) = solve(fact, b, UMFPACK_Aat)
At_ldiv_B{Ts<:UMFVTypes,Tb<:Number}(fact::UmfpackLU{Ts}, b::Vector{Tb}) = fact.'\convert(Vector{Ts},b)
At_ldiv_B{Tb<:Complex}(fact::UmfpackLU{Float64}, b::Vector{Tb}) = fact.'\b
Ac_ldiv_B{T<:UMFVTypes}(fact::UmfpackLU{T}, b::Vector{T}) = solve(fact, b, UMFPACK_At)
Ac_ldiv_B{Ts<:UMFVTypes,Tb<:Number}(fact::UmfpackLU{Ts}, b::Vector{Tb}) = fact'\convert(Vector{Ts},b)
Ac_ldiv_B{Tb<:Complex}(fact::UmfpackLU{Float64}, b::Vector{Tb}) = fact'\b

### Solve directly with matrix

(\)(S::SparseMatrixCSC, b::Vector) = lufact(S) \ b
At_ldiv_B{T<:UMFVTypes}(S::SparseMatrixCSC{T}, b::Vector{T}) = solve(lufact(S), b, UMFPACK_Aat)
At_ldiv_B{Ts<:UMFVTypes,Tb<:Number}(S::SparseMatrixCSC{Ts}, b::Vector{Tb}) = At_ldiv_B(S, convert(Vector{Ts}, b))
function At_ldiv_B{Tb<:Complex}(S::SparseMatrixCSC{Float64}, b::Vector{Tb})
F = lufact(S)
r = solve(F, [convert(Float64,real(be)) for be in b], UMFPACK_Aat)
i = solve(F, [convert(Float64,imag(be)) for be in b], UMFPACK_Aat)
Complex128[r[k]+im*i[k] for k = 1:length(r)]
A_ldiv_B!{T<:UMFVTypes}(lu::UmfpackLU{T}, b::Vector{T}) = solve(lu, b, UMFPACK_A)
function A_ldiv_B!{Tlu<:Real,Tb<:Complex}(lu::UmfpackLU{Tlu}, b::Vector{Tb})
r = solve(lu, [convert(Tlu,real(be)) for be in b], UMFPACK_A)
i = solve(lu, [convert(Tlu,imag(be)) for be in b], UMFPACK_A)
Tb[r[k]+im*i[k] for k = 1:length(r)]
end
Ac_ldiv_B{T<:UMFVTypes}(S::SparseMatrixCSC{T}, b::Vector{T}) = solve(lufact(S), b, UMFPACK_At)
Ac_ldiv_B{Ts<:UMFVTypes,Tb<:Number}(S::SparseMatrixCSC{Ts}, b::Vector{Tb}) = Ac_ldiv_B(S, convert(Vector{Ts}, b))
function Ac_ldiv_B{Tb<:Complex}(S::SparseMatrixCSC{Float64}, b::Vector{Tb})
F = lufact(S)
r = solve(F, [convert(Float64,real(be)) for be in b], UMFPACK_At)
i = solve(F, [convert(Float64,imag(be)) for be in b], UMFPACK_At)
Complex128[r[k]+im*i[k] for k = 1:length(r)]
A_ldiv_B!{Tlu<:UMFVTypes,Tb<:Number}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) = A_ldiv_B!(lu, convert(Vector{Tlu}, b))

Ac_ldiv_B!{T<:UMFVTypes}(lu::UmfpackLU{T}, b::Vector{T}) = solve(lu, b, UMFPACK_At)
function Ac_ldiv_B!{Tlu<:Real,Tb<:Complex}(lu::UmfpackLU{Tlu}, b::Vector{Tb})
r = solve(lu, [convert(Float64,real(be)) for be in b], UMFPACK_At)
i = solve(lu, [convert(Float64,imag(be)) for be in b], UMFPACK_At)
Tb[r[k]+im*i[k] for k = 1:length(r)]
end
Ac_ldiv_B!{Tlu<:UMFVTypes,Tb<:Number}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) = Ac_ldiv_B!(lu, convert(Vector{Tlu}, b))

solve(lu::UmfpackLU, b::Vector) = solve(lu, b, UMFPACK_A)
At_ldiv_B!{T<:UMFVTypes}(lu::UmfpackLU{T}, b::Vector{T}) = solve(lu, b, UMFPACK_Aat)
function At_ldiv_B!{Tlu<:Real,Tb<:Complex}(lu::UmfpackLU{Tlu}, b::Vector{Tb})
r = solve(lu, [convert(Float64,real(be)) for be in b], UMFPACK_Aat)
i = solve(lu, [convert(Float64,imag(be)) for be in b], UMFPACK_Aat)
Tb[r[k]+im*i[k] for k = 1:length(r)]
end
At_ldiv_B!{Tlu<:UMFVTypes,Tb<:Number}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) = At_ldiv_B!(lu, convert(Vector{Tlu}, b))

function getindex(lu::UmfpackLU, d::Symbol)
L,U,p,q,Rs = umf_extract(lu)
Expand Down
16 changes: 8 additions & 8 deletions base/profile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ end
#### User-level functions
####
function init(n::Integer, delay::Float64)
status = ccall(:profile_init, Cint, (Csize_t, Uint64), n, iround(10^9*delay))
status = ccall(:jl_profile_init, Cint, (Csize_t, Uint64), n, iround(10^9*delay))
if status == -1
error("could not allocate space for ", n, " instruction pointers")
end
end

clear() = ccall(:profile_clear_data, Void, ())
clear() = ccall(:jl_profile_clear_data, Void, ())

function print{T<:Unsigned}(io::IO = STDOUT, data::Vector{T} = fetch(); format = :tree, C = false, combine = true, cols = Base.tty_cols())
if format == :tree
Expand Down Expand Up @@ -75,17 +75,17 @@ isequal(a::LineInfo, b::LineInfo) = a.line == b.line && a.func == b.func && a.fi
hash(li::LineInfo) = bitmix(hash(li.func), bitmix(hash(li.file), hash(li.line)))

# C wrappers
start_timer() = ccall(:profile_start_timer, Cint, ())
start_timer() = ccall(:jl_profile_start_timer, Cint, ())

stop_timer() = ccall(:profile_stop_timer, Void, ())
stop_timer() = ccall(:jl_profile_stop_timer, Void, ())

is_running() = bool(ccall(:profile_is_running, Cint, ()))
is_running() = bool(ccall(:jl_profile_is_running, Cint, ()))

get_data_pointer() = convert(Ptr{Uint}, ccall(:profile_get_data, Ptr{Uint8}, ()))
get_data_pointer() = convert(Ptr{Uint}, ccall(:jl_profile_get_data, Ptr{Uint8}, ()))

len_data() = convert(Int, ccall(:profile_len_data, Csize_t, ()))
len_data() = convert(Int, ccall(:jl_profile_len_data, Csize_t, ()))

maxlen_data() = convert(Int, ccall(:profile_maxlen_data, Csize_t, ()))
maxlen_data() = convert(Int, ccall(:jl_profile_maxlen_data, Csize_t, ()))

function lookup(ip::Uint, doCframes::Bool)
info = ccall(:jl_lookup_code_address, Any, (Ptr{Void}, Bool), ip, doCframes)
Expand Down
16 changes: 8 additions & 8 deletions src/julia.expmap
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,14 @@
jl_lookup_code_address;
jl_read_sonames;
rec_backtrace;
profile_init;
profile_get_data;
profile_len_data;
profile_maxlen_data;
profile_clear_data;
profile_start_timer;
profile_stop_timer;
profile_is_running;
jl_profile_init;
jl_profile_get_data;
jl_profile_len_data;
jl_profile_maxlen_data;
jl_profile_clear_data;
jl_profile_start_timer;
jl_profile_stop_timer;
jl_profile_is_running;
jl_reshape_array;
jl_restore_system_image;
jl_run_event_loop;
Expand Down
28 changes: 14 additions & 14 deletions src/profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam )
hBtThread = 0;
return 0;
}
DLLEXPORT int profile_start_timer(void)
DLLEXPORT int jl_profile_start_timer(void)
{
running = 1;
if (hBtThread == 0) {
Expand All @@ -78,7 +78,7 @@ DLLEXPORT int profile_start_timer(void)
}
return (hBtThread != NULL ? 0 : -1);
}
DLLEXPORT void profile_stop_timer(void)
DLLEXPORT void jl_profile_stop_timer(void)
{
running = 0;
}
Expand Down Expand Up @@ -229,7 +229,7 @@ void *mach_profile_listener(void *arg)
}
}

DLLEXPORT int profile_start_timer(void)
DLLEXPORT int jl_profile_start_timer(void)
{
kern_return_t ret;
if (!profile_started) {
Expand Down Expand Up @@ -268,7 +268,7 @@ DLLEXPORT int profile_start_timer(void)
return 0;
}

DLLEXPORT void profile_stop_timer(void)
DLLEXPORT void jl_profile_stop_timer(void)
{
running = 0;
}
Expand Down Expand Up @@ -296,7 +296,7 @@ static void profile_bt(int dummy)
}
}

DLLEXPORT int profile_start_timer(void)
DLLEXPORT int jl_profile_start_timer(void)
{
timerprof.it_interval.tv_sec = 0;
timerprof.it_interval.tv_usec = 0;
Expand All @@ -311,7 +311,7 @@ DLLEXPORT int profile_start_timer(void)
return 0;
}

DLLEXPORT void profile_stop_timer(void)
DLLEXPORT void jl_profile_stop_timer(void)
{
running = 0;
}
Expand Down Expand Up @@ -343,7 +343,7 @@ static void profile_bt(int signal, siginfo_t *si, void *uc)
}
}

DLLEXPORT int profile_start_timer(void)
DLLEXPORT int jl_profile_start_timer(void)
{
struct sigevent sigprof;
struct sigaction sa;
Expand Down Expand Up @@ -376,7 +376,7 @@ DLLEXPORT int profile_start_timer(void)
return 0;
}

DLLEXPORT void profile_stop_timer(void)
DLLEXPORT void jl_profile_stop_timer(void)
{
if (running)
timer_delete(timerprof);
Expand All @@ -389,7 +389,7 @@ DLLEXPORT void profile_stop_timer(void)
///////////////////////
// Utility functions //
///////////////////////
DLLEXPORT int profile_init(size_t maxsize, u_int64_t delay_nsec)
DLLEXPORT int jl_profile_init(size_t maxsize, u_int64_t delay_nsec)
{
bt_size_max = maxsize;
nsecprof = delay_nsec;
Expand All @@ -402,27 +402,27 @@ DLLEXPORT int profile_init(size_t maxsize, u_int64_t delay_nsec)
return 0;
}

DLLEXPORT u_int8_t* profile_get_data(void)
DLLEXPORT u_int8_t* jl_profile_get_data(void)
{
return (u_int8_t*) bt_data_prof;
}

DLLEXPORT size_t profile_len_data(void)
DLLEXPORT size_t jl_profile_len_data(void)
{
return bt_size_cur;
}

DLLEXPORT size_t profile_maxlen_data(void)
DLLEXPORT size_t jl_profile_maxlen_data(void)
{
return bt_size_max;
}

DLLEXPORT void profile_clear_data(void)
DLLEXPORT void jl_profile_clear_data(void)
{
bt_size_cur = 0;
}

DLLEXPORT int profile_is_running(void)
DLLEXPORT int jl_profile_is_running(void)
{
return running;
}
11 changes: 11 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1165,3 +1165,14 @@ macro myassert4873(ex)
end
x4873 = 1
@myassert4873 (x -> x)(x4873) == 1

# issue from IRC
function invalid_tupleref()
A = (1, "2", 3.0)
try
return A[0]
catch
return true
end
end
@test invalid_tupleref()==true
Loading

0 comments on commit 54ddd9d

Please sign in to comment.