API Reference
dynampi::mpi_manager_worker_distribution
template <typename ResultT,
template <typename, typename, typename...> typename Distributor =
HierarchicalMPIWorkDistributor>
std::optional<std::vector<ResultT>> mpi_manager_worker_distribution(
size_t n_tasks,
std::function<ResultT(size_t)> worker_function,
MPI_Comm comm = MPI_COMM_WORLD,
int manager_rank = 0);
The primary entry point. Distributes n_tasks tasks (indices 0 .. n_tasks-1)
across the MPI communicator. The default Distributor template argument is
HierarchicalMPIWorkDistributor (same type as MPIDynamicWorkDistributor).
| Parameter | Default | Description |
|---|---|---|
n_tasks |
— | Number of tasks (0, 1, 2, …) |
worker_function |
— | size_t → ResultT |
comm |
MPI_COMM_WORLD |
MPI communicator |
manager_rank |
0 |
Manager rank |
| Returns | vector<ResultT> on manager, nullopt on workers |
dynampi::MPIDynamicWorkDistributor
The default distributor used by mpi_manager_worker_distribution. Hierarchical
tree of coordinators; use this type for incremental task insertion:
template <typename TaskT, typename ResultT, typename... Options>
using MPIDynamicWorkDistributor =
HierarchicalMPIWorkDistributor<TaskT, ResultT, Options...>;
Distributor Classes
Full distributors (NaiveMPIWorkDistributor, MPIDynamicWorkDistributor,
LockFreeMPIWorkDistributor) share a common interface:
MinimalLockFreeMPIWorkDistributor<ResultT> is a separate, smaller API for
index-only parallel-for (run(n_tasks)); see
Implementations.
Common Config Fields
| Field | Type | Default | Description |
|---|---|---|---|
comm |
MPI_Comm |
MPI_COMM_WORLD |
MPI communicator |
manager_rank |
int |
0 |
Rank that manages distribution |
auto_run_workers |
bool |
true |
Start workers automatically in constructor |
Common RunConfig Fields
| Field | Type | Default | Description |
|---|---|---|---|
target_num_tasks |
size_t |
SIZE_MAX |
Stop once this many results are ready |
allow_more_than_target_tasks |
bool |
true |
If false, clip return to target_num_tasks |
max_seconds |
optional<double> |
nullopt |
Time limit for this call |
Common Methods
| Method | Returns | Description |
|---|---|---|
is_root_manager() |
bool |
Whether this rank is the manager |
insert_task(TaskT) |
void |
Add one task (manager only) |
insert_tasks(vector) |
void |
Add multiple tasks (manager only) |
run_tasks(RunConfig) |
vector<ResultT> |
Process tasks, collect results (manager) |
finish_remaining_tasks() |
vector<ResultT> |
Process all remaining tasks (manager) |
run_worker() |
void |
Enter worker loop (non-manager) |
remaining_tasks_count() |
size_t |
Tasks still in the queue (manager) |
finalize() |
void |
Signal shutdown to all workers |
get_statistics() |
Statistics |
Communication statistics |
Distributor-Specific Config
See Implementations for additional configuration fields on each distributor class.
Options
Template options customise distributor behaviour via the Options...
parameter pack:
// Task prioritisation (NaiveMPIWorkDistributor)
using Dist = NaiveMPIWorkDistributor<int, double,
dynampi::enable_prioritization>;
// Tasks inserted with insert_task(task, priority) are processed in
// descending priority order.
// Statistics tracking
using Dist = NaiveMPIWorkDistributor<int, double,
dynampi::track_statistics<dynampi::StatisticsMode::Detailed>>;
// Tracks bytes sent/received, message counts, per-rank task counts.
| Option | Effect |
|---|---|
enable_prioritization |
Enables insert_task(task, priority) where supported (naive) |
track_statistics<None> |
No statistics (default) |
track_statistics<Aggregated> |
Per-rank task counts |
track_statistics<Detailed> |
Full communication statistics |
Version
#include <dynampi/dynampi.hpp>
namespace dv = dynampi::version;
dv::string; // "v0.0.1"
dv::major; dv::minor; dv::patch; // 0, 0, 1
dv::is_at_least(0, 0, 1); // true
dv::compile_date(); // "Jun 6 2026 12:34:56"
dv::commit_hash(); // "abc1234" or "abc1234-dirty"
Statistics
CommStatistics is shared. Each distributor defines its own nested
Statistics type returned by get_statistics():
struct CommStatistics {
int send_count, recv_count, collective_count;
size_t bytes_sent, bytes_received;
double send_time, recv_time;
double average_send_size() const;
double average_receive_size() const;
};
// NaiveMPIWorkDistributor / HierarchicalMPIWorkDistributor
struct Statistics {
const CommStatistics& comm_statistics;
std::vector<size_t> worker_task_counts; // naive
// std::optional<std::vector<size_t>> worker_task_counts; // hierarchical
};
// LockFreeMPIWorkDistributor
struct Statistics {
CommStatistics comm_statistics; // by value
std::vector<size_t> worker_task_counts;
};
Prefer auto& stats = dist.get_statistics(); and read the fields you need
rather than depending on a single shared Statistics layout.
Utilities
Timer
#include <dynampi/utilities/timer.hpp>
dynampi::Timer timer; // starts automatically
timer.elapsed(); // std::chrono::duration<double>
timer.stop(); // pause
timer.reset(); // restart from zero
std::cout << timer; // "12.345 seconds"
Assertions
#include <dynampi/utilities/assert.hpp>
// These are no-ops in release builds (-DNDEBUG):
DYNAMPI_ASSERT(condition); // abort with file:line on failure
DYNAMPI_ASSERT_EQ(a, b); // assert a == b, print both values
DYNAMPI_ASSERT_NE(a, b); // assert a != b
DYNAMPI_ASSERT_GT(a, b); // assert a > b
DYNAMPI_ASSERT_GE(a, b); // assert a >= b
DYNAMPI_ASSERT_LT(a, b); // assert a < b
DYNAMPI_ASSERT_LE(a, b); // assert a <= b
DYNAMPI_UNIMPLEMENTED(); // always fails — marks unimplemented paths
MPI Error Checking
// Wraps MPI calls and throws std::runtime_error with file:line on failure:
DYNAMPI_MPI_CHECK(MPI_Send, (buf, count, type, dest, tag, comm));