Skip to content

Remove resetGlobalScheduler calls from C API#3141

Open
odow wants to merge 3 commits into
latestfrom
od/resetGlobalScheduler
Open

Remove resetGlobalScheduler calls from C API#3141
odow wants to merge 3 commits into
latestfrom
od/resetGlobalScheduler

Conversation

@odow

@odow odow commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

It is not thread-safe for the C API to call resetGlobalScheduler because another thread may be in the middle of a Highs_ call.

Extracted from #3136

This should fix the random segfaults we are seeing with the Julia tests.

The Julia tests are a prime candidate for encountering this bug because they spawn many instances of HiGHS, Highs_destroy is called when the instances are garbage collected, and Julia's garbage collector runs in a separate thread.

It is not thread-safe for the C API to call resetGlobalScheduler because
another thread may be in the middle of a Highs_ call.
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.17%. Comparing base (8e8d4f6) to head (1c0769f).
⚠️ Report is 5 commits behind head on latest.

Additional details and impacted files
@@            Coverage Diff             @@
##           latest    #3141      +/-   ##
==========================================
+ Coverage   73.16%   73.17%   +0.01%     
==========================================
  Files         430      430              
  Lines      103967   104034      +67     
  Branches    16718    16727       +9     
==========================================
+ Hits        76069    76129      +60     
- Misses      27622    27629       +7     
  Partials      276      276              

☔ View full report in Codecov by Harness.
📢 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.

@filikat

filikat commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

I managed to reproduce segfaults and other weird behaviour with a unit test that runs two separate Highs instances in separate threads. The bad behaviour disappears using this branch.

@tobiass-sdl

Copy link
Copy Markdown

Sorry for highjacking this but if resetGlobalScheduler is not thread safe how do I change the number of threads used by a HiGHS instance?
Use case: running HiGHS inside a server that depending on user input either wants to put all cpu cores on one MIP or solve a bunch of small MIP in parallel with 1 thread each - the later is useful if you have a problem that is decomposable by domain knowledge...
If you set the option twice within the same thread, you get
"ERROR: Option 'threads' is set to 3 but global scheduler has already been initialized to use 2 threads. The previous scheduler instance can be destroyed by calling Highs::resetGlobalScheduler()."
Given this PR I guess the recommendation is not safe?

@filikat

filikat commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

It is not thread safe to call resetGlobalScheduler while a Highs instance is running.
If you generate multiple instances and run them in parallel, you should not call resetGlobalScheduler while another thread is calling Highs_run, or any other function that runs Highs.
It is completely safe to call resetGlobalScheduler while no Highs instance is running (e.g. before starting running any Highs instance, or after all instances have finished).

It is not possible to have multiple Highs instances running with different values of the thread option within the same process, as the parallel scheduler is shared by all instances.

@tobiass-sdl

Copy link
Copy Markdown

It is not thread safe to call resetGlobalScheduler while a Highs instance is running. If you generate multiple instances and run them in parallel, you should not call resetGlobalScheduler while another thread is calling Highs_run, or any other function that runs Highs. It is completely safe to call resetGlobalScheduler before starting running any Highs instance, or after all instances have finished.

If you're using HiGHS within a web server that serves more then one user you always have to assume that another HiGHS instance is running in parallel - or you keep track yourself how many highs instances are running and only set the thread call if this count is 0 and if not you can't set the thread count for the instance you are about to start... Which means that in my use case it's probably best disable the parallel mip solver and go for threads=1 all the time.

@filikat

filikat commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

You can set parallel=off for a given instance and most parallelism will be switched off. There is only a limited number of things that can run in parallel when parallel=off (see https://ergo-code.github.io/HiGHS/stable/parallel/).
If you're looking to fine tune how many threads each Highs instance is allowed to use within the same process, I don't think this is possible using the current Highs parallel scheduler.

@jajhall jajhall requested a review from filikat July 8, 2026 16:54
@jajhall jajhall self-assigned this Jul 8, 2026
@odow

odow commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

Ooops. Failing Julia tests were because I jumped the gun to make a change in HiGHS. I've reverted it for now: jump-dev/HiGHS.jl@c8a94c6 and restarted the tests.

(I thought it would just silently ignore the option, not error.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants