Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interface MA27 #215

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OpenBLAS32_jll = "656ef2d0-ae68-5445-9ca0-591084a874a2"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[weakdeps]
Quadmath = "be4d8f0f-7fa4-5f49-b795-2f01399ab2dd"

[extensions]
HSLQuadmathExt = "Quadmath"

[compat]
Quadmath = "0.5.10"
OpenBLAS32_jll = "0.3.9"
julia = "^1.6.0"

Expand Down
11 changes: 11 additions & 0 deletions ext/HSLQuadmathExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module HSLQuadmathExt

using HSL
using Quadmath
using LinearAlgebra
using SparseArrays
import HSL.libhsl_subset

include("Quadmath/wrappers.jl")

end
161 changes: 161 additions & 0 deletions ext/Quadmath/wrappers.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
function HSL.ma27iq(icntl, cntl)
@ccall libhsl_subset.ma27iq_(icntl::Ptr{Cint}, cntl::Ptr{Float128})::Cvoid
end

function HSL.ma27aq(n, nz, irn, icn, iw, liw, ikeep, iw1, nsteps, iflag, icntl, cntl, info, ops)
@ccall libhsl_subset.ma27aq_(n::Ref{Cint}, nz::Ref{Cint}, irn::Ptr{Cint}, icn::Ptr{Cint}, iw::Ptr{Cint},
liw::Ref{Cint}, ikeep::Ptr{Cint}, iw1::Ptr{Cint}, nsteps::Ref{Cint},
iflag::Ref{Cint}, icntl::Ptr{Cint}, cntl::Ptr{Float128}, info::Ptr{Cint},
ops::Ref{Float128})::Cvoid
end

function HSL.ma27bq(n, nz, irn, icn, a, la, iw, liw, ikeep, nsteps, maxfrt, iw1, icntl, cntl, info)
@ccall libhsl_subset.ma27bq_(n::Ref{Cint}, nz::Ref{Cint}, irn::Ptr{Cint}, icn::Ptr{Cint},
a::Ptr{Float128},
la::Ref{Cint}, iw::Ptr{Cint}, liw::Ref{Cint}, ikeep::Ptr{Cint},
nsteps::Ref{Cint}, maxfrt::Ref{Cint}, iw1::Ptr{Cint}, icntl::Ptr{Cint},
cntl::Ptr{Float128}, info::Ptr{Cint})::Cvoid
end

function HSL.ma27cq(n, a, la, iw, liw, w, maxfrt, rhs, iw1, nsteps, icntl, info)
@ccall libhsl_subset.ma27cq_(n::Ref{Cint}, a::Ptr{Float128}, la::Ref{Cint}, iw::Ptr{Cint},
liw::Ref{Cint},
w::Ptr{Float128}, maxfrt::Ref{Cint}, rhs::Ptr{Float128}, iw1::Ptr{Cint},
nsteps::Ref{Cint}, icntl::Ptr{Cint}, info::Ptr{Cint})::Cvoid
end

function HSL.ma27gq(n, nz, irn, icn, iw, lw, ipe, iq, flag, iwfr, icntl, info)
@ccall libhsl_subset.ma27gq_(n::Ref{Cint}, nz::Ref{Cint}, irn::Ptr{Cint}, icn::Ptr{Cint}, iw::Ptr{Cint},
lw::Ref{Cint}, ipe::Ptr{Cint}, iq::Ptr{Cint}, flag::Ptr{Cint},
iwfr::Ref{Cint}, icntl::Ptr{Cint}, info::Ptr{Cint})::Cvoid
end

function HSL.ma27hq(n, ipe, iw, lw, iwfr, nv, nxt, lst, ipd, flag, iovflo, ncmpa, fratio)
@ccall libhsl_subset.ma27hq_(n::Ref{Cint}, ipe::Ptr{Cint}, iw::Ptr{Cint}, lw::Ref{Cint}, iwfr::Ref{Cint},
nv::Ptr{Cint}, nxt::Ptr{Cint}, lst::Ptr{Cint}, ipd::Ptr{Cint},
flag::Ptr{Cint}, iovflo::Ref{Cint}, ncmpa::Ref{Cint},
fratio::Ref{Float128})::Cvoid
end

