@@ -9,96 +9,41 @@ void EwLayerOneDnn::run(const std::vector<Tensor>& input,
99 std::vector<Tensor>& output) {
1010 validate_input (input);
1111
12- const Tensor& input_tensor = input[0 ];
13- Type data_type = input_tensor .get_type ();
12+ const Tensor& in = input[0 ];
13+ Type type = in .get_type ();
1414
15- if (!initialized_) {
16- initialize_onednn (input_tensor.get_shape (), data_type);
15+ bool need_reinit =
16+ !initialized_ || last_type_ != type || last_shape_ != in.get_shape ();
17+
18+ if (need_reinit) {
19+ initialize_onednn (in.get_shape (), type);
1720 }
1821
19- try {
20- if (data_type == Type::kFloat ) {
21- const std::vector<float >& input_data = *input_tensor.as <float >();
22- std::vector<float > output_data (input_data.size ());
23-
24- dnnl::memory src_mem = dnnl::memory (
25- memory_desc_, *engine_, const_cast <float *>(input_data.data ()));
26- dnnl::memory dst_mem =
27- dnnl::memory (memory_desc_, *engine_, output_data.data ());
28-
29- eltwise_prim_->execute (
30- *stream_, {{DNNL_ARG_SRC , src_mem}, {DNNL_ARG_DST , dst_mem}});
31- stream_->wait ();
32-
33- output[0 ] = make_tensor (output_data, input_tensor.get_shape ());
34- } else if (data_type == Type::kInt ) {
35- const std::vector<int >& input_data = *input_tensor.as <int >();
36- std::vector<int > output_data (input_data.size ());
37-
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);
85- }
86-
87- dnnl::memory src_mem = dnnl::memory (memory_desc_, *engine_,
88- const_cast <int *>(input_data.data ()));
89- dnnl::memory dst_mem =
90- dnnl::memory (memory_desc_, *engine_, output_data.data ());
91-
92- eltwise_prim_->execute (
93- *stream_, {{DNNL_ARG_SRC , src_mem}, {DNNL_ARG_DST , dst_mem}});
94- stream_->wait ();
95-
96- output[0 ] = make_tensor (output_data, input_tensor.get_shape ());
97- }
98-
99- } catch (const std::exception& e) {
100- std::cerr << " oneDNN execution failed: " << e.what () << ' \n ' ;
101- throw ;
22+ if (type == Type::kFloat ) {
23+ const auto & src = *in.as <float >();
24+ std::vector<float > dst (src.size ());
25+
26+ dnnl::memory src_mem (memory_desc_, *engine_,
27+ const_cast <float *>(src.data ()));
28+ dnnl::memory dst_mem (memory_desc_, *engine_, dst.data ());
29+
30+ eltwise_prim_->execute (*stream_,
31+ {{DNNL_ARG_SRC , src_mem}, {DNNL_ARG_DST , dst_mem}});
32+
33+ stream_->wait ();
34+ output[0 ] = make_tensor (dst, in.get_shape ());
35+ } else if (type == Type::kInt ) {
36+ const auto & src = *in.as <int >();
37+ std::vector<int > dst (src.size ());
38+
39+ dnnl::memory src_mem (memory_desc_, *engine_, const_cast <int *>(src.data ()));
40+ dnnl::memory dst_mem (memory_desc_, *engine_, dst.data ());
41+
42+ eltwise_prim_->execute (*stream_,
43+ {{DNNL_ARG_SRC , src_mem}, {DNNL_ARG_DST , dst_mem}});
44+
45+ stream_->wait ();
46+ output[0 ] = make_tensor (dst, in.get_shape ());
10247 }
10348}
10449
@@ -110,74 +55,39 @@ void EwLayerOneDnn::validate_input(const std::vector<Tensor>& input) const {
11055 if (!is_function_supported (func_)) {
11156 throw std::invalid_argument (" Unsupported function for oneDNN: " + func_);
11257 }
113-
114- Type data_type = input[0 ].get_type ();
115- if (data_type != Type::kFloat && data_type != Type::kInt ) {
116- throw std::runtime_error (
117- " EwLayerOneDnn supports only float and int tensors" );
118- }
11958}
12059
12160void EwLayerOneDnn::initialize_onednn (const Shape& shape, Type data_type) {
122- try {
123- engine_ = std::make_unique<dnnl::engine>(dnnl::engine::kind::cpu, 0 );
124- stream_ = std::make_unique<dnnl::stream>(*engine_);
125-
126- std::vector<dnnl::memory::dim> dims;
127- for (size_t i = 0 ; i < shape.dims (); i++) {
128- dims.push_back (static_cast <dnnl::memory::dim>(shape.at (i)));
129- }
130-
131- dnnl::memory::format_tag format;
132- switch (dims.size ()) {
133- case 1 :
134- format = dnnl::memory::format_tag::a;
135- break ;
136- case 2 :
137- format = dnnl::memory::format_tag::ab;
138- break ;
139- case 3 :
140- format = dnnl::memory::format_tag::abc;
141- break ;
142- case 4 :
143- format = dnnl::memory::format_tag::abcd;
144- break ;
145- case 5 :
146- format = dnnl::memory::format_tag::abcde;
147- break ;
148- default :
149- throw std::invalid_argument (" Unsupported tensor dimensionality: " +
150- std::to_string (dims.size ()));
151- }
152-
153- dnnl::memory::data_type dnnl_data_type = get_dnnl_data_type (data_type);
154- memory_desc_ = dnnl::memory::desc (dims, dnnl_data_type, format);
155-
156- dnnl::algorithm algo = get_algorithm ();
157-
158- float primitive_alpha = 0 .0F ;
159- float primitive_beta = 0 .0F ;
160-
161- if (func_ == " relu" ) {
162- primitive_alpha = 0 .0F ;
163- } else if (func_ == " linear" ) {
164- primitive_alpha = alpha_;
165- primitive_beta = beta_;
166- }
167-
168- auto eltwise_pd = dnnl::eltwise_forward::primitive_desc (
169- *engine_, dnnl::prop_kind::forward_inference, algo, memory_desc_,
170- memory_desc_, primitive_alpha, primitive_beta);
171-
172- eltwise_prim_ = std::make_unique<dnnl::eltwise_forward>(eltwise_pd);
173-
174- initialized_ = true ;
175-
176- } catch (const std::exception& e) {
177- std::cerr << " oneDNN initialization failed for function '" << func_
178- << " ': " << e.what () << ' \n ' ;
179- throw ;
61+ engine_ = std::make_unique<dnnl::engine>(dnnl::engine::kind::cpu, 0 );
62+ stream_ = std::make_unique<dnnl::stream>(*engine_);
63+
64+ std::vector<dnnl::memory::dim> dims;
65+ for (size_t i = 0 ; i < shape.dims (); ++i) {
66+ dims.push_back (static_cast <dnnl::memory::dim>(shape.at (i)));
18067 }
68+
69+ auto format = pick_format (dims.size ());
70+ auto dnnl_type = get_dnnl_data_type (data_type);
71+
72+ memory_desc_ = dnnl::memory::desc (dims, dnnl_type, format);
73+
74+ float alpha = 0 .0f ;
75+ float beta = 0 .0f ;
76+
77+ if (func_ == " linear" ) {
78+ alpha = alpha_;
79+ beta = beta_;
80+ }
81+
82+ auto eltwise_pd = dnnl::eltwise_forward::primitive_desc (
83+ *engine_, dnnl::prop_kind::forward_inference, get_algorithm (),
84+ memory_desc_, memory_desc_, alpha, beta);
85+
86+ eltwise_prim_ = std::make_unique<dnnl::eltwise_forward>(eltwise_pd);
87+
88+ last_shape_ = shape;
89+ last_type_ = data_type;
90+ initialized_ = true ;
18191}
18292
18393dnnl::memory::data_type EwLayerOneDnn::get_dnnl_data_type (Type type) {
@@ -213,4 +123,22 @@ bool EwLayerOneDnn::is_function_supported(const std::string& function) {
213123 function == " linear" );
214124}
215125
126+ dnnl::memory::format_tag EwLayerOneDnn::pick_format (size_t ndims) {
127+ switch (ndims) {
128+ case 1 :
129+ return dnnl::memory::format_tag::a;
130+ case 2 :
131+ return dnnl::memory::format_tag::ab;
132+ case 3 :
133+ return dnnl::memory::format_tag::abc;
134+ case 4 :
135+ return dnnl::memory::format_tag::abcd;
136+ case 5 :
137+ return dnnl::memory::format_tag::abcde;
138+ default :
139+ throw std::invalid_argument (" Unsupported tensor dimensionality: " +
140+ std::to_string (ndims));
141+ }
142+ }
143+
216144} // namespace it_lab_ai
0 commit comments