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

Update cupdlp cpu code with updates to copt/cupdlp #2013

Closed
wants to merge 22 commits into from
Closed
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
100 changes: 98 additions & 2 deletions check/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,57 @@ if (NOT FAST_BUILD OR ALL_TESTS)
# "--parallel=on"
)

if (UNIX AND NOT APPLE)
set(pdlpInstances
"25fv47\; 5.50184588\;"
"adlittle\; 2.254949631\;"
"afiro\;-4.64753143\;"
"avgas\;-7.749999999\;"
"blending\;-3.19999999\;"
"chip\;-9.000000001\;"
"e226\;-1.163892906\;"
"scrs8\; 9.042969540\;"
"sctest\; 5.749999936\;"
"shell\; 1.2088253460\;"
"stair\;-2.5126695353\;"
"standata\; 1.257699499\;"
"standgub\; 1.2576994998\;"
)
elseif(WIN32)
# on windows e226 model status is unknown, rel gap e00
set(pdlpInstances
"25fv47\; 5.50184588\;"
"adlittle\; 2.254949631\;"
"afiro\;-4.64753143\;"
"avgas\;-7.749999999\;"
"blending\;-3.19999999\;"
"chip\;-9.000000001\;"
"scrs8\; 9.042969540\;"
"sctest\; 5.749999936\;"
"shell\; 1.2088253460\;"
"stair\;-2.5126695353\;"
"standata\; 1.257699499\;"
"standgub\; 1.2576994998\;"
)
endif()

set(pdlpMacArmInstances
"25fv47\; 5.50184589\;"
"adlittle\; 2.254949631\;"
"afiro\;-4.64753143\;"
"avgas\;-7.749999999\;"
"blending\;-3.19999999\;"
"chip\;-8.9999988715\;"
"e226\;-1.163892\;"
"scrs8\; 9.042969540\;"
"sctest\; 5.749999936\;"
"shell\; 1.2088253460\;"
# "stair\;-2.5126695353\;"
# "standata\; 1.257699499\;" #model status unknown, rel gap e00
# "standgub\; 1.2576994998\;"
)


# define a macro to add tests
#
# add_instancetests takes an instance group and a status
Expand Down Expand Up @@ -293,7 +344,8 @@ if (NOT FAST_BUILD OR ALL_TESTS)

add_instancetests(failInstances "Fail")
add_instancetests(infeasibleInstances "Infeasible")
#add_instancetests(unboundedInstances "Unbounded")
add_instancetests(unboundedInstances "Unbounded")


foreach(instance ${mipInstances})
list(GET instance 0 name)
Expand All @@ -320,6 +372,50 @@ if (NOT FAST_BUILD OR ALL_TESTS)
"Solution status infeasible")

endforeach(setting)
endforeach()
endforeach(instance)

if(FAST_BUILD AND NOT APPLE)
foreach(instance_pdlp ${pdlpInstances})
# add default tests
# treat the instance as a tuple (list) of two values
list(GET instance_pdlp 0 name_pdlp)
list(GET instance_pdlp 1 optval)

set(inst_pdlp "${HIGHS_SOURCE_DIR}/check/instances/${name_pdlp}.mps")

add_test(NAME ${name_pdlp}--pdlp COMMAND $<TARGET_FILE:highs-bin> "--solver=pdlp"
${inst_pdlp})

set_tests_properties (${name_pdlp}--pdlp PROPERTIES
PASS_REGULAR_EXPRESSION
"Model status : Optimal")

set_tests_properties (${name_pdlp}--pdlp PROPERTIES
PASS_REGULAR_EXPRESSION
"Objective value : ${optval}")
endforeach(instance_pdlp)
endif()

if (FAST_BUILD AND APPLE)
foreach(instance_pdlp ${pdlpMacArmInstances})
# add default tests
# treat the instance as a tuple (list) of two values
list(GET instance_pdlp 0 name_pdlp)
list(GET instance_pdlp 1 optval)

set(inst_pdlp "${HIGHS_SOURCE_DIR}/check/instances/${name_pdlp}.mps")

add_test(NAME ${name_pdlp}--pdlp COMMAND $<TARGET_FILE:highs-bin> "--solver=pdlp"
${inst_pdlp})

set_tests_properties (${name_pdlp}--pdlp PROPERTIES
PASS_REGULAR_EXPRESSION
"Model status : Optimal")

set_tests_properties (${name_pdlp}--pdlp PROPERTIES
PASS_REGULAR_EXPRESSION
"Objective value : ${optval}")
endforeach(instance_pdlp)
endif()

endif()
32 changes: 13 additions & 19 deletions check/TestPdlp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,20 @@ TEST_CASE("pdlp-distillation-lp", "[pdlp]") {
HighsStatus run_status = HighsStatus::kOk;
// First pass uses (HiGHS default) termination for PDLP solver to
// satisfy HiGHS primal/dual feasibility tolerances
bool optimal = true;
for (HighsInt k = 0; k < 2; k++) {
if (k == 1) {
// In second pass use native termination for PDLP solver,
// failing HiGHS optimality test
highs.setOptionValue("pdlp_native_termination", true);
optimal = false;
}
run_status = highs.run();
if (dev_run) highs.writeSolution("", 1);
REQUIRE(std::abs(info.objective_function_value - optimal_objective) <
double_equal_tolerance);
if (optimal) {
REQUIRE(run_status == HighsStatus::kOk);
REQUIRE(highs.getModelStatus() == HighsModelStatus::kOptimal);
} else {
REQUIRE(run_status == HighsStatus::kWarning);
REQUIRE(highs.getModelStatus() == HighsModelStatus::kUnknown);
}
bool optimal = false;

run_status = highs.run();
if (dev_run) highs.writeSolution("", 1);
REQUIRE(std::abs(info.objective_function_value - optimal_objective) <
double_equal_tolerance);
if (optimal) {
REQUIRE(run_status == HighsStatus::kOk);
REQUIRE(highs.getModelStatus() == HighsModelStatus::kOptimal);
} else {
REQUIRE(run_status == HighsStatus::kWarning);
REQUIRE(highs.getModelStatus() == HighsModelStatus::kUnknown);
}

HighsInt pdlp_iteration_count = highs.getInfo().pdlp_iteration_count;
REQUIRE(pdlp_iteration_count > 0);
REQUIRE(pdlp_iteration_count == 160);
Expand Down
8 changes: 0 additions & 8 deletions src/lp_data/HighsOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ struct HighsOptionsStruct {
HighsInt ipm_iteration_limit;

// Options for PDLP solver
bool pdlp_native_termination;
bool pdlp_scaling;
HighsInt pdlp_iteration_limit;
HighsInt pdlp_e_restart_method;
Expand Down Expand Up @@ -477,7 +476,6 @@ struct HighsOptionsStruct {
output_flag(false),
log_to_console(false),
ipm_iteration_limit(0),
pdlp_native_termination(false),
pdlp_scaling(false),
pdlp_iteration_limit(0),
pdlp_e_restart_method(0),
Expand Down Expand Up @@ -1064,12 +1062,6 @@ class HighsOptions : public HighsOptionsStruct {
&ipm_iteration_limit, 0, kHighsIInf, kHighsIInf);
records.push_back(record_int);

record_bool = new OptionRecordBool(
"pdlp_native_termination",
"Use native termination for PDLP solver: Default = false", advanced,
&pdlp_native_termination, false);
records.push_back(record_bool);

record_bool = new OptionRecordBool(
"pdlp_scaling", "Scaling option for PDLP solver: Default = true",
advanced, &pdlp_scaling, true);
Expand Down
3 changes: 0 additions & 3 deletions src/pdlp/CupdlpWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,9 +597,6 @@ void getUserParamsFromOptions(const HighsOptions& options,
//
ifChangeIntParam[E_RESTART_METHOD] = true;
intParam[E_RESTART_METHOD] = int(options.pdlp_e_restart_method);
//
ifChangeIntParam[I_INF_NORM_ABS_LOCAL_TERMINATION] = true;
intParam[I_INF_NORM_ABS_LOCAL_TERMINATION] = !options.pdlp_native_termination;
}

void analysePdlpSolution(const HighsOptions& options, const HighsLp& lp,
Expand Down
8 changes: 2 additions & 6 deletions src/pdlp/cupdlp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ This directory contains files from [cuPDLP-C v0.3.0](https://github.com/COPT-Pub

cuPDLP-C terminates when either the current or averaged iterates satisfy primal/dual feasibility, using a 2-norm measure relative to the size of the RHS/costs, and after scaling the LP.

HiGHS assesses primal/dual feasibility using a infinity-norm absolute measure for the unscaled LP. Thus the cuPDLP-C result frequently fails to satisfy HiGHS primal/dual feasibility. To get around this partially, `iInfNormAbsLocalTermination` has been introduced into cuPDLP-C.
HiGHS assesses primal/dual feasibility using a infinity-norm absolute measure for the unscaled LP. Thus the cuPDLP-C result frequently fails to satisfy HiGHS primal/dual feasibility.

By default, `iInfNormAbsLocalTermination` is false, so that the original cuPDLP-C termination criteria are used.

When `iInfNormAbsLocalTermination` is true, cuPDLP-C terminates only when primal/dual feasibility is satisfied for the infinity-norm absolute measure of the current iterate, so that HiGHS primal/dual feasibility is satisfied.

However, the cuPDLP-C scaling may still result in the HiGHS tolerances not being satisfied. Users can inspect `HighsInfo` values for the maximum and sum of infeasibilities, and the new `HighsInfo` values measuring the maximum and sum of complementarity violations.
The cuPDLP-C scaling may result in the HiGHS tolerances not being satisfied. Users can inspect `HighsInfo` values for the maximum and sum of infeasibilities, and the new `HighsInfo` values measuring the maximum and sum of complementarity violations.

## Preprocessing issue

Expand Down
4 changes: 0 additions & 4 deletions src/pdlp/cupdlp/cupdlp_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,8 @@ typedef enum {
N_LOG_LEVEL,
N_LOG_INTERVAL,
IF_PRESOLVE,
I_INF_NORM_ABS_LOCAL_TERMINATION,
N_INT_USER_PARAM
} CUPDLP_INT_USER_PARAM_INDEX;
//#define N_INT_USER_PARAM 12
typedef enum {
D_SCALING_LIMIT = 0,
D_PRIMAL_TOL,
Expand All @@ -116,7 +114,6 @@ typedef enum {
D_TIME_LIM,
N_FLOAT_USER_PARAM
} CUPDLP_FLOAT_USER_PARAM_INDEX;
//#define N_FLOAT_USER_PARAM 6

// used in sparse matrix-dense vector multiplication
struct CUPDLP_CUDA_DENSE_VEC {
Expand Down Expand Up @@ -182,7 +179,6 @@ struct CUPDLP_SETTINGS {
cupdlp_float dPrimalTol;
cupdlp_float dDualTol;
cupdlp_float dGapTol;
cupdlp_int iInfNormAbsLocalTermination;

// max iter and time
cupdlp_int nIterLim;
Expand Down
35 changes: 0 additions & 35 deletions src/pdlp/cupdlp/cupdlp_linalg.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,27 +141,6 @@ double nrminf(cupdlp_int n, const double *x, cupdlp_int incx) {
#endif
}

cupdlp_int nrminfindex(cupdlp_int n, const double *x, cupdlp_int incx) {
#ifdef USE_MY_BLAS
assert(incx == 1);

double nrm = 0.0;
cupdlp_int index = 0;

for (int i = 0; i < n; ++i) {
double tmp = fabs(x[i]);
if (tmp > nrm) {
nrm = tmp;
index = i;
}
}

return index;
#else
return dnrminfindex(n, x, incx);
#endif
}

double twoNorm(double *x, cupdlp_int n) { return nrm2(n, x, 1); }

double twoNormSquared(double *x, cupdlp_int n) { return pow(twoNorm(x, n), 2); }
Expand Down Expand Up @@ -592,20 +571,6 @@ cupdlp_int cupdlp_twoNorm(CUPDLPwork *w, const cupdlp_int n,
return 0;
}

cupdlp_int cupdlp_infNormIndex(CUPDLPwork *w, const cupdlp_int n,
const cupdlp_float *x, cupdlp_int *res) {
#ifndef CUPDLP_CPU
#ifndef SFLOAT
CHECK_CUBLAS(cublasIdamax(w->cublashandle, n, x, 1, res));
#else
CHECK_CUBLAS(cublasIsamax(w->cublashandle, n, x, 1, res));
#endif
#else
*res = nrminfindex(n, x, 1);
#endif
return 0;
}

cupdlp_int cupdlp_scaleVector(CUPDLPwork *w, const cupdlp_float weight,
cupdlp_float *x, const cupdlp_int n) {
#ifndef CUPDLP_CPU
Expand Down
8 changes: 0 additions & 8 deletions src/pdlp/cupdlp/cupdlp_linalg.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ double twoNormSquared(double *x, cupdlp_int n);

double infNorm(double *x, cupdlp_int n);

cupdlp_int infNormIndex(double *x, cupdlp_int n);

/*------------------------ new added --------------------*/

double GenNorm(double *x, cupdlp_int n, cupdlp_float p);
Expand Down Expand Up @@ -113,12 +111,6 @@ cupdlp_int cupdlp_dot(CUPDLPwork *w, const cupdlp_int n, const cupdlp_float *x,
cupdlp_int cupdlp_twoNorm(CUPDLPwork *w, const cupdlp_int n,
const cupdlp_float *x, cupdlp_float *res);

cupdlp_int cupdlp_infNorm(CUPDLPwork *w, const cupdlp_int n,
const cupdlp_float *x, cupdlp_float *res);

cupdlp_int cupdlp_infNormIndex(CUPDLPwork *w, const cupdlp_int n,
const cupdlp_float *x, cupdlp_int *res);

cupdlp_int cupdlp_scaleVector(CUPDLPwork *w, const cupdlp_float weight,
cupdlp_float *x, const cupdlp_int n);

Expand Down
Loading
Loading