Skip to content

Commit d9e51ae

Browse files
author
Christos Konstantinos Matzoros
committed
Fixing bugs
1 parent 41b299f commit d9e51ae

File tree

3 files changed

+100
-46
lines changed

3 files changed

+100
-46
lines changed

include/osp/bsp/scheduler/GreedySchedulers/GreedyVarianceSspScheduler.hpp

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,6 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
166166
p = i;
167167
found_allocation = true;
168168

169-
procReady[i].erase(it);
170-
171169
if (procType < procTypesCompatibleWithNodeType_skip_proctype.size()) {
172170
const auto &compatibleTypes =
173171
procTypesCompatibleWithNodeType_skip_proctype[procType]
@@ -191,8 +189,6 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
191189
p = i;
192190
found_allocation = true;
193191

194-
procReady[i].erase(it);
195-
196192
if (procType < procTypesCompatibleWithNodeType_skip_proctype.size()) {
197193
const auto &compatibleTypes =
198194
procTypesCompatibleWithNodeType_skip_proctype[procType]
@@ -243,8 +239,6 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
243239
node = it->first;
244240
p = i;
245241

246-
readyList.erase(it);
247-
248242
const auto &compatibleTypes =
249243
procTypesCompatibleWithNodeType_skip_proctype[procType]
250244
[instance.getComputationalDag().vertex_type(node)];
@@ -260,8 +254,6 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
260254
node = it->first;
261255
p = i;
262256

263-
readyList.erase(it);
264-
265257
const auto &compatibleTypes =
266258
procTypesCompatibleWithNodeType_skip_proctype[procType]
267259
[instance.getComputationalDag().vertex_type(node)];
@@ -270,11 +262,10 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
270262
if (otherType < allReady.size())
271263
allReady[otherType].erase(std::make_pair(node, work_variance[node]));
272264
}
273-
265+
274266
return;
275267
}
276268
}
277-
278269
++it;
279270
}
280271
}
@@ -364,20 +355,26 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
364355
return nr_nodes;
365356
}
366357

367-
368358
public:
369359