function HSL.ma27uq(n, ipe, iw, lw, iwfr, ncmpa)
@ccall libhsl_subset.ma27uq_(n::Ref{Cint}, ipe::Ptr{Cint}, iw::Ptr{Cint}, lw::Ref{Cint}, iwfr::Ref{Cint},
ncmpa::Ref{Cint})::Cvoid
end

function HSL.ma27jq(n, nz, irn, icn, perm, iw, lw, ipe, iq, flag, iwfr, icntl, info)
@ccall libhsl_subset.ma27jq_(n::Ref{Cint}, nz::Ref{Cint}, irn::Ptr{Cint}, icn::Ptr{Cint},
perm::Ptr{Cint},
iw::Ptr{Cint}, lw::Ref{Cint}, ipe::Ptr{Cint}, iq::Ptr{Cint},
flag::Ptr{Cint},
iwfr::Ref{Cint}, icntl::Ptr{Cint}, info::Ptr{Cint})::Cvoid
end

function HSL.ma27kq(n, ipe, iw, lw, iwfr, ips, ipv, nv, flag, ncmpa)
@ccall libhsl_subset.ma27kq_(n::Ref{Cint}, ipe::Ptr{Cint}, iw::Ptr{Cint}, lw::Ref{Cint}, iwfr::Ref{Cint},
ips::Ptr{Cint}, ipv::Ptr{Cint}, nv::Ptr{Cint}, flag::Ptr{Cint},
ncmpa::Ref{Cint})::Cvoid
end

function HSL.ma27lq(n, ipe, nv, ips, ne, na, nd, nsteps, nemin)
@ccall libhsl_subset.ma27lq_(n::Ref{Cint}, ipe::Ptr{Cint}, nv::Ptr{Cint}, ips::Ptr{Cint}, ne::Ptr{Cint},
na::Ptr{Cint}, nd::Ptr{Cint}, nsteps::Ref{Cint}, nemin::Ref{Cint})::Cvoid
end

function HSL.ma27mq(n, nz, irn, icn, perm, na, ne, nd, nsteps, lstki, lstkr, iw, info, ops)
@ccall libhsl_subset.ma27mq_(n::Ref{Cint}, nz::Ref{Cint}, irn::Ptr{Cint}, icn::Ptr{Cint},
perm::Ptr{Cint},
na::Ptr{Cint}, ne::Ptr{Cint}, nd::Ptr{Cint}, nsteps::Ref{Cint},
lstki::Ptr{Cint}, lstkr::Ptr{Cint}, iw::Ptr{Cint}, info::Ptr{Cint},
ops::Ref{Float128})::Cvoid
end

function HSL.ma27nq(n, nz, nz1, a, la, irn, icn, iw, liw, perm, iw2, icntl, info)
@ccall libhsl_subset.ma27nq_(n::Ref{Cint}, nz::Ref{Cint}, nz1::Ref{Cint}, a::Ptr{Float128},
la::Ref{Cint},
irn::Ptr{Cint}, icn::Ptr{Cint}, iw::Ptr{Cint}, liw::Ref{Cint},
perm::Ptr{Cint}, iw2::Ptr{Cint}, icntl::Ptr{Cint}, info::Ptr{Cint})::Cvoid
end

function HSL.ma27oq(n, nz, a, la, iw, liw, perm, nstk, nsteps, maxfrt, nelim, iw2, icntl, cntl, info)
@ccall libhsl_subset.ma27oq_(n::Ref{Cint}, nz::Ref{Cint}, a::Ptr{Float128}, la::Ref{Cint}, iw::Ptr{Cint},
liw::Ref{Cint}, perm::Ptr{Cint}, nstk::Ptr{Cint}, nsteps::Ref{Cint},
maxfrt::Ref{Cint}, nelim::Ptr{Cint}, iw2::Ptr{Cint}, icntl::Ptr{Cint},
cntl::Ptr{Float128}, info::Ptr{Cint})::Cvoid
end

