Skip to content

Commit

Permalink
Update PRIMA.jl for the updated artifact
Browse files Browse the repository at this point in the history
  • Loading branch information
amontoison authored and emmt committed Sep 22, 2023
1 parent 8808a82 commit 4dab2a9
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 111 deletions.
7 changes: 7 additions & 0 deletions gen/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[deps]
Clang = "40e3b903-d033-50b4-a0cc-940c62c95e31"
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
PRIMA_jll = "eead6e0c-2d5b-5641-a95c-b722de96d551"

[compat]
julia = "1.6"
9 changes: 9 additions & 0 deletions gen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Wrapping headers

This directory contains a script that can be used to automatically generate wrappers from the C headers provided by PRIMA.
This is done using Clang.jl.

# Usage

Either run `julia wrapper.jl` directly, or include it and call the `main()` function.
Be sure to activate the project environment in this folder (`julia --project`), which will install `Clang.jl` and `JuliaFormatter.jl`.
13 changes: 13 additions & 0 deletions gen/prima.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[general]
use_julia_native_enum_type = true
print_using_CEnum = false
library_name = "libprimac"

[codegen]
use_julia_bool = true
always_NUL_terminated_string = true
use_ccall_macro = true

[codegen.macro]
macro_mode = "basic"
add_comment_for_skipped_macro = true
30 changes: 30 additions & 0 deletions gen/wrapper.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Script to parse PRIMA headers and generate Julia wrappers.
using PRIMA_jll
using Clang
using Clang.Generators
using JuliaFormatter

function main()

cd(@__DIR__)
include = joinpath(PRIMA_jll.artifact_dir, "include", "prima")
headers = [joinpath(include, "prima.h")]

options = load_options(joinpath(@__DIR__, "prima.toml"))
options["general"]["output_file_path"] = joinpath("..", "src", "wrappers.jl")

args = get_default_args()
push!(args, "-I$include")

ctx = create_context(headers, args, options)
build!(ctx)

path = options["general"]["output_file_path"]
format_file(path, YASStyle())
return nothing
end

# If we want to use the file as a script with `julia wrapper.jl`
if abspath(PROGRAM_FILE) == @__FILE__
main()
end
125 changes: 14 additions & 111 deletions src/PRIMA.jl
Original file line number Diff line number Diff line change
@@ -1,50 +1,24 @@
module PRIMA

using PRIMA_jll
const libprimac = PRIMA_jll.libprimac
include("wrappers.jl")

export bobyqa, cobyla, lincoa, newuoa, uobyqa

using TypeUtils
using PRIMA_jll
const libprimac = PRIMA_jll.libprimac

#------------------------------------------------------------------------------
# PUBLIC INTERFACE

# Verbosity level
@enum Message::Cint begin
MSG_NONE = 0 # No messages
MSG_EXIT = 1 # Exit reasons
MSG_RHO = 2 # Rho changes
MSG_FEVL = 3 # The object/constraint functions get evaluated
end

# Possible return values
@enum Status::Cint begin
SMALL_TR_RADIUS = 0
FTARGET_ACHIEVED = 1
TRSUBP_FAILED = 2
MAXFUN_REACHED = 3
MAXTR_REACHED = 20
NAN_INF_X = -1
NAN_INF_F = -2
NAN_INF_MODEL = -3
NO_SPACE_BETWEEN_BOUNDS = 6
DAMAGING_ROUNDING = 7
ZERO_LINEAR_CONSTRAINT = 8
INVALID_INPUT = 100
ASSERTION_FAILS = 101
VALIDATION_FAILS = 102
MEMORY_ALLOCATION_FAILS = 103
end

"""
PRIMA.reason(rc) -> str
yields a textual message explaining `rc`, the code returned by one of the PRIMA
optimizers.
"""
reason(status::Union{Integer,Status}) =
unsafe_string(@ccall libprimac.prima_get_rc_string(Integer(status)::Cint)::Cstring)
reason(status::Union{Integer,Status}) = unsafe_string(prima_get_rc_string(status))

