3c095b38cdeafc402c5f7d4ed9fd150abd4ed664
[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         _dst_dyn_alloc_info_map.at(dst_tensor).dyn_tensor_manager->applyShape(dst_index, new_shape);
59         assert(dst_tensor->buffer() != nullptr);
60       }
61       catch (const std::out_of_range &e)
62       {
63         std::cerr << "Error: out_of_range in PermuteLayer: output's TensorManager does not support "
64                      "dynamic tensor"
65                   << '\n';
66         throw;
67       }
68     }
69     assert(exec::convertShape(src_tensor->getShape(), src_tensor->layout(), dst_tensor->layout()) ==
70            dst_tensor->getShape());
71   }
72   IPermuteFunction::run();
73 }
74
75 } // namespace kernel
76 } // namespace controlflow
77 } // namespace backend
78 } // namespace onert