Skip to content

Commit 92fdab4

Browse files
authored
Merge branch 'main' into cmake-arch-cleanup
2 parents db75f67 + 92737be commit 92fdab4

10 files changed

Lines changed: 1204 additions & 203 deletions

File tree

app/Graph/build.cpp

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ void build_graph_linear(it_lab_ai::Graph& graph, it_lab_ai::Tensor& input,
101101
<< '\n';
102102
}
103103
auto pool_layer =
104-
std::make_shared<it_lab_ai::PoolingLayer>(shape, pooltype);
104+
LayerFactory::createPoolingLayer(pooltype, shape, options);
105+
105106
layers.push_back(pool_layer);
106107
layerpostop.push_back(false);
107108
if (comments) std::cout << "PoolingLayer added to layers." << '\n';
@@ -408,8 +409,8 @@ ParseResult parse_json_model(RuntimeOptions options,
408409
<< '\n';
409410
}
410411
} else if (layer_type == "GlobalAveragePool") {
411-
auto pool_layer = std::make_shared<it_lab_ai::PoolingLayer>(
412-
it_lab_ai::Shape({0, 0}), "average");
412+
auto pool_layer = LayerFactory::createPoolingLayer(
413+
"average", it_lab_ai::Shape({0, 0}), options);
413414
layer = pool_layer;
414415
if (comments) {
415416
std::cout << "GlobalAveragePool layer added (will use input spatial "
@@ -470,30 +471,9 @@ ParseResult parse_json_model(RuntimeOptions options,
470471
}
471472
}
472473

473-
auto pool_layer =
474-
std::make_shared<it_lab_ai::PoolingLayer>(shape, pooltype);
475-
476-
try {
477-
if (strides[0] != 2 || strides[1] != 2) {
478-
pool_layer->setStrides(strides[0], strides[1]);
479-
}
480-
481-
if (pads[0] != 0 || pads[1] != 0 || pads[2] != 0 || pads[3] != 0) {
482-
pool_layer->setPads(pads[0], pads[1], pads[2], pads[3]);
483-
}
474+
auto pool_layer = LayerFactory::createPoolingLayer(
475+
pooltype, shape, options, strides, pads, dilations, ceil_mode);
484476

485-
if (dilations[0] != 1 || dilations[1] != 1) {
486-
pool_layer->setDilations(dilations[0], dilations[1]);
487-
}
488-
489-
pool_layer->setCeilMode(ceil_mode);
490-
491-
} catch (const std::exception& e) {
492-
if (comments) {
493-
std::cout << "Warning: Some pooling parameters not supported: "
494-
<< e.what() << '\n';
495-
}
496-
}
497477
layer = pool_layer;
498478
} else if (layer_type.find("Flatten") != std::string::npos) {
499479
int axis = 1;

app/Graph/build.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "layers/TransposeLayer.hpp"
3535
#include "layers_oneDNN/ConvLayer.hpp"
3636
#include "layers_oneDNN/EWLayer.hpp"
37+
#include "layers_oneDNN/PoolingLayer.hpp"
3738

3839
extern std::unordered_map<std::string, std::string> model_paths;
3940

@@ -99,6 +100,19 @@ class LayerFactory {
99100
return std::make_shared<ConvolutionalLayer>(step, pads, dilations, kernel,
100101
bias, group, useLegacyImpl);
101102
}
103+
104+
static std::shared_ptr<Layer> createPoolingLayer(
105+
const std::string& PoolType, const Shape& shape,
106+
const RuntimeOptions& options, const Shape& strides = {2, 2},
107+
const Shape& pads = {0, 0, 0, 0}, const Shape& dilations = {1, 1},
108+
bool ceil_mode = false) {
109+
if (options.backend == Backend::kOneDnn) {
110+
return std::make_shared<PoolingLayerOneDnn>(
111+
shape, strides, pads, dilations, ceil_mode, PoolType);
112+
}
113+
return std::make_shared<PoolingLayer>(shape, strides, pads, dilations,
114+
ceil_mode, PoolType);
115+
}
102116
};
103117

104118
} // namespace it_lab_ai

include/layers/Shape.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <iostream>
66
#include <numeric>
77
#include <ostream>
8+
#include <sstream>
89
#include <stdexcept>
910
#include <vector>
1011