370-
RETURN_STATUS computeSspSchedule(BspSchedule<Graph_t> &schedule, unsigned stale) {
360+
/**
361+
* @brief Default constructor for GreedyVarianceSspScheduler.
362+
*/
363+
GreedyVarianceSspScheduler(float max_percent_idle_processors_ = 0.2f, bool increase_parallelism_in_new_superstep_ = true)
364+
: max_percent_idle_processors(max_percent_idle_processors_),
365+
increase_parallelism_in_new_superstep(increase_parallelism_in_new_superstep_) {}
371366

367+
/**
368+
* @brief Default destructor for GreedyVarianceSspScheduler.
369+
*/
370+
virtual ~GreedyVarianceSspScheduler() = default;
371+
372+
RETURN_STATUS computeSspSchedule(BspSchedule<Graph_t> &schedule, unsigned stale) {
372373
const auto &instance = schedule.getInstance();
373374
const auto &G = instance.getComputationalDag();
374-
const auto &N = instance.numberOfVertices();
375+
const VertexType &N = instance.numberOfVertices();
375376
const unsigned &P = instance.numberOfProcessors();
376377

377-
for (auto v : G.vertices()) {
378-
schedule.setAssignedProcessor(v, std::numeric_limits<unsigned>::max());
379-
}
380-
381378
unsigned supstepIdx = 0;
382379

383380
if constexpr (is_memory_constraint_v<MemoryConstraint_t>) {
@@ -407,10 +404,13 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
407404
++nr_procs_per_type[instance.getArchitecture().processorType(proc)];
408405
}
409406

410-
std::vector<unsigned> nrPredecRemain(N);
411-
for (VertexType node = 0; node < static_cast<VertexType>(N); ++node) {
407+
std::vector<VertexType> nrPredecRemain(N);
408+
409+
for (VertexType node = 0; node < N; ++node) {
412410
const auto num_parents = G.in_degree(node);
413-
nrPredecRemain[node] = static_cast<unsigned>(num_parents);
411+
412+
nrPredecRemain[node] = num_parents;
413+
414414
if (num_parents == 0) {
415415
ready[0].insert(std::make_pair(node, work_variances[node]));
416416
nr_ready_stale_nodes_per_type[0][G.vertex_type(node)]++;
@@ -426,9 +426,6 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
426426
std::vector<unsigned> number_of_allocated_allReady_tasks_in_superstep(instance.getArchitecture().getNumberOfProcessorTypes(), 0);
427427
std::vector<unsigned> limit_of_number_of_allocated_allReady_tasks_in_superstep(instance.getArchitecture().getNumberOfProcessorTypes(), 0);
428428

429-
430-
431-
432429
bool endSupStep = true;
433430
bool begin_outer_while = true;
434431
bool able_to_schedule_in_step = false;
@@ -478,12 +475,11 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
478475
}
479476

480477
for (unsigned procType = 0; procType < instance.getArchitecture().getNumberOfProcessorTypes(); procType++) {
481-
unsigned equal_split = (static_cast<unsigned int>(allReady[procType].size()) + stale - 1) / stale;
478+
unsigned equal_split = (static_cast<unsigned>(allReady[procType].size()) + stale - 1) / stale;
482479
unsigned at_least_for_long_step = 3 * nr_procs_per_type[procType];
483-
484480
limit_of_number_of_allocated_allReady_tasks_in_superstep[procType] = std::max(at_least_for_long_step, equal_split);
485481
}
486-
482+
487483
endSupStep = false;
488484
finishTimes.emplace(0, std::numeric_limits<VertexType>::max());
489485
}
@@ -508,8 +504,7 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
508504
unsigned earliest_add = supstepIdx;
509505
for (const auto& pred : G.parents(succ)) {
510506
if (schedule.assignedProcessor(pred) != proc_of_node) {
511-
earliest_add = std::max(earliest_add,
512-
stale + schedule.assignedSuperstep(pred));
507+
earliest_add = std::max(earliest_add, stale + schedule.assignedSuperstep(pred));
513508
}
514509
}
515510

@@ -542,6 +537,7 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
542537
if (!CanChooseNode(instance, allReady, procReady[supstepIdx % stale], procFree)) {
543538
endSupStep = true;
544539
}
540+
545541
while (CanChooseNode(instance, allReady, procReady[supstepIdx % stale], procFree)) {
546542
VertexType nextNode = std::numeric_limits<VertexType>::max();
547543
unsigned nextProc = P;
@@ -567,6 +563,7 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
567563
nr_old_ready_nodes_per_type[G.vertex_type(nextNode)]--;
568564
const unsigned nextProcType = instance.getArchitecture().processorType(nextProc);
569565
number_of_allocated_allReady_tasks_in_superstep[nextProcType]++;
566+
570567
if (number_of_allocated_allReady_tasks_in_superstep[nextProcType] >= limit_of_number_of_allocated_allReady_tasks_in_superstep[nextProcType]) {
571568
allReady[nextProcType].clear();
572569
}
@@ -575,6 +572,7 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
575572
for (size_t i = 0; i < stale; i++) {
576573
ready[i].erase(std::make_pair(nextNode, work_variances[nextNode]));
577574
}
575+
578576
old_ready.erase(std::make_pair(nextNode, work_variances[nextNode]));
579577

580578
schedule.setAssignedProcessor(nextNode, nextProc);
@@ -605,7 +603,7 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
605603
else if (++successive_empty_supersteps > 100 + stale)
606604
return RETURN_STATUS::ERROR;
607605

608-
if (free > static_cast<decltype(free)>(P * max_percent_idle_processors) &&
606+
if (free > (P * max_percent_idle_processors) &&
609607
((!increase_parallelism_in_new_superstep) ||
610608
get_nr_parallelizable_nodes(
611609
instance, stale, nr_old_ready_nodes_per_type,
@@ -626,10 +624,12 @@ class GreedyVarianceSspScheduler : public Scheduler<Graph_t> {
626624
}
627625

628626
RETURN_STATUS computeSchedule(BspSchedule<Graph_t> &schedule) override {
627+
std::cout<< "BspSchedule"<< std::endl;
629628
return computeSspSchedule(schedule, 1U);
630629
}
631630

632-
RETURN_STATUS computeSchedule(MaxBspSchedule<Graph_t> &schedule) {
631+
RETURN_STATUS computeSchedule(MaxBspSchedule<Graph_t> &schedule) override {
632+
std::cout<< "MaxBspSchedule"<< std::endl;
633633
return computeSspSchedule(schedule, 2U);
634634
}
635635

include/osp/bsp/scheduler/Scheduler.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ limitations under the License.
2222
#include <iostream>
2323
#include "osp/bsp/model/BspInstance.hpp"
2424
#include "osp/bsp/model/BspSchedule.hpp"
25+
#include "osp/bsp/model/MaxBspSchedule.hpp"
2526
#include "osp/bsp/model/BspScheduleCS.hpp"
2627
#include "osp/concepts/computational_dag_concept.hpp"
2728

@@ -93,6 +94,26 @@ class Scheduler {
9394
*/
9495
virtual RETURN_STATUS computeSchedule(BspSchedule<Graph_t> &schedule) = 0;
9596

97+
/**
98+
* @brief Compute a Max-BSP (Stale Synchronous Parallel) schedule for the given instance.
99+
*
100+
* This overload allows schedulers that support the Max-BSP or SSP model
101+
* to implement asynchronous-like scheduling with configurable staleness.
102+
* By default, this base implementation throws an exception, since not all
103+
* schedulers provide Max-BSP support. Derived schedulers such as
104+
* GreedyVarianceSspScheduler should override this function to perform
105+
* their custom SSP scheduling logic.
106+
*
107+
* @param schedule Reference to a MaxBspSchedule object representing
108+
* the schedule to be computed and populated.
109+
* @return A RETURN_STATUS code indicating the success or failure of the computation.
110+
* @throws std::runtime_error If the scheduler does not implement Max-BSP scheduling.
111+
*/
112+
virtual RETURN_STATUS computeSchedule(MaxBspSchedule<Graph_t> &schedule) {
113+
(void)schedule;
114+
throw std::runtime_error("Not implemented for this scheduler");
115+
}
116+
96117
virtual RETURN_STATUS computeScheduleCS(BspScheduleCS<Graph_t> &schedule) {
97118

98119
auto result = computeSchedule(schedule);

tests/bsp_schedulers.cpp

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,51 @@ void run_test_2(Scheduler<Graph_t> *test_scheduler) {
149149
}
150150
};
151151

152+
template<typename Graph_t>
153+
void run_test_max_bsp(Scheduler<Graph_t>* test_scheduler) {
154+
std::vector<std::string> filenames_graph = tiny_spaa_graphs();
155+
std::vector<std::string> filenames_architectures = test_architectures();
156+
157+
// Locate project root
158+
std::filesystem::path cwd = std::filesystem::current_path();
159+
while ((!cwd.empty()) && (cwd.filename() != "OneStopParallel")) {
160+
cwd = cwd.parent_path();
161+
}
162+
163+
for (auto& filename_graph : filenames_graph) {
164+
for (auto& filename_machine : filenames_architectures) {
165+
std::string name_graph = filename_graph.substr(filename_graph.find_last_of("/\\") + 1);
166+
name_graph = name_graph.substr(0, name_graph.find_last_of("."));
167+
std::string name_machine = filename_machine.substr(filename_machine.find_last_of("/\\") + 1);
168+
name_machine = name_machine.substr(0, name_machine.rfind("."));
169+
170+
std::cout << std::endl
171+
<< "Scheduler (MaxBsp): " << test_scheduler->getScheduleName() << std::endl
172+
<< "Graph: " << name_graph << std::endl
173+
<< "Architecture: " << name_machine << std::endl;
174+
175+
computational_dag_edge_idx_vector_impl_def_int_t graph;
176+
BspArchitecture<Graph_t> arch;
177+
178+
bool status_graph = file_reader::readGraph((cwd / filename_graph).string(), graph);
179+
bool status_architecture =
180+
file_reader::readBspArchitecture((cwd / filename_machine).string(), arch);
181+
182+
BOOST_REQUIRE_MESSAGE(status_graph, "Failed to read graph: " << filename_graph);
183+
BOOST_REQUIRE_MESSAGE(status_architecture, "Failed to read architecture: " << filename_machine);
184+
185+
BspInstance<Graph_t> instance(graph, arch);
186+
187+
MaxBspSchedule<Graph_t> schedule(instance);
188+
189+
const auto result = test_scheduler->computeSchedule(schedule);
190+
191+
BOOST_CHECK_EQUAL(result, RETURN_STATUS::OSP_SUCCESS);
192+
BOOST_CHECK(schedule.satisfiesPrecedenceConstraints());
193+
}
194+
}
195+
}
196+
152197
BOOST_AUTO_TEST_CASE(GreedyBspScheduler_test) {
153198

154199
GreedyBspScheduler<computational_dag_vector_impl_def_t> test;
@@ -377,20 +422,8 @@ BOOST_AUTO_TEST_CASE(GreedyVarianceSspScheduler_test_edge_idx_impl) {
377422
}
378423

379424
// Tests computeSchedule(MaxBspSchedule&) → staleness = 2
380-
BOOST_AUTO_TEST_CASE(GreedyVarianceSspScheduler_MaxBspSchedule_integration) {
425+
BOOST_AUTO_TEST_CASE(GreedyVarianceSspScheduler_MaxBspSchedule_large_test) {
381426
using Graph_t = computational_dag_edge_idx_vector_impl_def_int_t;
382-
BspInstance<Graph_t> instance;
383-
instance.setNumberOfProcessors(2);
384-
auto &dag = instance.getComputationalDag();
385-
dag.add_vertex(5, 1, 0);
386-
dag.add_vertex(3, 1, 0);
387-
dag.add_edge(0, 1);
388-
389-
GreedyVarianceSspScheduler<Graph_t> scheduler;
390-
MaxBspSchedule<Graph_t> schedule(instance);
391-
const auto result = scheduler.computeSchedule(schedule);
392-
393-
BOOST_CHECK_EQUAL(result, RETURN_STATUS::OSP_SUCCESS);
394-
BOOST_CHECK(schedule.satisfiesPrecedenceConstraints());
395-
BOOST_CHECK(schedule.numberOfSupersteps() >= 2);
396-
}
427+
GreedyVarianceSspScheduler<Graph_t> test;
428+
run_test_max_bsp(&test);
429+
}

0 commit comments

Comments
 (0)