function HSL.ma27pq(a, iw, j1, j2, itop, ireal, ncmpbr, ncmpbi)
@ccall libhsl_subset.ma27pq_(a::Ptr{Float128}, iw::Ptr{Cint}, j1::Ref{Cint}, j2::Ref{Cint},
itop::Ref{Cint}, ireal::Ref{Cint}, ncmpbr::Ref{Cint},
ncmpbi::Ref{Cint})::Cvoid
end

function HSL.ma27qq(n, a, la, iw, liw, w, maxfnt, rhs, iw2, nblk, latop, icntl)
@ccall libhsl_subset.ma27qq_(n::Ref{Cint}, a::Ptr{Float128}, la::Ref{Cint}, iw::Ptr{Cint},
liw::Ref{Cint},
w::Ptr{Float128}, maxfnt::Ref{Cint}, rhs::Ptr{Float128}, iw2::Ptr{Cint},
nblk::Ref{Cint}, latop::Ref{Cint}, icntl::Ptr{Cint})::Cvoid
end

function HSL.ma27rq(n, a, la, iw, liw, w, maxfnt, rhs, iw2, nblk, latop, icntl)
@ccall libhsl_subset.ma27rq_(n::Ref{Cint}, a::Ptr{Float128}, la::Ref{Cint}, iw::Ptr{Cint},
liw::Ref{Cint},
w::Ptr{Float128}, maxfnt::Ref{Cint}, rhs::Ptr{Float128}, iw2::Ptr{Cint},
nblk::Ref{Cint}, latop::Ref{Cint}, icntl::Ptr{Cint})::Cvoid
end


for (iname, aname, bname, cname, T) in ((:ma27iq, :ma27aq, :ma27bq, :ma27cq, :Float128),)
@eval begin
function HSL.Ma27(A::SparseMatrixCSC{$T})
n = LinearAlgebra.checksquare(A)
nz = nnz(A)
irn, icn, a = findnz(A)
la = 4 * nz
liw = 2 * (2 * nz + 3 * n + 1)
iw = Vector{Cint}(undef, liw)
w = Vector{$T}(undef, 0)
ikeep = Vector{Cint}(undef, 3 * n)
iw1 = Vector{Cint}(undef, 2 * n)
nsteps = Ref{Cint}(0)
maxfrt = Ref{Cint}(1)
iflag = 0
icntl = Vector{Cint}(undef, 30)
cntl = Vector{$T}(undef, 5)
info = Vector{Cint}(undef, 20)
ops = Ref{$T}(0)
HSL.$iname(icntl, cntl)
return HSL.Ma27{$T}(n, nz, Cint.(irn), Cint.(icn), a, la, iw, liw, w, ikeep, iw1,
nsteps, maxfrt, iflag, icntl, cntl, info, ops)
end

function HSL.ma27_update!(F::HSL.Ma27{$T}, A::SparseMatrixCSC{$T})
copyto!(F.a, A.nzval)
return F
end

function HSL.ma27_analyze!(F::HSL.Ma27{$T})
HSL.$aname(F.n, F.nz, F.irn, F.icn, F.iw, F.liw, F.ikeep, F.iw1, F.nsteps, F.iflag, F.icntl, F.cntl, F.info, F.ops)
return F
end

function HSL.ma27_factorize!(F::HSL.Ma27{$T})
HSL.$bname(F.n, F.nz, F.irn, F.icn, F.a, F.la, F.iw, F.liw, F.ikeep, F.nsteps, F.maxfrt, F.iw1, F.icntl, F.cntl, F.info)
resize!(F.w, F.maxfrt[])
return F
end

function HSL.ma27_solve!(F::HSL.Ma27{$T}, x::Vector{$T}, b::Vector{$T})
copyto!(x, b)
HSL.$cname(F.n, F.a, F.la, F.iw, F.liw, F.w, F.maxfrt, x, F.iw1, F.nsteps, F.icntl, F.info)
return b
end

