Skip to content

Commit 68aa814

Browse files
committed
added accessor function calls for QP callback; formatted
1 parent df93014 commit 68aa814

11 files changed

Lines changed: 71 additions & 58 deletions

File tree

check/TestCAPI.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,9 @@ static void userCallback(const int callback_type, const char* message,
208208
static HighsInt cCallHessian(const HighsInt call_type,
209209
const HighsInt* x_num_entries,
210210
const HighsInt* x_index, const double* x_value,
211-
HighsInt* hessian_x_num_entries, HighsInt* hessian_x_index,
212-
double* hessian_x_value, void* hessian_p) {
211+
HighsInt* hessian_x_num_entries,
212+
HighsInt* hessian_x_index, double* hessian_x_value,
213+
void* hessian_p) {
213214
assert(kHighsHessianOracleCallTypeMin <= call_type &&
214215
call_type <= kHighsHessianOracleCallTypeMax);
215216
CHessian hessian = *(CHessian*)hessian_p;

check/TestCallbacks.cpp

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -271,40 +271,42 @@ HighsCallbackFunctionType userkMipUserSetPartialSolution =
271271
}
272272
};
273273

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-
};
274+
HighsCallbackFunctionType userQpCallback = [](int callback_type,
275+
const std::string& message,
276+
const HighsCallbackOutput*
277+
data_out,
278+
HighsCallbackInput* data_in,
279+
void* user_callback_data) {
280+
// Extract local_callback_data from user_callback_data unless it
281+
// is nullptr
282+
if (callback_type == kCallbackQpFirstFeasiblePoint) {
283+
// Use local_callback_data to maintain the objective value from
284+
// the previous callback
285+
assert(user_callback_data);
286+
// Extract the double value pointed to from void* user_callback_data
287+
const double local_callback_data = *(double*)user_callback_data;
288+
if (dev_run)
289+
printf(
290+
"userQpCallback(type %2d; data %11.4g): %s with solution[0] = %g\n",
291+
callback_type, local_callback_data, message.c_str(),
292+
data_out->qp_solution[0]);
293+
} else if (callback_type == kCallbackQpInterrupt) {
294+
const int local_callback_data =
295+
user_callback_data
296+
? static_cast<int>(reinterpret_cast<intptr_t>(user_callback_data))
297+
: kUserCallbackNoData;
298+
REQUIRE(local_callback_data == kUserCallbackData);
299+
if (dev_run)
300+
printf(
301+
"userInterruptCallback(type %2d; data %2d): %s with iteration "
302+
"count = %d and objective_value = %g\n",
303+
callback_type, local_callback_data, message.c_str(),
304+
int(data_out->qpasm_iteration_count),
305+
data_out->objective_function_value);
306+
data_in->user_interrupt =
307+
data_out->qpasm_iteration_count > primal1_qp_iteration_limit;
308+
}
309+
};
308310

309311
std::function<void(int, const std::string&, const HighsCallbackOutput*,
310312
HighsCallbackInput*, void*)>
@@ -647,7 +649,8 @@ TEST_CASE("highs-callback-mip-user-solution-c", "[highs-callback]") {
647649
}
648650

649651
TEST_CASE("highs-callback-qpasm", "[highs_callback]") {
650-
std::string filename = std::string(HIGHS_DIR) + "/check/instances/primal1.mps";
652+
std::string filename =
653+
std::string(HIGHS_DIR) + "/check/instances/primal1.mps";
651654
Highs highs;
652655
// highs.setOptionValue("output_flag", dev_run);
653656
highs.readModel(filename);
@@ -660,4 +663,3 @@ TEST_CASE("highs-callback-qpasm", "[highs_callback]") {
660663

661664
highs.resetGlobalScheduler(true);
662665
}
663-

check/TestQpOracle.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ void testOracleSolve(const HighsModel& model);
3636
//
3737
// kHessianOracleCallTypeColumn
3838
//
39-
// Set *hessian_x_num_entries, *hessian_x_index and *hessian_x_value as Hessian column
40-
// *x_index, where *hessian_x_index contains the *hessian_x_num_entries indices of
41-
// the column nonzeros, and their values are assumed to be scattered
39+
// Set *hessian_x_num_entries, *hessian_x_index and *hessian_x_value as Hessian
40+
// column *x_index, where *hessian_x_index contains the *hessian_x_num_entries
41+
// indices of the column nonzeros, and their values are assumed to be scattered
4242
// in *hessian_x_value
4343
//
4444
// Return 0 if the Hessian column is available, otherwise, return a nonzero
@@ -59,8 +59,8 @@ void testOracleSolve(const HighsModel& model);
5959
HighsHessianFunctionType oracleCallSquareHessian =
6060
[](const HighsInt call_type, const HighsInt* x_num_entries,
6161
const HighsInt* x_index, const double* x_value,
62-
HighsInt* hessian_x_num_entries, HighsInt* hessian_x_index, double* hessian_x_value,
63-
void* hessian_p) {
62+
HighsInt* hessian_x_num_entries, HighsInt* hessian_x_index,
63+
double* hessian_x_value, void* hessian_p) {
6464
assert(kHessianOracleCallTypeMin <= call_type &&
6565
call_type <= kHessianOracleCallTypeMax);
6666

@@ -261,8 +261,8 @@ TEST_CASE("hessian-oracle-check", "[qp-oracle]") {
261261
HighsHessianFunctionType oracleCallSquareHessianCustomised =
262262
[&](const HighsInt call_type, const HighsInt* x_num_entries,
263263
const HighsInt* x_index, const double* x_value,
264-
HighsInt* hessian_x_num_entries, HighsInt* hessian_x_index, double* hessian_x_value,
265-
void* hessian_p) {
264+
HighsInt* hessian_x_num_entries, HighsInt* hessian_x_index,
265+
double* hessian_x_value, void* hessian_p) {
266266
assert(kHessianOracleCallTypeMin <= call_type &&
267267
call_type <= kHessianOracleCallTypeMax);
268268

check/TestRunData.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ TEST_CASE("highs-run-data-presolve", "[highs_run_data]") {
7575
const bool reduces_to_empty = false;
7676
for (auto& solver : solvers) {
7777
h.setOptionValue("solver", solver);
78-
if (dev_run)
79-
printf("\n!>>>>%s-%s<<<<\n", model.c_str(), solver.c_str());
78+
if (dev_run) printf("\n!>>>>%s-%s<<<<\n", model.c_str(), solver.c_str());
8079

8180
REQUIRE(h.presolve() == HighsStatus::kOk);
8281
HighsLp presolved_lp = h.getPresolvedLp();
@@ -93,7 +92,6 @@ TEST_CASE("highs-run-data-presolve", "[highs_run_data]") {
9392

9493
void testRunData(Highs& h, const bool irreducible, const bool reduces_to_empty,
9594
const std::string& run_data_file) {
96-
9795
assert(!(irreducible && reduces_to_empty));
9896
const HighsRunData& run_data = h.getRunData();
9997
const HighsLp& lp = h.getLp();

highs/interfaces/highs_c_api.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1566,6 +1566,8 @@ const void* Highs_getCallbackDataOutItem(const HighsCallbackDataOut* data_out,
15661566
return (void*)(&data_out->ipm_iteration_count);
15671567
} else if (!strcmp(item_name, kHighsCallbackDataOutPdlpIterationCountName)) {
15681568
return (void*)(&data_out->pdlp_iteration_count);
1569+
} else if (!strcmp(item_name, kHighsCallbackDataOutQpasmIterationCountName)) {
1570+
return (void*)(&data_out->qpasm_iteration_count);
15691571
} else if (!strcmp(item_name,
15701572
kHighsCallbackDataOutObjectiveFunctionValueName)) {
15711573
return (void*)(&data_out->objective_function_value);
@@ -1598,6 +1600,8 @@ const void* Highs_getCallbackDataOutItem(const HighsCallbackDataOut* data_out,
15981600
return (void*)(data_out->cutpool_lower);
15991601
} else if (!strcmp(item_name, kHighsCallbackDataOutCutpoolUpperName)) {
16001602
return (void*)(data_out->cutpool_upper);
1603+
} else if (!strcmp(item_name, kHighsCallbackDataOutQpSolutionName)) {
1604+
return (void*)(data_out->qp_solution);
16011605
}
16021606
return nullptr;
16031607
}

highs/interfaces/highs_c_api.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ static const char* const kHighsCallbackDataOutIpmIterationCountName =
117117
"ipm_iteration_count";
118118
static const char* const kHighsCallbackDataOutPdlpIterationCountName =
119119
"pdlp_iteration_count";
120+
static const char* const kHighsCallbackDataOutQpasmIterationCountName =
121+
"qpasm_iteration_count";
120122
static const char* const kHighsCallbackDataOutObjectiveFunctionValueName =
121123
"objective_function_value";
122124
static const char* const kHighsCallbackDataOutMipNodeCountName =
@@ -145,6 +147,7 @@ static const char* const kHighsCallbackDataOutCutpoolLowerName =
145147
"cutpool_lower";
146148
static const char* const kHighsCallbackDataOutCutpoolUpperName =
147149
"cutpool_upper";
150+
static const char* const kHighsCallbackDataOutQpSolutionName = "qp_solution";
148151

149152
const HighsInt kHighsIisStrategyLight = 0;
150153
// Forces full IIS calculation as before - ie with the

highs/lp_data/HStruct.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,9 @@ struct HighsUserScaleData {
249249

250250
using HighsHessianFunctionType = std::function<HighsInt(
251251
const HighsInt call_type, const HighsInt* x_num_entries,
252-
const HighsInt* x_index, const double* x_value, HighsInt* hessian_x_num_entries,
253-
HighsInt* hessian_x_index, double* hessian_x_value, void*)>;
252+
const HighsInt* x_index, const double* x_value,
253+
HighsInt* hessian_x_num_entries, HighsInt* hessian_x_index,
254+
double* hessian_x_value, void*)>;
254255

255256
struct HessianOracle {
256257
// Oracle to obtain values of Q' = multiplier_*Q + shift_*I and form

highs/lp_data/Highs.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,10 +725,12 @@ HighsStatus Highs::passHessian(const HighsInt dim,
725725
oracle.call_ = [c_oracleCall](
726726
const HighsInt type, const HighsInt* x_num_entries,
727727
const HighsInt* x_index, const double* x_value,
728-
HighsInt* hessian_x_num_entries, HighsInt* hessian_x_index,
729-
double* hessian_x_value, void* data) {
728+
HighsInt* hessian_x_num_entries,
729+
HighsInt* hessian_x_index, double* hessian_x_value,
730+
void* data) {
730731
return c_oracleCall(type, x_num_entries, x_index, x_value,
731-
hessian_x_num_entries, hessian_x_index, hessian_x_value, data);
732+
hessian_x_num_entries, hessian_x_index,
733+
hessian_x_value, data);
732734
};
733735
} else {
734736
oracle.call_ = oracleCall;

highs/lp_data/HighsCallback.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ HighsCallbackOutput::operator HighsCallbackDataOut() const {
140140
: const_cast<double*>(cutpool_upper.data());
141141

142142
data.qp_solution_size = qp_solution.size();
143-
data.qp_solution = qp_solution.empty() ? nullptr : const_cast<double*>(qp_solution.data());
144-
143+
data.qp_solution =
144+
qp_solution.empty() ? nullptr : const_cast<double*>(qp_solution.data());
145+
145146
data.external_solution_query_origin =
146147
static_cast<HighsInt>(external_solution_query_origin);
147148

highs/model/HighsHessian.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,8 @@ void HessianOracle::product(const std::vector<double>& x_value,
741741
}
742742

743743
// For full x
744-
void HessianOracle::product(const double* x_value, double* hessian_x_value) const {
744+
void HessianOracle::product(const double* x_value,
745+
double* hessian_x_value) const {
745746
assert(this->call_);
746747
this->call_(kHessianOracleCallTypeProduct, nullptr, nullptr, x_value, nullptr,
747748
nullptr, hessian_x_value, this->data_);

0 commit comments

Comments
 (0)