@@ -39,6 +40,16 @@ class Shape {
3940
}
4041
[[nodiscard]] size_t dims() const noexcept { return dims_.size(); }
4142
[[nodiscard]] size_t get_index(const std::vector<size_t>& coords) const;
43+
[[nodiscard]] std::string to_string() const {
44+
std::stringstream ss;
45+
ss << "(";
46+
for (size_t i = 0; i < dims_.size(); ++i) {
47+
if (i > 0) ss << ", ";
48+
ss << dims_[i];
49+
}
50+
ss << ")";
51+
return ss.str();
52+
}
4253
bool operator==(const Shape& other) const {
4354
if (dims_.size() != other.dims_.size()) return false;
4455
for (size_t i = 0; i < dims_.size(); ++i) {
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#pragma once
2+
3+
#include <dnnl.hpp>
4+
#include <memory>
5+
#include <string>
6+
#include <vector>
7+
8+
#include "layers/Layer.hpp"
9+
10+
namespace it_lab_ai {
11+
12+
class PoolingLayerOneDnn : public Layer {
13+
public:
14+
explicit PoolingLayerOneDnn(const Shape& pooling_shape,
15+
const Shape& strides = {2, 2},
16+
const Shape& pads = {0, 0, 0, 0},
17+
const Shape& dilations = {1, 1},
18+
bool ceil_mode = false,
19+
std::string pooling_type = "average")
20+
: Layer(kPooling),
21+
poolingShape_(pooling_shape),
22+
strides_(strides),
23+
pads_(pads),
24+
dilations_(dilations),
25+
ceil_mode_(ceil_mode),
26+
poolingType_(std::move(pooling_type)),
27+
engine_(std::make_unique<dnnl::engine>(dnnl::engine::kind::cpu, 0)),
28+
stream_(std::make_unique<dnnl::stream>(*engine_)) {}
29+
30+
void run(const std::vector<Tensor>& input,
31+
std::vector<Tensor>& output) override;
32+
33+
void setStrides(size_t h, size_t w) {
34+
strides_ = {h, w};
35+
initialized_ = false;
36+
}
37+
38+
void setPads(size_t top, size_t bottom, size_t left, size_t right) {
39+
pads_ = {top, bottom, left, right};
40+
initialized_ = false;
41+
}
42+
43+
void setDilations(size_t h, size_t w) {
44+
dilations_ = {h, w};
45+
initialized_ = false;
46+
}
47+
48+
void setCeilMode(bool ceil_mode) {
49+
ceil_mode_ = ceil_mode;
50+
initialized_ = false;
51+
}
52+
53+
#ifdef ENABLE_STATISTIC_WEIGHTS
54+
Tensor get_weights() override {
55+
std::vector<int> v = {0};
56+
Tensor a = make_tensor(v);
57+
return a;
58+
}
59+
#endif
60+
61+
private:
62+
void initialize_onednn(const Shape& shape, Type data_type);
63+
[[nodiscard]] dnnl::algorithm get_PoolType() const;
64+
static void validate_input(const std::vector<Tensor>& input);
65+
[[nodiscard]] static dnnl::memory::data_type get_dnnl_data_type(Type type);
66+
[[nodiscard]] Shape calculate_output_shape(const Shape& input_shape) const;
67+
68+
Shape poolingShape_;
69+
Shape strides_;
70+
Shape pads_;
71+
Shape dilations_;
72+
bool ceil_mode_;
73+
std::string poolingType_;
74+
75+
bool initialized_ = false;
76+
Shape last_shape_;
77+
Type last_type_;
78+
79+
std::unique_ptr<dnnl::engine> engine_;
80+
std::unique_ptr<dnnl::stream> stream_;
81+
std::unique_ptr<dnnl::pooling_forward> pool_prim_;
82+
dnnl::memory::desc src_memory_desc_;
83+
dnnl::memory::desc dst_memory_desc_;
84+
Shape output_shape_;
85+
};
86+
87+
} // namespace it_lab_ai

src/layers_oneDNN/ConvLayer.cpp

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,9 @@ void ConvLayerOneDnn::initialize_special_conv(const Shape& input_shape,
369369
if (has_bias) {
370370
bias_md = dnnl::memory::desc(
371371
{static_cast<dnnl::memory::dim>(bias_.get_shape()[0])}, dt,
372-
dnnl::memory::format_tag::any);
372+
dnnl::memory::format_tag::a);
373373
}
374+
374375
dnnl::convolution_forward::primitive_desc conv_pd =
375376
has_bias ? dnnl::convolution_forward::primitive_desc(
376377
*engine_, dnnl::prop_kind::forward_inference,
@@ -391,20 +392,21 @@ void ConvLayerOneDnn::initialize_special_conv(const Shape& input_shape,
391392

392393
if (data_type == Type::kFloat) {
393394
const std::vector<float>& kernel_data = *kernel_.as<float>();
395+
394396
size_t kh = k_shape[0];
395397
size_t kw = k_shape[1];
396398
size_t kic = k_shape[2];
397399
size_t koc = k_shape[3];
398400

399401
std::vector<float> reordered(koc * kic * kh * kw);
400-
size_t idx = 0;
401402

402-
for (size_t oc = 0; oc < koc; oc++) {
403-
for (size_t ic = 0; ic < kic; ic++) {
404-
for (size_t h = 0; h < kh; h++) {
405-
for (size_t w = 0; w < kw; w++) {
403+
for (size_t oc = 0; oc < koc; ++oc) {
404+
for (size_t ic = 0; ic < kic; ++ic) {
405+
for (size_t h = 0; h < kh; ++h) {
406+
for (size_t w = 0; w < kw; ++w) {
406407
size_t src_idx = ((h * kw + w) * kic + ic) * koc + oc;
407-
reordered[idx++] = kernel_data[src_idx];
408+
size_t dst_idx = ((oc * kic + ic) * kh + h) * kw + w;
409+
reordered[dst_idx] = kernel_data[src_idx];
408410
}
409411
}
410412
}
@@ -421,14 +423,13 @@ void ConvLayerOneDnn::initialize_special_conv(const Shape& input_shape,
421423
size_t koc = k_shape[3];
422424

423425
std::vector<float> reordered(koc * kic * kh * kw);
424-
size_t idx = 0;
425-
426-
for (size_t oc = 0; oc < koc; oc++) {
427-
for (size_t ic = 0; ic < kic; ic++) {
428-
for (size_t h = 0; h < kh; h++) {
429-
for (size_t w = 0; w < kw; w++) {
426+
for (size_t oc = 0; oc < koc; ++oc) {
427+
for (size_t ic = 0; ic < kic; ++ic) {
428+
for (size_t h = 0; h < kh; ++h) {
429+
for (size_t w = 0; w < kw; ++w) {
430430
size_t src_idx = ((h * kw + w) * kic + ic) * koc + oc;
431-
reordered[idx++] = static_cast<float>(kernel_data_int[src_idx]);
431+
size_t dst_idx = ((oc * kic + ic) * kh + h) * kw + w;
432+
reordered[dst_idx] = static_cast<float>(kernel_data_int[src_idx]);
432433
}
433434
}
434435
}
@@ -438,6 +439,22 @@ void ConvLayerOneDnn::initialize_special_conv(const Shape& input_shape,
438439
reordered.size() * sizeof(float));
439440
}
440441

442+
if (has_bias) {
443+
if (data_type == Type::kFloat) {
444+
const std::vector<float>& bias_data = *bias_.as<float>();
445+
std::memcpy(bias_memory_.get_data_handle(), bias_data.data(),
446+
bias_data.size() * sizeof(float));
447+
} else if (data_type == Type::kInt) {
448+
const std::vector<int>& bias_data_int = *bias_.as<int>();
449+
std::vector<float> float_bias(bias_data_int.size());
450+
std::transform(bias_data_int.begin(), bias_data_int.end(),
451+
float_bias.begin(),
452+
[](int val) { return static_cast<float>(val); });
453+
std::memcpy(bias_memory_.get_data_handle(), float_bias.data(),
454+
float_bias.size() * sizeof(float));
455+
}
456+
}
457+
441458
conv_prim_ = std::make_unique<dnnl::convolution_forward>(conv_pd);
442459
initialized_ = true;
443460

@@ -494,8 +511,8 @@ void ConvLayerOneDnn::run_special_conv(const std::vector<Tensor>& input,
494511
Shape output_shape = get_output_shape(input_shape);
495512

496513
if (data_type == Type::kFloat) {
497-
std::vector<float> output_data(dst_memory_.get_desc().get_size() /
498-
sizeof(float));
514+
size_t output_size = dst_memory_.get_desc().get_size() / sizeof(float);
515+
std::vector<float> output_data(output_size);
499516
std::memcpy(output_data.data(), dst_memory_.get_data_handle(),
500517
output_data.size() * sizeof(float));
501518
output[0] = make_tensor(output_data, output_shape);

0 commit comments

Comments
 (0)