Skip to content

Commit

Permalink
Merge branch 'dev' into relocatable
Browse files Browse the repository at this point in the history
  • Loading branch information
tmmsartor committed Jul 18, 2024
2 parents 96733f2 + 1b0eb05 commit 19ccf35
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 70 deletions.
12 changes: 11 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,18 @@ add_custom_command(
)

add_custom_command(
OUTPUT ${PROJECT_BINARY_DIR}/PackageCompiler_env_status.txt
OUTPUT ${PROJECT_BINARY_DIR}/MadNLP_C_parses.txt
DEPENDS ${PROJECT_SOURCE_DIR}/Manifest.toml
DEPENDS ${PROJECT_BINARY_DIR}/MadNLP_env_status.txt
COMMAND ${Julia_EXECUTABLE} --startup-file=no --project=./ compiler/generate_precompile.jl > ${PROJECT_BINARY_DIR}/MadNLP_C_parses.txt
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Parses Julia packages"
VERBATIM
)

add_custom_command(
OUTPUT ${PROJECT_BINARY_DIR}/PackageCompiler_env_status.txt
DEPENDS ${PROJECT_BINARY_DIR}/MadNLP_C_parses.txt
DEPENDS ${PROJECT_SOURCE_DIR}/compiler/Manifest.toml
COMMAND ${Julia_EXECUTABLE} --startup-file=no --project=compiler -e "using Pkg; Pkg.instantiate()"
COMMAND ${Julia_EXECUTABLE} --startup-file=no --project=compiler -e "using Pkg; Pkg.status()" > ${PROJECT_BINARY_DIR}/PackageCompiler_env_status.txt
Expand Down
2 changes: 2 additions & 0 deletions compiler/generate_precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,6 @@ for (lin_solver_id,print_level, max_iters) in cases
println("mul_L: ", mul_L)
println("mul_U: ", mul_U)

madnlp_c_destroy(s)

end
131 changes: 62 additions & 69 deletions src/MadNLP_C.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ using UnsafePointers

export MadnlpCSolver, MadnlpCInterface, MadnlpCNumericIn, MadnlpCNumericOut, madnlp_c_get_stats, madnlp_c_startup, madnlp_c_shutdown, madnlp_c_create, madnlp_c_option_type, madnlp_c_set_option_double, madnlp_c_set_option_bool, madnlp_c_set_option_int, madnlp_c_set_option_string, madnlp_c_input, madnlp_c_output, madnlp_c_solve, madnlp_c_destroy



struct CPUBuffers
x::Vector{Float64}
grad_f::Vector{Float64}
Expand Down Expand Up @@ -89,8 +91,6 @@ mutable struct MadnlpCNumericOut
mul::Ptr{Cdouble}
mul_L::Ptr{Cdouble}
mul_U::Ptr{Cdouble}
primal_feas::Ptr{Cdouble}
dual_feas::Ptr{Cdouble}
MadnlpCNumericOut() = new()
end

Expand All @@ -108,20 +108,31 @@ mutable struct MadnlpCSolver
max_iters::Int64
print_level::Int64
minimize::Bool
res::MadNLP.MadNLPExecutionStats{Float64, Vector{Float64}}
in_c::MadnlpCNumericIn{Ptr{Cdouble}}
out_c::MadnlpCNumericOut
stats_c::MadnlpCStats
in::MadnlpCNumericIn{Vector{Float64}}

nzj_i::Array{Int64}
nzj_j::Array{Int64}
nzh_i::Array{Int64}
nzh_j::Array{Int64}
nzj_i::Vector{Int64}
nzj_j::Vector{Int64}
nzh_i::Vector{Int64}
nzh_j::Vector{Int64}

solution::Vector{Float64}
objective::Float64
constraints::Vector{Float64}
multipliers::Vector{Float64}
multipliers_L::Vector{Float64}
multipliers_U::Vector{Float64}

MadnlpCSolver() = new()
end


ref_store::Dict{Ptr{MadnlpCSolver},Union{Ref{MadnlpCSolver},Nothing}} = Dict()



function NLPModels.jac_structure!(nlp::GenericModel, I::AbstractVector{T}, J::AbstractVector{T}) where T
copyto!(I, nlp.nzj_i)
copyto!(J, nlp.nzj_j)
Expand Down Expand Up @@ -235,7 +246,7 @@ end


function set_option(s::Ptr{MadnlpCSolver}, name::String, value::Any)
s_jl::MadnlpCSolver = unsafe_load(s)
s_jl::MadnlpCSolver = unsafe_pointer_to_objref(s)
if name == "print_level"
if value > 5 value = 5 end
if value < 0 value = 0 end
Expand All @@ -252,7 +263,6 @@ function set_option(s::Ptr{MadnlpCSolver}, name::String, value::Any)
else
@warn "Unknown option $name"
end
unsafe_store!(s, s_jl)
end

Base.@ccallable function madnlp_c_startup(argc::Cint, argv::Ptr{Ptr{Cchar}})::Cvoid
Expand All @@ -264,15 +274,12 @@ Base.@ccallable function madnlp_c_shutdown()::Cvoid
end

Base.@ccallable function madnlp_c_create(nlp_interface::Ptr{MadnlpCInterface})::Ptr{MadnlpCSolver}
# Allocate memory for the solver
solver_ptr = Ptr{MadnlpCSolver}(Libc.malloc(sizeof(MadnlpCSolver)))

# Create the solver object
solver = MadnlpCSolver()
solver.nlp_interface = unsafe_load(nlp_interface)
solver.lin_solver_id = 0
solver.max_iters = 3000
solver.print_level = 5
solver.print_level = 3
solver.minimize = true

interf = solver.nlp_interface
Expand All @@ -298,59 +305,49 @@ Base.@ccallable function madnlp_c_create(nlp_interface::Ptr{MadnlpCInterface})::
solver.stats_c = MadnlpCStats()

# nzj_i may not be properly aligned, so copying is neededs
solver.nzj_i = Array{Int64}(undef, interf.nnzj)
solver.nzj_j = Array{Int64}(undef, interf.nnzj)
solver.nzh_i = Array{Int64}(undef, interf.nnzh)
solver.nzh_j = Array{Int64}(undef, interf.nnzh)
solver.nzj_i = Vector{Int64}(undef, interf.nnzj)
solver.nzj_j = Vector{Int64}(undef, interf.nnzj)
solver.nzh_i = Vector{Int64}(undef, interf.nnzh)
solver.nzh_j = Vector{Int64}(undef, interf.nnzh)

unsafe_copyto!(Base.unsafe_convert(Ptr{Int64}, solver.nzj_i), interf.nzj_i, interf.nnzj)
unsafe_copyto!(Base.unsafe_convert(Ptr{Int64}, solver.nzj_j), interf.nzj_j, interf.nnzj)
unsafe_copyto!(Base.unsafe_convert(Ptr{Int64}, solver.nzh_i), interf.nzh_i, interf.nnzh)
unsafe_copyto!(Base.unsafe_convert(Ptr{Int64}, solver.nzh_j), interf.nzh_j, interf.nnzh)

solver.res = MadNLP.MadNLPExecutionStats{Float64, Vector{Float64}}(
MadNLP.MadNLPOptions(tol=0, callback=MadNLP.SparseCallback, kkt_system=MadNLP.SparseKKTSystem, linear_solver=MadNLPMumps.MumpsSolver),
MadNLP.INTERNAL_ERROR,
Vector{Float64}(undef, interf.nw),
0.0,
Vector{Float64}(undef, interf.nc),
0.0,
0.0,
Vector{Float64}(undef, interf.nc),
Vector{Float64}(undef, interf.nw),
Vector{Float64}(undef, interf.nw),
0,
MadNLP.MadNLPCounters(start_time=0.0)
)
solver.solution = Vector{Float64}(undef, interf.nw)
solver.objective = 0.0
solver.constraints = Vector{Float64}(undef, interf.nc)
solver.multipliers = Vector{Float64}(undef, interf.nc)
solver.multipliers_L = Vector{Float64}(undef, interf.nw)
solver.multipliers_U = Vector{Float64}(undef, interf.nw)

# Copy the solver object to the allocated memory
unsafe_store!(solver_ptr, solver)
solver_ref = Ref(solver)

solver_ptr = Base.unsafe_convert(Ptr{MadnlpCSolver}, solver_ref)

ref_store[solver_ptr] = solver_ref

# Return the pointer to the solver object
return solver_ptr
end

Base.@ccallable function madnlp_c_input(s::Ptr{MadnlpCSolver})::Ptr{MadnlpCNumericIn{Ptr{Cdouble}}}
solver = unsafe_load(s)
solver = unsafe_pointer_to_objref(s)

return Base.unsafe_convert(Ptr{MadnlpCNumericIn{Ptr{Cdouble}}},Ref(solver.in_c))
return pointer_from_objref(solver.in_c)
end

Base.@ccallable function madnlp_c_output(s::Ptr{MadnlpCSolver})::Ptr{MadnlpCNumericOut}
solver = unsafe_load(s)
solver = unsafe_pointer_to_objref(s)

return Base.unsafe_convert(Ptr{MadnlpCNumericOut},Ref(solver.out_c))
return pointer_from_objref(solver.out_c)
end

Base.@ccallable function madnlp_c_get_stats(s::Ptr{MadnlpCSolver})::Ptr{MadnlpCStats}
solver = unsafe_load(s)
solver = unsafe_pointer_to_objref(s)

solver.stats_c.iter = solver.res.iter
solver.stats_c.status = Integer(solver.res.status)
solver.stats_c.dual_feas = solver.res.dual_feas
solver.stats_c.primal_feas = solver.res.primal_feas

return Base.unsafe_convert(Ptr{MadnlpCStats},Ref(solver.stats_c))
return pointer_from_objref(solver.stats_c)
end

Base.@ccallable function madnlp_c_option_type(name::Ptr{Cchar})::Cint
Expand Down Expand Up @@ -402,7 +399,7 @@ end

Base.@ccallable function madnlp_c_solve(s::Ptr{MadnlpCSolver})::Cint

solver = unsafe_load(s)
solver = unsafe_pointer_to_objref(s)
nlp_interface = solver.nlp_interface
nvar = nlp_interface.nw
ncon = nlp_interface.nc
Expand Down Expand Up @@ -555,39 +552,35 @@ Base.@ccallable function madnlp_c_solve(s::Ptr{MadnlpCSolver})::Cint

madnlp_solver = MadNLPSolver(nlp; print_level = madnlp_log, linear_solver = linear_solver)
res = MadNLP.solve!(madnlp_solver, max_iter = Int(solver.max_iters))
if GPU_DEVICE
copyto!(solver.res.solution, res.solution)
solver.res.objective = res.objective
copyto!(solver.res.constraints, res.constraints)
copyto!(solver.res.multipliers, res.multipliers)
copyto!(solver.res.multipliers_L, res.multipliers_L)
copyto!(solver.res.multipliers_U, res.multipliers_U)
solver.res.dual_feas = res.dual_feas
solver.res.primal_feas = res.primal_feas
solver.res.counters = res.counters
solver.res.iter = res.iter
solver.res.options = res.options
solver.res.status = res.status
else
solver.res = res
end

solver.stats_c.iter = res.iter
solver.stats_c.status = Integer(res.status)
solver.stats_c.dual_feas = res.dual_feas
solver.stats_c.primal_feas = res.primal_feas

copyto!(solver.solution, res.solution)
solver.objective = res.objective
copyto!(solver.constraints, res.constraints)
copyto!(solver.multipliers, res.multipliers)
copyto!(solver.multipliers_L, res.multipliers_L)
copyto!(solver.multipliers_U, res.multipliers_U)

# Make results available to C
solver.out_c.sol = Base.unsafe_convert(Ptr{Cdouble},solver.res.solution)
solver.out_c.obj = Base.unsafe_convert(Ptr{Cdouble},[solver.res.objective])
solver.out_c.con = Base.unsafe_convert(Ptr{Cdouble},solver.res.constraints)
solver.out_c.mul = Base.unsafe_convert(Ptr{Cdouble},solver.res.multipliers)
solver.out_c.mul_L = Base.unsafe_convert(Ptr{Cdouble},solver.res.multipliers_L)
solver.out_c.mul_U = Base.unsafe_convert(Ptr{Cdouble},solver.res.multipliers_U)
solver.out_c.sol = Base.unsafe_convert(Ptr{Cdouble},solver.solution)
solver.out_c.obj = Base.unsafe_convert(Ptr{Cdouble},[solver.objective])
solver.out_c.con = Base.unsafe_convert(Ptr{Cdouble},solver.constraints)
solver.out_c.mul = Base.unsafe_convert(Ptr{Cdouble},solver.multipliers)
solver.out_c.mul_L = Base.unsafe_convert(Ptr{Cdouble},solver.multipliers_L)
solver.out_c.mul_U = Base.unsafe_convert(Ptr{Cdouble},solver.multipliers_U)

return 0

end


Base.@ccallable function madnlp_c_destroy(s::Ptr{MadnlpCSolver})::Cvoid
# Free the allocated memory
Libc.free(s)
ref_store[s] = nothing
GC.gc()
end

end # module MadNLP_C
4 changes: 4 additions & 0 deletions tests/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ int main(int argc, char** argv) {
cout << "dual_feas: " << stats->dual_feas << endl;
cout << "primal_feas: " << stats->primal_feas << endl;

madnlp_c_solve(solver);

madnlp_c_destroy(solver);

shutdown_julia(0);

return 0;
Expand Down

0 comments on commit 19ccf35

Please sign in to comment.