Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / runtime / onert / backend / gpu_cl / BackendContext.cc
1 /*
2  * Copyright (c) 2021 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 "BackendContext.h"
18
19 #include "ConstantInitializer.h"
20 #include "TensorBuilder.h"
21 #include "KernelGenerator.h"
22
23 #include "util/logging.h"
24 #include "ir/Index.h"
25 #include "ir/Operations.h"
26 #include "ir/OperandIndexMap.h"
27 #include "ir/OperandIndexSequence.h"
28
29 namespace onert
30 {
31 namespace backend
32 {
33 namespace gpu_cl
34 {
35
36 void BackendContext::registerTensorInfo(const ir::OperandIndex &ind, const ir::OperandInfo &info,
37                                         ir::Layout backend_layout)
38 {
39   TensorType type = TensorType::TENSOR_TYPE_VALID;
40   tensor_builder->registerTensorInfo(ind, info, backend_layout, type);
41 }
42
43 ITensorRegistry *BackendContext::genTensors()
44 {
45   ir::OperandIndexMap<TensorType> type_map;
46
47   for (const auto &ind : graph()->getInputs())
48   {
49     type_map[ind] = TensorType::TENSOR_TYPE_INPUT;
50   }
51
52   for (const auto &ind : graph()->getOutputs())
53   {
54     type_map[ind] = TensorType::TENSOR_TYPE_OUTPUT;
55   }
56   graph()->operands().iterate([&](const ir::OperandIndex &ind, const ir::Operand &obj) {
57     if (external_operands().contains(ind))
58       return;
59
60     const auto frontend_layout = graph()->layout();
61     const auto backend_layout = operand_layouts().at(ind);
62     ir::OperandInfo backend_info{permuteShape(obj.shape(), frontend_layout, backend_layout),
63                                  obj.typeInfo(), obj.info().memAllocType(), obj.isConstant()};
64     if (obj.isConstant())
65     {
66       type_map[ind] = TensorType::TENSOR_TYPE_INPUT;
67     }
68     tensor_builder->registerTensorInfo(ind, backend_info, backend_layout, type_map[ind]);
69   });
70
71   // TODO Get compiler options from compiler, and use it rather than getting it from Env
72   if (util::getConfigString(util::config::EXECUTOR) == "Linear")
73   {
74     planTensors();
75   }
76   else
77   {
78     // For the executors that does not have fixed linear execution order:
79     // To make tensors never be deallocated, this is a workaround to use static memory planner
80     graph()->operands().iterate([&](const ir::OperandIndex &ind, const ir::Operand &) {
81       if (tensor_builder->isRegistered(ind))
82         tensor_builder->notifyFirstUse(ind);
83     });
84   }
85   tensor_builder->prepare();
86   return tensor_registry.get();
87 }
88
89 FunctionMap BackendContext::genKernels()
90 {
91   FunctionMap fn_map;
92
93   for (auto &&op_ind : _data.op_order)
94   {
95     auto fn_seq = kernel_gen->generate(op_ind);
96     fn_map.emplace_back(op_ind, std::move(fn_seq));
97   }
98
99   kernel_gen->get_operation(fn_map);
100   tensor_builder->allocate();
101   // NOTE For memory optimization, we want to free some operand data
102   const_cast<ir::Graph &>(*_data.graph)
103     .operands()
104     .iterate([&](const ir::OperandIndex &, ir::Operand &obj) { obj.releaseData(); });
105
106   for (auto &&it : fn_map)
107   {
108     auto &fn_seq = it.second;
109     fn_seq->iterate([&](exec::IFunction &ifunc) { ifunc.prepare(); });
110   }
111
112   return fn_map;
113 }
114
115 } // namespace gpu_cl
116 } // namespace backend
117 } // namespace onert