function HSL.ma27(A::SparseMatrixCSC{$T}, b::Vector{$T})
F = HSL.Ma27(A)
HSL.ma27_analyze!(F)
HSL.ma27_factorize!(F)
x = Vector{$T}(undef, A.n)
HSL.ma27_solve!(F, x, b)
end
end
end
4 changes: 2 additions & 2 deletions gen/analyzer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
using HSL_jll
using JuliaFormatter

release = "2023.11.7"
libhsl = "/home/alexis/Bureau/git/hsl/libhsl/libHSL-$release/"
release = "2024.11.8"
libhsl = "/home/alexis/Bureau/git/hsl/libhsl/libHSL.v$release/"

# Symbols of the shared library libhsl
symbols_path = "symbols.txt"
Expand Down
4 changes: 2 additions & 2 deletions gen/wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function wrapper(name::String, headers::Vector{String}, optimized::Bool)
@info "Wrapping $name"

cd(@__DIR__)
include_dir = joinpath(HSL_jll.artifact_dir, "include")
include_dir = joinpath(HSL_jll.artifact_dir, "include", "libhsl")
options = load_options(joinpath(@__DIR__, "hsl.toml"))
options["general"]["output_file_path"] = joinpath("..", "src", "C", "$(name).jl")

Expand Down Expand Up @@ -47,7 +47,7 @@ function hsl_headers(include::String, package::String, precisions::Vector{Char})
end

function main(name::String="all"; optimized::Bool=false)
include = joinpath(HSL_jll.artifact_dir, "include")
include = joinpath(HSL_jll.artifact_dir, "include", "libhsl")

if name == "all" || name == "libhsl"
wrapper("libhsl", [joinpath(include, "libhsl.h")], optimized)
Expand Down
18 changes: 18 additions & 0 deletions src/Fortran/ma27.jl
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,21 @@ function ma27r(n, a, la, iw, liw, w, maxfnt, rhs, iw2, nblk, latop, icntl)
w::Ptr{Float32}, maxfnt::Ref{Cint}, rhs::Ptr{Float32}, iw2::Ptr{Cint},
nblk::Ref{Cint}, latop::Ref{Cint}, icntl::Ptr{Cint})::Cvoid
end

# Routines available in the extension HSLQuadmathExt.jl
function ma27iq end
function ma27aq end
function ma27bq end
function ma27cq end
function ma27gq end
function ma27hq end
function ma27uq end
function ma27jq end
function ma27kq end
function ma27lq end
function ma27mq end
function ma27nq end
function ma27oq end
function ma27pq end
function ma27qq end
function ma27rq end
9 changes: 8 additions & 1 deletion src/HSL.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ module HSL
using Libdl
using LinearAlgebra
using SparseArrays
import LinearAlgebra: checksquare

if haskey(ENV, "JULIA_HSL_LIBRARY_PATH")
const libhsl = joinpath(ENV["JULIA_HSL_LIBRARY_PATH"], "libhsl.$dlext")
const libhsl_subset = joinpath(ENV["JULIA_HSL_LIBRARY_PATH"], "libhsl_subset.$dlext")
const libhsl_subset_64 = joinpath(ENV["JULIA_HSL_LIBRARY_PATH"], "libhsl_subset_64.$dlext")
const HSL_INSTALLATION = "CUSTOM"
else
using OpenBLAS32_jll
using HSL_jll
import HSL_jll
const libhsl = HSL_jll.libhsl
const libhsl_subset = HSL_jll.libhsl_subset
const libhsl_subset_64 = HSL_jll.libhsl_subset_64
const HSL_INSTALLATION = "ARTIFACT"
end

Expand Down Expand Up @@ -37,6 +43,7 @@ include("wrappers.jl")
include("hsl_ma57.jl")
include("hsl_ma97.jl")
include("kb07.jl")
include("ma27.jl")
include("mc21.jl")
include("mc77.jl")

