Imported Upstream version 1.12.0
[platform/core/ml/nnfw.git] / runtime / onert / core / src / backend / controlflow / kernel / IfLayer.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 "IfLayer.h"
18
19 #include <backend/ITensor.h>
20 #include "exec/ExecutorBase.h"
21 #include "PermuteLayer.h"
22
23 namespace onert
24 {
25 namespace backend
26 {
27 namespace controlflow
28 {
29 namespace kernel
30 {
31
32 IfLayer::IfLayer(backend::IPortableTensor *cond_tensor,
33                  const std::vector<backend::IPortableTensor *> input_tensors,
34                  const std::vector<backend::IPortableTensor *> output_tensors,
35                  const ir::SubgraphIndex &then_subg_index, const ir::SubgraphIndex &else_subg_index,
36                  exec::ExecutorMap *executor_map,
37                  const std::shared_ptr<ExternalContext> &external_context)
38     : _cond_tensor{cond_tensor}, _input_tensors{input_tensors}, _output_tensors{output_tensors},
39       _then_subg_index{then_subg_index}, _else_subg_index{else_subg_index},
40       _executor_map{executor_map}, _external_context{external_context}
41 {
42   // At this point, executor_map may not have executors of then subg and else subg
43 }
44
45 void IfLayer::run()
46 {
47   // Check condition
48   // // If true
49   // // // Set _input_tensors -> then-subg's inputs
50   // // // Set outputs of then-subg -> _output_tensors
51   // // // Run then-subg
52   // // Else
53   // // // Set _input_tensors -> else-subg's inputs
54   // // // Set outputs of else-subg -> _output_tensors
55   // // // Run else-subg
56
57   auto getResultCond = [](backend::IPortableTensor *tensor) -> bool {
58     bool ret = false;
59     tensor->access([&](ITensor &tensor) { ret = *reinterpret_cast<bool *>(tensor.buffer()); });
60     return ret;
61   };
62
63   exec::IExecutor *subg_exec = nullptr;
64   bool cond_result = getResultCond(_cond_tensor);
65   if (cond_result)
66   {
67     VERBOSE(If) << "Call to $" << _then_subg_index << " (then)" << std::endl;
68     subg_exec = _executor_map->at(_then_subg_index).get();
69   }
70   else
71   {
72     VERBOSE(If) << "Call to $" << _else_subg_index << " (else)" << std::endl;
73     subg_exec = _executor_map->at(_else_subg_index).get();
74   }
75
76   subg_exec->execute(_input_tensors, _output_tensors);
77   VERBOSE(If) << "Return from $" << (cond_result ? _then_subg_index : _else_subg_index)
78               << std::endl;
79 }
80
81 } // namespace kernel
82 } // namespace controlflow
83 } // namespace backend
84 } // namespace onert