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

highspy: Passing user_callback_data to setCallback raises exception #1904

Closed
few opened this issue Sep 1, 2024 · 3 comments
Closed

highspy: Passing user_callback_data to setCallback raises exception #1904

few opened this issue Sep 1, 2024 · 3 comments
Assignees

Comments

@few
Copy link
Contributor

few commented Sep 1, 2024

The following code raises an exception (at least on the latest branch):


h = highspy.Highs()

def callback(callback_type, message, data_out, data_in, user_callback_data):
    pass

user_callback_data = {}
h.setCallback(callback, user_callback_data)
TypeError: setCallback(): incompatible function arguments. The following argument types are supported:
    1. (self: highspy._core._Highs, arg0: Callable[[int, str, HighsCallbackDataOut, HighsCallbackDataIn, capsule], None], arg1: capsule) -> highspy._core.HighsStatus

Invoked with: <highspy.highs.Highs object at 0x7f9b12ffa160>, <function callback at 0x7f9b132b7d90>, {}

Passing None as user_callback_data works.

@jajhall
Copy link
Member

jajhall commented Sep 2, 2024

This is done so that users can pass data required in a callback. It works fine in C++ (and C, I think). I've got no idea how to make it work in Python

@jajhall jajhall self-assigned this Sep 2, 2024
@few
Copy link
Contributor Author

few commented Sep 2, 2024

I found a workaround:

import highspy

h = highspy.Highs()
h.readModel("30n20b8.mps")
h.setOptionValue("time_limit", 90)

class CallbackManager:
    mip_solution = None

    def callback(self, callback_type, message, data_out, data_in, user_callback_data):
        self.mip_solution = data_out.mip_solution

callback_manager = CallbackManager()
h.setCallback(callback_manager.callback, None)
h.startCallback(highspy.cb.HighsCallbackType.kCallbackMipImprovingSolution)
h.run()
h.stopCallback(highspy.cb.HighsCallbackType.kCallbackMipImprovingSolution)

print("best solution so far:", callback_manager.mip_solution)

This way one can store arbitrary data in the CallbackManager object. Maybe user_callback_data is not needed in highspy?

mathgeekcoder added a commit to mathgeekcoder/HiGHS that referenced this issue Sep 16, 2024
Major highspy update:
* changed `highs_linear_expression` to be immutable by default
* improved callback support
* improved test coverage (99%)
* performance and usability enhancements
* Support `__iadd__`, `__imul__`, etc.
* Updated chain comparison support in immutable setting
* `h.val()` can take `highs_linear_expression`
* `expr == [lb,ub]` -> `lb <= expr <= ub` syntax
* `qsum`
* added pretty print `__repr__` and `__str__`
* added KeyboardInterrupt support
* added user interrupt
* fixed slicing issues with numpy and highs
* added `resetGlobalScheduler`
* released GIL for `Presolve`
* fixed issues with deadlock on Windows
* fixed MIP solution callback issue
* support `getExpr` that creates a `highs_linear_expression` from existing row

Should address multiple issues: ERGO-Code#1865, ERGO-Code#1882, ERGO-Code#1888, ERGO-Code#1892, ERGO-Code#1903, ERGO-Code#1904, and perhaps ERGO-Code#1905
@jajhall
Copy link
Member

jajhall commented Sep 26, 2024

Closed by #1942

@jajhall jajhall closed this as completed Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants