Skip to content

Commit df93014

Browse files
committed
Added highs-callback-qpasm unit test
1 parent 642a865 commit df93014

4 files changed

Lines changed: 67 additions & 1 deletion

File tree

check/TestCallbacks.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ const double egout_objective_target = 610;
1616
const HighsInt adlittle_ipm_iteration_limit = 5;
1717
const HighsInt adlittle_simplex_iteration_limit = 30;
1818

19+
const HighsInt primal1_qp_iteration_limit = 5;
20+
1921
const HighsInt kLogBufferSize = kIoBufferSize;
2022
const HighsInt kUserCallbackNoData = -1;
2123
const HighsInt kUserCallbackData = 99;
@@ -269,6 +271,41 @@ HighsCallbackFunctionType userkMipUserSetPartialSolution =
269271
}
270272
};
271273

274+
HighsCallbackFunctionType userQpCallback =
275+
[](int callback_type, const std::string& message,
276+
const HighsCallbackOutput* data_out, HighsCallbackInput* data_in,
277+
void* user_callback_data) {
278+
// Extract local_callback_data from user_callback_data unless it
279+
// is nullptr
280+
if (callback_type == kCallbackQpFirstFeasiblePoint) {
281+
// Use local_callback_data to maintain the objective value from
282+
// the previous callback
283+
assert(user_callback_data);
284+
// Extract the double value pointed to from void* user_callback_data
285+
const double local_callback_data = *(double*)user_callback_data;
286+
if (dev_run)
287+
printf(
288+
"userQpCallback(type %2d; data %11.4g): %s with solution[0] = %g\n",
289+
callback_type, local_callback_data, message.c_str(),
290+
data_out->qp_solution[0]);
291+
} else if (callback_type == kCallbackQpInterrupt) {
292+
const int local_callback_data =
293+
user_callback_data ? static_cast<int>(reinterpret_cast<intptr_t>(
294+
user_callback_data))
295+
: kUserCallbackNoData;
296+
REQUIRE(local_callback_data == kUserCallbackData);
297+
if (dev_run)
298+
printf(
299+
"userInterruptCallback(type %2d; data %2d): %s with iteration "
300+
"count = "
301+
"%d\n",
302+
callback_type, local_callback_data, message.c_str(),
303+
int(data_out->qpasm_iteration_count));
304+
data_in->user_interrupt =
305+
data_out->qpasm_iteration_count > primal1_qp_iteration_limit;
306+
}
307+
};
308+
272309
std::function<void(int, const std::string&, const HighsCallbackOutput*,
273310
HighsCallbackInput*, void*)>
274311
userDataCallback = [](int callback_type, const std::string& message,
@@ -608,3 +645,19 @@ TEST_CASE("highs-callback-mip-user-solution-c", "[highs-callback]") {
608645
highs.run();
609646
highs.resetGlobalScheduler(true);
610647
}
648+
649+
TEST_CASE("highs-callback-qpasm", "[highs_callback]") {
650+
std::string filename = std::string(HIGHS_DIR) + "/check/instances/primal1.mps";
651+
Highs highs;
652+
// highs.setOptionValue("output_flag", dev_run);
653+
highs.readModel(filename);
654+
void* p_user_callback_data = nullptr;
655+
656+
highs.setCallback(userQpCallback, p_user_callback_data);
657+
highs.startCallback(kCallbackQpFirstFeasiblePoint);
658+
highs.startCallback(kCallbackQpInterrupt);
659+
highs.run();
660+
661+
highs.resetGlobalScheduler(true);
662+
}
663+

highs/lp_data/HighsCallback.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ void HighsCallback::clearHighsCallbackOutput() {
2424
this->data_out.simplex_iteration_count = -1;
2525
this->data_out.ipm_iteration_count = -1;
2626
this->data_out.pdlp_iteration_count = -1;
27+
this->data_out.qpasm_iteration_count = -1;
2728
this->data_out.objective_function_value = -kHighsInf;
2829
this->data_out.mip_node_count = -1;
2930
this->data_out.mip_primal_bound = kHighsInf;
@@ -35,6 +36,7 @@ void HighsCallback::clearHighsCallbackOutput() {
3536
this->data_out.cutpool_value.clear();
3637
this->data_out.cutpool_lower.clear();
3738
this->data_out.cutpool_upper.clear();
39+
this->data_out.qp_solution.clear();
3840
this->data_out.external_solution_query_origin =
3941
ExternalMipSolutionQueryOrigin::kExternalMipSolutionQueryOriginAfterSetup;
4042
}
@@ -96,7 +98,8 @@ bool HighsCallback::callbackAction(const int callback_type,
9698

9799
// Conversions for C API
98100

99-
// Convert HighsCallbackDataOut to HighsCCallbackDataOut
101+
// Return HighsCallbackDataOut (ie pointer-based) data structure from
102+
// HighsCallbackOutput
100103
HighsCallbackOutput::operator HighsCallbackDataOut() const {
101104
HighsCallbackDataOut data;
102105
data.cbdata = static_cast<void*>(const_cast<HighsCallbackOutput*>(this));
@@ -105,6 +108,7 @@ HighsCallbackOutput::operator HighsCallbackDataOut() const {
105108
data.simplex_iteration_count = simplex_iteration_count;
106109
data.ipm_iteration_count = ipm_iteration_count;
107110
data.pdlp_iteration_count = pdlp_iteration_count;
111+
data.qpasm_iteration_count = qpasm_iteration_count;
108112
data.objective_function_value = objective_function_value;
109113

110114
data.mip_node_count = mip_node_count;
@@ -135,8 +139,12 @@ HighsCallbackOutput::operator HighsCallbackDataOut() const {
135139
? nullptr
136140
: const_cast<double*>(cutpool_upper.data());
137141

142+
data.qp_solution_size = qp_solution.size();
143+
data.qp_solution = qp_solution.empty() ? nullptr : const_cast<double*>(qp_solution.data());
144+
138145
data.external_solution_query_origin =
139146
static_cast<HighsInt>(external_solution_query_origin);
147+
140148
return data;
141149
}
142150

highs/lp_data/HighsCallback.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct HighsCallbackOutput {
4040
HighsInt simplex_iteration_count;
4141
HighsInt ipm_iteration_count;
4242
HighsInt pdlp_iteration_count;
43+
HighsInt qpasm_iteration_count;
4344
double objective_function_value;
4445
int64_t mip_node_count;
4546
int64_t mip_total_lp_iterations;
@@ -54,6 +55,7 @@ struct HighsCallbackOutput {
5455
std::vector<double> cutpool_value;
5556
std::vector<double> cutpool_lower;
5657
std::vector<double> cutpool_upper;
58+
std::vector<double> qp_solution;
5759
ExternalMipSolutionQueryOrigin external_solution_query_origin;
5860

5961
operator HighsCallbackDataOut() const;

highs/lp_data/HighsCallbackStruct.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef struct HighsCallbackDataOut {
2828
HighsInt simplex_iteration_count;
2929
HighsInt ipm_iteration_count;
3030
HighsInt pdlp_iteration_count;
31+
HighsInt qpasm_iteration_count;
3132
double objective_function_value;
3233
int64_t mip_node_count;
3334
int64_t mip_total_lp_iterations;
@@ -44,6 +45,8 @@ typedef struct HighsCallbackDataOut {
4445
double* cutpool_value;
4546
double* cutpool_lower;
4647
double* cutpool_upper;
48+
double* qp_solution;
49+
HighsInt qp_solution_size;
4750
HighsInt external_solution_query_origin;
4851
} HighsCallbackDataOut;
4952

0 commit comments

Comments
 (0)