-
Notifications
You must be signed in to change notification settings - Fork 0
[WIP] MOI wrapper test (some failed) #6
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
base: MOI
Are you sure you want to change the base?
Conversation
src/LibcuPDLPx.jl
Outdated
|
|
||
| using cuPDLPx_jll | ||
| # TODO: I have to add this in my local environment. This might be a issue in JLL. | ||
| const libcupdlpx = "/home/zdpeng/.julia/artifacts/4d407e51174c3bfe2f138e6e1db2531d0bc6240d/lib/libcupdlpx.so" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually had the same issue and it prevented me to run it locally, for me, it seems to be because I have CUDA v13.0
$ nvidia-smi
Thu Dec 18 08:27:35 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.105.08 Driver Version: 580.105.08 CUDA Version: 13.0 |
+-----------------------------------------+------------------------+----------------------+
julia> CUDA.versioninfo()
CUDA toolchain:
- runtime 13.0, artifact installation
- driver 580.105.8 for 13.0
- compiler 13.1
and cuPDLPx is only available on CUDA up to v12.9:
https://github.com/JuliaBinaryWrappers/cuPDLPx_jll.jl/tree/main/src/wrappers
The issue seems to be this line:
https://github.com/JuliaPackaging/Yggdrasil/blob/96df50e83da84ec3a4c48b4d9360abaa9c5a843d/C/cuPDLPx/build_tarballs.jl#L51
If you can run it locally and show me test errors here I can help. Otherwise, if the jll is fixed for CUDA v13 then I will be able to run the tests locally and it should be more efficient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot! I’ll update build_tarballs.jl to add CUDA 13 support.
For the const libcupdlpx = "/home/zdpeng/.julia/artifacts/..." workaround: I asked Gemini and it suggested changing LibraryProduct("libcupdlpx", :libcupdlpx), to LibraryProduct("cupdlpx", :libcupdlpx), in build_tarballs.jl.
Do you think that makes sense here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not an expert in BinaryBuilder but looking at the docs, the libname should be libcupdlpx here:
https://docs.binarybuilder.org/stable/reference/#BinaryBuilderBase.LibraryProducthttps://docs.binarybuilder.org/stable/reference/#BinaryBuilderBase.LibraryProduct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have updated cuPDLPx_jll to v0.1.5, which should support CUDA 13 now.
|
Hi @blegat . I updated test_DualObjectiveValue_Max_ScalarAffine_LessThan: Error During Test at /home/zdpeng/.julia/packages/MathOptInterface/03Qtw/src/Test/Test.jl:264
Got exception outside of a @test
DivideError: integer division error
Stacktrace:
[1] solve_lp_problem
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/src/LibcuPDLPx.jl:170 [inlined]
[2] optimize!(dest::cuPDLPx.Optimizer, src::cuPDLPx.OptimizerCache)
@ cuPDLPx /orcd/home/002/zdpeng/github/cuPDLPx.jl/src/MOI_wrapper.jl:231
[3] optimize!
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/src/MOI_wrapper.jl:242 [inlined]
[4] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{cuPDLPx.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
@ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/03Qtw/src/Utilities/cachingoptimizer.jl:370
[5] optimize!
@ ~/.julia/packages/MathOptInterface/03Qtw/src/Bridges/bridge_optimizer.jl:367 [inlined]
[6] test_DualObjectiveValue_Max_ScalarAffine_LessThan(model::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{cuPDLPx.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, config::MathOptInterface.Test.Config{Float64})
@ MathOptInterface.Test ~/.julia/packages/MathOptInterface/03Qtw/src/Test/test_solve.jl:2013
[7] macro expansion
@ ~/.julia/packages/MathOptInterface/03Qtw/src/Test/Test.jl:270 [inlined]
[8] macro expansion
@ /orcd/home/002/zdpeng/.julia/juliaup/julia-1.12.2+0.x64.linux.gnu/share/julia/stdlib/v1.12/Test/src/Test.jl:1776 [inlined]
[9] runtests(model::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{cuPDLPx.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, config::MathOptInterface.Test.Config{Float64}; include::Vector{String}, exclude::Vector{Regex}, warn_unsupported::Bool, verbose::Bool, exclude_tests_after::VersionNumber, test_module::Module)
@ MathOptInterface.Test ~/.julia/packages/MathOptInterface/03Qtw/src/Test/Test.jl:265
[10] runtests
@ ~/.julia/packages/MathOptInterface/03Qtw/src/Test/Test.jl:223 [inlined]
[11] test_runtests()
@ Main.TestMOI /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/MOI_wrapper.jl:29
[12] macro expansion
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/MOI_wrapper.jl:80 [inlined]
[13] macro expansion
@ /orcd/home/002/zdpeng/.julia/juliaup/julia-1.12.2+0.x64.linux.gnu/share/julia/stdlib/v1.12/Test/src/Test.jl:1776 [inlined]
[14] runtests()
@ Main.TestMOI /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/MOI_wrapper.jl:80
[15] top-level scope
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/MOI_wrapper.jl:89
[16] include(mapexpr::Function, mod::Module, _path::String)
@ Base ./Base.jl:307
[17] top-level scope
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/runtests.jl:254
[18] include(mapexpr::Function, mod::Module, _path::String)
@ Base ./Base.jl:307
[19] top-level scope
@ none:6
[20] eval(m::Module, e::Any)
@ Core ./boot.jl:489
[21] exec_options(opts::Base.JLOptions)
@ Base ./client.jl:283
[22] _start()
@ Base ./client.jl:550
---------------------------------------------------------------------------------------
cuPDLPx v0.1.5
A GPU-Accelerated First-Order LP Solver
(c) Haihao Lu, Massachusetts Institute of Technology, 2025
---------------------------------------------------------------------------------------
problem:
variables : 1
constraints : 1
nonzeros(A) : 1
settings:
iter_limit : 247049344
time_limit : 0.00 sec
eps_opt : 5.9e-316
eps_feas : 1.1e-310
eps_infeas_detect : 3.0e-323
l_inf_ruiz_iter : 0
pock_chambolle_alpha : 1.1e-310
has_pock_chambolle_alpha : off
bound_obj_rescaling : on
sv_max_iter : 256
sv_tol : 1.1e-310
evaluation_freq : 0
feasibility_polishing : on
eps_feas_polish_relative : 1.1e-310
---------------------------------------------------------------------------------------
runtime | objective | absolute residuals | relative residuals
iter time | pr obj du obj | pr res du res gap | pr res du res gap
---------------------------------------------------------------------------------------
0 1.4e-04 | 0.0e+00 0.0e+00 | 2.0e+00 3.0e+00 0.0e+00 | 6.7e-01 7.5e-01 0.0e+00
test_DualObjectiveValue_Min_ScalarAffine_GreaterThan: Error During Test at /home/zdpeng/.julia/packages/MathOptInterface/03Qtw/src/Test/Test.jl:264
Got exception outside of a @test
DivideError: integer division error
Stacktrace:
[1] solve_lp_problem
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/src/LibcuPDLPx.jl:170 [inlined]
[2] optimize!(dest::cuPDLPx.Optimizer, src::cuPDLPx.OptimizerCache)
@ cuPDLPx /orcd/home/002/zdpeng/github/cuPDLPx.jl/src/MOI_wrapper.jl:231
[3] optimize!
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/src/MOI_wrapper.jl:242 [inlined]
[4] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{cuPDLPx.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
@ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/03Qtw/src/Utilities/cachingoptimizer.jl:370
[5] optimize!
@ ~/.julia/packages/MathOptInterface/03Qtw/src/Bridges/bridge_optimizer.jl:367 [inlined]
[6] test_DualObjectiveValue_Min_ScalarAffine_GreaterThan(model::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{cuPDLPx.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, config::MathOptInterface.Test.Config{Float64})
@ MathOptInterface.Test ~/.julia/packages/MathOptInterface/03Qtw/src/Test/test_solve.jl:1971
[7] macro expansion
@ ~/.julia/packages/MathOptInterface/03Qtw/src/Test/Test.jl:270 [inlined]
[8] macro expansion
@ /orcd/home/002/zdpeng/.julia/juliaup/julia-1.12.2+0.x64.linux.gnu/share/julia/stdlib/v1.12/Test/src/Test.jl:1776 [inlined]
[9] runtests(model::MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{cuPDLPx.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, config::MathOptInterface.Test.Config{Float64}; include::Vector{String}, exclude::Vector{Regex}, warn_unsupported::Bool, verbose::Bool, exclude_tests_after::VersionNumber, test_module::Module)
@ MathOptInterface.Test ~/.julia/packages/MathOptInterface/03Qtw/src/Test/Test.jl:265
[10] runtests
@ ~/.julia/packages/MathOptInterface/03Qtw/src/Test/Test.jl:223 [inlined]
[11] test_runtests()
@ Main.TestMOI /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/MOI_wrapper.jl:29
[12] macro expansion
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/MOI_wrapper.jl:80 [inlined]
[13] macro expansion
@ /orcd/home/002/zdpeng/.julia/juliaup/julia-1.12.2+0.x64.linux.gnu/share/julia/stdlib/v1.12/Test/src/Test.jl:1776 [inlined]
[14] runtests()
@ Main.TestMOI /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/MOI_wrapper.jl:80
[15] top-level scope
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/MOI_wrapper.jl:89
[16] include(mapexpr::Function, mod::Module, _path::String)
@ Base ./Base.jl:307
[17] top-level scope
@ /orcd/home/002/zdpeng/github/cuPDLPx.jl/test/runtests.jl:254
[18] include(mapexpr::Function, mod::Module, _path::String)
@ Base ./Base.jl:307
[19] top-level scope
@ none:6
[20] eval(m::Module, e::Any)
@ Core ./boot.jl:489
[21] exec_options(opts::Base.JLOptions)
@ Base ./client.jl:283
[22] _start()
@ Base ./client.jl:550The following Updated codeimport MathOptInterface as MOI
const Lib = cuPDLPx.LibcuPDLPx
MOI.Utilities.@product_of_sets(
_LPProductOfSets,
MOI.EqualTo{T},
MOI.GreaterThan{T},
MOI.LessThan{T},
MOI.Interval{T},
)
const OptimizerCache = MOI.Utilities.GenericModel{
Cdouble,
MOI.Utilities.ObjectiveContainer{Cdouble},
MOI.Utilities.VariablesContainer{Cdouble},
MOI.Utilities.MatrixOfConstraints{
Cdouble,
MOI.Utilities.MutableSparseMatrixCSC{Cdouble,Cint,MOI.Utilities.ZeroBasedIndexing},
MOI.Utilities.Hyperrectangle{Cdouble},
_LPProductOfSets{Cdouble},
},
}
Base.show(io::IO, ::Type{OptimizerCache}) = print(io, "cuPDLPx.OptimizerCache")
const BOUND_SETS = Union{
MOI.GreaterThan{Float64},
MOI.LessThan{Float64},
MOI.EqualTo{Float64},
MOI.Interval{Float64},
}
"""
Optimizer()
Create a new cuPDLPx optimizer.
"""
mutable struct Optimizer <: MOI.AbstractOptimizer
result::Union{Nothing,Lib.cupdlpx_result_t}
native_result_ptr::Ptr{Lib.cupdlpx_result_t}
parameters::Lib.pdhg_parameters_t
sets::Union{Nothing,_LPProductOfSets{Cdouble}}
max_sense::Bool
silent::Bool
function Optimizer()
params_ref = Ref{Lib.pdhg_parameters_t}()
Lib.set_default_parameters(
Base.unsafe_convert(Ptr{Lib.pdhg_parameters_t}, params_ref),
)
return new(nothing, C_NULL, params_ref[], nothing, false, false)
end
end
function MOI.default_cache(::Optimizer, ::Type)
return OptimizerCache()
end
# ====================
# Helper: Immutable Update
# ====================
function _update_immutable(obj::T, field::Symbol, value) where {T}
args = map(fieldnames(T)) do f
f == field ? value : getfield(obj, f)
end
return T(args...)
end
# ====================
# Parameters
# ====================
MOI.get(::Optimizer, ::MOI.SolverName) = "cuPDLPx"
function MOI.supports(::Optimizer, param::MOI.RawOptimizerAttribute)
return hasfield(Lib.pdhg_parameters_t, Symbol(param.name))
end
function MOI.set(optimizer::Optimizer, param::MOI.RawOptimizerAttribute, value)
if !MOI.supports(optimizer, param)
throw(MOI.UnsupportedAttribute(param))
end
optimizer.parameters =
_update_immutable(optimizer.parameters, Symbol(param.name), value)
return
end
function MOI.get(optimizer::Optimizer, param::MOI.RawOptimizerAttribute)
if !MOI.supports(optimizer, param)
throw(MOI.UnsupportedAttribute(param))
end
return getfield(optimizer.parameters, Symbol(param.name))
end
MOI.supports(::Optimizer, ::MOI.TimeLimitSec) = true
function MOI.set(optimizer::Optimizer, ::MOI.TimeLimitSec, value::Real)
current_criteria = optimizer.parameters.termination_criteria
new_criteria = _update_immutable(current_criteria, :time_sec_limit, Float64(value))
optimizer.parameters =
_update_immutable(optimizer.parameters, :termination_criteria, new_criteria)
return
end
function MOI.get(optimizer::Optimizer, ::MOI.TimeLimitSec)
return optimizer.parameters.termination_criteria.time_sec_limit
end
MOI.supports(::Optimizer, ::MOI.Silent) = true
function MOI.set(optimizer::Optimizer, ::MOI.Silent, value::Bool)
optimizer.silent = value
new_verbose = value ? 0 : 1
optimizer.parameters = _update_immutable(optimizer.parameters, :verbose, new_verbose)
return
end
MOI.get(optimizer::Optimizer, ::MOI.Silent) = optimizer.silent
# ====================
# Empty & Status
# ====================
function MOI.is_empty(optimizer::Optimizer)
return isnothing(optimizer.result)
end
function MOI.empty!(optimizer::Optimizer)
if optimizer.native_result_ptr != C_NULL
Lib.cupdlpx_result_free(optimizer.native_result_ptr)
optimizer.native_result_ptr = C_NULL
end
optimizer.result = nothing
optimizer.sets = nothing
return
end
# ========================================
# Constraints & Objectives
# ========================================
function MOI.supports_constraint(
::Optimizer,
::Type{MOI.VariableIndex},
::Type{<:BOUND_SETS},
)
return true
end
function MOI.supports_constraint(
::Optimizer,
::Type{MOI.ScalarAffineFunction{Float64}},
::Type{<:BOUND_SETS},
)
return true
end
MOI.supports(::Optimizer, ::MOI.ObjectiveSense) = true
function MOI.supports(
::Optimizer,
::MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}},
)
return true
end
# ===============================
# Optimize
# ===============================
function _flip_sense(optimizer::Optimizer, obj)
return optimizer.max_sense ? -obj : obj
end
function create_matrix_desc_ref(
A::MOI.Utilities.MutableSparseMatrixCSC{Cdouble,Cint,MOI.Utilities.ZeroBasedIndexing},
)
A_csc = Lib.MatrixCSC(
length(A.rowval),
pointer(A.colptr),
pointer(A.rowval),
pointer(A.nzval),
)
desc_ref = Ref{Lib.matrix_desc_t}()
desc_val = Lib.matrix_desc_t(ntuple(_ -> UInt8(0), 56))
desc_ref[] = desc_val
desc_ptr = Base.unsafe_convert(Ptr{Lib.matrix_desc_t}, desc_ref)
desc_ptr.m = Cint(A.m)
desc_ptr.n = Cint(A.n)
desc_ptr.fmt = Lib.matrix_csc
desc_ptr.zero_tolerance = 1e-12
desc_ptr.data.csc = A_csc
return desc_ref
end
function MOI.optimize!(dest::Optimizer, src::OptimizerCache)
MOI.empty!(dest)
if src.constraints.coefficients.n == 0
dest.result = nothing
return MOI.Utilities.identity_index_map(src), false
end
dest.max_sense = MOI.get(src, MOI.ObjectiveSense()) == MOI.MAX_SENSE
obj = MOI.get(src, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}())
c = zeros(Cdouble, src.constraints.coefficients.n)
for term in obj.terms
c[term.variable.value] += _flip_sense(dest, term.coefficient)
end
obj_const = [_flip_sense(dest, MOI.constant(obj))]
dest.sets = src.constraints.sets
matrix_desc_ref = create_matrix_desc_ref(src.constraints.coefficients)
matrix_desc_ptr = Base.unsafe_convert(Ptr{Lib.matrix_desc_t}, matrix_desc_ref)
params_ref = Ref(dest.parameters)
params_ptr = Base.unsafe_convert(Ptr{Lib.pdhg_parameters_t}, params_ref)
const_lb = src.constraints.constants.lower
const_ub = src.constraints.constants.upper
var_lb = src.variables.lower
var_ub = src.variables.upper
GC.@preserve c obj_const matrix_desc_ref params_ref const_lb const_ub var_lb var_ub begin
prob = Lib.create_lp_problem(
pointer(c),
matrix_desc_ptr,
pointer(const_lb),
pointer(const_ub),
pointer(var_lb),
pointer(var_ub),
pointer(obj_const),
)
@assert prob != C_NULL
result_ptr = Lib.solve_lp_problem(prob, params_ptr)
@assert result_ptr != C_NULL
dest.result = unsafe_load(result_ptr)
dest.native_result_ptr = result_ptr
Lib.cupdlpx_result_free(result_ptr)
Lib.lp_problem_free(prob)
end
return MOI.Utilities.identity_index_map(src), false
end
function MOI.optimize!(dest::Optimizer, src::MOI.ModelLike)
cache = OptimizerCache()
index_map = MOI.copy_to(cache, src)
MOI.optimize!(dest, cache)
return index_map, false
end
# ====================
# Result Getters
# ====================
function MOI.get(optimizer::Optimizer, ::MOI.SolveTimeSec)
return optimizer.result.cumulative_time_sec
end
function MOI.get(optimizer::Optimizer, ::MOI.RawStatusString)
return isnothing(optimizer.result) ? "Optimize not called" : "Solver finished"
end
const _TERMINATION_STATUS_MAP = Dict(
Lib.TERMINATION_REASON_UNSPECIFIED => MOI.OPTIMIZE_NOT_CALLED,
Lib.TERMINATION_REASON_OPTIMAL => MOI.OPTIMAL,
Lib.TERMINATION_REASON_PRIMAL_INFEASIBLE => MOI.INFEASIBLE,
Lib.TERMINATION_REASON_DUAL_INFEASIBLE => MOI.DUAL_INFEASIBLE,
Lib.TERMINATION_REASON_TIME_LIMIT => MOI.TIME_LIMIT,
Lib.TERMINATION_REASON_ITERATION_LIMIT => MOI.ITERATION_LIMIT,
Lib.TERMINATION_REASON_FEAS_POLISH_SUCCESS => MOI.OTHER_ERROR,
)
function MOI.get(optimizer::Optimizer, ::MOI.TerminationStatus)
return isnothing(optimizer.result) ? MOI.OPTIMIZE_NOT_CALLED :
_TERMINATION_STATUS_MAP[optimizer.result.termination_reason]
end
function MOI.get(optimizer::Optimizer, attr::MOI.ObjectiveValue)
MOI.check_result_index_bounds(optimizer, attr)
return _flip_sense(optimizer, optimizer.result.primal_objective_value)
end
function MOI.get(optimizer::Optimizer, attr::MOI.DualObjectiveValue)
MOI.check_result_index_bounds(optimizer, attr)
return _flip_sense(optimizer, optimizer.result.dual_objective_value)
end
const _PRIMAL_STATUS_MAP = Dict(
Lib.TERMINATION_REASON_UNSPECIFIED => MOI.NO_SOLUTION,
Lib.TERMINATION_REASON_OPTIMAL => MOI.FEASIBLE_POINT,
Lib.TERMINATION_REASON_PRIMAL_INFEASIBLE => MOI.NO_SOLUTION,
Lib.TERMINATION_REASON_DUAL_INFEASIBLE => MOI.INFEASIBILITY_CERTIFICATE,
Lib.TERMINATION_REASON_TIME_LIMIT => MOI.UNKNOWN_RESULT_STATUS,
Lib.TERMINATION_REASON_ITERATION_LIMIT => MOI.UNKNOWN_RESULT_STATUS,
Lib.TERMINATION_REASON_FEAS_POLISH_SUCCESS => MOI.UNKNOWN_RESULT_STATUS,
)
const _DUAL_STATUS_MAP = Dict(
LibcuPDLPx.TERMINATION_REASON_UNSPECIFIED => MOI.NO_SOLUTION,
LibcuPDLPx.TERMINATION_REASON_OPTIMAL => MOI.FEASIBLE_POINT,
LibcuPDLPx.TERMINATION_REASON_PRIMAL_INFEASIBLE => MOI.INFEASIBILITY_CERTIFICATE,
LibcuPDLPx.TERMINATION_REASON_DUAL_INFEASIBLE => MOI.NO_SOLUTION,
LibcuPDLPx.TERMINATION_REASON_TIME_LIMIT => MOI.UNKNOWN_RESULT_STATUS,
LibcuPDLPx.TERMINATION_REASON_ITERATION_LIMIT => MOI.UNKNOWN_RESULT_STATUS,
LibcuPDLPx.TERMINATION_REASON_FEAS_POLISH_SUCCESS => MOI.UNKNOWN_RESULT_STATUS,
)
function MOI.get(optimizer::Optimizer, attr::MOI.PrimalStatus)
if attr.result_index > MOI.get(optimizer, MOI.ResultCount())
return MOI.NO_SOLUTION
end
return _PRIMAL_STATUS_MAP[optimizer.result.termination_reason]
end
function MOI.get(optimizer::Optimizer, attr::MOI.VariablePrimal, vi::MOI.VariableIndex)
MOI.check_result_index_bounds(optimizer, attr)
return unsafe_load(optimizer.result.primal_solution, vi.value)
end
function MOI.get(optimizer::Optimizer, attr::MOI.DualStatus)
if attr.result_index > MOI.get(optimizer, MOI.ResultCount())
return MOI.NO_SOLUTION
end
return _DUAL_STATUS_MAP[optimizer.result.termination_reason]
end
function MOI.get(
optimizer::Optimizer,
attr::MOI.ConstraintDual,
ci::MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64}},
)
MOI.check_result_index_bounds(optimizer, attr)
row = only(MOI.Utilities.rows(optimizer.sets, ci))
return unsafe_load(optimizer.result.dual_solution, row)
end
function MOI.get(optimizer::Optimizer, ::MOI.ResultCount)
return isnothing(optimizer.result) ? 0 : 1
end
|
src/MOI_wrapper.jl
Outdated
| error("TODO") | ||
| optimizer.silent = value | ||
| new_verbose = value ? 0 : 1 | ||
| optimizer.parameters = _update_immutable(optimizer.parameters, :verbose, new_verbose) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When Silent is set back to false, the :verbose parameters should get back to the value it had before Silent was set to true. Since you erase it here, it won't be possible. What we do (and it's the reason why we keep new_verbose as a separate field), is, in optimize!, if silent is true, you set the verbose field to 0, then you call solve_lp then you reset to its value, and you keep a local variable to remember the old value in optimize!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to update the code as below, but it still doesn’t work. Do you have any idea what I might be missing?
Lines 227 to 233 in 30da5c9
| # TODO: not working | |
| # solve_params = dest.parameters | |
| # if dest.silent | |
| # solve_params = _update_immutable(solve_params, :verbose, Cint(0)) | |
| # end | |
| # params_ref = Ref{Lib.pdhg_parameters_t}(solve_params) | |
| # params_ptr = Base.unsafe_convert(Ptr{Lib.pdhg_parameters_t}, params_ref) |
Yes it's good, just a minor comment in https://github.com/MIT-Lu-Lab/cuPDLPx.jl/pull/6/files#r2645187112 |
|
Hi @blegat . When I run the package tests, I hit the following error. (cuPDLPx) pkg> test
Test Summary: | Pass Total Time
LibcuPDLPx Translation Tests | 19 19 1.3s
Skipping feasibility polishing as the solution is already sufficiently feasible.
Solution Summary
Status : OPTIMAL
Presolve time : 0.000132 sec
Solve time : 3e-05 sec
Iterations : 0
Primal objective : -6
Dual objective : -6
Objective gap : 0.000e+00
Primal infeas : 0.000e+00
Dual infeas : 0.000e+00
CUDA Error at /workspace/srcdir/cuPDLPx/src/solver.cu:460: cudaErrorInvalidValue
ERROR: Package cuPDLPx errored during testingRelated code: https://github.com/MIT-Lu-Lab/cuPDLPx/blob/4513094a4dfec9be1da5df35f2691205e090bde0/src/solver.cu#L453-L460 It seems to occur for LPs with no linear constraints (or cases where presolve removes all linear constraints). One example is Output Do you have any idea which part of the MOI wrapper/test harness could be triggering this, or where I should look first? Thanks in advance! |
Hi @blegat, thank you very much for your help with the MOI wrapper.
Following your instructions, I’ve tested the MOI wrapper. Could you please take a look at the implementation when you have a chance?
The tests are now able to run, although some currently fail due to issues in cuPDLPx itself. I’ll update the source code to fix these shortly.