Skip to content

Commit f5408c0

Browse files
Using RuntimeOptions to set up the graph (#242)
close #226 --------- Co-authored-by: Arseniy Obolenskiy <gooddoog@student.su>
1 parent cd1798b commit f5408c0

20 files changed

Lines changed: 593 additions & 181 deletions

app/Accuracy/accuracy_check.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
using namespace it_lab_ai;
1111

1212
int main() {
13+
RuntimeOptions options;
14+
options.backend = Backend::kNaive;
15+
options.threads = 4;
16+
options.parallel = true;
1317
std::string image_path = IMAGE1_PATH;
1418
cv::Mat image = cv::imread(image_path);
1519
if (image.empty()) {
@@ -66,7 +70,7 @@ int main() {
6670
graph.makeConnection(a4_ptr, a5_ptr);
6771
graph.makeConnection(a5_ptr, a6_ptr);
6872
graph.setOutput(a5_ptr, output);
69-
graph.inference();
73+
graph.inference(options);
7074
std::vector<float> tmp = *output.as<float>();
7175
std::vector<float> tmp_output = softmax<float>(*output.as<float>());
7276
for (float i : tmp) {

app/Graph/acc_check.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,45 @@ using namespace it_lab_ai;
1212

1313
int main(int argc, char* argv[]) {
1414
std::string model_name = "alexnet_mnist";
15-
bool onednn = false;
15+
RuntimeOptions options;
16+
1617
for (int i = 1; i < argc; ++i) {
1718
if (std::string(argv[i]) == "--model" && i + 1 < argc) {
1819
model_name = argv[++i];
1920
} else if (std::string(argv[i]) == "--onednn") {
20-
onednn = true;
21+
options.backend = Backend::kOneDnn;
22+
if (options.isParallel()) {
23+
std::cout << "Warning: oneDNN backend is not compatible with parallel "
24+
"execution. Disabling parallelism."
25+
<< '\n';
26+
options.setParallelBackend(ParBackend::kSeq);
27+
}
28+
} else if (std::string(argv[i]) == "--parallel" && i + 1 < argc) {
29+
if (options.backend == Backend::kOneDnn) {
30+
std::cout << "Warning: Parallel execution is not compatible with "
31+
"oneDNN backend. Ignoring --parallel option."
32+
<< '\n';
33+
i++;
34+
continue;
35+
}
36+
37+
std::string backend_str = argv[++i];
38+
if (backend_str == "tbb") {
39+
options.setParallelBackend(ParBackend::kTbb);
40+
} else if (backend_str == "threads" || backend_str == "stl") {
41+
options.setParallelBackend(ParBackend::kThreads);
42+
} else if (backend_str == "omp") {
43+
options.setParallelBackend(ParBackend::kOmp);
44+
} else {
45+
std::cerr << "Unknown parallel backend: " << backend_str
46+
<< ". Using default (Threads)." << '\n';
47+
options.setParallelBackend(ParBackend::kThreads);
48+
}
49+
} else if (std::string(argv[i]) == "--threads" && i + 1 < argc) {
50+
options.threads = std::stoi(argv[++i]);
2151
}
2252
}
23-
it_lab_ai::LayerFactory::configure(onednn);
53+
2454
std::string dataset_path;
2555
if (model_name == "alexnet_mnist") {
2656
dataset_path = MNIST_PATH;
@@ -77,8 +107,8 @@ int main(int argc, char* argv[]) {
77107
Tensor t = make_tensor<float>(res, sh);
78108
input = t;
79109
Graph graph;
80-
build_graph_linear(graph, input, output, false);
81-
graph.inference();
110+
build_graph_linear(graph, input, output, options, false);
111+
graph.inference(options);
82112
print_time_stats(graph);
83113
std::vector<std::vector<float>> tmp_output =
84114
softmax<float>(*output.as<float>(), 10);
@@ -186,8 +216,8 @@ int main(int argc, char* argv[]) {
186216
it_lab_ai::Tensor(output_shape, it_lab_ai::Type::kFloat);
187217

188218
Graph graph;
189-
build_graph(graph, input, output, json_path, false);
190-
graph.inference();
219+
build_graph(graph, input, output, json_path, options, false);
220+
graph.inference(options);
191221
print_time_stats(graph);
192222
std::vector<std::vector<float>> processed_outputs;
193223
const std::vector<float>& raw_output = *output.as<float>();

app/Graph/build.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
using namespace it_lab_ai;
66

7-
bool LayerFactory::onednn_ = false;
8-
97
std::unordered_map<std::string, std::string> model_paths = {
108
{"alexnet_mnist", MODEL_PATH_H5},
119
{"googlenet", MODEL_PATH_GOOGLENET_ONNX},
@@ -14,7 +12,8 @@ std::unordered_map<std::string, std::string> model_paths = {
1412
{"yolo", MODEL_PATH_YOLO11NET_ONNX}};
1513

1614
void build_graph_linear(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
17-
it_lab_ai::Tensor& output, bool comments) {
15+
it_lab_ai::Tensor& output, RuntimeOptions options,
16+
bool comments) {
1817
if (comments) {
1918
for (size_t i = 0; i < input.get_shape().dims(); i++) {
2019
std::cout << input.get_shape()[i] << ' ';
@@ -83,14 +82,14 @@ void build_graph_linear(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
8382
it_lab_ai::Tensor tmp_values = tensor;
8483
it_lab_ai::Tensor tmp_bias = it_lab_ai::make_tensor(tensor.get_bias());
8584
auto conv_layer = std::make_unique<it_lab_ai::ConvolutionalLayer>(
86-
1, pads, 1, tmp_values, tmp_bias, kDefault, 1, true);
85+
1, pads, 1, tmp_values, tmp_bias, 1, true);
8786
layer_ptrs.push_back(conv_layer.get());
8887
layers.push_back(std::move(conv_layer));
8988
layerpostop.push_back(false);
9089
if (comments) std::cout << "ConvLayer added to layers." << '\n';
9190
}
9291
if (layer_type.find("relu") != std::string::npos) {
93-
auto ew_layer = LayerFactory::createEwLayer("relu");
92+
auto ew_layer = LayerFactory::createEwLayer("relu", options);
9493
layer_ptrs.push_back(ew_layer.get());
9594
layers.push_back(std::move(ew_layer));
9695
layerpostop.push_back(true);
@@ -120,7 +119,7 @@ void build_graph_linear(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
120119
<< '\n';
121120
}
122121
auto pool_layer =
123-
std::make_unique<it_lab_ai::PoolingLayer>(shape, pooltype, kDefault);
122+
std::make_unique<it_lab_ai::PoolingLayer>(shape, pooltype);
124123
layer_ptrs.push_back(pool_layer.get());
125124
layers.push_back(std::move(pool_layer));
126125
layerpostop.push_back(false);
@@ -195,8 +194,8 @@ std::string get_base_layer_name(const std::string& tensor_name) {
195194

196195
void build_graph(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
197196
it_lab_ai::Tensor& output, const std::string& json_path,
198-
bool comments) {
199-
auto parse_result = parse_json_model(json_path, comments);
197+
RuntimeOptions options, bool comments) {
198+
auto parse_result = parse_json_model(options, json_path, comments);
200199

201200
auto& layers = parse_result.layers;
202201
auto& name_to_layer_ptr = parse_result.name_to_layer_ptr;
@@ -300,7 +299,8 @@ void build_graph(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
300299
}
301300
}
302301

303-
ParseResult parse_json_model(const std::string& json_path, bool comments) {
302+
ParseResult parse_json_model(RuntimeOptions options,
303+
const std::string& json_path, bool comments) {
304304
ParseResult result;
305305

306306
auto& layers = result.layers;
@@ -411,13 +411,13 @@ ParseResult parse_json_model(const std::string& json_path, bool comments) {
411411
it_lab_ai::Tensor tmp_bias = it_lab_ai::make_tensor(tensor.get_bias());
412412

413413
auto conv_layer = std::make_unique<it_lab_ai::ConvolutionalLayer>(
414-
stride, pads, dilations, tmp_tensor, tmp_bias, kDefault, group);
414+
stride, pads, dilations, tmp_tensor, tmp_bias, group);
415415
layer = std::move(conv_layer);
416416
} else if (layer_type.find("Relu") != std::string::npos ||
417417
layer_type.find("relu") != std::string::npos) {
418-
layer = LayerFactory::createEwLayer("relu");
418+
layer = LayerFactory::createEwLayer("relu", options);
419419
} else if (layer_type.find("Sigmoid") != std::string::npos) {
420-
layer = LayerFactory::createEwLayer("sigmoid");
420+
layer = LayerFactory::createEwLayer("sigmoid", options);
421421
} else if (layer_type.find("Dense") != std::string::npos ||
422422
layer_type.find("FullyConnected") != std::string::npos) {
423423
it_lab_ai::Tensor tensor = it_lab_ai::create_tensor_from_json(
@@ -448,7 +448,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments) {
448448
}
449449
} else if (layer_type == "GlobalAveragePool") {
450450
auto pool_layer = std::make_unique<it_lab_ai::PoolingLayer>(
451-
it_lab_ai::Shape({0, 0}), "average", kDefault);
451+
it_lab_ai::Shape({0, 0}), "average");
452452
layer = std::move(pool_layer);
453453
if (comments) {
454454
std::cout << "GlobalAveragePool layer added (will use input spatial "
@@ -509,8 +509,8 @@ ParseResult parse_json_model(const std::string& json_path, bool comments) {
509509
}
510510
}
511511

512-
auto pool_layer = std::make_unique<it_lab_ai::PoolingLayer>(
513-
shape, pooltype, kDefault);
512+
auto pool_layer =
513+
std::make_unique<it_lab_ai::PoolingLayer>(shape, pooltype);
514514

515515
try {
516516
if (strides[0] != 2 || strides[1] != 2) {
@@ -637,13 +637,16 @@ ParseResult parse_json_model(const std::string& json_path, bool comments) {
637637

638638
if (layer_type == "Mul") {
639639
ew_operation = "linear";
640-
layer = LayerFactory::createEwLayer(ew_operation, value, 0.0F);
640+
layer =
641+
LayerFactory::createEwLayer(ew_operation, options, value, 0.0F);
641642
} else if (layer_type == "Add") {
642643
ew_operation = "linear";
643-
layer = LayerFactory::createEwLayer(ew_operation, 1.0F, value);
644+
layer =
645+
LayerFactory::createEwLayer(ew_operation, options, 1.0F, value);
644646
} else if (layer_type == "Sub") {
645647
ew_operation = "linear";
646-
layer = LayerFactory::createEwLayer(ew_operation, 1.0F, -value);
648+
layer = LayerFactory::createEwLayer(ew_operation, options, 1.0F,
649+
-value);
647650
} else {
648651
continue;
649652
}

app/Graph/build.hpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "Weights_Reader/reader_weights.hpp"
1515
#include "graph/graph.hpp"
16+
#include "graph/runtime_options.hpp"
1617
#include "layers/BatchNormalizationLayer.hpp"
1718
#include "layers/BinaryOpLayer.hpp"
1819
#include "layers/ConcatLayer.hpp"
@@ -52,13 +53,15 @@ struct ParseResult {
5253

5354
void build_graph(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
5455
it_lab_ai::Tensor& output, const std::string& json_path,
55-
bool comments);
56+
it_lab_ai::RuntimeOptions options, bool comments);
5657
void build_graph_linear(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
57-
it_lab_ai::Tensor& output, bool comments);
58+
it_lab_ai::Tensor& output,
59+
it_lab_ai::RuntimeOptions options, bool comments);
5860
std::unordered_map<int, std::string> load_class_names(
5961
const std::string& filename);
6062

61-
ParseResult parse_json_model(const std::string& json_path, bool comments);
63+
ParseResult parse_json_model(it_lab_ai::RuntimeOptions options,
64+
const std::string& json_path, bool comments);
6265

6366
std::vector<int> get_input_shape_from_json(const std::string& json_path);
6467
std::vector<float> process_model_output(const std::vector<float>& output,
@@ -69,19 +72,15 @@ it_lab_ai::Tensor prepare_image(const cv::Mat& image,
6972
it_lab_ai::Tensor prepare_mnist_image(const cv::Mat& image);
7073

7174
void print_time_stats(it_lab_ai::Graph& graph);
72-
7375
namespace it_lab_ai {
7476
class LayerFactory {
75-
private:
76-
static bool onednn_;
77-
7877
public:
79-
static void configure(bool onednn) { onednn_ = onednn; }
80-
8178
static std::unique_ptr<Layer> createEwLayer(const std::string& function,
79+
const RuntimeOptions& options,
8280
float alpha = 1.0F,
8381
float beta = 0.0F) {
84-
if (onednn_ && EwLayerOneDnn::is_function_supported(function)) {
82+
if (options.backend == Backend::kOneDnn &&
83+
EwLayerOneDnn::is_function_supported(function)) {
8584
return std::make_unique<EwLayerOneDnn>(function, alpha, beta);
8685
}
8786
return std::make_unique<EWLayer>(function, alpha, beta);

app/Graph/graph_build.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,45 @@ using namespace it_lab_ai;
99

1010
int main(int argc, char* argv[]) {
1111
std::string model_name = "alexnet_mnist";
12-
bool onednn = false;
12+
RuntimeOptions options;
13+
1314
for (int i = 1; i < argc; ++i) {
1415
if (std::string(argv[i]) == "--model" && i + 1 < argc) {
1516
model_name = argv[++i];
1617
} else if (std::string(argv[i]) == "--onednn") {
17-
onednn = true;
18+
options.backend = Backend::kOneDnn;
19+
if (options.isParallel()) {
20+
std::cout << "Warning: oneDNN backend is not compatible with parallel "
21+
"execution. Disabling parallelism."
22+
<< '\n';
23+
options.setParallelBackend(ParBackend::kSeq);
24+
}
25+
} else if (std::string(argv[i]) == "--parallel" && i + 1 < argc) {
26+
if (options.backend == Backend::kOneDnn) {
27+
std::cout << "Warning: Parallel execution is not compatible with "
28+
"oneDNN backend. Ignoring --parallel option."
29+
<< '\n';
30+
i++;
31+
continue;
32+
}
33+
34+
std::string backend_str = argv[++i];
35+
if (backend_str == "tbb") {
36+
options.setParallelBackend(ParBackend::kTbb);
37+
} else if (backend_str == "threads" || backend_str == "stl") {
38+
options.setParallelBackend(ParBackend::kThreads);
39+
} else if (backend_str == "omp") {
40+
options.setParallelBackend(ParBackend::kOmp);
41+
} else {
42+
std::cerr << "Unknown parallel backend: " << backend_str
43+
<< ". Using default (Threads)." << '\n';
44+
options.setParallelBackend(ParBackend::kThreads);
45+
}
46+
} else if (std::string(argv[i]) == "--threads" && i + 1 < argc) {
47+
options.threads = std::stoi(argv[++i]);
1848
}
1949
}
2050

21-
it_lab_ai::LayerFactory::configure(onednn);
22-
2351
std::string json_path = model_paths[model_name];
2452

2553
std::vector<int> input_shape;
@@ -62,11 +90,11 @@ int main(int argc, char* argv[]) {
6290
std::vector<float> vec(75, 3);
6391
it_lab_ai::Tensor output = it_lab_ai::make_tensor(vec, sh1);
6492
Graph graph;
65-
build_graph_linear(graph, input, output, true);
93+
build_graph_linear(graph, input, output, options, true);
6694

6795
std::cout << "Starting inference..." << '\n';
6896
try {
69-
graph.inference();
97+
graph.inference(options);
7098
std::cout << "Inference completed successfully." << '\n';
7199
} catch (const std::exception& e) {
72100
std::cerr << "ERROR during inference: " << e.what() << '\n';
@@ -102,11 +130,11 @@ int main(int argc, char* argv[]) {
102130
it_lab_ai::Tensor output({1, output_classes}, it_lab_ai::Type::kFloat);
103131

104132
Graph graph;
105-
build_graph(graph, input, output, json_path, false);
133+
build_graph(graph, input, output, json_path, options, false);
106134

107135
std::cout << "Starting inference..." << '\n';
108136
try {
109-
graph.inference();
137+
graph.inference(options);
110138
std::cout << "Inference completed successfully." << '\n';
111139
} catch (const std::exception& e) {
112140
std::cerr << "ERROR during inference: " << e.what() << '\n';

include/graph/graph.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <vector>
1212

1313
#include "layers/Layer.hpp"
14+
#include "runtime_options.hpp"
1415

1516
namespace it_lab_ai {
1617

@@ -224,7 +225,7 @@ class Graph {
224225
return false;
225226
}
226227

227-
void inference() {
228+
void inference(const RuntimeOptions& options) {
228229
std::vector<std::pair<int, int>> countinout = getInOutDegrees();
229230
std::vector<int> traversal = getTraversalOrder();
230231
count_used_split_distribution_ = 0;
@@ -262,7 +263,7 @@ class Graph {
262263
}
263264
}
264265
}
265-
layers_[current_layer]->run(inten_, outten_);
266+
layers_[current_layer]->run(inten_, outten_, options);
266267

267268
#ifdef ENABLE_STATISTIC_TENSORS
268269
tensors_.push_back(inten_[0]);
@@ -277,7 +278,8 @@ class Graph {
277278
if (layers_[current_layer]->postops.count > 0) {
278279
for (unsigned int j = 0; j < layers_[current_layer]->postops.count;
279280
j++) {
280-
layers_[current_layer]->postops.layers[j]->run(inten_, outten_);
281+
layers_[current_layer]->postops.layers[j]->run(inten_, outten_,
282+
options);
281283
}
282284
inten_ = outten_;
283285
}

0 commit comments

Comments
 (0)