-
Notifications
You must be signed in to change notification settings - Fork 23
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
Segfault when using multithreaded instances of KNITRO #93
Comments
CPLEX has similar issues: jump-dev/JuMP.jl#904 |
Investigating it further, it appears that the problem arises only when we are using Knitro's callbacks. We should figure out a thread-safe way to use them. |
Great. So it sounds like this is likely a more classic thread safety issue rather than anything to do with pthreads? |
Yes, which is a good news! I think the problem arises as we are embedding a I am working on a fix to get rid of that. |
Perfect. @arnavs is on vacation for a few weeks, but if anything is ready around that time, we can test it. |
Investigating it further, it seems that the issue arises because Knitro callbacks do not respect this rule: |
@frapac Great. Seems like a pain, but they provide a workaround? But, if I understand the workaround, we would need to be careful that we don't just end up executing all of the julia callabacks in a single julia thread, or else the advantages of parallel knitro are limited. Perhaps what is needed is that you would start up julia NUM_THREADS with roughly the same amount you want to do with the knitro threads, and then the first-layer of the callback would schedule the execution using the new PARTR stuff? Regardless, I think that multithreading support in knitro should target Julia 1.3 and above. Too much changed in the threading model in the 1.2 to 1.3 release to make backwards compatibility worthwhile. |
Even if I set A
So, Knitro creates a new thread (here with id |
Alas, I fear this is outside of my paygrade and I don't have any students who would be likely to know the answers. Should we beg help from the experts? @ChrisRackauckas do you know a good person we could ask about these sorts of multi-threading issues with external libraries? Have you run into this with DiffEq callbacks, for example? |
Looks like this was closed accidentally by #138. |
Right, thank you! |
Hello @frapac! Do you have any updates on this? I was just now looking into computing finite difference gradient values in parallel with |
Hi @ferrolho! There was indeed a few updates due to Knitro 12.2. Now Knitro enables parallel multistart by default in its internal, hence causing segfault in Knitro.jl when using parallel multistart. To catch this use case, Knitro.jl now set explicitly the number of threads to 1. |
Okay, thanks! Just to make sure: finite-difference gradient computation with more than one thread is not possible at the moment, correct? |
If you are using a callback function coded in Julia, that's correct. But if you have a pure linear/quadratic/conic structure (hence you do not rely on any callback) parallel finite-difference or multistart should work. |
I see... Thank you for the clarification. Indeed I was trying to do it for a general callback implemented in Julia. I will keep in mind this would work if I wanted to do it for pure Knitro structures though. Thanks! |
Thanks @frapac Are parallel nonlinear problems with knitro hopeless in the short term? Anything Artelys can do about it? |
Currently, I think parallel evaluations are hopeless in the near term. However, I see some hope in the long term. From what we have investigated, the segfault occurs when we are calling a Julia callback from an external C thread (cf previous stacktrace). Two workarounds would be
|
Since 1.9, threads started outside the Julia runtime (i.e. from Knitro) can now become able to call into Julia code by calling |
I haven't looked into the details, but to enable this it seems we'd need to remove: Lines 514 to 528 in 33db39c
|
Hi @frapac and @odow! set_optimizer_attributes(model,"mip_numthreads"=> 3) Is being ignored anyway. I haven't defined any user callbacks or anything, why is it still happening then? julia> versioninfo()
Julia Version 1.9.0
Commit 8e63055292 (2023-05-07 11:25 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: 8 × 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-14.0.6 (ORCJIT, tigerlake)
Threads: 1 on 8 virtual cores |
Yes. the |
I took a look here, #281, but the answer is fairly obvious in retrospect: JuMP/MOI cache data for the functions and gradients in a tape that is not thread safe, so this can never be a safe operation. At the C level, you can opt-out of the thread safety by calling |
Hi, how was this actually solved? |
It wasn't.
It is always overwritten to |
For instance, if we set a number of threads greater to one in the example
tuner.jl
:https://github.com/Artelys/KNITRO.jl/blob/fp/moi/examples/tuner.jl#L185
KNITRO returns a segfault.
The text was updated successfully, but these errors were encountered: