Bertini 2 d882924 (2026-10-06 19:56 UTC)
Numerical algebraic geometry library (C++ core)
Loading...
Searching...
No Matches
worker.hpp
Go to the documentation of this file.
1//This file is part of Bertini 2.
2//
3//bertini2/parallel/worker.hpp is free software: you can redistribute it and/or modify
4//it under the terms of the GNU General Public License as published by
5//the Free Software Foundation, either version 3 of the License, or
6//(at your option) any later version.
7//
8//bertini2/parallel/worker.hpp is distributed in the hope that it will be useful,
9//but WITHOUT ANY WARRANTY; without even the implied warranty of
10//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11//GNU General Public License for more details.
12//
13//You should have received a copy of the GNU General Public License
14//along with bertini2/parallel/worker.hpp. If not, see <http://www.gnu.org/licenses/>.
15//
16// Copyright(C) Bertini2 Development Team
17
34
35#pragma once
36
37#ifdef BERTINI2_HAVE_MPI
38
42
44
45#include <chrono>
46#include <functional>
47#include <limits>
48#include <string>
49#include <thread>
50
51namespace bertini {
52namespace parallel {
53
54
62template<typename TaskT, typename ResultT>
63void RunWorkerLoop(
64 MPI_Comm comm,
65 std::function<void(TaskT const&)> track_fn,
66 std::function<ResultT(TaskT const&)> pack_fn)
67{
68 // Announce capacity: a serial worker can have exactly one task in flight.
69 int capacity = 1;
70 MPI_Send(&capacity, 1, MPI_INT, 0, TAG_CAPACITY, comm);
71
72 while (true)
73 {
74 TaskT task;
75 mpi_recv_serialized(comm, 0, TAG_WORK_ITEM, task);
76
77 if (detail::is_sentinel(task))
78 break;
79
80 track_fn(task);
81
82 ResultT result = pack_fn(task);
83 mpi_send_serialized(comm, 0, TAG_RESULT, result);
84 }
85}
86
87
115template<typename TaskT, typename ResultT, typename StateFactory, typename TrackFn>
116void RunWorkerLoopThreaded(
117 MPI_Comm comm,
118 StateFactory state_factory,
119 TrackFn track_fn,
120 int n_threads)
121{
122 int capacity = n_threads;
123 MPI_Send(&capacity, 1, MPI_INT, 0, TAG_CAPACITY, comm);
124
125 WorkerThreadPool<TaskT, ResultT, StateFactory, TrackFn> pool(n_threads, state_factory, track_fn);
126
127 int in_flight = 0; // tasks submitted to the pool but not yet collected
128 bool got_sentinel = false;
129
130 while (!got_sentinel || in_flight > 0)
131 {
132 bool did_work = false;
133
134 // Forward all completed results to the manager.
135 while (auto opt = pool.try_collect())
136 {
137 mpi_send_serialized(comm, 0, TAG_RESULT, *opt);
138 --in_flight;
139 did_work = true;
140 }
141
142 // Non-blocking check for an incoming task (or the sentinel).
143 if (!got_sentinel)
144 {
145 int flag = 0;
146 MPI_Status status;
147 MPI_Iprobe(0, TAG_WORK_ITEM, comm, &flag, &status);
148 if (flag)
149 {
150 TaskT task;
151 mpi_recv_serialized(comm, 0, TAG_WORK_ITEM, task);
152
153 if (detail::is_sentinel(task))
154 got_sentinel = true;
155 else
156 {
157 pool.submit(std::move(task));
158 ++in_flight;
159 }
160 did_work = true;
161 }
162 }
163
164 // Idle: nothing arrived and nothing finished. Tracking a path takes
165 // milliseconds to seconds, so a short sleep costs nothing measurable.
166 if (!did_work)
167 std::this_thread::sleep_for(std::chrono::microseconds(200));
168 }
169
170 pool.shutdown();
171}
172
173
174} // namespace parallel
175} // namespace bertini
176
177#endif // BERTINI2_HAVE_MPI
Thread pool for parallel path tracking within a single MPI worker rank.
Definition thread_pool.hpp:198
Single include point for the MPI C API.
Serialization-aware MPI send/recv helpers using plain C MPI + Boost.Serialization.
bool is_sentinel(std::size_t v)
Query whether a plain index value is the sentinel.
Definition path_result.hpp:186
Definition initialize_finalize.hpp:43
constexpr int TAG_CAPACITY
MPI message tag: worker -> manager, max tasks in flight on that rank.
Definition path_result.hpp:49
constexpr int TAG_RESULT
MPI message tag: worker -> manager result.
Definition path_result.hpp:48
constexpr int TAG_WORK_ITEM
MPI message tag: manager -> worker work item.
Definition path_result.hpp:47
Definition algorithm_builder.hpp:36
Result struct used in the manager-worker MPI protocol for ZeroDim.
Thread-safe queue and worker thread pool for MPI+thread hybrid parallelism.