Skip to content

Conversation

darrylmelander
Copy link
Contributor

@darrylmelander darrylmelander commented Jun 24, 2025

Give access to some callbacks in C#, as events on the C# HighsLpSolver class. Only a handful of callbacks are made available by this commit. The callbacks, and the new events they map to, are as follows:

kCallbackLogging => LogMessageReceived
kCallbackMipLogging => MipStatusReported
kCallbackMipImprovingSolution => MipImprovingSolutionFound
kCallbackMipInterrupt => MipInterruptCheck
kCallbackSimplexInterrupt => SimplexInterruptCheck
kCallbackIpmInterrupt => IpmInterruptCheck

Clients subscribe to and unsubscribe from these events as they would for any other event, using syntax such as solver.LogMessageReceived += MyLoggingFunc. Event data only includes what's relevant to the type of event. The *InterruptCheck events allow you to set the interrupt flag, the others don't.

The events in this PR address #2042.

Several HiGHS callbacks are each exposed as its own event in the C# HighsLpSolver
class. The event names are as follows:

    kCallbackLogging => LogMessageReceived
    kCallbackMipLogging => MipStatusReported
    kCallbackMipImprovingSolution => MipImprovingSolutionFound
    kCallbackMipInterrupt => MipInterruptCheck
    kCallbackSimplexInterrupt => SimplexInterruptCheck
    kCallbackIpmInterrupt => IpmInterruptCheck

Clients subscribe to and unsubscribe from these events as they would for any other event,
using syntax such as `lp.LogMessageReceived += MyLoggingFunc`. Subscribers don't need
to call Highs_startCallback or Highs_stopCallback. The events are written so that they
automatically call startCallback when the first client subscribes to the event, and
automatically call stopCallback when the last client unsubscribes from the event.

The interrupt check events include a `user_interrupt` flag in their event args. If an event
handler sets this flag, it is passed back to HiGHS via the cbDataIn callback function argument,
which causes the event's algorithm to stop.
Copy link

codecov bot commented Jun 24, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 79.44%. Comparing base (5849657) to head (b29f05e).
Report is 36 commits behind head on latest.

Additional details and impacted files
@@            Coverage Diff             @@
##           latest    #2433      +/-   ##
==========================================
+ Coverage   79.30%   79.44%   +0.14%     
==========================================
  Files         346      346              
  Lines       84987    85060      +73     
==========================================
+ Hits        67400    67579     +179     
+ Misses      17587    17481     -106     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@darrylmelander
Copy link
Contributor Author

I'm submitting this as a draft PR to get feedback from the HiGHS team, and to give me more time to run it through its paces.

In particular I'd like to discuss testing of this particular feature. I'd love for it to be included in CI so we can detect if future callback changes break the integration. Locally, I tested by adding a function to the C interface that lets you trigger callbacks with supplied data to a specified callback function. This function is only useful for testing purposes and wouldn't belong in the released C interface. I also added a C# test library that calls the callback trigger function. Without testing for specific callbacks with specific data, we can't be confident data is getting across the C/C# boundary correctly. My testing approach is a lot more intrusive than just adding some code to existing test files, so I'd be interested in hearing how the team would like to approach regression testing for this feature.

@galabovaa
Copy link
Contributor

Thank you, @darrylmelander!

Yes, we would like to add such tests to our CI too. We would possibly try to follow or extend what we already have in terms of testing.

  1. Examples

So far, we have a csharp executable, which calls the csharp API: https://github.com/ERGO-Code/HiGHS/blob/master/examples/call_highs_from_csharp.cs

Perhaps we could have another example, which uses some callbacks from C#, to illustrate how to do it. This is built by cmake.

  1. Nuget

Additionally, we also test the nuget package: https://github.com/ERGO-Code/HiGHS/blob/master/.github/workflows/test-nuget-win.yml

It is worth adding callback examples tests to the nuget as well.

  1. External repos

We are developing some code in external repositories with additional tests to be run before we tag a new release. I could add more C# tests there too, containing specific callbacks with specific data.

Perhaps it is worth having a short call about this. We are busy this week organising our workshop, but we could arrange a call next week. Please send me an email at galabovaa@gmail.com with your availability if you have the time and would like to discuss some of the details.

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

Successfully merging this pull request may close these issues.

2 participants