Skip to content

Commit 0c4ee15

Browse files
authored
Instance revision 2 (#60)
* update architecture * removed some bounds checking * cosmetics * to_string * noexcept * Processor range * return_status.hpp update update update, bugfix * documentation docu updates * arch constructor
1 parent 98c59be commit 0c4ee15

26 files changed

+707
-786
lines changed

apps/test_suite_runner/AbstractTestSuiteRunner.hpp

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@ limitations under the License.
2828
#include <string>
2929
#include <vector>
3030

31-
#include <boost/property_tree/json_parser.hpp>
32-
#include <boost/property_tree/ptree.hpp>
3331
#include "ConfigParser.hpp"
3432
#include "StatsModules/IStatsModule.hpp"
35-
#include "osp/bsp/model/BspInstance.hpp"
3633
#include "osp/auxiliary/io/arch_file_reader.hpp"
3734
#include "osp/auxiliary/io/general_file_reader.hpp"
35+
#include "osp/auxiliary/return_status.hpp"
36+
#include "osp/bsp/model/BspInstance.hpp"
37+
#include <boost/property_tree/json_parser.hpp>
38+
#include <boost/property_tree/ptree.hpp>
3839

39-
//#define EIGEN_FOUND 1
40+
// #define EIGEN_FOUND 1
4041

4142
#ifdef EIGEN_FOUND
4243
#include <Eigen/Sparse>
@@ -83,7 +84,7 @@ class AbstractTestSuiteRunner {
8384

8485
if (write_target_object_to_file) {
8586
output_target_object_dir_path = parser.global_params.get_child("scheduleDirectory")
86-
.get_value<std::string>();
87+
.get_value<std::string>();
8788
if (output_target_object_dir_path.substr(0, 1) != "/")
8889
output_target_object_dir_path = executable_dir + output_target_object_dir_path;
8990
if (!output_target_object_dir_path.empty() && !std::filesystem::exists(output_target_object_dir_path)) {
@@ -167,13 +168,13 @@ class AbstractTestSuiteRunner {
167168
}
168169
}
169170

170-
virtual RETURN_STATUS compute_target_object_impl(const BspInstance<GraphType> &instance, std::unique_ptr<TargetObjectType>& target_object,
171-
const pt::ptree &algo_config,
172-
long long &computation_time_ms) = 0;
171+
virtual RETURN_STATUS compute_target_object_impl(const BspInstance<GraphType> &instance, std::unique_ptr<TargetObjectType> &target_object,
172+
const pt::ptree &algo_config,
173+
long long &computation_time_ms) = 0;
173174

174175
virtual void create_and_register_statistic_modules(const std::string &module_name) = 0;
175176

176-
virtual void write_target_object_hook(const TargetObjectType&, const std::string &, const std::string &,
177+
virtual void write_target_object_hook(const TargetObjectType &, const std::string &, const std::string &,
177178
const std::string &) {
178179
} // default in case TargetObjectType cannot be written to file
179180

@@ -250,7 +251,7 @@ class AbstractTestSuiteRunner {
250251
log_stream << "Start Graph: " + filename_graph + "\n";
251252

252253
BspInstance<GraphType> bsp_instance;
253-
bsp_instance.setArchitecture(arch);
254+
bsp_instance.getArchitecture() = arch;
254255
bool graph_status = false;
255256
std::string ext;
256257
if (filename_graph.rfind('.') != std::string::npos)
@@ -268,12 +269,12 @@ class AbstractTestSuiteRunner {
268269
SM_csc_int64 L_csc_int64{};
269270

270271
if constexpr (std::is_same_v<GraphType, sparse_matrix_graph_int32_t> || std::is_same_v<GraphType, sparse_matrix_graph_int64_t>) {
271-
if (ext != "mtx"){
272+
if (ext != "mtx") {
272273
log_stream << "Error: Only .mtx file is accepted for SpTRSV" << std::endl;
273274
return 0;
274275
}
275-
276-
if constexpr (std::is_same_v<GraphType, sparse_matrix_graph_int32_t>){
276+
277+
if constexpr (std::is_same_v<GraphType, sparse_matrix_graph_int32_t>) {
277278
graph_status = Eigen::loadMarket(L_csr_int32, filename_graph);
278279
if (!graph_status) {
279280
std::cerr << "Failed to read matrix from " << filename_graph << std::endl;
@@ -297,7 +298,7 @@ class AbstractTestSuiteRunner {
297298
}
298299
} else {
299300
#endif
300-
graph_status = file_reader::readGraph(filename_graph, bsp_instance.getComputationalDag());
301+
graph_status = file_reader::readGraph(filename_graph, bsp_instance.getComputationalDag());
301302

302303
#ifdef EIGEN_FOUND
303304
}
@@ -309,22 +310,20 @@ class AbstractTestSuiteRunner {
309310

310311
for (auto &algorithm_config_pair : parser.scheduler) {
311312
const pt::ptree &algo_config = algorithm_config_pair.second;
312-
313-
314313

315314
std::string current_algo_name = algo_config.get_child("name").get_value<std::string>();
316315
log_stream << "Start Algorithm " + current_algo_name + "\n";
317316

318317
long long computation_time_ms;
319-
std::unique_ptr<TargetObjectType> target_object;
320-
318+
std::unique_ptr<TargetObjectType> target_object;
319+
321320
RETURN_STATUS exec_status = compute_target_object_impl(bsp_instance, target_object, algo_config, computation_time_ms);
322321

323322
if (exec_status != RETURN_STATUS::OSP_SUCCESS && exec_status != RETURN_STATUS::BEST_FOUND) {
324323
if (exec_status == RETURN_STATUS::ERROR)
325324
log_stream << "Error computing with " << current_algo_name << "." << std::endl;
326325
else if (exec_status == RETURN_STATUS::TIMEOUT)
327-
log_stream << "Scheduler " << current_algo_name << " timed out." << std::endl;
326+
log_stream << "Scheduler " << current_algo_name << " timed out." << std::endl;
328327
continue;
329328
}
330329

apps/test_suite_runner/StringToScheduler/run_bsp_scheduler.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ limitations under the License.
5757
namespace osp {
5858

5959
const std::set<std::string> get_available_bsp_scheduler_names() {
60-
return {"Serial", "GreedyBsp", "GrowLocal", "BspLocking", "Cilk", "Etf", "GreedyRandom",
61-
"GreedyChildren", "Variance", "MultiHC", "LocalSearch", "Coarser", "FullILP", "MultiLevel"};
60+
return {"Serial", "GreedyBsp", "GrowLocal", "BspLocking", "Cilk", "Etf", "GreedyRandom",
61+
"GreedyChildren", "Variance", "MultiHC", "LocalSearch", "Coarser", "FullILP", "MultiLevel"};
6262
}
6363

6464
template<typename Graph_t>
@@ -247,7 +247,7 @@ RETURN_STATUS run_bsp_scheduler(const ConfigParser &parser, const boost::propert
247247
if (!status)
248248
return RETURN_STATUS::ERROR;
249249

250-
instance_coarse.setArchitecture(instance.getArchitecture());
250+
instance_coarse.getArchitecture() = instance.getArchitecture();
251251
instance_coarse.setNodeProcessorCompatibility(instance.getProcessorCompatibilityMatrix());
252252
BspSchedule<boost_graph_t> schedule_coarse(instance_coarse);
253253

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Copyright 2024 Huawei Technologies Co., Ltd.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
16+
@author Toni Boehnlein, Benjamin Lozes, Pal Andras Papp, Raphael S. Steiner
17+
*/
18+
19+
#pragma once
20+
21+
#include <iostream>
22+
23+
namespace osp {
24+
25+
enum class RETURN_STATUS { OSP_SUCCESS,
26+
BEST_FOUND,
27+
TIMEOUT,
28+
ERROR };
29+
30+
/**
31+
* @brief Converts the enum to a string literal.
32+
* Returns const char* to avoid std::string allocation overhead.
33+
*/
34+
inline const char *to_string(const RETURN_STATUS status) {
35+
switch (status) {
36+
case RETURN_STATUS::OSP_SUCCESS:
37+
return "SUCCESS";
38+
case RETURN_STATUS::BEST_FOUND:
39+
return "BEST FOUND";
40+
case RETURN_STATUS::TIMEOUT:
41+
return "TIMEOUT";
42+
case RETURN_STATUS::ERROR:
43+
return "ERROR";
44+
default:
45+
return "UNKNOWN";
46+
}
47+
}
48+
49+
/**
50+
* @brief Stream operator overload using the helper function.
51+
*/
52+
inline std::ostream &operator<<(std::ostream &os, RETURN_STATUS status) {
53+
return os << to_string(status);
54+
}
55+
56+
} // namespace osp

include/osp/bsp/model/BspArchitecture.hpp

Lines changed: 38 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,12 @@ inline std::ostream &operator<<(std::ostream &os, MEMORY_CONSTRAINT_TYPE type) {
9090
* bounds. It provides methods to set and retrieve these values.
9191
*
9292
* **Processors:**
93-
* The architecture consists of p processors, indexed from 0 to p-1.
93+
* The architecture consists of p processors, indexed from 0 to p-1. Note that processor indices are represented using `unsigned`.
9494
*
9595
* **Processor Types:**
9696
* Processors can have different types, which are represented by non-negative integers.
97-
* Processor types are assumed to be consecutive integers starting from 0.
97+
* Processor types are assumed to be consecutive integers starting from 0. Note that processor types are represented using `unsigned`.
98+
* Processor types are used to express compatabilities, which can be specified in the BspInstance, regarding node types.
9899
*
99100
* **Communication and Synchronization Costs:**
100101
* - Communication Cost (g): The cost of communicating a unit of data between processors, i.e., the bandwidth.
@@ -185,46 +186,53 @@ class BspArchitecture {
185186
}
186187

187188
public:
188-
/**
189-
* @brief Default constructor.
190-
* Initializes a BSP architecture with 2 processors, 1 processor type,
191-
* communication costs of 1, synchronisation costs of 2, memory bounds of 100,
192-
* and send costs of 1 between all processors.
193-
*/
194-
BspArchitecture()
195-
: numberOfProcessors_(2U), numberOfProcessorTypes_(1U), communicationCosts_(1U), synchronisationCosts_(2U),
196-
memoryBound_(numberOfProcessors_, 100U), isNuma_(false),
197-
processorTypes_(numberOfProcessors_, 0U), sendCosts_(numberOfProcessors_ * numberOfProcessors_, 1U) {
198-
SetSendCostDiagonalToZero();
199-
}
200-
201-
BspArchitecture(const BspArchitecture &other) = default;
202-
BspArchitecture(BspArchitecture &&other) noexcept = default;
203-
BspArchitecture &operator=(const BspArchitecture &other) = default;
204-
BspArchitecture &operator=(BspArchitecture &&other) noexcept = default;
205-
virtual ~BspArchitecture() = default;
206-
207189
/**
208190
* @brief Constructs a BspArchitecture object with the specified number of processors, communication cost, and
209191
* synchronization cost.
210192
*
211-
* @param NumberOfProcessors The number of processors in the architecture. Must be greater than 0.
212-
* @param CommunicationCost The communication cost between processors.
213-
* @param SynchronisationCost The synchronization cost between processors.
193+
* @param NumberOfProcessors The number of processors in the architecture. Must be greater than 0. Default: 2.
194+
* @param CommunicationCost The communication cost between processors. Default: 1.
195+
* @param SynchronisationCost The synchronization cost between processors. Default: 2.
214196
* @param MemoryBound The memory bound for each processor (default: 100).
197+
* @param SendCosts The matrix of send costs between processors. Needs to be a processors x processors matrix. Diagonal entries are forced to zero. Default: empty (uniform costs).
215198
*/
216-
BspArchitecture(const unsigned NumberOfProcessors, const v_commw_t<Graph_t> CommunicationCost, const v_commw_t<Graph_t> SynchronisationCost,
217-
const v_memw_t<Graph_t> MemoryBound = 100U)
199+
BspArchitecture(const unsigned NumberOfProcessors = 2U, const v_commw_t<Graph_t> CommunicationCost = 1U, const v_commw_t<Graph_t> SynchronisationCost = 2U,
200+
const v_memw_t<Graph_t> MemoryBound = 100U, const std::vector<std::vector<v_commw_t<Graph_t>>> &SendCosts = {})
218201
: numberOfProcessors_(NumberOfProcessors), numberOfProcessorTypes_(1U), communicationCosts_(CommunicationCost),
219202
synchronisationCosts_(SynchronisationCost),
220203
memoryBound_(NumberOfProcessors, MemoryBound), isNuma_(false),
221-
processorTypes_(NumberOfProcessors, 0U), sendCosts_(NumberOfProcessors * NumberOfProcessors, 1U) {
204+
processorTypes_(NumberOfProcessors, 0U) {
222205
if (NumberOfProcessors == 0U) {
223206
throw std::runtime_error("BspArchitecture: Number of processors must be greater than 0.");
224207
}
225-
SetSendCostDiagonalToZero();
208+
209+
if (SendCosts.empty()) {
210+
InitializeUniformSendCosts();
211+
} else {
212+
if (NumberOfProcessors != SendCosts.size()) {
213+
throw std::invalid_argument("sendCosts_ needs to be a processors x processors matrix.\n");
214+
}
215+
if (std::any_of(SendCosts.begin(), SendCosts.end(),
216+
[NumberOfProcessors](const auto &thing) { return thing.size() != NumberOfProcessors; })) {
217+
throw std::invalid_argument("sendCosts_ needs to be a processors x processors matrix.\n");
218+
}
219+
220+
sendCosts_.reserve(NumberOfProcessors * NumberOfProcessors);
221+
for (const auto &row : SendCosts) {
222+
sendCosts_.insert(sendCosts_.end(), row.begin(), row.end());
223+
}
224+
225+
SetSendCostDiagonalToZero();
226+
isNuma_ = AreSendCostsNuma();
227+
}
226228
}
227229

230+
BspArchitecture(const BspArchitecture &other) = default;
231+
BspArchitecture(BspArchitecture &&other) noexcept = default;
232+
BspArchitecture &operator=(const BspArchitecture &other) = default;
233+
BspArchitecture &operator=(BspArchitecture &&other) noexcept = default;
234+
virtual ~BspArchitecture() = default;
235+
228236
/**
229237
* @brief Copy constructor from a BspArchitecture with a different graph type.
230238
*
@@ -258,62 +266,7 @@ class BspArchitecture {
258266
*/
259267
BspArchitecture(const unsigned NumberOfProcessors, const v_commw_t<Graph_t> CommunicationCost, const v_commw_t<Graph_t> SynchronisationCost,
260268
const std::vector<std::vector<v_commw_t<Graph_t>>> &SendCosts)
261-
: numberOfProcessors_(NumberOfProcessors), numberOfProcessorTypes_(1U), communicationCosts_(CommunicationCost),
262-
synchronisationCosts_(SynchronisationCost), memoryBound_(NumberOfProcessors, 100U),
263-
processorTypes_(NumberOfProcessors, 0U) {
264-
if (NumberOfProcessors == 0U) {
265-
throw std::runtime_error("BspArchitecture: Number of processors must be greater than 0.");
266-
}
267-
if (NumberOfProcessors != SendCosts.size()) {
268-
throw std::invalid_argument("sendCosts_ needs to be a processors x processors matrix.\n");
269-
}
270-
if (std::any_of(SendCosts.begin(), SendCosts.end(),
271-
[NumberOfProcessors](const auto &thing) { return thing.size() != NumberOfProcessors; })) {
272-
throw std::invalid_argument("sendCosts_ needs to be a processors x processors matrix.\n");
273-
}
274-
275-
sendCosts_.reserve(NumberOfProcessors * NumberOfProcessors);
276-
for (const auto &row : SendCosts) {
277-
sendCosts_.insert(sendCosts_.end(), row.begin(), row.end());
278-
}
279-
280-
SetSendCostDiagonalToZero();
281-
isNuma_ = AreSendCostsNuma();
282-
}
283-
284-
/**
285-
* @brief Constructs a BspArchitecture object with custom send costs and memory bound.
286-
*
287-
* @param NumberOfProcessors The number of processors. Must be greater than 0.
288-
* @param CommunicationCost The communication cost.
289-
* @param SynchronisationCost The synchronization cost.
290-
* @param MemoryBound The memory bound for each processor.
291-
* @param SendCosts The matrix of send costs between processors. Needs to be a processors x processors matrix. Diagonal entries are forced to zero.
292-
*/
293-
BspArchitecture(const unsigned NumberOfProcessors, const v_commw_t<Graph_t> CommunicationCost, const v_commw_t<Graph_t> SynchronisationCost,
294-
const v_memw_t<Graph_t> MemoryBound, const std::vector<std::vector<v_commw_t<Graph_t>>> &SendCosts)
295-
: numberOfProcessors_(NumberOfProcessors), numberOfProcessorTypes_(1U), communicationCosts_(CommunicationCost),
296-
synchronisationCosts_(SynchronisationCost), memoryBound_(NumberOfProcessors, MemoryBound),
297-
processorTypes_(NumberOfProcessors, 0U) {
298-
if (NumberOfProcessors == 0U) {
299-
throw std::runtime_error("BspArchitecture: Number of processors must be greater than 0.");
300-
}
301-
if (NumberOfProcessors != SendCosts.size()) {
302-
throw std::invalid_argument("sendCosts_ needs to be a processors x processors matrix.\n");
303-
}
304-
if (std::any_of(SendCosts.begin(), SendCosts.end(),
305-
[NumberOfProcessors](const auto &thing) { return thing.size() != NumberOfProcessors; })) {
306-
throw std::invalid_argument("sendCosts_ needs to be a processors x processors matrix.\n");
307-
}
308-
309-
sendCosts_.reserve(NumberOfProcessors * NumberOfProcessors);
310-
for (const auto &row : SendCosts) {
311-
sendCosts_.insert(sendCosts_.end(), row.begin(), row.end());
312-
}
313-
314-
SetSendCostDiagonalToZero();
315-
isNuma_ = AreSendCostsNuma();
316-
}
269+
: BspArchitecture(NumberOfProcessors, CommunicationCost, SynchronisationCost, 100U, SendCosts) {}
317270

318271
/**
319272
* @brief Sets the uniform send cost for each pair of processors.
@@ -636,6 +589,7 @@ class BspArchitecture {
636589

637590
/**
638591
* @brief Returns the send costs between two processors. Does not perform bounds checking.
592+
* Does not the communication costs into account.
639593
*
640594
* @param p1 The index of the first processor.
641595
* @param p2 The index of the second processor.

0 commit comments

Comments
 (0)