/** \page openmp Multithreaded evaluation using OpenMP \tableofcontents \imp support multithreaded evaluation using \external{http://openmp.org/wp/, OpenMP} (version 3.0 or later). OpenMP 3.0 is supported by recent versions of `gcc`, but not `clang++`. Multithreaded evaluation uses OpenMP tasks, with each IMP::Restraint or IMP::ScoreState being made into one or more tasks that are executed independently. \imp uses the information in the IMP::DepdendencyGraph to automatically determine which IMP::ScoreState objects can be used in parallel. That is, two score states are independent if neither depend on data written by the other. \section activating Activating OpenMP To use OpenMP with \imp, turn it on during compilation by adding the following scons flags to `config.py` or through the command line: ``` cxxflags="-fopenmp" linkflags="-fopenmp" ``` \section controlling Controlling OpenMP The functions IMP::base::get_number_of_threads(), IMP::base::set_number_of_threads(), and the RAII class IMP::base::SetNumberOfThreads can be used to control OpenMP evaluation, as can the command line flag "number_of_threads" in executables that use \imp's flags suport (see base/flags.h). \section Writing code with OpenMP If you want to parallelize code, see the helper macros in base/thread_macros.h. In particular, you can define a new task with IMP_TASK() and make your executable multithreaded with IMP_THREADS(). If you define tasks yourself, be sure to add `\#pragma omp taskwait` to make sure all the tasks are finished before returning. In general, you probably need to read various OpenMP documentation to get things to work right. IMP::Restraints that want to create tasks should implement IMP::Restraint::do_add_score_and_derivatives() rather than IMP::Restraint::unprotected_evaluate() as it is hard to properly get the return value back otherwise. Examples will come. */