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

Prevent the Highs instance from being called by a callback that it calls. #1523

Open
jeffreydeankelly2 opened this issue Nov 22, 2023 · 5 comments
Assignees
Labels

Comments

@jeffreydeankelly2
Copy link

I recently upgraded to HiGHS 1.6.0 using JuMP supplied Windows non-static binaries and added the MIP logging and improving solution callbacks - thank you for adding these.

I interfaced the HighsCallbackDataOut structure from C to Intel Fortran using the Fortran derived types.

The callback to retrieve the variable-length double 1D-array mip_solution(*) works well except that I noticed an arbitrary five (5) element offset in order to properly align the C mip_solution() vector into the Fortran mip_solution() i.e., mip_solution(1+5:n+5) where "n" is the known length of variables. Otherwise, the variable solution data for each integer-feasible solution is received properly including the mix of reals and integers placed before mip_solution().

However I noticed that when CRTL-C is typed, HiGHS returns immediately with the text "Press any key to continue . . .". All other key-strokes such as CRTL-A, -B, -D,..,-Z have no effect.

Therefore, it seems that HiGHS has some CRTL-C signal handler invoked inherently?

In our industrial software we use CRTL-C consistently across all 3rd-party LP, QP, MIP and NLP solvers in order for the user to terminate the MIP solving process gracefully but unfortunately with HiGHS, CRTL-C is preempted before our signal handler can be invoked.

@jeffreydeankelly2 jeffreydeankelly2 changed the title Is there a implied/inherent Control-C signal handler in HiGHS? Is there an implied/inherent Control-C signal handler in HiGHS? Nov 22, 2023
@jajhall
Copy link
Member

jajhall commented Nov 22, 2023

Oops, yes, I was trying to put a CRTL-C handler into HiGHS but gave up, and failed to remove the development code (Lines 52 onwards in lp_data/Highs.cpp)

void highsSignalHandler(int signum) {
// std::cout << "Interrupt signal (" << signum << ") received.\n";
exit(signum);
}
Highs::Highs() { signal(SIGINT, highsSignalHandler); }

Since there is not (yet) anything in the HiGHS Fortran API to handle callbacks, do I infer from the following that you had to wrote something yourself and had to get around the fact that in HighsCallbackDataOut (see lp_data/HighsCallbackStruct.h) the pointer to the values of the solution is not on an 8-byte boundary - since an int, two HighsInt (which can be 4 or 8 bytes) and an int64_t constitute an odd number of 4-byte words. I can get around this by making double* mip_solution the first member of the HighsCallbackDataOut struct. That scalar doubles won't be on 8-byte boundaries presumably has little overhead.

Assuming that you wrote your own Fortran API to handle callbacks, could you share it with me since I wouldn't know how to write it.

The callback to retrieve the variable-length double 1D-array mip_solution(*) works well except that I noticed an arbitrary five (5) element offset in order to properly align the C mip_solution() vector into the Fortran mip_solution() i.e., mip_solution(1+5:n+5) where "n" is the known length of variables. Otherwise, the variable solution data for each integer-feasible solution is received properly including the mix of reals and integers placed before mip_solution().

@jeffreydeankelly2
Copy link
Author

jeffreydeankelly2 commented Nov 22, 2023 via email

@jajhall
Copy link
Member

jajhall commented Nov 22, 2023

Thanks for letting me know about the CRTL-C signal handler - I look forward
to it being removed in your next release :-)

I've asked the two other folk with whom I've communicated regarding the CRTL-C signal handler, just out of politeness, as removing it would, technically, break the API

Technically speaking, all C to Fortran API's seem to be redundant given
standard Fortran's C Interoperability capability. Hence I never use these
API's supplied by 3rd C/C++ based solvers as they are usually out-of-date
and incomplete as well.

That's interesting to know. Our Fortran API can certainly be classed as "out-of-date and incomplete". I'll still keep it, as it does no harm, but add a comment to the effect that it's out-of-date and incomplete, and that folk should exploit standard Fortran's C Interoperability capability.

The way all of the other MIP callbacks are implemented is to allow the user
to call for example your Highs_getSolution() routine (or the like) to
retrieve the MIP improving solutions inside the callback routine.

This wouldn't work in HiGHS, as no MIP solver data can be reached via the Highs C++ API. Indeed, if a user's callback function were to start calling methods in the instance of the Highs class (by passing a pointer to it via the void* user_data parameter) then all sorts of chaos could ensue! I should add code to the Highs C++ API to ensure that all methods give an immediate error return!

Thanks for the Fortran callback function. I'll add it to examples/call_highs_from_fortran.f90.

I can get around this by making double* mip_solution the first member of
the HighsCallbackDataOut struct. That scalar doubles won't be on 8-byte
boundaries presumably has little overhead.

That may work but I am not sure if the other appended integers and doubles
will be affected with offsets in a similar way when receiving their values
in Fortran.

Ah, so they may be wrong, not just slower to access. I'm forgetting my Fortran implications!

@jeffreydeankelly2
Copy link
Author

jeffreydeankelly2 commented Nov 22, 2023 via email

@jajhall jajhall self-assigned this Nov 22, 2023
@jajhall jajhall added code-quality bug enhancement New feature or request labels Nov 22, 2023
@jajhall jajhall changed the title Is there an implied/inherent Control-C signal handler in HiGHS? Prevent the Highs instance from being called by a callback that it calls. Nov 22, 2023
@jajhall
Copy link
Member

jajhall commented Nov 22, 2023

I'm trying to call the Highs instance from a call-back in check/TestCallbacks.cpp, but don't see how to pass and use the Highs instance via the void* pointer in highs-callback-no-highs-call in check/TestCallbacks.cpp

See branch fix-1523-latest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants