#include <ParallelFactory.hpp>
Public Types | |
enum class | TaskMode { Distributed , RootOnly } |
Public Member Functions | |
ParallelFactory () | |
ParallelFactory (SimulationItem *parent) | |
~ParallelFactory () | |
int | maxThreadCount () const |
Parallel * | parallel (TaskMode mode, int maxThreadCount=0) |
Parallel * | parallelDistributed (int maxThreadCount=0) |
Parallel * | parallelRootOnly (int maxThreadCount=0) |
void | setMaxThreadCount (int value) |
![]() | |
template<class T > | |
T * | find (bool setup=true) const |
template<class T > | |
T * | interface (int levels=-999999, bool setup=true) const |
virtual string | itemName () const |
void | setup () |
string | typeAndName () const |
![]() | |
Item (const Item &)=delete | |
virtual | ~Item () |
void | addChild (Item *child) |
const vector< Item * > & | children () const |
virtual void | clearItemListProperty (const PropertyDef *property) |
void | destroyChild (Item *child) |
virtual bool | getBoolProperty (const PropertyDef *property) const |
virtual vector< double > | getDoubleListProperty (const PropertyDef *property) const |
virtual double | getDoubleProperty (const PropertyDef *property) const |
virtual string | getEnumProperty (const PropertyDef *property) const |
virtual int | getIntProperty (const PropertyDef *property) const |
virtual vector< Item * > | getItemListProperty (const PropertyDef *property) const |
virtual Item * | getItemProperty (const PropertyDef *property) const |
virtual string | getStringProperty (const PropertyDef *property) const |
int | getUtilityProperty (string name) const |
virtual void | insertIntoItemListProperty (const PropertyDef *property, int index, Item *item) |
Item & | operator= (const Item &)=delete |
Item * | parent () const |
virtual void | removeFromItemListProperty (const PropertyDef *property, int index) |
virtual void | setBoolProperty (const PropertyDef *property, bool value) |
virtual void | setDoubleListProperty (const PropertyDef *property, vector< double > value) |
virtual void | setDoubleProperty (const PropertyDef *property, double value) |
virtual void | setEnumProperty (const PropertyDef *property, string value) |
virtual void | setIntProperty (const PropertyDef *property, int value) |
virtual void | setItemProperty (const PropertyDef *property, Item *item) |
virtual void | setStringProperty (const PropertyDef *property, string value) |
void | setUtilityProperty (string name, int value) |
virtual string | type () const |
Static Public Member Functions | |
static int | defaultThreadCount () |
Private Types | |
enum class | ParallelType { Null , Serial , MultiThread , MultiHybrid } |
Private Attributes | |
std::map< std::pair< ParallelType, int >, std::unique_ptr< Parallel > > | _children |
int | _maxThreadCount |
std::thread::id | _parentThread |
Additional Inherited Members | |
![]() | |
SimulationItem () | |
virtual bool | offersInterface (const std::type_info &interfaceTypeInfo) const |
virtual void | setupSelfAfter () |
virtual void | setupSelfBefore () |
![]() | |
Item () | |
A ParallelFactory object serves as a factory for instances of Parallel subclasses, called its children. An important property of a factory object is the maximum number of parallel execution threads per process to be handed to its children. During construction of a ParallelFactory instance, the maximum thread count is set to the return value of the defaultThreadCount() function. The value can be changed after construction by calling the setMaxThreadCount() function, but it should not be changed after any children have been requested. When requesting a new child, the client can specify a more stringent limit on the number of threads, but the factory's limit is never exceeded. This allows a client to request a Parallel object with a smaller number of threads, usually for performance reasons.
A factory object assumes ownership for all its children. If a child of the appropriate type (see below) and with the appropriate number of threads already exists, it will be handed out again. As a result, a particular Parallel instance may be reused several times, reducing the overhead of creating and destroying the threads. However, the children of a particular factory should never be used in parallel. Also, recursively invoking the call() function on a Parallel instance is not allowed and results in undefined behavior. The recommended use is to have a single ParallelFactory instance per simulation, and to use yet another ParallelFactory instance to run multiple simulations at the same time.
ParallelFactory clients can request a Parallel instance for one of the two task allocation modes described in the table below.
Task mode | Description |
---|---|
Distributed | All threads in all processes perform the tasks in parallel |
RootOnly | All threads in the root process perform the tasks in parallel; the other processes ignore the tasks |
In support of these task modes, the Parallel class has several subclasses, each implementing a specific parallelization scheme as described in the table below.
Shorthand | Parallel subclass | Description |
---|---|---|
S | SerialParallel | Single thread in the current process; isolated from any other processes |
MT | MultiThreadParallel | Multiple coordinated threads in the current process; isolated from any other processes |
MTP | MultiHybridParallel | One or more threads in each of multiple processes, all coordinated as a group |
0 | NullParallel | No operation; any requests for performing tasks are ignored |
Depending on the requested task mode and the current run-time configuration (number of processes and number of threads in each process), a ParallelFactory object hands out the appropriate Parallel subclass as listed in the table below. (Header: P=process, T=thread, 1=one, M=multiple.)
Mode/Runtime | 1P 1T | 1P MT | MP 1T | MP MT |
---|---|---|---|---|
Distributed | S | MT | MTP | MTP |
RootOnly | S | MT | S/0 | MT/0 |
|
strong |
This enumeration includes a constant for each task allocation mode supported by ParallelFactory and the Parallel subclasses.
ParallelFactory::ParallelFactory | ( | ) |
This constructor creates a standalone parallel factory that is not hooked into a simulation item hierarchy; the caller is responsible for its destruction. Although the setup() function is not called by this constructor, no further setup is required to use the standalone object.
|
explicit |
This constructor creates a parallel factory that is hooked up as a child to the specified parent in the simulation hierarchy, so that it will automatically be deleted. The setup() function is not called by this constructor.
ParallelFactory::~ParallelFactory | ( | ) |
The destructor releases any resources held by the parallel factory.
|
static |
Returns the number of logical cores detected on the computer running the code, with a minimum of one and a maximum of 24 (additional threads in single process do not increase performance).
int ParallelFactory::maxThreadCount | ( | ) | const |
Returns the maximum number of threads to be handed out to Parallel objects manufactured by this factory object.
This function returns a Parallel subclass instance of the appropriate type and with an appropriate number of execution threads, depending on the requested task allocation mode, the specified maximum number of threads, and the current run-time environment (number of threads in the factory maximum and number of processes in the MPI group). The recipe for determining the appropriate paralllization scheme is described in the main documentation for this class.
The first argument specifies the task mode. The second argument, if present, limits the maximum number of threads to the specified number.
|
inline |
This function calls the parallel() function for the Distributed task allocation mode.
|
inline |
This function calls the parallel() function for the RootOnly task allocation mode.
void ParallelFactory::setMaxThreadCount | ( | int | value | ) |
Sets the maximum number of threads to be handed out to Parallel objects manufactured by this factory object. The minimum value is 1 thread.