Go to the documentation of this file.
14 #include <boost/date_time.hpp>
25 #define HMP_CHUNK_PROPERTY_STACK 0
26 #define HMP_CHUNK_PROPERTY_BEGIN 1
27 #define HMP_CHUNK_PROPERTY_END 2
30 #define HMP_MPI_ENABLED
31 #define HMP_ENABLE_IF_MPI(X) X
32 #define HMP_DISABLE_IF_MPI(X)
33 #define HMP_APPEND_IF_MPI(X) ,X
35 #define HMP_ENABLE_IF_MPI(X)
36 #define HMP_DISABLE_IF_MPI(X) X
37 #define HMP_APPEND_IF_MPI(X)
134 #ifdef HMP_MPI_ENABLED
143 virtual void send(
const int offset,
const int count,
const int serverRank,
const MPI_Comm communicator)
const {};
154 virtual void receive(
const int offset,
const int count,
const int rank,
const MPI_Comm communicator, MPI_Request &request) {};
162 virtual void broadcast(
const int serverRank,
const MPI_Comm communicator) {};
204 #ifdef HMP_MPI_ENABLED
213 void send(
const int offset,
const int count,
const int serverRank,
const MPI_Comm communicator)
const override
227 void receive(
const int offset,
const int count,
const int rank,
const MPI_Comm communicator, MPI_Request &request)
override
238 void broadcast(
const int serverRank,
const MPI_Comm communicator)
override
270 Chunk(
const int stackId,
const int begin,
const int end)
326 template <
class StackT>
StackIdentifier addMasterStackExplicit(StackT *
const data,
const int size,
const std::function<StackT(
int)> &calculator,
const int recommendedChunkSizeMultiple = 1,
const int recommendedChunksPerRank = 10,
const bool autoBroadcast =
false)
357 template <
class StackT>
StackIdentifier addMasterStackImplicit(StackT *
const data,
const int size,
const std::function<
void(
int)> &calculator,
const int typeMultiplicity = 1,
const int recommendedChunkSizeMultiple = 1,
const int recommendedChunksPerRank = 10,
const bool autoBroadcast =
false)
433 void calculate(
const std::initializer_list<StackIdentifier> &stackIds)
435 calculate(stackIds.begin(),
int(stackIds.size()));
453 std::vector<StackIdentifier> all(
_stacks.size());
466 #ifdef HMP_MPI_ENABLED
467 for (
int i = 0; i < size; ++i)
482 void broadcast(
const std::initializer_list<StackIdentifier> &stackIds)
484 broadcast(stackIds.begin(),
int(stackIds.size()));
502 std::vector<StackIdentifier> all(
_stacks.size());
554 #pragma omp parallel for schedule(guided)
594 boost::posix_time::ptime tic = boost::posix_time::microsec_clock::local_time();
602 #ifdef HMP_MPI_ENABLED
608 MPI_Status receiveStatus;
612 for (
int rank = 0; rank <
_commSize; ++rank)
616 if (receiveFlag == 1)
631 for (
int s = 0; s < size; ++s)
647 boost::posix_time::ptime toc = boost::posix_time::microsec_clock::local_time();
656 Log::log << Log::LogLevel::Debug <<
"LoadManager total time spent in calculate() calls is " <<
_totalCalculationTime <<
"ms" << Log::endl;
659 float timePerRank = 0.0;
661 Log::log << Log::LogLevel::Debug <<
"LoadManager (rank " << i <<
") active computing time was " << std::setiosflags(std::ios::fixed) << std::setprecision(0) << timePerRank <<
"ms (Efficiency: " << std::setprecision(1) << 100.0f * timePerRank /
_totalCalculationTime <<
"%)" << Log::endl;
683 #ifdef HMP_MPI_ENABLED
738 boost::posix_time::ptime tic = boost::posix_time::microsec_clock::local_time();
740 boost::posix_time::ptime toc = boost::posix_time::microsec_clock::local_time();
808 maximumWorkShare = (int(maximumWorkShare /
_stacks[s]->recommendedChunkSizeMultiple) + 1) *
_stacks[s]->recommendedChunkSizeMultiple;
809 if (maximumWorkShare < 1) maximumWorkShare = 1;
813 float totalComputePower = 0;
817 int newCurrentCalculationProgress;
818 if (std::isfinite(myComputePower) && std::isfinite(totalComputePower))
822 int myWorkShare = int((myComputePower / totalComputePower) * remainingWork);
823 myWorkShare = (int(myWorkShare /
_stacks[s]->recommendedChunkSizeMultiple) + 1) *
_stacks[s]->recommendedChunkSizeMultiple;
826 int minumumWorkTime = 100;
827 int minimumWorkShare = int(myComputePower * minumumWorkTime);
828 if (minimumWorkShare < 1) minimumWorkShare = 1;
829 if (myWorkShare < minimumWorkShare) myWorkShare = minimumWorkShare;
830 if (myWorkShare > maximumWorkShare) myWorkShare = maximumWorkShare;
836 if (newCurrentCalculationProgress >=
_stacks[s]->size) newCurrentCalculationProgress =
_stacks[s]->size;
843 Log::log << Log::LogLevel::Debug <<
"LoadManager spawned chunk (stack " << s <<
", from " <<
_currentCalculationStackProgress[s] <<
", to " << newCurrentCalculationProgress <<
", rank " << rank <<
")" << Log::endl;
861 #ifdef HMP_MPI_ENABLED
920 #ifdef HMP_MPI_ENABLED
931 boost::posix_time::ptime tic = boost::posix_time::microsec_clock::local_time();
933 boost::posix_time::ptime toc = boost::posix_time::microsec_clock::local_time();
941 for (
int s = 0; s < size; ++s)
982 #ifdef HMP_MPI_ENABLED
995 #ifdef HMP_MPI_ENABLED
996 for (
int i = 0; i < int(
_stacks.size()); ++i)
1026 #undef HMP_CHUNK_PROPERTY_STACK
1027 #undef HMP_CHUNK_PROPERTY_BEGIN
1028 #undef HMP_CHUNK_PROPERTY_END
1030 #undef HMP_MPI_ENABLED
1031 #undef HMP_ENABLE_IF_MPI
1032 #undef HMP_DISABLE_IF_MPI
1033 #undef HMP_APPEND_IF_MPI
@ Passive
Passive DataStack.
int recommendedChunkSizeMultiple
When breaking the data stack down into smaller work chunks, attempt to form chunks whose size is a mu...
Definition: LoadManager.hpp:169
Definition of a small chunk of work. Used to communicate workload between different LoadManager insta...
Definition: LoadManager.hpp:252
LoadManager master implementation, which is responsible for distributing work and synchronizing data.
Definition: LoadManager.hpp:571
void calculateAll()
Calculate all stacks.
Definition: LoadManager.hpp:451
std::vector< float > * _totalComputeTime
_totalComputeTime[rank][stack] is the accumulated time in milliseconds which MPI rank rank spent comp...
Definition: LoadManager.hpp:890
virtual void printRuntimeStatistics() const
Virtual implementation to print runtime statistics, including information on the efficiency of LoadMa...
Definition: LoadManager.hpp:510
MPI_Comm _communicator
MPI communicator to operate on.
Definition: LoadManager.hpp:563
StackT * data
Internal data array.
Definition: LoadManager.hpp:246
virtual ~DataStackBase()
Virtual destructor.
Definition: LoadManager.hpp:125
StackIdentifier addSlaveStack(StackT *const data, const int size, const StackIdentifier master, const int typeMultiplicity=1)
Create a slave data stack and attach it to the LoadManager.
Definition: LoadManager.hpp:385
void receive(const int offset, const int count, const int rank, const MPI_Comm communicator, MPI_Request &request) override
Asynchronously receive a data block from a different MPI rank.
Definition: LoadManager.hpp:227
int recommendedChunksPerRank
When breaking the data stack down into smaller work chunks, attempt to form approximately the specifi...
Definition: LoadManager.hpp:170
std::function< StackT(int)> explicitCalculator
Explicit calculator. Only relevant if DataStackBase::type is set to StackType::Explicit.
Definition: LoadManager.hpp:244
#define HMP_ENABLE_IF_MPI(X)
Print argument if MPI parallelization is enabled.
Definition: LoadManager.hpp:31
virtual StackIdentifier _registerStack(DataStackBase *stack)
Register a DataStackBase with the LoadManager. By registering the stack, the LoadManager assumes resp...
Definition: LoadManager.hpp:537
#define HMP_CHUNK_PROPERTY_STACK
Memory offset of the stack id in the chunk properties.
Definition: LoadManager.hpp:25
int StackIdentifier
DataStack identifier.
Definition: LoadManager.hpp:42
LoadManagerMaster(const int serverRank, const MPI_Comm communicator)
Construct a new LoadManagerMaster object.
Definition: LoadManager.hpp:674
Chunk _spawnChunk(const int rank)
The chunk spawner routine, which is responsible for breaking down the overall workload of calculator ...
Definition: LoadManager.hpp:796
DataStack()
Construct a new Data Stack object.
Definition: LoadManager.hpp:191
int size
Number of elements (or tuples of elements if DataStackBase::typeMultiplicity is greater than one) sto...
Definition: LoadManager.hpp:167
void printRuntimeStatistics() const override
Print runtime statistics, including information on the efficiency of LoadManager instances running on...
Definition: LoadManager.hpp:654
StackType
List to identify the different traits of DataStack.
Definition: LoadManager.hpp:81
void broadcast(const StackIdentifier stackId)
Broadcast a single stack.
Definition: LoadManager.hpp:492
std::vector< DataStackBase * > _stacks
List of all registered stacks.
Definition: LoadManager.hpp:559
~LoadManagerMaster()
Destroy the LoadManagerMaster object.
Definition: LoadManager.hpp:692
LoadManager * newLoadManager(const int serverRank=0, const MPI_Comm communicator=MPI_COMM_WORLD)
Create a new LoadManager instance. If the current MPI rank is the designated master rank,...
Definition: LoadManager.hpp:1014
boost::posix_time::ptime * _currentCalculationChunkSpawntime
_currentCalculationChunkSpawntime[rank] specifies time at which the most recent chunk has been issued...
Definition: LoadManager.hpp:893
@ ChunkReturn
MPI message contains the result of a chunk computation.
int _rank
MPI rank of the current LoadManager instance.
Definition: LoadManager.hpp:561
void broadcast(const int serverRank, const MPI_Comm communicator) override
Broadcast a data block from the server rank to all other MPI ranks.
Definition: LoadManager.hpp:238
void _returnChunk(const Chunk &chunk) const
Return the result of the workload defined by a specific chunk.
Definition: LoadManager.hpp:993
MPI_Request * _pendingRequests
MPI request objects associated with the return values for workload chunks that have been issued.
Definition: LoadManager.hpp:900
virtual void calculate(const StackIdentifier *stackIds, const int size)=0
Calculate a list of stacks, where the stack identifiers are provided in list form.
void calculate(const std::initializer_list< StackIdentifier > &stackIds)
Calculate a list of stacks, where the stack identifiers are provided in initializer list form.
Definition: LoadManager.hpp:433
std::vector< int > _currentCalculationStackProgress
_currentCalculationStackProgress[stack] specifies the current progress (pointer to the next unissued ...
Definition: LoadManager.hpp:897
bool autoBroadcast
If set to true, modifications to the stack's data that are a consequence of the onvication of calcula...
Definition: LoadManager.hpp:171
@ MpiError
MPI error, raised when MPI communication fails.
std::vector< int > * _currentCalculationWorkDone
_currentCalculationWorkDone[rank][stack] is the number of calculations which have been performed by M...
Definition: LoadManager.hpp:891
virtual void calculate(const StackIdentifier *stackIds, const int size) override
Calculate a list of stacks, where the stack identifiers are provided in list form.
Definition: LoadManager.hpp:918
std::vector< bool > _currentCalculationStackMask
_currentCalculationStackMask[stack] specifies whether stack should be computed in the current calcula...
Definition: LoadManager.hpp:896
void calculate(const StackIdentifier stackId)
Calculate a single stack.
Definition: LoadManager.hpp:443
void _calculateChunk(const Chunk &chunk)
Calculate the workload defined by a specific chunk.
Definition: LoadManager.hpp:551
Descriptor object for exceptions.
Definition: Exception.hpp:17
int properties[3]
Workload specification. First value describes the stack id, second value describes the first element ...
Definition: LoadManager.hpp:295
#define HMP_CHUNK_PROPERTY_BEGIN
Memory offset of the workload begin in the chunk properties.
Definition: LoadManager.hpp:26
Chunk * _currentCalculationChunkSpawned
_currentCalculationChunkSpawned[rank] stores the most recent chunk generated for MPI rank rank in the...
Definition: LoadManager.hpp:894
bool operator!=(const Chunk &rhs) const
Negative comparison operator.
Definition: LoadManager.hpp:290
StackIdentifier addMasterStackExplicit(StackT *const data, const int size, const std::function< StackT(int)> &calculator, const int recommendedChunkSizeMultiple=1, const int recommendedChunksPerRank=10, const bool autoBroadcast=false)
Create an explicit data stack and attach it to the LoadManager.
Definition: LoadManager.hpp:326
void _issueChunk(const int rank)
Send a workload chunk to a specified MPI rank.
Definition: LoadManager.hpp:859
@ Implicit
Implicit DataStack.
virtual void calculate(const StackIdentifier *stackIds, const int size) override
Calculate a list of stacks, where the stack identifiers are provided in list form.
Definition: LoadManager.hpp:581
virtual void broadcast(const int serverRank, const MPI_Comm communicator)
Virtual function to broadcast a data block from the server rank to all other MPI ranks.
Definition: LoadManager.hpp:162
void broadcast(const StackIdentifier *stackIds, const int size)
Broadcast a list of stacks, where the stack identifiers are provided in list form.
Definition: LoadManager.hpp:464
int _commSize
MPI communicator size.
Definition: LoadManager.hpp:562
LoadManagerSlave(const int serverRank, const MPI_Comm communicator)
Construct a new LoadManagerSlave object.
Definition: LoadManager.hpp:958
LoadManager(const int serverRank, const MPI_Comm communicator)
Construct a new Load Manager object.
Definition: LoadManager.hpp:519
LoadManager slave implementation, responsible for receiving and executing workload chunks form a Load...
Definition: LoadManager.hpp:908
friend LoadManager * newLoadManager(const int serverRank, const MPI_Comm communicator)
Create a new LoadManager instance. If the current MPI rank is the designated master rank,...
Definition: LoadManager.hpp:1014
void _initChunkSpawner(const StackIdentifier *stackIds, const int size)
Prepare the chunk spawner, i.e. the routine responsible for breaking down workload into smaller chuns...
Definition: LoadManager.hpp:753
virtual ~LoadManager()
Destroy the LoadManager object.
Definition: LoadManager.hpp:300
std::vector< float > _currentCalculationComputeTimeBuffer
_currentCalculationComputeTimeBuffer[stack] is a buffer for the time in milliseconds spent on computi...
Definition: LoadManager.hpp:1003
bool isVoid() const
Check of the workload is empty.
Definition: LoadManager.hpp:278
bool operator==(const Chunk &rhs) const
Comparison operator.
Definition: LoadManager.hpp:284
virtual void receive(const int offset, const int count, const int rank, const MPI_Comm communicator, MPI_Request &request)
Virtual function to asynchronously receive a data block from a different MPI rank.
Definition: LoadManager.hpp:154
Abstract base class for DataStack types.
Definition: LoadManager.hpp:76
#define HMP_CHUNK_PROPERTY_END
Memory offset of the workload end in the chunk properties.
Definition: LoadManager.hpp:27
virtual StackIdentifier _registerStack(DataStackBase *stack) override
Register a DataStackBase with the LoadManager. By registering the stack, the LoadManager assumes resp...
Definition: LoadManager.hpp:709
StackType type
Specifies the trait of the stack.
Definition: LoadManager.hpp:162
@ ArgumentError
Argument error, raised when a function is invoked with an invalid argument.
float _totalCalculationTime
Accumulated time in milliseconds which has been spent on calculate() calls over the lifetime of the L...
Definition: LoadManager.hpp:889
void _initChunkSpawner(const std::initializer_list< StackIdentifier > &stackIds)
Prepare the chunk spawner, i.e. the routine responsible for breaking down workload into smaller chuns...
Definition: LoadManager.hpp:779
virtual StackIdentifier _registerStack(DataStackBase *stack) override
Register a DataStackBase with the LoadManager. By registering the stack, the LoadManager assumes resp...
Definition: LoadManager.hpp:966
void _runLocalClient()
Worker loop to run calculators locally.
Definition: LoadManager.hpp:730
StackIdentifier addMasterStackImplicit(StackT *const data, const int size, const std::function< void(int)> &calculator, const int typeMultiplicity=1, const int recommendedChunkSizeMultiple=1, const int recommendedChunksPerRank=10, const bool autoBroadcast=false)
Create an implicit data stack and attach it to the LoadManager.
Definition: LoadManager.hpp:357
virtual void applyCalculator(const int n)
Virtual function to apply an internal calculator to the n-th value stored in the stack.
Definition: LoadManager.hpp:132
@ Chunk
MPI message contains Chunk information.
Descriptor object for exceptions.
std::mutex _currentCalculationChunkSpawnerLock
Lock to synchronize chunk spawning for remote calculations and for local worker threads.
Definition: LoadManager.hpp:898
#define HMP_DISABLE_IF_MPI(X)
Do not print argument if MPI parallelization is enabled.
Definition: LoadManager.hpp:32
void send(const int offset, const int count, const int serverRank, const MPI_Comm communicator) const override
Send a data block to a different MPI rank, typically the server rank.
Definition: LoadManager.hpp:213
std::vector< float > _currentCalculationComputeTimeBuffer
_currentCalculationComputeTimeBuffer[rank*_stacks.size()+stack] is a buffer for the time in milliseco...
Definition: LoadManager.hpp:895
void applyCalculator(const int i) override
Invoke internal calculator and write result to the data array at the specified index.
Definition: LoadManager.hpp:198
Lightweight logging interface with output filtering.
MessageTag
Internal message tags for MPI communication.
Definition: LoadManager.hpp:116
std::function< void(int)> implicitCalculator
Implicit calculator. Only relevant if DataStackBase::type is set to StackType::Implicit.
Definition: LoadManager.hpp:245
@ Explicit
Explicit DataStack.
Common load manager interface for both, the MPI server rank and slave ranks.
Definition: LoadManager.hpp:66
void _despawnChunk(const int rank)
Mark a workload chunk as completed. Relevant only for runtime statistics information.
Definition: LoadManager.hpp:882
friend LoadManager * newLoadManager(const int serverRank, const MPI_Comm communicator)
Create a new LoadManager instance. If the current MPI rank is the designated master rank,...
Definition: LoadManager.hpp:1014
virtual void send(const int offset, const int count, const int serverRank, const MPI_Comm communicator) const
Virtual function to send a data block to a DataStack on a different MPI rank, typically the server ra...
Definition: LoadManager.hpp:143
Concrete derivation of DataStackBase, managing an array of fundamental data types (or tuples thereof,...
Definition: LoadManager.hpp:179
void broadcastAll()
Broadcast all stacks.
Definition: LoadManager.hpp:500
std::vector< float > * _currentCalculationTime
_currentCalculationTime[rank][stack] is the time in milliseconds spent by MPI rank rank until returni...
Definition: LoadManager.hpp:892
void broadcast(const std::initializer_list< StackIdentifier > &stackIds)
Broadcast a list of stacks, where the stack identifiers are provided in initializer list form.
Definition: LoadManager.hpp:482
void _waitChunk(Chunk &chunk) const
Wait until a workload chunk has been received from a LoadManagerMaster instance.
Definition: LoadManager.hpp:980
Chunk()
Construct an empty work chunk.
Definition: LoadManager.hpp:256
Chunk(const int stackId, const int begin, const int end)
Construct a work chunk for a specific workload.
Definition: LoadManager.hpp:270
int _serverRank
Designated MPI master rank.
Definition: LoadManager.hpp:560
#define HMP_APPEND_IF_MPI(X)
Append argument if MPI parallelizatino is enabled.
Definition: LoadManager.hpp:33
StackIdentifier addPassiveStack(StackT *const data, const int size)
Create a passive data stack and attach it to the LoadManager.
Definition: LoadManager.hpp:408
int typeMultiplicity
Multiplicity of each element. Cannot be greater than one for explicit stacks. If greater than one,...
Definition: LoadManager.hpp:168
StackIdentifier master
Specifies the id of an associated stack. Only relevant for slave stacks, otherwise set to -1.
Definition: LoadManager.hpp:166