11#include " layers_oneDNN/EWLayer.hpp"
22
3- #include < chrono>
4- #include < cmath>
53#include < iostream>
64#include < stdexcept>
75
@@ -22,37 +20,79 @@ void EwLayerOneDnn::run(const std::vector<Tensor>& input,
2220 if (data_type == Type::kFloat ) {
2321 const std::vector<float >& input_data = *input_tensor.as <float >();
2422 std::vector<float > output_data (input_data.size ());
23+
2524 dnnl::memory src_mem = dnnl::memory (
2625 memory_desc_, *engine_, const_cast <float *>(input_data.data ()));
2726 dnnl::memory dst_mem =
2827 dnnl::memory (memory_desc_, *engine_, output_data.data ());
28+
2929 eltwise_prim_->execute (
3030 *stream_, {{DNNL_ARG_SRC , src_mem}, {DNNL_ARG_DST , dst_mem}});
3131 stream_->wait ();
32+
3233 output[0 ] = make_tensor (output_data, input_tensor.get_shape ());
3334 } else if (data_type == Type::kInt ) {
3435 const std::vector<int >& input_data = *input_tensor.as <int >();
3536 std::vector<int > output_data (input_data.size ());
3637
37- std::vector<float > float_input;
38- float_input.reserve (input_data.size ());
39- for (int val : input_data) {
40- float_input.push_back (static_cast <float >(val));
38+ if (memory_desc_.get_data_type () != dnnl::memory::data_type::s32) {
39+ std::vector<dnnl::memory::dim> dims;
40+ const Shape& shape = input_tensor.get_shape ();
41+ for (size_t i = 0 ; i < shape.dims (); i++) {
42+ dims.push_back (static_cast <dnnl::memory::dim>(shape.at (i)));
43+ }
44+
45+ dnnl::memory::format_tag format;
46+ switch (dims.size ()) {
47+ case 1 :
48+ format = dnnl::memory::format_tag::a;
49+ break ;
50+ case 2 :
51+ format = dnnl::memory::format_tag::ab;
52+ break ;
53+ case 3 :
54+ format = dnnl::memory::format_tag::abc;
55+ break ;
56+ case 4 :
57+ format = dnnl::memory::format_tag::abcd;
58+ break ;
59+ case 5 :
60+ format = dnnl::memory::format_tag::abcde;
61+ break ;
62+ default :
63+ throw std::invalid_argument (" Unsupported tensor dimensionality: " +
64+ std::to_string (dims.size ()));
65+ }
66+
67+ memory_desc_ =
68+ dnnl::memory::desc (dims, dnnl::memory::data_type::s32, format);
69+
70+ float primitive_alpha = 0 .0F ;
71+ float primitive_beta = 0 .0F ;
72+
73+ if (func_ == " relu" ) {
74+ primitive_alpha = 0 .0F ;
75+ } else if (func_ == " linear" ) {
76+ primitive_alpha = alpha_;
77+ primitive_beta = beta_;
78+ }
79+
80+ auto eltwise_pd = dnnl::eltwise_forward::primitive_desc (
81+ *engine_, dnnl::prop_kind::forward_inference, get_algorithm (),
82+ memory_desc_, memory_desc_, primitive_alpha, primitive_beta);
83+
84+ eltwise_prim_ = std::make_unique<dnnl::eltwise_forward>(eltwise_pd);
4185 }
4286
43- std::vector<float > float_output (input_data.size ());
44-
45- dnnl::memory src_mem =
46- dnnl::memory (memory_desc_, *engine_, float_input.data ());
87+ dnnl::memory src_mem = dnnl::memory (memory_desc_, *engine_,
88+ const_cast <int *>(input_data.data ()));
4789 dnnl::memory dst_mem =
48- dnnl::memory (memory_desc_, *engine_, float_output.data ());
90+ dnnl::memory (memory_desc_, *engine_, output_data.data ());
91+
4992 eltwise_prim_->execute (
5093 *stream_, {{DNNL_ARG_SRC , src_mem}, {DNNL_ARG_DST , dst_mem}});
5194 stream_->wait ();
5295
53- for (size_t i = 0 ; i < float_output.size (); ++i) {
54- output_data[i] = static_cast <int >(std::round (float_output[i]));
55- }
5696 output[0 ] = make_tensor (output_data, input_tensor.get_shape ());
5797 } else {
5898 throw std::runtime_error (" EwLayerOneDnn: Unsupported data type" );
@@ -112,13 +152,7 @@ void EwLayerOneDnn::initialize_onednn(const Shape& shape, Type data_type) {
112152 std::to_string (dims.size ()));
113153 }
114154
115- dnnl::memory::data_type dnnl_data_type;
116- if (data_type == Type::kFloat ) {
117- dnnl_data_type = dnnl::memory::data_type::f32 ;
118- } else {
119- throw std::invalid_argument (" Unsupported data type for oneDNN EW layer" );
120- }
121-
155+ dnnl::memory::data_type dnnl_data_type = get_dnnl_data_type (data_type);
122156 memory_desc_ = dnnl::memory::desc (dims, dnnl_data_type, format);
123157
124158 dnnl::algorithm algo = get_algorithm ();
@@ -148,6 +182,17 @@ void EwLayerOneDnn::initialize_onednn(const Shape& shape, Type data_type) {
148182 }
149183}
150184
185+ dnnl::memory::data_type EwLayerOneDnn::get_dnnl_data_type (Type type) const {
186+ switch (type) {
187+ case Type::kFloat :
188+ return dnnl::memory::data_type::f32 ;
189+ case Type::kInt :
190+ return dnnl::memory::data_type::s32;
191+ default :
192+ throw std::runtime_error (" Unsupported data type for oneDNN" );
193+ }
194+ }
195+
151196dnnl::algorithm EwLayerOneDnn::get_algorithm () const {
152197 if (func_ == " relu" ) {
153198 return dnnl::algorithm::eltwise_relu;
@@ -170,4 +215,4 @@ bool EwLayerOneDnn::is_function_supported(const std::string& function) {
170215 function == " linear" );
171216}
172217
173- } // namespace it_lab_ai
218+ } // namespace it_lab_ai
0 commit comments