Imported Upstream version 1.9.0
[platform/core/ml/nnfw.git] / runtime / onert / core / src / backend / controlflow / kernel / PermuteLayer.cc
1 /*
2  * Copyright (c) 2020 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 "PermuteLayer.h"
18
19 #include "exec/ShapeConverter.h"
20
21 namespace onert
22 {
23 namespace backend
24 {
25 namespace controlflow
26 {
27 namespace kernel
28 {
29
30 void PermuteLayer::run()
31 {
32   assert(_src_tensors.size() == _dst_tensors.size());
33   // PermuteLayer infers dynamic shape inside itself whenever run is called for the following
34   // reasons:
35   // 1. PermuteLayer has to access dynamic tensor manager for input/output tensors of other backends
36   // 2. Other controlflow operation(If/While) uses this layout for copying tensors of other
37   // subgraphs(with other backends)
38   // 3. This infering code is placed here to avoid duplicated code that can be caused by above 2
39   // reasons
40
41   // check if output is not dynamic
42   for (size_t i = 0; i < _src_tensors.size(); ++i)
43   {
44     auto dst_tensor = _dst_tensors.at(i);
45     auto src_tensor = _src_tensors.at(i);
46     if (src_tensor->is_dynamic() || dst_tensor->is_dynamic())
47     {
48       // getting output shape
49       auto src_shape = src_tensor->getShape();
50
51       // set output shape and output buffer
52       ir::Shape new_shape =
53           exec::convertShape(src_shape, src_tensor->layout(), dst_tensor->layout());
54
55       try
56       {
57         const auto dst_index = _dst_dyn_alloc_info_map.at(dst_tensor).ind;
58         auto dyn_tensor_manager = dst_tensor->dynamic_tensor_manager();
59         if (!dyn_tensor_manager)
60           throw std::runtime_error{
61               "Error: PermuteLayer: output's TensorManager does not support dynamic tensor"};
62         dyn_tensor_manager->applyShape(dst_index, new_shape);
63         assert(dst_tensor->buffer() != nullptr);
64       }
65       catch (const std::out_of_range &e)
66       {
67         std::cerr << "Error: out_of_range in PermuteLayer: output's TensorManager does not support "
68                      "dynamic tensor"
69                   << '\n';
70         throw;
71       }
72     }
73     assert(exec::convertShape(src_tensor->getShape(), src_tensor->layout(), dst_tensor->layout()) ==
74            dst_tensor->getShape());
75   }
76   IPermuteFunction::run();
77 }
78
79 } // namespace kernel
80 } // namespace controlflow
81 } // namespace backend
82 } // namespace onert