# The high level wrappers. First the methods, then their documentation.
for func in (:bobyqa, :newuoa, :uobyqa, :lincoa, :cobyla)
Expand Down Expand Up @@ -314,20 +288,7 @@ function bobyqa!(f, x::DenseVector{Cdouble};
fp = _push_wrapper(fw) # pointer to C-callable function
try
# Call low-level optimizer.
rc = @ccall libprimac.prima_bobyqa(
fp ::Ptr{Cvoid}, # C-type: prima_obj
n ::Cint,
x ::Ptr{Cdouble}, # n elements
fx ::Ref{Cdouble},
xl ::Ptr{Cdouble}, # const, n elements
xu ::Ptr{Cdouble}, # const, n elements
nf ::Ref{Cint},
rhobeg ::Cdouble,
rhoend ::Cdouble,
ftarget ::Cdouble,
maxfun ::Cint, # maxfun
npt ::Cint,
Integer(iprint) ::Cint)::Cint
rc = prima_bobyqa(calfun, n, x, f, xl, xu, nf, rhobeg, rhoend, ftarget, maxfun, npt, iprint)
return (fx[], Int(nf[]), rc)
finally
_pop_wrapper(fw)
Expand Down Expand Up @@ -360,18 +321,7 @@ function newuoa!(f, x::DenseVector{Cdouble};
fp = _push_wrapper(fw) # pointer to C-callable function
try
# Call low-level optimizer.
rc = @ccall libprimac.prima_newuoa(
fp ::Ptr{Cvoid}, # C-type: prima_obj
n ::Cint,
x ::Ptr{Cdouble}, # n elements
fx ::Ref{Cdouble},
nf ::Ref{Cint},
rhobeg ::Cdouble,
rhoend ::Cdouble,
ftarget ::Cdouble,
maxfun ::Cint,
npt ::Cint,
Integer(iprint) ::Cint)::Cint
rc = prima_newuoa(calfun, n, x, f, nf, rhobeg, rhoend, ftarget, maxfun, npt, iprint)
return (fx[], Int(nf[]), rc)
finally
_pop_wrapper(fw)
Expand Down Expand Up @@ -402,17 +352,7 @@ function uobyqa!(f, x::DenseVector{Cdouble};
fp = _push_wrapper(fw) # pointer to C-callable function
try
# Call low-level optimizer.
rc = @ccall libprimac.prima_uobyqa(
fp ::Ptr{Cvoid}, # C-type: prima_obj
n ::Cint,
x ::Ptr{Cdouble}, # n elements
fx ::Ref{Cdouble},
nf ::Ref{Cint},
rhobeg ::Cdouble,
rhoend ::Cdouble,
ftarget ::Cdouble,
maxfun ::Cint,
Integer(iprint) ::Cint)::Cint
rc = prima_uobyqa(calfun, n, x, f, nf, rhobeg, rhoend, ftarget, maxfun, iprint)
return (fx[], Int(nf[]), rc)
finally
_pop_wrapper(fw)
Expand Down Expand Up @@ -458,28 +398,9 @@ function cobyla!(f, x::DenseVector{Cdouble};

try
# Call low-level optimizer.
rc = GC.@preserve nlconstr ineqconstr eqconstr @ccall libprimac.prima_cobyla(
m_nlcon ::Cint,
fp ::Ptr{Cvoid}, # C-type: prima_objcon
n ::Cint,
x ::Ptr{Cdouble}, # n elements
fx ::Ref{Cdouble},
cstrv ::Ref{Cdouble},
nlcon_ptr ::Ptr{Cdouble}, # m_nlcon elements
m_ineq ::Cint,
A_ineq ::Ptr{Cdouble}, # const, m_ineq*n elements
b_ineq ::Ptr{Cdouble}, # const, m_ineq elements
m_eq ::Cint,
A_eq ::Ptr{Cdouble}, # const, m_eq*n elements
b_eq ::Ptr{Cdouble}, # const, m_eq elements
xl ::Ptr{Cdouble}, # const, n elements
xu ::Ptr{Cdouble}, # const, n elements
nf ::Ref{Cint},
rhobeg ::Cdouble,
rhoend ::Cdouble,
ftarget ::Cdouble,
maxfun ::Cint,
Integer(iprint) ::Cint)::Cint
rc = GC.@preserve nlconstr ineqconstr eqconstr prima_cobyla(m_nlcon, calcfc,
n, x, f, cstrv, nlconstr, m_ineq, Aineq, bineq, m_eq, Aeq, beq, xl, xu,
nf, rhobeg, rhoend, ftarget, maxfun, iprint)
return (fx[], Int(nf[]), rc, cstrv[])
finally
_pop_wrapper(fw)
Expand Down Expand Up @@ -522,27 +443,9 @@ function lincoa!(f, x::DenseVector{Cdouble};
fp = _push_wrapper(fw) # pointer to C-callable function
try
# Call low-level optimizer.
rc = GC.@preserve ineqconstr eqconstr @ccall libprimac.prima_lincoa(
fp ::Ptr{Cvoid}, # C-type: prima_objcon
n ::Cint,
x ::Ptr{Cdouble}, # n elements
fx ::Ref{Cdouble},
cstrv ::Ref{Cdouble},
m_ineq ::Cint,
A_ineq ::Ptr{Cdouble}, # const, m_ineq*n elements
b_ineq ::Ptr{Cdouble}, # const, m_ineq elements
m_eq ::Cint,
A_eq ::Ptr{Cdouble}, # const, m_eq*n elements
b_eq ::Ptr{Cdouble}, # const, m_eq elements
xl ::Ptr{Cdouble}, # const, n elements
xu ::Ptr{Cdouble}, # const, n elements
nf ::Ref{Cint},
rhobeg ::Cdouble,
rhoend ::Cdouble,
ftarget ::Cdouble,
maxfun ::Cint,
npt ::Cint,
Integer(iprint) ::Cint)::Cint
rc = GC.@preserve ineqconstr eqconstr prima_lincoa(calfun, n, x, f,
cstrv, m_ineq, Aineq, bineq, m_eq, Aeq, beq, xl, xu, nf,
rhobeg, rhoend, ftarget, maxfun, npt, iprint)
return (fx[], Int(nf[]), rc, cstrv[])
finally
_pop_wrapper(fw)
Expand Down
73 changes: 73 additions & 0 deletions src/wrappers.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
@enum prima_message::UInt32 begin
PRIMA_MSG_NONE = 0
PRIMA_MSG_EXIT = 1
PRIMA_MSG_RHO = 2
PRIMA_MSG_FEVL = 3
end

@enum prima_rc::Int32 begin
PRIMA_SMALL_TR_RADIUS = 0
PRIMA_FTARGET_ACHIEVED = 1
PRIMA_TRSUBP_FAILED = 2
PRIMA_MAXFUN_REACHED = 3
PRIMA_MAXTR_REACHED = 20
PRIMA_NAN_INF_X = -1
PRIMA_NAN_INF_F = -2
PRIMA_NAN_INF_MODEL = -3
PRIMA_NO_SPACE_BETWEEN_BOUNDS = 6
PRIMA_DAMAGING_ROUNDING = 7
PRIMA_ZERO_LINEAR_CONSTRAINT = 8
PRIMA_INVALID_INPUT = 100
PRIMA_ASSERTION_FAILS = 101
PRIMA_VALIDATION_FAILS = 102
PRIMA_MEMORY_ALLOCATION_FAILS = 103
end

function prima_get_rc_string(rc)
@ccall libprimac.prima_get_rc_string(rc::Cint)::Cstring
end

function prima_bobyqa(calfun, n, x, f, xl, xu, nf, rhobeg, rhoend, ftarget, maxfun, npt,
iprint)
@ccall libprimac.prima_bobyqa(calfun::Ptr{Cvoid}, n::Cint, x::Ptr{Cdouble},
f::Ptr{Cdouble}, xl::Ptr{Cdouble}, xu::Ptr{Cdouble},
nf::Ptr{Cint}, rhobeg::Cdouble, rhoend::Cdouble,
ftarget::Cdouble, maxfun::Cint, npt::Cint,
iprint::Cint)::Cint
end

function prima_newuoa(calfun, n, x, f, nf, rhobeg, rhoend, ftarget, maxfun, npt, iprint)
@ccall libprimac.prima_newuoa(calfun::Ptr{Cvoid}, n::Cint, x::Ptr{Cdouble},
f::Ptr{Cdouble}, nf::Ptr{Cint}, rhobeg::Cdouble,
rhoend::Cdouble, ftarget::Cdouble, maxfun::Cint,
npt::Cint, iprint::Cint)::Cint
end

function prima_uobyqa(calfun, n, x, f, nf, rhobeg, rhoend, ftarget, maxfun, iprint)
@ccall libprimac.prima_uobyqa(calfun::Ptr{Cvoid}, n::Cint, x::Ptr{Cdouble},
f::Ptr{Cdouble}, nf::Ptr{Cint}, rhobeg::Cdouble,
rhoend::Cdouble, ftarget::Cdouble, maxfun::Cint,
iprint::Cint)::Cint
end

function prima_cobyla(m_nlcon, calcfc, n, x, f, cstrv, nlconstr, m_ineq, Aineq, bineq, m_eq,
Aeq, beq, xl, xu, nf, rhobeg, rhoend, ftarget, maxfun, iprint)
@ccall libprimac.prima_cobyla(m_nlcon::Cint, calcfc::Ptr{Cvoid}, n::Cint,
x::Ptr{Cdouble}, f::Ptr{Cdouble}, cstrv::Ptr{Cdouble},
nlconstr::Ptr{Cdouble}, m_ineq::Cint, Aineq::Ptr{Cdouble},
bineq::Ptr{Cdouble}, m_eq::Cint, Aeq::Ptr{Cdouble},
beq::Ptr{Cdouble}, xl::Ptr{Cdouble}, xu::Ptr{Cdouble},
nf::Ptr{Cint}, rhobeg::Cdouble, rhoend::Cdouble,
ftarget::Cdouble, maxfun::Cint, iprint::Cint)::Cint
end

function prima_lincoa(calfun, n, x, f, cstrv, m_ineq, Aineq, bineq, m_eq, Aeq, beq, xl, xu,
nf, rhobeg, rhoend, ftarget, maxfun, npt, iprint)
@ccall libprimac.prima_lincoa(calfun::Ptr{Cvoid}, n::Cint, x::Ptr{Cdouble},
f::Ptr{Cdouble}, cstrv::Ptr{Cdouble}, m_ineq::Cint,
Aineq::Ptr{Cdouble}, bineq::Ptr{Cdouble}, m_eq::Cint,
Aeq::Ptr{Cdouble}, beq::Ptr{Cdouble}, xl::Ptr{Cdouble},
xu::Ptr{Cdouble}, nf::Ptr{Cint}, rhobeg::Cdouble,
rhoend::Cdouble, ftarget::Cdouble, maxfun::Cint,
npt::Cint, iprint::Cint)::Cint
end

0 comments on commit 4dab2a9

Please sign in to comment.