2 * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "NodeExecution.h"
19 #include "NodeDataImpl.h"
20 #include "NodeDomain.h"
21 #include "Validation.h"
23 #include <nncc/core/ADT/tensor/IndexEnumerator.h>
24 #include <nncc/core/ADT/tensor/LexicalLayout.h>
28 using nncc::core::ADT::tensor::Shape;
29 using nncc::core::ADT::tensor::Index;
30 using nncc::core::ADT::tensor::IndexEnumerator;
31 using nncc::core::ADT::tensor::LexicalLayout;
32 using nncc::core::ADT::tensor::make_buffer;
37 using namespace locomotiv;
39 void execute_node(loco::TensorConstantPad *pad)
41 validate(pad, "TensorConstantPad is nullptr");
43 auto input_data = annot_data(pad->input());
44 auto input_domain = annot_domain(pad->input());
45 validate(input_data, "Input not ready");
46 validate(input_domain == loco::Domain::Tensor, "Input domain of TensorConstantPad is not Tensor");
48 auto input_shape = input_data->shape();
49 const uint32_t input_rank = input_shape->rank();
51 auto padding = pad->padding();
52 validate(input_rank == padding->rank(), "input and padding should have same rank");
54 auto constant_node = pad->constant();
55 auto constant_data = annot_data(constant_node);
56 validate(constant_data->dtype() == input_data->dtype(), "constant and input have same data type");
57 validate(constant_data->shape()->rank() == 1 && constant_data->shape()->dim(0) == 1,
58 "constant should have one rank with one dimension at zero axis");
60 std::unique_ptr<NodeData> pad_data = nullptr;
62 base_index.resize(input_rank);
64 // Tensor is padded by relocating its base.
65 // padded output index = input index + base index
66 for (uint32_t axis = 0; axis < padding->rank(); axis++)
68 base_index.at(axis) = padding->front(axis);
71 // calculate output shape
73 output_shape.resize(input_rank);
74 for (uint32_t i = 0; i < input_rank; i++)
76 output_shape.dim(i) = input_shape->dim(i) + padding->front(i) + padding->back(i);
79 switch (input_data->dtype())
81 case loco::DataType::FLOAT32:
83 auto input_buf = input_data->as_f32_bufptr();
84 auto constant_data_buf = constant_data->as_f32_bufptr();
85 const auto constant_value = constant_data_buf->at(Index{0});
87 auto output_buf = make_buffer<float, LexicalLayout>(output_shape);
89 for (IndexEnumerator ie{*input_shape}, oe{output_shape}; oe.valid(); oe.advance())
91 auto input_index = ie.current();
92 auto output_index = oe.current();
94 if ((input_index + base_index) == output_index)
96 output_buf.at(output_index) = input_buf->at(input_index);
101 output_buf.at(output_index) = constant_value;
105 pad_data = make_data(output_buf);
109 throw std::runtime_error("NYI for this DataType");
112 assert(pad_data != nullptr);
113 annot_data(pad, std::move(pad_data));
114 annot_domain(pad, annot_domain(pad->input()));
122 void NodeExecution::execute(loco::TensorConstantPad *pad) { execute_node(pad); }
124 } // namespace locomotiv