Skip to content

Commit ee6a106

Browse files
AndreySorokin7AndreySorokin7
andauthored
Implement PostOp structure (#188)
Closes #180 --------- Co-authored-by: AndreySorokin7 <andrey_sorokin_nn@mail,ru>
1 parent 68ec25c commit ee6a106

4 files changed

Lines changed: 93 additions & 1 deletion

File tree

app/Graph/build.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ void build_graph(Tensor& input, Tensor& output, bool comments,
2424
ImplType impl1 = parallel ? kTBB : kDefault;
2525
ImplType impl2 = parallel ? kSTL : kDefault;
2626
std::vector<std::shared_ptr<Layer>> layers;
27+
std::vector<bool> layerpostop;
2728

2829
std::string json_file = MODEL_PATH_H5;
2930
json model_data = read_json(json_file);
@@ -73,12 +74,14 @@ void build_graph(Tensor& input, Tensor& output, bool comments,
7374
1, pads, 1, tmp_values, tmp_bias, impl2);
7475
conv_layer->setName(kConvolution);
7576
layers.push_back(conv_layer);
77+
layerpostop.push_back(false);
7678
if (comments) std::cout << "ConvLayer added to layers." << std::endl;
7779
}
7880
if (layer_type.find("relu") != std::string::npos) {
7981
auto ew_layer = std::make_shared<EWLayer>("relu");
8082
ew_layer->setName(kElementWise);
8183
layers.push_back(ew_layer);
84+
layerpostop.push_back(true);
8285
if (comments)
8386
std::cout << "Element wise (relu) added to layers" << std::endl;
8487
}
@@ -99,6 +102,7 @@ void build_graph(Tensor& input, Tensor& output, bool comments,
99102
auto fc_layer = std::make_shared<FCLayer>(tensor, tmp_bias);
100103
fc_layer->setName(kFullyConnected);
101104
layers.push_back(fc_layer);
105+
layerpostop.push_back(false);
102106
if (comments) std::cout << "DenseLayer added to layers." << std::endl;
103107
}
104108

@@ -116,6 +120,7 @@ void build_graph(Tensor& input, Tensor& output, bool comments,
116120
auto pool_layer = std::make_shared<PoolingLayer>(shape, pooltype, impl1);
117121
pool_layer->setName(kPooling);
118122
layers.push_back(pool_layer);
123+
layerpostop.push_back(false);
119124
if (comments) std::cout << "PoolingLayer added to layers." << std::endl;
120125
}
121126

@@ -124,13 +129,15 @@ void build_graph(Tensor& input, Tensor& output, bool comments,
124129
std::make_shared<FlattenLayer>(std::vector<size_t>({0, 3, 2, 1}));
125130
flatten_layer->setName(kFlatten);
126131
layers.push_back(flatten_layer);
132+
layerpostop.push_back(false);
127133
if (comments) std::cout << "FlattenLayer added to layers." << std::endl;
128134
}
129135

130136
if (layer_type.find("Dropout") != std::string::npos) {
131137
auto dropout_layer = std::make_shared<DropOutLayer>(0.0);
132138
dropout_layer->setName(kDropout);
133139
layers.push_back(dropout_layer);
140+
layerpostop.push_back(false);
134141
if (comments)
135142
std::cout
136143
<< "DropOutLayer added to layers with probability 0.4 (turned "
@@ -155,7 +162,12 @@ void build_graph(Tensor& input, Tensor& output, bool comments,
155162
<< std::endl;
156163

157164
for (size_t i = 0; i < layers.size() - 1; ++i) {
158-
graph.makeConnection(*layers[i], *layers[i + 1]);
165+
if (layerpostop[i]) {
166+
layers[i - 1]->postops.layers.push_back(layers[i].get());
167+
layers[i - 1]->postops.count++;
168+
graph.makeConnection(*layers[i - 1], *layers[i + 1]);
169+
} else if (!layerpostop[i + 1])
170+
graph.makeConnection(*layers[i], *layers[i + 1]);
159171
}
160172

161173
graph.setOutput(*layers.back(), output);

include/graph/graph.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ class Graph {
114114
weights_.push_back(layers_[i]->get_weights());
115115
#endif
116116
inten_ = *outten_;
117+
if (layers_[i]->postops.count > 0) {
118+
for (unsigned int j = 0; j < layers_[i]->postops.count; j++) {
119+
layers_[i]->postops.layers[j]->run(inten_, *outten_);
120+
}
121+
inten_ = *outten_;
122+
}
117123
#ifdef ENABLE_STATISTIC_TIME
118124
auto end = std::chrono::high_resolution_clock::now();
119125
auto elapsed =

include/layers/Layer.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,18 @@ enum LayerType : uint8_t {
2525

2626
enum ImplType : uint8_t { kDefault, kTBB, kSTL };
2727

28+
class Layer;
29+
30+
struct PostOperations {
31+
std::vector<Layer*> layers;
32+
unsigned int count = 0;
33+
};
34+
2835
class Layer {
2936
public:
3037
Layer() = default;
3138
virtual ~Layer() = default;
39+
PostOperations postops;
3240
int getID() const { return id_; }
3341
void setID(int id) { id_ = id; }
3442
LayerType getName() const { return type_; }

test/inference/test_inference.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,69 @@ TEST(bfs, check_end_to_end) {
138138
std::vector<float> res(3, 21);
139139
ASSERT_EQ(tmp, res);
140140
}
141+
TEST(bfs, check_struct_layer) {
142+
Graph graph(5);
143+
Shape sh1({1, 5, 5, 3});
144+
std::vector<int> vec;
145+
vec.reserve(75);
146+
for (int i = 0; i < 75; ++i) {
147+
vec.push_back(3);
148+
}
149+
Tensor input = make_tensor(vec, sh1);
150+
Tensor output = make_tensor(vec, sh1);
151+
InputLayer a1(kNhwc, kNchw, 1, 2);
152+
a1.setName(kInput);
153+
std::vector<int> kernelvec = {1, 1, 1, 1, 1, 1, 1, 1, 1};
154+
Shape sh2({3, 3});
155+
Tensor kernel = make_tensor(kernelvec, sh2);
156+
ConvolutionalLayer a2(1, 0, 1, kernel);
157+
ConvolutionalLayer a3(1, 0, 1, kernel);
158+
159+
// EWLayer a4("linear", 2.0F, 3.0F);
160+
// a2.ewops.layers.push_back(&a4);
161+
// a2.ewops.countlayers++;
162+
163+
a2.setName(kConvolution);
164+
a3.setName(kConvolution);
165+
graph.setInput(a1, input);
166+
graph.makeConnection(a1, a2);
167+
graph.makeConnection(a2, a3);
168+
graph.setOutput(a3, output);
169+
graph.inference();
170+
std::vector<int> tmp = *output.as<int>();
171+
std::vector<int> res = {81, 81, 81};
172+
ASSERT_EQ(tmp, res);
173+
}
174+
TEST(bfs, check_struct_layer_added) {
175+
Graph graph(5);
176+
Shape sh1({1, 5, 5, 3});
177+
std::vector<int> vec;
178+
vec.reserve(75);
179+
for (int i = 0; i < 75; ++i) {
180+
vec.push_back(3);
181+
}
182+
Tensor input = make_tensor(vec, sh1);
183+
Tensor output = make_tensor(vec, sh1);
184+
InputLayer a1(kNhwc, kNchw, 1, 2);
185+
a1.setName(kInput);
186+
std::vector<int> kernelvec = {1, 1, 1, 1, 1, 1, 1, 1, 1};
187+
Shape sh2({3, 3});
188+
Tensor kernel = make_tensor(kernelvec, sh2);
189+
ConvolutionalLayer a2(1, 0, 1, kernel);
190+
ConvolutionalLayer a3(1, 0, 1, kernel);
191+
192+
EWLayer a4("linear", 2.0F, 3.0F);
193+
a2.postops.layers.push_back(&a4);
194+
a2.postops.count++;
195+
196+
a2.setName(kConvolution);
197+
a3.setName(kConvolution);
198+
graph.setInput(a1, input);
199+
graph.makeConnection(a1, a2);
200+
graph.makeConnection(a2, a3);
201+
graph.setOutput(a3, output);
202+
graph.inference();
203+
std::vector<int> tmp = *output.as<int>();
204+
std::vector<int> res = {189, 189, 189};
205+
ASSERT_EQ(tmp, res);
206+
}

0 commit comments

Comments
 (0)