Update: 10.03.2016: added performance results of latest QuantLib test-suite build on a 32 Core SMP machine using boost interprocess instead of MPI.
Running QuantLib’s test suite on a recent computer takes around 10min. The situation will improve a lot if the test runner utilises more than one core of today’s multi-core CPUs to run the tests in parallel. Unfortunately multi-threading won’t work because the boost unit test framework is not thread safe. A reasonable way forward to speed-up the test suite is via multiprocessing using message passing between the compute nodes based on the master-slave paradigm. The cross platform standard MPI together with boost::mpi is tailor-made for this task.
The missing piece is an external, parallel unit test runner, which uses MPI for load balancing and to collect the test results. The runner for QuantLib ‘s test suite needs boost version 1.59 or higher and can be found here. Please replace in quantlibtestsuite.cpp line 24
#include <boost/test/unit_test.hpp>
by
#include <mpiparalleltestrunner.hpp>
and do not link the executable with libboost_unit_test_framework.so because the new header file includes the header only version of the boost test framework (Thanks to Peter Caspers for the hint). Load balancing is a crucial point for the overall speed-up because QuantLib’s test suite has a handful of long running tests (max. around 90 seconds), which should be scheduled first. Therefore the MPI test runner collects the statistics of every unit-test’s runtime and stores these in a local file to plan the schedule of the next runs.
The diagram above shows the runtime of QuantLib’s test suite for a different number of parallel processes and CPU configurations. The minimum runtime is set by the longest running test case, which is around 50 seconds. On a single CPU the performance scales pretty linear with the number of cores being utilised and also hyper-threading cores help. Using more than sixteen real cores does not improve the situation any further because the overall runtime is already dominated by the longest running test case.
brilliant!
I agree with Peter, that’s brilliant. Any chance that we’ll see a configure switch for this in a pull request? What are the dependencies besides Boost?
Unfortunately the mpi runner comes with a bunch of dependencies, namely libmpi, libmpi_cxx, boost_thread, boost_system, boost_serialization and boost_mpi.
Only a few people have mpi and boost_mpi on their systems. For this reason I’m also working on a “unix” runner based on plain fork and boost_interprocess only. I tend to submit this one together with a configure switch.
Peter has spotted an critical issue on OSX for both runners, which needs to be fixed first. Afterwards we are happy to set-up a pull request.
This looks great. Any update on developing a fork-based runner? I am looking to use Boost.Test for testing SystemC (which really requires separate tests to be run in separate processes).
The fork-based runner has been integrated into QuantLib a while ago (see e.g. https://github.com/lballabio/QuantLib/blob/master/test-suite/paralleltestrunner.hpp). It works with the way QuantLib uses the bost unit test framework but I don’t know if it works with all features of the framework.