@@ -16,6 +16,8 @@ const double egout_objective_target = 610;
1616const HighsInt adlittle_ipm_iteration_limit = 5 ;
1717const HighsInt adlittle_simplex_iteration_limit = 30 ;
1818
19+ const HighsInt primal1_qp_iteration_limit = 5 ;
20+
1921const HighsInt kLogBufferSize = kIoBufferSize ;
2022const HighsInt kUserCallbackNoData = -1 ;
2123const 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+
272309std::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+
0 commit comments