What is the right way to use QuantLib from multiple threads?
Asked Answered
J

2

6

I haven't been able to find any documentation explicitly describing QuantLib's thread-safety properties (or the absence of them!). The QuantLib configuration documentation lists a number of compile-time options related to thread safety, from which i infer that, by default, QuantLib is not entirely threadsafe.

In particular, there are:

  • QL_ENABLE_SESSIONS - "If defined, singletons will return different instances for different sessions. You will have to provide and link with the library a sessionId() function in namespace QuantLib, returning a different session id for each session. Undefined by default."

  • QL_ENABLE_THREAD_SAFE_OBSERVER_PATTERN - "If defined, a thread-safe (but less performant) version of the observer pattern will be used. You should define it if you want to use QuantLib via the SWIG layer within the JVM or .NET eco system or any environment with an async garbage collector. Undefined by default."

  • QL_ENABLE_SINGLETON_THREAD_SAFE_INIT - "Define this to make Singleton initialization thread-safe. Undefined by default. Not compatible with multiple sessions."

Which options should i use, and what other steps should i take, if i want to use QuantLib:

  1. From multiple threads, but never at the same time (eg only when holding a global lock)?

  2. From multiple threads at the same time, but not sharing any objects between them?

  3. From multiple threads at the same time, sharing objects between them?

The natural structure for my application is a directed acyclic graph, with a constant stream of market data entering at one end, being used to compute and update various objects, and producing a stream of estimated prices leaving at the other end. I would very much like to be able to have multiple cores working in parallel, as some calculations take a long time.

The application will mostly be written in Java, with minimal parts in C++ to interface with QuantLib. I am not planning to use the SWIG wrapper. I am happy to do memory management of QuantLib objects without help from Java's garbage collector.


EDIT! If you decide to set any of these options, then on unix, do it with the corresponding flag to ./configure:

--enable-sessions
--enable-thread-safe-observer-pattern
--enable-thread-safe-singleton-init
Jennelljenner answered 25/10, 2017 at 13:50 Comment(0)
R
6

The answer from SmallChess is not far from the truth. There are almost no locks or safety nets in QuantLib, so most people use multiprocessing if they need to distribute calculations over processors---and with good reason.

For those who want a bit more insight, and not as an endorsement of using multi-threading in QuantLib:

  • whatever else you do, if possible, enable the configuration switches that give you some safety, such as the one for thread-safe initialization of singletons (with a caveat, see below);

  • you might have multiple threads running at once if they don't share any objects, and if they don't try to modify globals such as the evaluation date (look for classes inheriting from Singleton for the list of globals).

  • if you need different evaluation dates for different threads, you can use another compilation switch to build QuantLib so that the singletons are not actually singletons, but there's an instance per thread. Caveat: this switch is not compatible with thread-safe initialization of singletons. You still shouldn't share objects between threads.

  • if you want to share objects, you might be in for more trouble than it's worth. The problems are: (1) any change to the underlying data of, say, a curve will trigger a recalculation; and (2) the recalculations (such as the bootstrap of a curve) are not executed right away, but only when needed, i.e., when some curve method is called. This means that you must keep the various steps separate: first, set the values of any quotes and make sure that there aren't any further changes; then, go around the curves and trigger recalculation, for instance by asking a discount factor at some date; finally, pass the curves to the instruments and price them. Changing a value during the calculations will result in a bootstrap being done in the middle of them; and not triggering full construction before calculations might lead to two instruments triggering two simultaneous bootstraps, which wouldn't end well for any concerned parties.

As I said, it's probably more trouble than it's worth. Ideally, don't share objects between threads and don't touch the globals. Otherwise, prefer multiprocessing.

Rising answered 3/11, 2017 at 14:28 Comment(0)
B
3

Unfortunately, QuantLib is not thread safe. None of the option you have will help you. QuantLib is a free project, it's focus is on the actual mathematical modelling and not computational optimisations such as thread safe.

You should definitely wrap QuantLib in a process. Multithreading is not encourage for QuantLib unless you absolutely know what you're doing and have checked the relevant source code.

Bastion answered 28/10, 2017 at 15:3 Comment(7)
When you say "none of the option you have will help you", do you mean that they don't do what i think they do, or they don't work, or they aren't sufficient for some reason, or what?Jennelljenner
@TomAnderson They won't do what you want to do. Please search QuantLib mailing list, there were some posts about thread safe. Depend on what you want to do, some code functions are thread safe because they don't use global variables.Bastion
@TomAnderson For example, if you just want to compute Black Scholes. It's definitely thread safe because the BlackScholesCalculator has no global dependency.Bastion
@TomAnderson Overall, the project provides no thread-safe guarantee but functions that don't have global dependency might be thread-safe.Bastion
@TomAnderson For example, functions that required global evaluation date variable can't be thread safe.Bastion
@TomAnderson You might want to figure out what functions you want to use, and take a look at the source code.Bastion
I'm sorry i doubted you!Jennelljenner

© 2022 - 2024 — McMap. All rights reserved.