ONE - On-device Neural Engine
Loading...
Searching...
No Matches
onert::compiler::Compiler Class Referencefinal

Class to compile NN package. More...

#include <Compiler.h>

Collaboration diagram for onert::compiler::Compiler:

Public Member Functions

 Compiler (std::unique_ptr< ir::NNPkg > nnpkg, CompilerOptions *copts)
 Construct a new Compiler object for NN package.
 
 ~Compiler ()=default
 Destroy the Compiler object.
 
std::unique_ptr< CompilerArtifactcompile (void)
 Do compilation with the options.
 
- Public Member Functions inherited from onert::compiler::ICompiler
virtual ~ICompiler ()=default
 Virtual ICompiler destructor.
 

Detailed Description

Class to compile NN package.

Definition at line 35 of file Compiler.h.

Constructor & Destructor Documentation

◆ Compiler()

onert::compiler::Compiler::Compiler ( std::unique_ptr< ir::NNPkg nnpkg,
CompilerOptions copts 
)

Construct a new Compiler object for NN package.

Parameters
[in]nnpkgNN package to compile
[in]coptsCompiler option for package

Definition at line 41 of file Compiler.cc.

42 : _nnpkg{std::move(nnpkg)}, _options{copts}
43{
44 // DO NOTHING
45}

◆ ~Compiler()

onert::compiler::Compiler::~Compiler ( )
default

Destroy the Compiler object.

Member Function Documentation

◆ compile()

std::unique_ptr< CompilerArtifact > onert::compiler::Compiler::compile ( void  )
virtual

Do compilation with the options.

Returns
std::shared_ptr<CompilerArtifact> MultiModelExecutors as a result of compilation

Implements onert::compiler::ICompiler.

Definition at line 97 of file Compiler.cc.

98{
99 /***************************************************
100 * Prepare compilation phase
101 ***************************************************/
102 {
103 if (!_options)
104 throw std::runtime_error{"Empty compile option"};
105
106 // Mode check
107 // TODO handle option for each model
108 if (_options->he_profiling_mode)
109 {
110 if (!_options->he_scheduler)
111 throw std::runtime_error("Heterogeneous scheduler must be enabled during profiling.");
112
113 if (_options->executor != "Dataflow")
114 throw std::runtime_error("Profiling mode works only with 'Dataflow' executor");
115 }
116
117 _options->forceInternalOptions();
118 _options->verboseOptions();
119 }
120
121 // NYI: allow one model compilation
122 auto const model_count = _nnpkg->model_count();
123 for (uint16_t i = 0; i < model_count; i++)
124 {
125 if (!_nnpkg->model(ir::ModelIndex{i})->hasOnly<ir::Graph>())
126 throw std::runtime_error("Compiler can only compile models for inference.");
127 }
128
129 std::unordered_map<ir::ModelIndex, CompilerOptions> model_options;
130 for (uint16_t i = 0; i < model_count; i++)
131 {
132 auto model_index = ir::ModelIndex{i};
133 model_options[model_index] = optionForSingleModel(model_index);
134 _nnpkg->model(ir::ModelIndex{i})->iterate([&](const ir::SubgraphIndex &, ir::IGraph &graph) {
135 auto &subg = nnfw::misc::polymorphic_downcast<ir::Graph &>(graph);
136
137 // Mandatory passes
138 pass::PassRunner{}
139 .append(std::make_unique<pass::ConstantOutputPass>(subg))
140 .append(std::make_unique<pass::OddOutputPass>(subg))
141 .append(std::make_unique<pass::PermutationIOPass>(subg, model_options[model_index]))
142 .run();
143
144 // Optimizations
145 pass::PassRunner{}.append(std::make_unique<pass::UnusedOperandEliminationPass>(subg)).run();
146 });
147 }
148
149 /***************************************************
150 * Backend independent analysis & optimization phase
151 ***************************************************/
152 // TODO Handle dump level for each model
153 auto dump_level = static_cast<dumper::dot::DotDumper::Level>(_options->graph_dump_level);
154 onert::dumper::dot::DotDumper dot_dumper(dump_level);
155
156 // Tracing context
157 auto tracing_ctx = std::make_unique<util::TracingCtx>();
158
159 // Model edge context: copy model edge context
160 auto model_edges = std::make_unique<ir::ModelEdges>(_nnpkg->model_edges());
161
162 // Custom kernels
163 std::unordered_map<ir::ModelIndex, std::shared_ptr<backend::custom::IKernelBuilder>>
164 custom_kernel_builders;
165 for (uint16_t i = 0; i < model_count; i++)
166 {
167 auto const model_index = ir::ModelIndex{i};
168 custom_kernel_builders[model_index] = _nnpkg->model(model_index)->getKernelBuilder();
169 }
170
171 // Lower: Assign backend
172 std::unordered_map<ir::ModelIndex,
173 std::unordered_map<ir::SubgraphIndex, std::unique_ptr<compiler::LoweredGraph>>>
174 lowered_subgs;
175
176 for (uint16_t i = 0; i < model_count; i++)
177 {
178 auto const model_index = ir::ModelIndex{i};
179 auto model = _nnpkg->model(model_index);
180
181 model->iterate([&](const ir::SubgraphIndex &subg_index, ir::IGraph &graph) {
182 auto &subg = nnfw::misc::polymorphic_downcast<ir::Graph &>(graph);
183
184 dot_dumper.dump(subg,
185 nnfw::misc::str("before_lower_model-", i, "-subg-", subg_index.value()));
186 // Lower: Assign backend
187 lowered_subgs[model_index][subg_index] =
188 std::make_unique<compiler::LoweredGraph>(subg, model_options[model_index]);
189 // Set tracing_ctx for copied graph
190 tracing_ctx->setSubgraphIndex(&(lowered_subgs[model_index][subg_index]->graph()),
191 {model_index, subg_index});
192 });
193 }
194
195 _nnpkg.reset();
196
197 for (const auto &[model_index, model_lsubg] : lowered_subgs)
198 {
199 for (const auto &[subg_index, lowered_subg] : model_lsubg)
200 {
201 dot_dumper.dump(*lowered_subg, nnfw::misc::str("after_lower_model-", model_index.value(),
202 "-subg-", subg_index.value()));
203 }
204 }
205
206 // Shape inference.
207 for (auto &&pair : lowered_subgs)
208 {
209 auto &model_lsubgs = pair.second;
210 // Run the StaticShapeInfer of primary subg. All child StaticShapeInferers are called
211 // recursively
212 std::unordered_map<ir::SubgraphIndex, std::unique_ptr<StaticShapeInferer>> inferers =
213 createStaticShapeInferers(model_lsubgs);
214
215 const auto primary_subg_idx = ir::SubgraphIndex{0};
216 inferers.at(primary_subg_idx)->infer();
217
218 for (const auto &pair_inferer : inferers)
219 {
220 const auto inferer = pair_inferer.second.get();
221 inferer->dump();
222 }
223 }
224
225 // Shape validation
226 // TODO Move shape independent feature check from ShapeValidator to OperationValidator
227 // TODO Move ShapeValidator into shape inference
228 // - Check input tensor shape validation
229 // - Check parameter value validation which valid value is depend on input tensor shape
230 // - Output tensor shape validation check is needless because
231 // static/dynamic shape inferer will make valid output shape
232 for (const auto &pair : lowered_subgs)
233 {
234 const auto &model_lsubgs = pair.second;
235
236 for (const auto &pair_inner : model_lsubgs)
237 {
238 const auto &lowered_subg = pair_inner.second;
239 compiler::ShapeValidator{lowered_subg->graph()}();
240 }
241 }
242
243 /*************************************************************
244 * Backend independent analysis & optimization phase finished
245 *************************************************************/
246 std::shared_ptr<exec::IExecutors> executors = nullptr;
247 const auto &pkg_outputs = model_edges->pkg_outputs;
248 if (model_count == 1)
249 executors = std::make_shared<exec::SingleModelExecutors>();
250 else
251 executors = std::make_shared<exec::MultiModelExecutors>(std::move(model_edges));
252
253 for (auto &&pair : lowered_subgs)
254 {
255 auto const &model_index = pair.first;
256 auto &model_lsubgs = pair.second;
257
258 for (auto &&pair_inner : model_lsubgs)
259 {
260 auto const subg_index = pair_inner.first;
261 auto &lowered_subg = pair_inner.second;
262 auto const indexed_ranks = lowered_subg->indexed_ranks();
263
264 ir::OperationDumper dumper("Executor generation of Subgraph " +
265 std::to_string(subg_index.value()));
266 lowered_subg->graph().operations().iterate(
267 [&](const ir::OperationIndex &, const ir::IOperation &op) { op.accept(dumper); });
268
269 ExecutorFactoryArgs args;
270 args.tracing_ctx = tracing_ctx.get();
271 args.options = &model_options[model_index];
272 args.model_index = model_index;
273 args.custom_kernel_builder = custom_kernel_builders[model_index];
274 if (_options->internal_output_alloc)
275 {
276 for (const auto &desc : pkg_outputs)
277 {
278 // Only outputs of this entry
279 if (const auto &[m, s, io] = desc; m == model_index && s == subg_index)
280 {
281 // Map IOIndex to OperandIndex
282 auto idx = lowered_subg->graph().getOutputs().at(io);
283 args.internal_io_indexes.add(idx);
284 }
285 }
286 }
287 auto executor = std::unique_ptr<exec::IExecutor>{
288 ExecutorFactory::get().create(std::move(lowered_subg), executors, args)};
289 executor->setIndexedRanks(indexed_ranks);
290 executors->emplace(model_index, subg_index, std::move(executor));
291 }
292 }
293
294 /********************************
295 * Code generation phase finished
296 ********************************/
297 return std::make_unique<CompilerArtifact>(executors, std::move(tracing_ctx));
298}
exec::IExecutor * create(std::unique_ptr< compiler::LoweredGraph > lowered_graph, const std::shared_ptr< exec::IExecutors > &executors, const ExecutorFactoryArgs &args)
static ExecutorFactory & get()
args
Definition infer.py:21
IndexIterator iterate(const Shape &shape)
Create an object of IndexIterator for kernel.
std::string str(Args &&...args)
::onert::util::Index< uint32_t, OperationIndexTag > OperationIndex
Definition Index.h:30
::onert::util::Index< uint16_t, ModelIndexTag > ModelIndex
Definition Index.h:42
::onert::util::Index< uint16_t, SubgraphIndexTag > SubgraphIndex
Definition Index.h:39
void forceInternalOptions()
Force default values of CompilerOptions for correct compilations.
void verboseOptions()
Print option value.
virtual void setIndexedRanks(std::shared_ptr< ir::OperationIndexMap< int64_t > >)=0
Set an ordering on operations.

References onert::ir::IOperation::accept(), onert::compiler::pass::PassRunner::append(), onert::compiler::ExecutorFactory::create(), onert::dumper::dot::DotDumper::dump(), onert::compiler::CompilerOptions::executor, onert::compiler::CompilerOptions::forceInternalOptions(), onert::compiler::ExecutorFactory::get(), onert::compiler::CompilerOptions::graph_dump_level, onert::compiler::CompilerOptions::he_profiling_mode, onert::compiler::CompilerOptions::he_scheduler, onert::compiler::CompilerOptions::internal_output_alloc, m, onert::compiler::pass::PassRunner::run(), onert::exec::IExecutor::setIndexedRanks(), nnfw::misc::str(), onert::util::Index< T, DummyTag >::value(), and onert::compiler::CompilerOptions::verboseOptions().


The documentation for this class was generated from the following files: