Imported Upstream version 1.9.0
[platform/core/ml/nnfw.git] / compiler / locomotiv / src / Node / BiasAdd.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "NodeExecution.h"
18
19 #include "NodeDataImpl.h"
20 #include "NodeDomain.h"
21 #include "Validation.h"
22
23 #include <nncc/core/ADT/tensor/Shape.h>
24 #include <nncc/core/ADT/tensor/Buffer.h>
25 #include <nncc/core/ADT/tensor/IndexEnumerator.h>
26 #include <nncc/core/ADT/tensor/LexicalLayout.h>
27
28 using nncc::core::ADT::tensor::IndexEnumerator;
29 using nncc::core::ADT::tensor::LexicalLayout;
30 using nncc::core::ADT::tensor::make_buffer;
31
32 #include <cassert>
33 #include <stdexcept>
34
35 namespace
36 {
37 using locomotiv::NodeData;
38
39 std::unique_ptr<NodeData> calc(const NodeData *input_data, const NodeData *bias_data,
40                                uint32_t axis);
41
42 } // namespace
43
44 namespace
45 {
46
47 using namespace locomotiv;
48
49 void execute_node(loco::BiasAdd<loco::Domain::Tensor> *bias_add)
50 {
51   validate(bias_add, "BiasAdd is nullptr");
52
53   auto input_data = locomotiv::annot_data(bias_add->value());
54   auto bias_data = locomotiv::annot_data(bias_add->bias());
55
56   validate(input_data && bias_data, "Input not ready");
57   validate(locomotiv::annot_domain(bias_add->value()) == loco::Domain::Tensor &&
58                locomotiv::annot_domain(bias_add->bias()) == loco::Domain::Bias,
59            "Wrong input domain");
60
61   std::unique_ptr<NodeData> bias_add_data = calc(input_data, bias_data, bias_add->axis());
62
63   assert(bias_add_data != nullptr);
64   annot_data(bias_add, std::move(bias_add_data));
65   annot_domain(bias_add, annot_domain(bias_add->value()));
66 }
67
68 void execute_node(loco::BiasAdd<loco::Domain::Feature> *bias_add)
69 {
70   validate(bias_add, "BiasAdd is nullptr");
71
72   auto input_data = locomotiv::annot_data(bias_add->value());
73   auto bias_data = locomotiv::annot_data(bias_add->bias());
74
75   validate(input_data && bias_data, "Input not ready");
76   validate(locomotiv::annot_domain(bias_add->value()) == loco::Domain::Feature &&
77                locomotiv::annot_domain(bias_add->bias()) == loco::Domain::Bias,
78            "Wrong input domain");
79
80   std::unique_ptr<NodeData> bias_add_data = calc(input_data, bias_data, 3);
81
82   assert(bias_add_data != nullptr);
83   annot_data(bias_add, std::move(bias_add_data));
84   annot_domain(bias_add, loco::Domain::Feature);
85 }
86
87 } // namespace
88
89 namespace
90 {
91 using locomotiv::NodeData;
92 using locomotiv::validate;
93 using locomotiv::make_data;
94
95 std::unique_ptr<NodeData> calc(const NodeData *input_data, const NodeData *bias_data, uint32_t axis)
96 {
97   validate(input_data->shape()->dim(axis) == bias_data->shape()->dim(0), "Bias size mismatch");
98
99   std::unique_ptr<NodeData> bias_add_data = nullptr;
100
101   switch (input_data->dtype())
102   {
103     case loco::DataType::FLOAT32:
104     {
105       auto input_bufptr = input_data->as_f32_bufptr();
106       auto bias_bufptr = bias_data->as_f32_bufptr();
107       auto bias_add_buf = make_buffer<float, LexicalLayout>(*input_data->shape());
108
109       auto *shape = input_data->shape();
110
111       for (IndexEnumerator e{*shape}; e.valid(); e.advance())
112       {
113         const auto &index = e.current();
114         nncc::core::ADT::tensor::Index bias_index({index.at(axis)});
115         bias_add_buf.at(index) = input_bufptr->at(index) + bias_bufptr->at(bias_index);
116       }
117
118       bias_add_data = make_data(bias_add_buf);
119       break;
120     }
121     default:
122       throw std::runtime_error("NYI for this DataType");
123   }
124   return bias_add_data;
125 }
126
127 } // namespace
128
129 namespace locomotiv
130 {
131
132 void NodeExecution::execute(loco::BiasAdd<loco::Domain::Tensor> *bias_add)
133 {
134   execute_node(bias_add);
135 }
136
137 void NodeExecution::execute(loco::BiasAdd<loco::Domain::Feature> *bias_add)
138 {
139   execute_node(bias_add);
140 }
141
142 } // namespace locomotiv