Skip to content

Commit e581001

Browse files
authored
Fuse Convolution + Activation node as a part of graph transformations pipeline (#276)
1 parent be46b0f commit e581001

18 files changed

Lines changed: 1457 additions & 13 deletions

File tree

app/Graph/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ target_link_libraries(BuildGraph PUBLIC ${OpenCV_LIBS})
1111
target_link_libraries(BuildGraph PUBLIC reader_lib)
1212
target_link_libraries(BuildGraph PUBLIC TBB_unified)
1313
target_link_libraries(BuildGraph PUBLIC layers_lib)
14+
target_link_libraries(BuildGraph PUBLIC layers_fused_lib)
1415
target_link_libraries(BuildGraph PUBLIC layers_oneDNN_lib)
1516
target_link_libraries(BuildGraph PUBLIC gtest_main)
1617

@@ -25,6 +26,7 @@ target_link_libraries(ACC BuildGraph)
2526
add_executable(onnx_subgraphs onnx_subgraphs.cpp)
2627
target_link_libraries(onnx_subgraphs BuildGraph)
2728
target_link_libraries(onnx_subgraphs OpenMP::OpenMP_CXX)
29+
target_link_libraries(onnx_subgraphs ${OpenCV_LIBS})
2830
target_link_libraries(onnx_subgraphs graphT_lib)
2931

3032
file(DOWNLOAD

app/Graph/build.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ std::unordered_map<std::string, std::string> model_paths = {
1313

1414
void build_graph_linear(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
1515
it_lab_ai::Tensor& output, RuntimeOptions options,
16-
bool comments) {
16+
bool comments, bool enable_postops) {
1717
if (comments) {
1818
for (size_t i = 0; i < input.get_shape().dims(); i++) {
1919
std::cout << input.get_shape()[i] << ' ';
@@ -75,7 +75,7 @@ void build_graph_linear(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
7575
if (layer_type.find("relu") != std::string::npos) {
7676
auto ew_layer = LayerFactory::createEwLayer("relu", options);
7777
layers.push_back(ew_layer);
78-
layerpostop.push_back(true);
78+
layerpostop.push_back(enable_postops);
7979
if (comments) {
8080
std::cout << "Element wise (relu) added to layers" << '\n';
8181
}

app/Graph/build.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ void build_graph(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
6161
it_lab_ai::RuntimeOptions options, bool comments);
6262
void build_graph_linear(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
6363
it_lab_ai::Tensor& output,
64-
it_lab_ai::RuntimeOptions options, bool comments);
64+
it_lab_ai::RuntimeOptions options, bool comments,
65+
bool enable_postops = true);
6566
std::unordered_map<int, std::string> load_class_names(
6667
const std::string& filename);
6768

app/Graph/onnx_subgraphs.cpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,85 @@
11
#include <algorithm>
22
#include <filesystem>
33
#include <iomanip>
4+
#include <iostream>
45
#include <numeric>
6+
#include <opencv2/opencv.hpp>
57
#include <sstream>
68
#include <unordered_map>
79

810
#include "build.hpp"
911
#include "graph_transformations/graph_transformations.hpp"
12+
#include "layers_fused/ConvRelu.hpp"
1013
#include "perf/benchmarking.hpp"
1114

1215
using namespace it_lab_ai;
1316

17+
void alexnet_inf_careless(Graph& graph, const RuntimeOptions& options,
18+
Tensor& input, Tensor& output) {
19+
auto* o = new Tensor(output);
20+
auto* i = new Tensor(input);
21+
graph.inference(options);
22+
if (graph.getLayersCount() == 0) {
23+
throw std::runtime_error("No layers");
24+
}
25+
graph.setOutput(graph.getLayerFromID(graph.getLayersCount() - 1), *o);
26+
graph.setInput(graph.getLayerFromID(0), *i);
27+
}
28+
29+
void alexnet_comparison() {
30+
std::vector<size_t> counts = {979, 1134, 1031, 1009, 981,
31+
891, 957, 1027, 973, 1008};
32+
size_t sum = std::accumulate(counts.begin(), counts.end(), size_t{0});
33+
int count_pic = static_cast<int>(sum) + 10;
34+
std::vector<float> res(count_pic * 28 * 28, 1.0F);
35+
Tensor input;
36+
Shape sh1({1, 5, 5, 3});
37+
std::vector<float> vec;
38+
vec.reserve(75);
39+
for (int i = 0; i < 75; ++i) {
40+
vec.push_back(3);
41+
}
42+
Tensor output = make_tensor(vec, sh1);
43+
44+
Shape sh({static_cast<size_t>(count_pic), 1, 28, 28});
45+
Tensor t = make_tensor<float>(res, sh);
46+
input = t;
47+
48+
RuntimeOptions options;
49+
Graph graph;
50+
Graph graph2;
51+
build_graph_linear(graph, input, output, options, true, false);
52+
Graph subgraph;
53+
std::shared_ptr<Layer> layer_0 = std::make_shared<ConvolutionalLayer>();
54+
std::shared_ptr<Layer> layer_1 = std::make_shared<EWLayer>("relu");
55+
subgraph.setInput(layer_0, input);
56+
subgraph.makeConnection(layer_0, layer_1);
57+
std::shared_ptr<Layer> layer_to = std::make_shared<ConvReluLayer>(
58+
std::dynamic_pointer_cast<ConvolutionalLayer>(layer_0));
59+
changed_subgraphs(graph, subgraph, layer_to, graph2, input, options);
60+
Tensor input_c = input;
61+
Tensor output_c = output;
62+
auto time1 = elapsed_time_avg<double, std::milli>(
63+
4, alexnet_inf_careless, graph, options, input_c, output_c);
64+
print_time_stats(graph);
65+
auto time2 = elapsed_time_avg<double, std::milli>(
66+
4, alexnet_inf_careless, graph2, options, input_c, output_c);
67+
print_time_stats(graph2);
68+
std::cout << time1 << " for unchanged graph\n";
69+
std::cout << time2 << " for convrelu graph\n";
70+
}
71+
1472
int main() {
1573
int type = 2;
1674
Tensor input = make_tensor(std::vector<int>({0}));
1775
RuntimeOptions options;
76+
alexnet_comparison();
1877
if (type == 0) {
1978
Graph graph1;
2079
build_graph(graph1, input, input, MODEL_PATH_DENSENET_ONNX, options, false);
2180

2281
Graph subgraph;
23-
Tensor scale = make_tensor(std::vector<float>({1.0}));
82+
Tensor scale = make_tensor(std::vector<float>({1.0F}));
2483
std::shared_ptr<Layer> layer_0 =
2584
std::make_shared<BatchNormalizationLayer>(scale, scale, scale, scale);
2685
std::shared_ptr<Layer> layer_1 = std::make_shared<EWLayer>("relu");

include/CMakeLists.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ file(GLOB_RECURSE graphT_headers graph_transformations/*.h graph_transformations
55
set(GRAPHT_HEADERS "${graphT_headers}" PARENT_SCOPE)
66

77
file(GLOB_RECURSE layers_headers layers/*.h layers/*.hpp)
8-
set(LAYERS_HEADERS "${layers_headers}" PARENT_SCOPE)
8+
file(GLOB_RECURSE parallel_headers parallel/*.h parallel/*.hpp)
9+
set(LAYERS_HEADERS "${layers_headers}" "${parallel_headers}" PARENT_SCOPE)
910

1011
file(GLOB_RECURSE layers_oneDNN_headers layers_oneDNN/*.h layers_oneDNN/*.hpp)
1112
set(LAYERS_ONEDNN_HEADERS "${layers_oneDNN_headers}" PARENT_SCOPE)
1213

14+
file(GLOB_RECURSE layers_fused_headers layers_fused/*.h layers_fused/*.hpp)
15+
set(LAYERS_FUSED_HEADERS "${layers_fused_headers}" PARENT_SCOPE)
16+
1317
file(GLOB_RECURSE perf_headers perf/*.h perf/*.hpp)
1418
set(PERF_HEADERS "${perf_headers}" PARENT_SCOPE)
1519

1620
file(GLOB_RECURSE reader_headers Weights_Reader/*.h Weights_Reader/*.hpp)
1721
set(READER_HEADERS "${reader_headers}" PARENT_SCOPE)
18-
19-
file(GLOB_RECURSE parallel_headers parallel/*.h parallel/*.hpp)
20-
set(LAYERS_HEADERS "${parallel_headers}" PARENT_SCOPE)

include/graph/graph.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ static std::unordered_map<LayerType, std::string> label_map = {
3131
{kReshape, "Reshape"},
3232
{kSoftmax, "Softmax"},
3333
{kReduce, "Reduce"},
34-
{kBatchNormalization, "Normalization"}};
34+
{kBatchNormalization, "Normalization"},
35+
{kConvRelu, "ConvRelu"}};
3536

3637
struct LayerTimeStats {
3738
std::string layer_name;

include/graph_transformations/graph_transformations.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
#include <vector>
33

44
#include "graph/graph.hpp"
5+
#include "layers/ConvLayer.hpp"
56
#include "layers/EWLayer.hpp"
67
#include "layers/Layer.hpp"
8+
#include "layers_fused/ConvRelu.hpp"
79

810
namespace it_lab_ai {
911

include/layers/ConvLayer.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,19 @@ class ConvolutionalLayer : public Layer {
5858
dilations_ = dilations;
5959
useLegacyImpl_ = useLegacyImpl;
6060
}
61+
62+
[[nodiscard]] std::vector<size_t> getNumericParams() const {
63+
std::vector<size_t> res = {stride_, pads_, dilations_, group_};
64+
return res;
65+
}
66+
67+
[[nodiscard]] std::vector<std::shared_ptr<Tensor>> getTensorParams() {
68+
std::vector<std::shared_ptr<Tensor>> res = {kernel_, bias_};
69+
return res;
70+
}
71+
72+
[[nodiscard]] bool getLegacyImplBool() const { return useLegacyImpl_; }
73+
6174
void run(const std::vector<Tensor>& input,
6275
std::vector<Tensor>& output) override;
6376
void run(const std::vector<Tensor>& input, std::vector<Tensor>& output,

include/layers/Layer.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ enum LayerType : uint8_t {
3434
kReshape,
3535
kSoftmax,
3636
kMatmul,
37-
kBatchNormalization
37+
kBatchNormalization,
38+
kConvRelu
3839
};
3940

4041
enum ImplType : uint8_t { kDefault, kTBB, kSTL };

include/layers/Tensor.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ std::vector<T>* Tensor::as() {
170170
}
171171

172172
template <typename T>
173-
const std::vector<T>* Tensor::as() const {
173+
[[nodiscard]] const std::vector<T>* Tensor::as() const {
174174
if (GetTypeEnum<T>() != type_) {
175175
throw std::invalid_argument("Template type doesn't fit this Tensor");
176176
}

0 commit comments

Comments
 (0)