#include "MultiModelCompiler.h"
+#include "CompilerHelpers.h"
#include "ExecutorFactory.h"
#include "ShapeValidator.h"
#include "pass/ConstantOutputPass.h"
#include "compiler/StaticShapeInferer.h"
#include <misc/string_helpers.h>
+#include <misc/polymorphic_downcast.h>
namespace onert
{
/***************************************************
* Prepare compilation phase
***************************************************/
- for (auto options : _voptions)
+ for (auto &&options : _voptions)
{
if (!options)
throw std::runtime_error{"Empty compile option"};
if (options->he_profiling_mode)
throw std::runtime_error("NYI: Profiling mode for multiple model is not supported yet");
+ if (!options->minmax_filepath.empty())
+ throw std::runtime_error("Recording minmax is not supported for multiple models");
+
options->forceInternalOptions();
options->verboseOptions();
}
for (uint16_t i = 0; i < model_count; i++)
{
- _nnpkg->model(ir::ModelIndex{i})->iterate([&](const ir::SubgraphIndex &, ir::Graph &subg) {
+ if (!_nnpkg->model(ir::ModelIndex{i})->hasOnly<ir::Graph>())
+ throw std::runtime_error("MultiModelCompiler can only compile models for inference.");
+ }
+
+ for (uint16_t i = 0; i < model_count; i++)
+ {
+ _nnpkg->model(ir::ModelIndex{i})->iterate([&](const ir::SubgraphIndex &, ir::IGraph &graph) {
+ auto &subg = nnfw::misc::polymorphic_downcast<ir::Graph &>(graph);
+
// Mandatory passes
pass::PassRunner{}
.append(std::make_unique<pass::ConstantOutputPass>(subg))
// Model edge context: copy model edge context
auto model_edges = std::make_unique<ir::ModelEdges>(_nnpkg->model_edges());
+ // Custom kernels
+ std::unordered_map<ir::ModelIndex, std::shared_ptr<backend::custom::IKernelBuilder>>
+ custom_kernel_builders;
+ for (uint16_t i = 0; i < model_count; i++)
+ {
+ auto const model_index = ir::ModelIndex{i};
+ custom_kernel_builders[model_index] = _nnpkg->model(model_index)->getKernelBuilder();
+ }
+
// Lower: Assign backend
std::unordered_map<ir::ModelIndex,
std::unordered_map<ir::SubgraphIndex, std::unique_ptr<compiler::LoweredGraph>>>
auto const model_index = ir::ModelIndex{i};
auto model = _nnpkg->model(model_index);
- model->iterate([&](const ir::SubgraphIndex &subg_index, ir::Graph &subg) {
+ model->iterate([&](const ir::SubgraphIndex &subg_index, ir::IGraph &graph) {
+ auto &subg = nnfw::misc::polymorphic_downcast<ir::Graph &>(graph);
+
dot_dumper.dump(subg,
nnfw::misc::str("before_lower_model-", i, "-subg-", subg_index.value()));
// Lower: Assign backend
// Run the StaticShapeInfer of primary subg. All child StaticShapeInferers are called
// recursively
std::unordered_map<ir::SubgraphIndex, std::unique_ptr<StaticShapeInferer>> inferers =
- StaticShapeInferer::createStaticShapeInferers(model_lsubgs);
+ createStaticShapeInferers(model_lsubgs);
const auto primary_subg_idx = ir::SubgraphIndex{0};
inferers.at(primary_subg_idx)->infer();
ir::OperationDumper dumper("Executor generation of Subgraph " +
std::to_string(subg_index.value()));
lowered_subg->graph().operations().iterate(
- [&](const ir::OperationIndex &, const ir::Operation &op) { op.accept(dumper); });
-
- auto &options = *_voptions[model_index.value()];
- auto executor = std::unique_ptr<exec::IExecutor>{ExecutorFactory::get().create(
- std::move(lowered_subg), tracing_ctx.get(), options, executors, model_index)};
+ [&](const ir::OperationIndex &, const ir::IOperation &op) { op.accept(dumper); });
+
+ ExecutorFactoryArgs args;
+ args.tracing_ctx = tracing_ctx.get();
+ args.options = _voptions[model_index.value()];
+ args.model_index = model_index;
+ args.custom_kernel_builder = custom_kernel_builders[model_index];
+ auto executor = std::unique_ptr<exec::IExecutor>{
+ ExecutorFactory::get().create(std::move(lowered_subg), executors, args)};
executor->setIndexedRanks(indexed_ranks);
executors->emplace(model_index, subg_index, std::move(executor));
}