Expand Down
79 changes: 79 additions & 0 deletions src/ma27.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
export ma27

mutable struct Ma27{T}
n::Cint
nz::Cint
irn::Vector{Cint}
icn::Vector{Cint}
a::Vector{T}
la::Cint
iw::Vector{Cint}
liw::Cint
w::Vector{T}
ikeep::Vector{Cint}
iw1::Vector{Cint}
nsteps::Ref{Cint}
maxfrt::Ref{Cint}
iflag::Cint
icntl::Vector{Cint}
cntl::Vector{T}
info::Vector{Cint}
ops::Ref{T}
end

for (iname, aname, bname, cname, T) in ((:ma27i , :ma27a , :ma27b , :ma27c , :Float32),
(:ma27id, :ma27ad, :ma27bd, :ma27cd, :Float64))
@eval begin
function Ma27(A::SparseMatrixCSC{$T})
n = checksquare(A)
nz = nnz(A)
irn, icn, a = findnz(A)
la = 4 * nz
liw = 2 * (2 * nz + 3 * n + 1)
iw = Vector{Cint}(undef, liw)
w = Vector{$T}(undef, 0)
ikeep = Vector{Cint}(undef, 3 * n)
iw1 = Vector{Cint}(undef, 2 * n)
nsteps = Ref{Cint}(0)
maxfrt = Ref{Cint}(1)
iflag = 0
icntl = Vector{Cint}(undef, 30)
cntl = Vector{$T}(undef, 5)
info = Vector{Cint}(undef, 20)
ops = Ref{$T}(0)
$iname(icntl, cntl)
return HSL.Ma27{$T}(n, nz, Cint.(irn), Cint.(icn), a, la, iw, liw, w, ikeep, iw1,
nsteps, maxfrt, iflag, icntl, cntl, info, ops)
end

function ma27_update!(F::Ma27{$T}, A::SparseMatrixCSC{$T})
copyto!(F.a, A.nzval)
return F
end

function ma27_analyze!(F::Ma27{$T})
$aname(F.n, F.nz, F.irn, F.icn, F.iw, F.liw, F.ikeep, F.iw1, F.nsteps, F.iflag, F.icntl, F.cntl, F.info, F.ops)
return F
end

function ma27_factorize!(F::Ma27{$T})
$bname(F.n, F.nz, F.irn, F.icn, F.a, F.la, F.iw, F.liw, F.ikeep, F.nsteps, F.maxfrt, F.iw1, F.icntl, F.cntl, F.info)
resize!(F.w, F.maxfrt[])
return F
end

function ma27_solve!(F::Ma27{$T}, x::Vector{$T}, b::Vector{$T})
copyto!(x, b)
$cname(F.n, F.a, F.la, F.iw, F.liw, F.w, F.maxfrt, x, F.iw1, F.nsteps, F.icntl, F.info)
return b
end

function ma27(A::SparseMatrixCSC{$T}, b::Vector{$T})
F = Ma27(A)
ma27_analyze!(F)
ma27_factorize!(F)
x = Vector{$T}(undef, A.n)
ma27_solve!(F, x, b)
end
end
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ if LIBHSL_isfunctional()
include("test_hsl_ma57.jl")
include("test_hsl_ma97.jl")
include("test_kb07.jl")
include("test_ma27.jl")
include("test_mc21.jl")
include("test_mc77.jl")
else
Expand Down
21 changes: 21 additions & 0 deletions test/test_ma27.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@testset "ma27" begin
A = [2 3 0 0 0;
3 0 4 0 6;
0 4 1 5 0;
0 0 5 0 0;
0 6 0 0 1] |> sparse
b = [8; 45; 31; 15; 17]
xstar = [1; 2; 3; 4; 5]

T = Float32
A2 = T.(A)
b2 = T.(b)
x = ma27(A2, b2)
@test x ≈ xstar

T = Float64
A2 = T.(A)
b2 = T.(b)
x = ma27(A2, b2)
@test x ≈ xstar
end
Loading