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