Skip to content

Commit

Permalink
[HSL_MC66] Add a Julia interface
Browse files Browse the repository at this point in the history
  • Loading branch information
amontoison committed Oct 17, 2022
1 parent 9c93a1d commit b50ab7c
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 8 deletions.
10 changes: 2 additions & 8 deletions deps/versions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,7 @@ hsl_collection["hsl_mc66"] = [
"bc17cfca531bb2407ab53570bf8fa725e0c3265a0bfa4ce492ac54ad89856abc",
".zip",
),
]

hsl_collection["hsl_mi35"] = [
HSLVersion(
"2.0.1",
"39d22d55dd36776e5400313b8c2915bb39823b19740aee7a390937072f7cd7b1",
".zip",
),
HSLVersion("2.2.1", "cb7df2591c1a01783f8a07cfe7a20bcd4ba9ef7a1169a68b0f117cd1683066dd", ".tar.gz"),
HSLVersion("2.2.1", "8ff58f90855a67081a35d79fcca60ad4fc97c2dce78c99c1ff4f225cdcd39b6c", ".zip"),
]
#! format: on
102 changes: 102 additions & 0 deletions src/hsl_mc66.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
export mc66, mc66_control

mutable struct fa14_seed
ix::Int32
end

fa14_seed() = fa14_seed(65535)

mutable struct mc66_control{T <: BLAS.BlasReal}
lp::Int32
wp::Int32
mp::Int32
print_level::Int32
kl_aggressive::T
max_imbalance::T
mglevel::Int32
grid_rdc_fac::T
coarsest_size::Int32
coarsen_scheme::Int32
num_coarsest_kl::Int32
end

function mc66_control{T}(; lp=6, wp=6, mp=6, print_level=-1, kl_aggressive=-1, max_imbalance=0.01,
mglevel=typemax(Int32), grid_rdc_fac=0.75, coarsest_size=100,
coarsen_scheme=1, num_coarsest_kl=4) where {T <: BLAS.BlasReal}

control = mc66_control{T}(lp, wp, mp, print_level, kl_aggressive, max_imbalance, mglevel,
grid_rdc_fac, coarsest_size, coarsen_scheme, num_coarsest_kl)
return control
end

#! format: off
# Thanks to `nm -D libhsl_mc66.so`!
function mc66s(m, n, nz, irn, jcn, nblocks, control, seed, row_order, info, rowptr, column_order, colptr, netcut, rowdiff, kblocks)
ccall((:__hsl_mc66_simple_MOD_monet, libhsl_mc66),
Cvoid,
(Ref{Int32}, Ref{Int32}, Ref{Int32}, Ptr{Int32}, Ptr{Int32}, Ref{Int32}, Ref{mc66_control{Float32}}, Ref{fa14_seed}, Ptr{Int32}, Ref{Int32}, Ptr{Int32}, Ptr{Int32} , Ptr{Int32}, Ref{Int32}, Ref{Float32}, Ref{Int32}),
m , n , nz , irn , jcn , nblocks , control , seed , row_order , info , rowptr , column_order, colptr , netcut , rowdiff , kblocks )
end

function mc66s_print_message(info)
lp = Ref{Int32}(6)
wp = Ref{Int32}(6)
context = Ptr{Cvoid}()
ccall((:__hsl_mc66_single_MOD_monet_print_message, libhsl_mc66),
Cvoid,
(Ref{Int32}, Ref{Int32}, Ref{Int32}, Cstring),
info , lp , wp , context)
end

function mc66d(m, n, nz, irn, jcn, nblocks, control, seed, row_order, info, rowptr, column_order, colptr, netcut, rowdiff, kblocks)
ccall((:__hsl_mc66_double_MOD_monet, libhsl_mc66),
Cvoid,
(Ref{Int32}, Ref{Int32}, Ref{Int32}, Ptr{Int32}, Ptr{Int32}, Ref{Int32}, Ref{mc66_control{Float64}}, Ref{fa14_seed}, Ptr{Int32}, Ref{Int32}, Ptr{Int32}, Ptr{Int32} , Ptr{Int32}, Ref{Int32}, Ref{Float64}, Ref{Int32}),
m , n , nz , irn , jcn , nblocks , control , seed , row_order , info , rowptr , column_order, colptr , netcut , rowdiff , kblocks )
end

function mc66d_print_message(info, control)
context = Ptr{Cvoid}()
ccall((:__hsl_mc66_double_MOD_monet_print_message, libhsl_mc66),
Cvoid,
(Ref{Int32}, Ref{Int32}, Ref{Int32}, Cstring),
info , control.lp, control.wp, context)
end
#! format: on

"""
rp, cp = mc66(A::SparseMatrixCSC, k::Integer)
Order an unsymmetric matrix A into singly bordered blocked diagonal (SBBD) form.
A[rp, cp] = [ A₁₁ S₁]
[ A₂₂ S₂]
[ • • ]
[ • • ]
[ • • ]
[ Aₖₖ Sₖ]
"""
function mc66(A::SparseMatrixCSC, nblocks::Integer)
m, n = size(A)
nblocks min(m,n) || error("1 ≤ nblocks ≤ min(m,n)")
m = Ref{Int32}(m)
n = Ref{Int32}(n)
nz = Ref{Int32}(nnz(A))
irn, jcn, val = findnz(A)
irn = convert(Vector{Cint}, irn)
jcn = convert(Vector{Cint}, jcn)
nblocks = Ref{Int32}(nblocks)
control = mc66_control{Float64}()
seed = fa14_seed()
row_order = zeros(Cint, m[])
info = Ref{Cint}()
rowptr = zeros(Cint, nblocks[]+1)
column_order = zeros(Cint, n[])
colptr = zeros(Cint, nblocks[]+1)
netcut = Ref{Cint}()
rowdiff = Ref{Float64}()
kblocks = Ref{Cint}()
mc66d(m, n, nz, irn, jcn, nblocks, control, seed, row_order, info, rowptr, column_order, colptr, netcut, rowdiff, kblocks)
mc66d_print_message(info[], control)
return row_order, column_order
end
18 changes: 18 additions & 0 deletions test/test_hsl_mc66.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@testset "hsl_mc66" begin
#! format: off
A = [1 1 0 0;
1 0 1 1;
1 1 0 0;
1 0 1 1]

B = [1 0 0 1;
1 0 0 1;
0 1 1 1;
0 1 1 1]
#! format: on
C = SparseMatrixCSC(A)
rp, cp = mc66(C, 2)
@test isperm(rp)
@test isperm(cp)
@test A[rp,cp] == B
end

0 comments on commit b50ab7c

Please sign in to comment.