44#define MAX_BACKEND_NAME_LENGTH 32
45#define MAX_OP_NAME_LENGTH 64
46#define MAX_PATH_LENGTH 1024
47#define MAX_TENSOR_NAME_LENGTH 64
53bool null_terminating(
const char *str, uint32_t length)
55 for (uint32_t i = 0; i < length; i++)
57 if (*(str + i) ==
'\0')
79 uint32_t *index,
bool is_input)
81 if (!tensorname || !index)
86 std::cerr <<
"nnpackage path is too long" << std::endl;
90 auto ind_found = is_input ? graph.getInputIndex(tensorname) : graph.getOutputIndex(tensorname);
92 if (ind_found.undefined())
99 *index = ind_found.value();
104std::string trim(
const std::string &value)
106 std::string whitespace =
" \t";
107 auto begin = value.find_first_not_of(whitespace);
108 if (
begin == std::string::npos)
111 auto end = value.find_last_not_of(whitespace);
112 auto range = end -
begin + 1;
113 return value.substr(
begin, range);
118 std::ifstream ifs(cfgfile);
122 while (std::getline(ifs, line))
124 auto cmtpos = line.find(
'#');
125 if (cmtpos != std::string::npos)
127 line = line.substr(0, cmtpos);
129 std::istringstream isline(line);
131 if (std::getline(isline, key,
'='))
134 if (std::getline(isline, value))
137 keyValues[key] = trim(value);
152 case DataType::FLOAT32:
154 case DataType::INT32:
156 case DataType::QUANT_UINT8_ASYMM:
158 case DataType::BOOL8:
160 case DataType::UINT8:
162 case DataType::INT64:
164 case DataType::QUANT_INT8_ASYMM:
166 case DataType::QUANT_INT16_SYMM:
168 case DataType::UINT32:
169 case DataType::QUANT_INT8_SYMM:
171 throw std::runtime_error(
"Error: Model has type that runtime API does not support.");
178 ti->
rank = shape.rank();
179 for (
int j = 0; j < ti->
rank; ++j)
181 ti->
dims[j] = shape.dim(j);
183 ti->
dtype = datatype_to_nnfw_dtype(dtype);
186std::unique_ptr<onert::ir::Model> loadModel(
const std::string filename,
187 const std::string model_type)
191 if (model_type ==
"tflite")
193 if (model_type ==
"circle")
198 catch (
const std::exception &e)
200 std::cerr <<
"Fail to load model: " << e.what() <<
'\n';
203 return std::unique_ptr<onert::ir::Model>(
nullptr);
206std::unique_ptr<onert::ir::train::TrainingInfo>
207loadTrainingInfo(
const std::shared_ptr<onert::ir::Model> &model)
210 if (model->exists_metadata(tinfo_name))
212 const auto buffer = model->extract_metadata(tinfo_name);
215 return std::make_unique<onert::ir::train::TrainingInfo>();
220 static int elmsize[] = {
232 for (int32_t i = 0; i <
info->rank; ++i)
234 assert(
info->dims[i] >= 0);
237 return elmsize[
info->dtype] * n;
241nnfw_session::nnfw_session()
242 : _nnpkg{nullptr}, _coptions{
onert::compiler::CompilerOptions::fromGlobalConfig()},
243 _compiler_artifact{nullptr}, _execution{nullptr}, _kernel_registry{nullptr},
244 _train_info{nullptr}, _quant_manager{
std::make_unique<
onert::odc::QuantizeManager>()},
245 _codegen_manager{
std::make_unique<
onert::odc::CodegenManager>()}, _model_path{}
252 if (session ==
nullptr)
256 auto new_session = std::unique_ptr<nnfw_session>(
new nnfw_session());
257 new_session->_kernel_registry = std::make_shared<onert::api::CustomKernelRegistry>();
258 *
session = new_session.release();
260 catch (
const std::bad_alloc &e)
262 std::cerr <<
"Error during session creation" << std::endl;
266 catch (
const std::exception &e)
268 std::cerr <<
"Error during session initialization : " << e.what() << std::endl;
279 if (!isStateInitialized())
292 _nnpkg = std::make_shared<onert::ir::NNPkg>(std::move(model));
293 _train_info = loadTrainingInfo(_nnpkg->primary_model());
294 _state = State::MODEL_LOADED;
296 catch (
const std::exception &e)
298 std::cerr <<
"Error during model loading : " << e.what() << std::endl;
306 if (!isStateInitialized())
311 std::cerr <<
"Path is null." << std::endl;
317 std::cerr <<
"Path is too long" << std::endl;
323 std::filesystem::path filename{path};
324 if (!std::filesystem::is_directory(filename) && filename.has_extension())
326 std::string model_type = filename.extension().string().substr(1);
327 return loadModelFile(filename, model_type);
330 const auto &package_dir = filename;
333 if (!std::filesystem::is_directory(package_dir))
335 std::cerr <<
"invalid path: " << package_dir << std::endl;
339 const auto manifest_file_name = package_dir /
"metadata/MANIFEST";
340 std::ifstream mfs(manifest_file_name);
346 const Json::Value &models = root[
"models"];
347 const Json::Value &model_types = root[
"model-types"];
348 const Json::Value &configs = root[
"configs"];
350 if (!configs.empty() && !configs[0].empty())
352 const auto filepath = package_dir /
"metadata" / configs[0].asString();
355 if (loadConfigure(filepath.string(), keyValues))
360 _nnpkg = std::make_shared<onert::ir::NNPkg>();
361 auto num_models = models.size();
364 std::cerr <<
"Invalid model size - " << std::to_string(num_models) << std::endl;
370 if (num_models > 1 && _coptions->manual_scheduler_options.index_to_backend.size() != 0)
372 std::cerr <<
"Cannot set backend to operator index for multiple models" << std::endl;
376 for (uint16_t i = 0; i < num_models; ++i)
378 const auto model_file_path = package_dir / models[i].asString();
379 const auto model_type = model_types[i].asString();
380 auto model = loadModel(model_file_path.string(), model_type);
381 if (model ==
nullptr)
383 _model_path = model_file_path;
384 model->bindKernelBuilder(_kernel_registry->getBuilder());
388 _train_info = loadTrainingInfo(_nnpkg->primary_model());
390 auto toIODesc = [](std::string str) {
392 if (indices.size() != 3)
394 std::cerr <<
"IODesc should be 3-tuple." << std::endl;
397 auto model_idx =
static_cast<uint32_t
>(std::stoi(indices.at(0)));
398 auto subgraph_idx =
static_cast<uint32_t
>(std::stoi(indices.at(1)));
399 auto operand_idx =
static_cast<uint32_t
>(std::stoi(indices.at(2)));
403 const Json::Value &pkg_inputs = root[
"pkg-inputs"];
404 for (uint32_t i = 0; i < pkg_inputs.size(); ++i)
405 _nnpkg->addInput(toIODesc(pkg_inputs[i].asString()));
406 const Json::Value &pkg_outputs = root[
"pkg-outputs"];
407 for (uint32_t i = 0; i < pkg_outputs.size(); ++i)
408 _nnpkg->addOutput(toIODesc(pkg_outputs[i].asString()));
410 const Json::Value &fromtos = root[
"model-connect"];
411 for (uint32_t i = 0; i < fromtos.size(); ++i)
413 const Json::Value &tos = fromtos[i][
"to"];
414 for (uint32_t j = 0; j < tos.size(); ++j)
415 _nnpkg->addEdge(toIODesc(fromtos[i][
"from"].asString()), toIODesc(tos[j].asString()));
419 _state = State::MODEL_LOADED;
421 catch (
const std::exception &e)
423 std::cerr <<
"Error during model loading : " << e.what() << std::endl;
432 if (!isStateModelLoaded())
434 std::cerr <<
"Error during model prepare : ";
435 if (isStateInitialized())
437 std::cerr <<
"prepare should be run once";
441 std::cerr <<
"invalid state";
443 std::cerr << std::endl;
451 _compiler_artifact = compiler->compile();
452 _execution = std::make_unique<onert::exec::Execution>(_compiler_artifact->_executors);
454 catch (
const std::exception &e)
456 std::cerr <<
"Error during model prepare : " << e.what() << std::endl;
460 _state = State::PREPARED;
466 if (!isStatePreparedOrFinishedRun())
468 std::cerr <<
"Error during nnfw_session::run : "
469 <<
"run should be run after prepare" << std::endl;
475 _execution->execute();
480 std::cerr <<
"Error during nnfw_session::run : " << e.
what() << std::endl;
483 catch (
const std::exception &e)
485 std::cerr <<
"Error during nnfw_session::run : " << e.
what() << std::endl;
489 _state = State::FINISHED_RUN;
495 if (!isStatePreparedOrFinishedRun())
497 std::cerr <<
"Error during nnfw_session::run_async : "
498 <<
"run_async should be run after prepare" << std::endl;
502 _execution->startExecute();
504 _state = State::RUNNING;
510 if (!isStateRunning())
512 std::cerr <<
"Error during nnfw_session::run_await : "
513 <<
"run_await should be run after run_async" << std::endl;
517 _execution->waitFinish();
519 _state = State::FINISHED_RUN;
526 if (!isStatePreparedOrFinishedRun())
528 std::cerr <<
"Error during nnfw_session::set_input : invalid state" << std::endl;
532 if (!buffer && length != 0)
535 <<
"Error during nnfw_session::set_input : given buffer is NULL but the length is not 0"
548 catch (
const std::exception &e)
550 std::cerr <<
"Error during nnfw_session::set_input : " << e.what() << std::endl;
558 if (!isStatePreparedOrFinishedRun())
560 std::cerr <<
"Error during nnfw_session::set_output : invalid state" << std::endl;
564 if (!buffer && length != 0)
567 <<
"Error during nnfw_session::set_output : given buffer is NULL but the length is not 0"
580 catch (
const std::exception &e)
582 std::cerr <<
"Error during nnfw_session::set_output : " << e.what() << std::endl;
590 if (isStateInitialized())
595 if (number ==
nullptr)
597 std::cerr <<
"Error during nnfw_session::input_size, number is null pointer." << std::endl;
600 *number = getInputSize();
602 catch (
const std::exception &e)
604 std::cerr <<
"Error during nnfw_session::input_size : " << e.what() << std::endl;
612 if (isStateInitialized())
617 if (number ==
nullptr)
619 std::cerr <<
"Error during nnfw_session::output_size, number is null pointer." << std::endl;
622 *number = getOutputSize();
624 catch (
const std::exception &e)
626 std::cerr <<
"Error during nnfw_session::output_size" << e.what() << std::endl;
634 if (!isStatePreparedOrFinishedRun())
636 std::cerr <<
"Error during nnfw_session::set_input_layout : "
637 <<
"run should be run after prepare" << std::endl;
646 std::cerr <<
"Error during nnfw_session::set_input_layout, not supported layout" << std::endl;
652 catch (
const std::exception &e)
654 std::cerr <<
"Error during nnfw_session::set_input_layout : " << e.what() << std::endl;
662 if (!isStatePreparedOrFinishedRun())
664 std::cerr <<
"Error during nnfw_session::set_output_layout : "
665 <<
"run should be run after prepare" << std::endl;
674 std::cerr <<
"Error during nnfw_session::set_output_layout, not supported layout"
681 catch (
const std::exception &e)
683 std::cerr <<
"Error during nnfw_session::set_output_layout : " << e.what() << std::endl;
693 if (isStateInitialized())
695 std::cerr <<
"Error during set_input_tensorinfo : should be run after load_model"
702 std::cerr <<
"Error during nnfw_session::set_input_tensorinfo : tensorinfo is null"
709 std::cerr <<
"unsupported rank: " << ti->
rank << std::endl;
713 for (int32_t i = 0; i < ti->
rank; ++i)
715 if (ti->
dims[i] <= 0)
717 std::cerr <<
"dim must be positive integer but was " << ti->
dims[i] << std::endl;
724 for (int32_t i = 0; i < ti->
rank; i++)
725 new_shape.dim(i) = ti->
dims[i];
727 if (!isStatePreparedOrFinishedRun())
731 _nnpkg->changeInputShape(index, new_shape);
741 if (isStateInitialized())
748 std::cerr <<
"Error during nnfw_session::input_tensorinfo, tensorinfo is null pointer."
753 if (index >= getInputSize())
755 std::cerr <<
"Error during nnfw_session::input_tensorinfo, index is out of range."
760 if (isStateModelLoaded())
762 auto info = _nnpkg->inputInfo(index);
763 fillTensorInfo(ti,
info.shape(),
info.typeInfo().type());
768 auto shape = _execution->getInputShape(io_index);
769 auto dtype = _compiler_artifact->_executors->inputInfo(io_index).typeInfo().type();
770 fillTensorInfo(ti, shape, dtype);
773 catch (
const std::exception &e)
775 std::cerr <<
"Error during nnfw_session::input_tensorinfo : " << e.what() << std::endl;
783 if (isStateInitialized())
788 std::cerr <<
"Error during nnfw_session::output_tensorinfo, tensorinfo is null pointer."
795 if (index >= getOutputSize())
797 std::cerr <<
"Error during nnfw_session::output_tensorinfo, index is out of range."
802 if (isStateModelLoaded())
804 auto info = _nnpkg->outputInfo(index);
805 fillTensorInfo(ti,
info.shape(),
info.typeInfo().type());
810 auto shape = _execution->getOutputShape(io_index);
811 auto dtype = _compiler_artifact->_executors->outputInfo(io_index).typeInfo().type();
812 fillTensorInfo(ti, shape, dtype);
815 catch (
const std::exception &e)
817 std::cerr <<
"Error during nnfw_session::output_tensorinfo : " << e.what() << std::endl;
827 _kernel_registry->registerKernel(
id, eval_func);
833 if (!isStateModelLoaded())
847 catch (
const std::exception &e)
849 std::cerr <<
"Error during nnfw_session::set_available_backends : " << e.what() << std::endl;
862 if (!isStateInitialized())
865 _coptions->workspace_dir = std::string(dir);
872 std::cerr << msg << std::endl;
878 if (!isStateModelLoaded())
886 const std::string skey = key;
888 if (skey == config::GRAPH_DOT_DUMP)
890 _coptions->graph_dump_level = toInt(value);
892 else if (skey == config::EXECUTOR)
894 _coptions->executor = value;
896 else if (skey == config::OP_BACKEND_ALLOPS)
898 _coptions->manual_scheduler_options.backend_for_all = value;
900 else if (skey == config::USE_SCHEDULER)
902 _coptions->he_scheduler = toBool(value);
904 else if (skey == config::PROFILING_MODE)
906 _coptions->he_profiling_mode = toBool(value);
917 if (_nnpkg !=
nullptr)
919 assert(_execution ==
nullptr);
920 return _nnpkg->primary_model()->primary_subgraph().get();
924 assert(_execution !=
nullptr);
926 return &_execution->primary_subgraph();
930uint32_t nnfw_session::getInputSize()
932 if (isStateInitialized())
933 throw std::runtime_error{
"Model is not loaded yet"};
935 if (isStateModelLoaded())
936 return _nnpkg->inputSize();
939 return _compiler_artifact->_executors->inputSize();
942uint32_t nnfw_session::getOutputSize()
944 if (isStateInitialized())
945 throw std::runtime_error{
"Model is not loaded yet"};
947 if (isStateModelLoaded())
948 return _nnpkg->outputSize();
951 return _compiler_artifact->_executors->outputSize();
954NNFW_STATUS nnfw_session::loadModelFile(
const std::string &model_file_path,
955 const std::string &model_type)
958 if (model ==
nullptr)
961 _nnpkg = std::make_shared<onert::ir::NNPkg>(std::move(model));
962 _model_path = std::filesystem::path(model_file_path);
963 _compiler_artifact.reset();
965 _train_info = loadTrainingInfo(_nnpkg->primary_model());
966 _state = State::MODEL_LOADED;
973 if (!isStateModelLoaded())
979 auto check_boundary = [](
size_t dest_size, std::string &src) {
980 if (dest_size < src.length() + 1 )
982 std::cerr <<
"buffer is small to copy config value." << std::endl;
988 const std::string skey = key;
990 if (skey == onert::util::config::BACKENDS)
992 if (_coptions->backend_list.size() == 0)
996 nnfw::misc::join(_coptions->backend_list.begin(), _coptions->backend_list.end(),
";");
998 if (!check_boundary(value_size, str))
1001 strncpy(value, str.c_str(), value_size);
1003 else if (skey == onert::util::config::EXECUTOR)
1005 if (!check_boundary(value_size, _coptions->executor))
1008 strncpy(value, _coptions->executor.c_str(), _coptions->executor.length());
1018bool nnfw_session::isStateInitialized()
1020 if (_state == State::INITIALIZED)
1022 assert(_nnpkg ==
nullptr);
1023 assert(_execution ==
nullptr);
1032bool nnfw_session::isStateModelLoaded()
1034 if (_state == State::MODEL_LOADED)
1036 assert(_nnpkg !=
nullptr);
1037 assert(_execution ==
nullptr);
1046bool nnfw_session::isStatePrepared()
1048 if (_state == State::PREPARED)
1050 assert(_nnpkg ==
nullptr);
1051 assert(_execution !=
nullptr);
1060bool nnfw_session::isStateRunning()
1062 if (_state == State::RUNNING)
1064 assert(_nnpkg ==
nullptr);
1065 assert(_execution !=
nullptr);
1071bool nnfw_session::isStateFinishedRun()
1073 if (_state == State::FINISHED_RUN)
1075 assert(_nnpkg ==
nullptr);
1076 assert(_execution !=
nullptr);
1085bool nnfw_session::isStatePreparedOrFinishedRun()
1087 return isStatePrepared() || isStateFinishedRun();
1092 return getTensorIndexImpl(*primary_subgraph(), tensorname, index,
true);
1097 return getTensorIndexImpl(*primary_subgraph(), tensorname, index,
false);
1102 if (backend_settings == NULL)
1105 if (!isStateModelLoaded())
1110 if (_nnpkg->model_count() > 1)
1112 std::cerr <<
"Not supported multiple model" << std::endl;
1119 auto &ms_options = _coptions->manual_scheduler_options;
1120 ms_options.setBackendMap(std::string{backend_settings});
1122 catch (
const std::exception &e)
1124 std::cerr <<
"Error during nnfw_session::set_backends_per_operation" << e.what() << std::endl;
1133 if (isStateInitialized())
1136 std::cerr <<
"Error during nnfw_session::train_get_traininfo : invalid state";
1140 if (
info ==
nullptr)
1142 std::cerr <<
"Error during nnfw_session::train_get_traininfo : info is nullptr" << std::endl;
1147 assert(_train_info !=
nullptr);
1159 throw std::runtime_error{
"fail to convert ir::train::LossCode"};
1163 auto convertLossReduction =
1174 throw std::runtime_error{
"fail to convert from ir::train::LossReductionType"};
1179 auto convertOptimizerCode =
1190 throw std::runtime_error{
"fail to convert from ir::train::OptimizerCode"};
1194 const auto &loss = _train_info->lossInfo();
1195 const auto &optim = _train_info->optimizerInfo();
1199 info->learning_rate = optim.learning_rate;
1200 info->batch_size = _train_info->batchSize();
1201 info->loss_info.loss = convertLossCode(loss.loss_code);
1202 info->loss_info.reduction_type = convertLossReduction(loss.reduction_type);
1203 info->opt = convertOptimizerCode(optim.optim_code);
1205 if (_train_info->getTrainableOps().size() > 0)
1207 const uint32_t first_trainable_idx = _train_info->getTrainableOps().cbegin()->value();
1208 const uint32_t last_trainable_idx = _train_info->getTrainableOps().crbegin()->value();
1209 const uint32_t ops_size = primary_subgraph()->
operations().
size();
1210 const uint32_t trainable_indexes_range = last_trainable_idx - first_trainable_idx + 1;
1213 if (last_trainable_idx == ops_size - 1 &&
1214 trainable_indexes_range == _train_info->getTrainableOps().size())
1217 if (0 == first_trainable_idx)
1223 info->num_of_trainable_ops = trainable_indexes_range;
1229 std::cerr <<
"conversion from set of trainable ops to num_of_trainable_ops is impossible"
1240 catch (
const std::exception &e)
1242 std::cerr <<
"Error during nnfw_session::train_get_traininfo" << e.what() << std::endl;
1251 if (not isStateModelLoaded())
1253 std::cerr <<
"Error during nnfw_session::train_set_traininfo : invalid state" << std::endl;
1257 if (
info ==
nullptr)
1259 std::cerr <<
"nnfw_session::train_set_traininfo : info is nullptr" << std::endl;
1264 assert(_train_info !=
nullptr);
1266 auto convertLossType = [](
const int &
type) {
1272 throw std::runtime_error(
"not supported loss type");
1281 throw std::runtime_error(
"not supported loss reduction type");
1284 auto convertOptType = [](
const int &
type) {
1290 throw std::runtime_error(
"not supported optimizer type");
1296 loss_info.
loss_code = convertLossType(
info->loss_info.loss);
1303 _train_info->setBatchSize(
info->batch_size);
1304 _train_info->setLossInfo(loss_info);
1305 _train_info->setOptimizerInfo(opt_info);
1307 if (
info->num_of_trainable_ops < -1)
1309 std::cerr <<
"Error during nnfw_session::train_set_traininfo: provided num_of_trainable_ops "
1310 "has incorrect value: "
1311 <<
info->num_of_trainable_ops << std::endl;
1315 const uint32_t ops_size = primary_subgraph()->
operations().
size();
1316 std::set<onert::ir::OperationIndex> trainable_ops;
1320 for (uint32_t idx = 0; idx < ops_size; ++idx)
1322 trainable_ops.emplace(idx);
1327 if (
static_cast<uint32_t
>(
info->num_of_trainable_ops) > ops_size)
1330 <<
"Error during nnfw_session::train_set_traininfo: provided num_of_trainable_ops="
1331 <<
info->num_of_trainable_ops <<
" is out of operators range equals: " << ops_size
1335 for (uint32_t i = 1; i <= static_cast<uint32_t>(
info->num_of_trainable_ops); ++i)
1337 trainable_ops.emplace(ops_size - i);
1341 _train_info->setTrainableOps(trainable_ops);
1343 catch (
const std::exception &e)
1345 std::cerr <<
"Error during nnfw_session::train_set_traininfo : " << e.what() << std::endl;
1355 if (!isStateModelLoaded())
1357 std::cerr <<
"Error during model prepare training: ";
1358 if (_state == State::PREPARED_TRAINING)
1359 std::cerr <<
"prepare should be run once";
1361 std::cerr <<
"invalid state";
1362 std::cerr << std::endl;
1367 assert(_train_info !=
nullptr);
1371 if (not _train_info->isValid())
1372 throw std::runtime_error{
"training info is not valid"};
1375 _train_info->trainingStep() = 0;
1380 _compiler_artifact = compiler->compile();
1381 _execution = std::make_unique<onert::exec::Execution>(_compiler_artifact->_executors);
1383 catch (
const std::exception &e)
1385 std::cerr <<
"Error during nnfw_session::train_prepare : " << e.what() << std::endl;
1389 _state = State::PREPARED_TRAINING;
1395 if (!isStatePreparedOrFinishedTraining())
1397 std::cerr <<
"Error during nnfw_session::train_input_tensorinfo : invalid state" << std::endl;
1411 if (!isStatePreparedOrFinishedTraining())
1413 std::cerr <<
"Error during nnfw_session::train_expected_tensorinfo : invalid state"
1429 if (input ==
nullptr)
1431 std::cerr <<
"Error during nnfw_session::train_set_input : input buffer is null" << std::endl;
1435 if (!isStatePreparedOrFinishedTraining())
1437 std::cerr <<
"Error during nnfw_session::train_set_input : invalid state" << std::endl;
1441 if (index >= getInputSize())
1443 std::cerr <<
"Error during nnfw_session::train_set_input : index is out of range" << std::endl;
1450 auto size = _execution->getInputTotalSize(ind);
1454 <<
"Error during nnfw_session::train_set_input : not supporeted to change tensorinfo"
1459 _execution->setInput(ind, input,
size);
1461 catch (
const std::exception &e)
1463 std::cerr <<
"Error during nnfw_session::train_set_input : " << e.what() << std::endl;
1473 if (expected ==
nullptr)
1475 std::cerr <<
"Error during nnfw_session::train_set_expected : expected buffer is null"
1480 if (!isStatePreparedOrFinishedTraining())
1482 std::cerr <<
"Error during nnfw_session::train_set_expected : invalid state" << std::endl;
1486 if (index >= getOutputSize())
1488 std::cerr <<
"Error during nnfw_session::train_set_expected : index is out of range"
1496 auto size = _execution->getOutputTotalSize(output_ind);
1497 if (expected_tensorinfo && getBufSize(expected_tensorinfo) !=
size)
1499 std::cerr <<
"Error during nnfw_session::train_set_expected : invalid tensorinfo"
1508 auto input_index = getInputSize() - getOutputSize() + index;
1510 _execution->setInput(input_ind, expected,
size);
1512 catch (
const std::exception &e)
1514 std::cerr <<
"Error during nnfw_session::train_set_expected : " << e.what() << std::endl;
1524 if (!isStatePreparedOrFinishedTraining())
1526 std::cerr <<
"Error during nnfw_session::train_set_output : invalid state" << std::endl;
1530 if (!buffer && length != 0)
1532 std::cerr <<
"Error during nnfw_session::train_set_output : given buffer is NULL but the "
1542 catch (
const std::exception &e)
1544 std::cerr <<
"Error during nnfw_session::train_set_output : " << e.what() << std::endl;
1552 if (!isStatePreparedOrFinishedTraining())
1554 std::cerr <<
"Error during nnfw_session::train_run : invalid state" << std::endl;
1562 auto &training_step = _train_info->trainingStep();
1563 _execution->train(training_step++);
1566 _execution->execute();
1571 std::cerr <<
"Error during nnfw_session::train_run : " << e.
what() << std::endl;
1574 catch (
const std::exception &e)
1576 std::cerr <<
"Error during nnfw_session::train_run : " << e.what() << std::endl;
1580 _state = State::FINISHED_TRAINING;
1586 if (loss ==
nullptr)
1588 std::cerr <<
"Error during nnfw_session::train_get_loss : loss is null" << std::endl;
1592 if (!isStateFinishedTraining())
1594 std::cerr <<
"Error during nnfw_session::train_get_loss : invalid state" << std::endl;
1598 if (index >= getOutputSize())
1600 std::cerr <<
"Error during nnfw_session::train_get_loss : index is out of range" << std::endl;
1607 *loss = _execution->getLoss(ind);
1609 catch (
const std::exception &e)
1611 std::cerr <<
"Error during nnfw_session::train_get_loss : " << e.what() << std::endl;
1620 if (path ==
nullptr)
1622 std::cerr <<
"Error during nnfw_session::train_export_circle : path is null" << std::endl;
1627 if (!isStateFinishedTraining())
1629 std::cerr <<
"Error during nnfw_session::train_export_circle : invalid state" << std::endl;
1636 exporter.updateWeight(_execution);
1638 catch (
const std::exception &e)
1640 std::cerr <<
"Error during nnfw_session::train_export_circle : " << e.what() << std::endl;
1649 if (path ==
nullptr)
1651 std::cerr <<
"Error during nnfw_session::train_export_circleplus : path is null" << std::endl;
1655 if (!isStatePreparedOrFinishedTraining())
1657 std::cerr <<
"Error during nnfw_session::train_export_circleplus : invalid state" << std::endl;
1667 catch (
const std::exception &e)
1669 std::cerr <<
"Error during nnfw_session::train_export_circleplus : " << e.what() << std::endl;
1678 if (path ==
nullptr)
1680 std::cerr <<
"Error during nnfw_session::train_import_checkpoint : path is null" << std::endl;
1684 if (!isStatePreparedOrFinishedTraining())
1686 std::cerr <<
"Error during nnfw_session::train_import_checkpoint : invalid state" << std::endl;
1694 catch (
const std::exception &e)
1696 std::cerr <<
"Error during nnfw_session::train_import_checkpoint : " << e.what() << std::endl;
1705 if (path ==
nullptr)
1707 std::cerr <<
"Error during nnfw_session::train_export_checkpoint : path is null" << std::endl;
1712 if (!isStateFinishedTraining())
1714 std::cerr <<
"Error during nnfw_session::train_export_checkpoint : invalid state" << std::endl;
1722 catch (
const std::exception &e)
1724 std::cerr <<
"Error during nnfw_session::train_export_checkpoint : " << e.what() << std::endl;
1731bool nnfw_session::isStatePreparedTraining()
1733 if (_state == State::PREPARED_TRAINING)
1735 assert(_nnpkg ==
nullptr);
1736 assert(_execution !=
nullptr);
1743bool nnfw_session::isStateFinishedTraining()
1745 if (_state == State::FINISHED_TRAINING)
1747 assert(_nnpkg ==
nullptr);
1748 assert(_execution !=
nullptr);
1755bool nnfw_session::isStatePreparedOrFinishedTraining()
1757 return isStatePreparedTraining() || isStateFinishedTraining();
1765 if (isStateInitialized() || isStateRunning())
1767 std::cerr <<
"invalid state" << std::endl;
1789 _quant_manager->quantizeType(odc_qtype);
1791 catch (
const std::exception &e)
1793 std::cerr <<
"Error during nnfw_session::set_quantization_type : " << e.what() << std::endl;
1804 if (isStateInitialized() || isStateRunning())
1806 std::cerr <<
"invalid state" << std::endl;
1810 _quant_manager->exportModelPath(std::string(path));
1812 catch (
const std::exception &e)
1814 std::cerr <<
"Error during nnfw_session::set_quantized_model_path : " << e.what() << std::endl;
1825 if (isStateInitialized() || isStateRunning())
1827 std::cerr <<
"invalid state" << std::endl;
1831 auto result = _quant_manager->quantize(_model_path.string());
1837 return loadModelFile(_quant_manager->exportModelPath(),
"circle");
1839 catch (
const std::exception &e)
1841 std::cerr <<
"Error during nnfw_session::quantize : " << e.what() << std::endl;
1850 if (isStateInitialized() || isStateRunning())
1852 std::cerr <<
"invalid state" << std::endl;
1856 assert(_codegen_manager !=
nullptr);
1857 _codegen_manager->exportModelPath(std::string(path));
1859 catch (
const std::exception &e)
1861 std::cerr <<
"Error during nnfw_session::set_codegen_model_path : " << e.what() << std::endl;
1872 if (isStateInitialized() || isStateRunning())
1874 std::cerr <<
"Error during nnfw_session::codegen : Invalid state" << std::endl;
1878 std::string target_str{target};
1879 if (target_str.empty() || target_str.size() < 5 ||
1880 target_str.substr(target_str.size() - 4) !=
"-gen")
1882 std::cerr <<
"Error during nnfw_session::codegen : Invalid target" << std::endl;
1902 std::cerr <<
"Error during nnfw_session::codegen : Invalid preference" << std::endl;
1906 assert(_codegen_manager !=
nullptr);
1907 auto export_model_path = std::filesystem::path(_codegen_manager->exportModelPath());
1908 const auto model_type = target_str.substr(0, target_str.size() - 4);
1911 if (export_model_path.empty())
1915 export_model_path = _model_path.replace_extension(model_type);
1916 _codegen_manager->exportModelPath(export_model_path.string());
1919 _codegen_manager->codegen(_model_path, target, codegen_pref);
1923 return loadModelFile(export_model_path, model_type);
1925 catch (
const std::exception &e)
1927 std::cerr <<
"Error during nnfw_session::compile : " << e.what() << std::endl;
1934 if (!isStateModelLoaded())
1936 std::cerr <<
"Error during nnfw_session::set_prepare_config : Invalid state" << std::endl;
1943 _coptions->he_profiling_mode =
true;
1954 if (!isStateModelLoaded())
1956 std::cerr <<
"Error during nnfw_session::reset_prepare_config : Invalid state" << std::endl;
1960 _coptions->he_profiling_mode =
false;
1967 if (!isStatePreparedOrFinishedRun())
1969 std::cerr <<
"Error during nnfw_session::set_execution_config : Invalid state" << std::endl;
1976 if (_coptions->workspace_dir.empty())
1978 _execution->executionOptions().dump_minmax =
true;
1981 if (_coptions->workspace_dir.empty())
1983 _execution->executionOptions().trace =
true;
1986 _execution->executionOptions().profile =
true;
1997 if (!isStatePreparedOrFinishedRun())
1999 std::cerr <<
"Error during nnfw_session::set_execution_config : Invalid state" << std::endl;
2003 _execution->executionOptions().dump_minmax =
false;
2004 _execution->executionOptions().trace =
false;
2005 _execution->executionOptions().profile =
false;
2012 if (isStateInitialized() || isStateRunning())
2014 std::cerr <<
"invalid state" << std::endl;
2018 if (_quant_manager->setMinMaxRecordsThreshold(minmax_records_count))
2026 if (isStateRunning())
2028 std::cerr <<
"invalid state" << std::endl;
2032 if (_quant_manager->deleteMinMaxFile())
2042 if (!isStatePreparedOrFinishedRun())
2044 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : "
2045 <<
"run should be after preparation" << std::endl;
2050 std::string target_str{target};
2051 if (_quant_manager->exportModelPath().empty() || _codegen_manager->exportModelPath().empty() ||
2052 target_str.empty() || target_str.substr(target_str.size() - 4) !=
"-gen")
2054 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : "
2055 <<
"quantization and code generation parameters should be set" << std::endl;
2061 std::ifstream file_quantized_model(_quant_manager->exportModelPath());
2062 std::ifstream file_compiled_model(_codegen_manager->exportModelPath());
2064 if (!file_quantized_model.good() && !file_compiled_model.good())
2069 auto saved_options = _execution->executionOptions();
2071 _execution->executionOptions().dump_minmax =
true;
2075 _execution->execute();
2080 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : " << e.
what()
2084 catch (
const std::exception &e)
2086 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : " << e.
what()
2091 _state = State::FINISHED_RUN;
2094 _execution->executionOptions().dump_minmax = saved_options.dump_minmax;
2097 if (_quant_manager->readyForQuantize())
2101 if (isStateInitialized() || isStateRunning())
2103 std::cerr <<
"invalid state" << std::endl;
2107 auto result = _quant_manager->quantize(_model_path);
2112 result = _quant_manager->deleteMinMaxFile();
2116 catch (
const std::exception &e)
2119 <<
"Error during nnfw_session::run_with_auto_compilation in quantize operation: "
2120 << e.what() << std::endl;
2132 _execution->executionOptions().dump_minmax =
false;
2135 if (_autoCompilationState == nnfw_session::AutoCompilationState::INITIAL_STATE)
2137 auto dotidx = _codegen_manager->exportModelPath().rfind(
'.');
2138 if (dotidx == std::string::npos)
2140 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : Invalid compiled "
2141 "model path. Please use a "
2142 "path that includes the extension."
2147 std::string compiled_model_type =
2148 _codegen_manager->exportModelPath().substr(dotidx + 1);
2150 dotidx = _quant_manager->exportModelPath().rfind(
'.');
2151 if (dotidx == std::string::npos)
2153 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : Invalid quantized "
2154 "model path. Please use a "
2155 "path that includes the extension."
2159 std::string quantized_model_type =
2160 _quant_manager->exportModelPath().substr(dotidx + 1);
2163 auto input_size = _compiler_artifact->_executors->inputSize();
2164 auto output_size = _compiler_artifact->_executors->outputSize();
2166 std::vector<const void *> _input_buffers;
2167 std::vector<void *> _output_buffers;
2170 for (
size_t input_index = 0; input_index <
input_size; input_index++)
2173 auto input_Shape = _execution->getInputShape(io_input_index);
2174 auto input_buffer = _execution->getInputBuffer(io_input_index);
2176 _input_buffers.push_back(input_buffer);
2180 for (
size_t output_index = 0; output_index <
output_size; output_index++)
2184 auto output_Shape = _execution->getOutputShape(io_output_index);
2185 auto output_buffer = _execution->getOutputBuffer(io_output_index);
2187 _output_buffers.push_back(output_buffer);
2191 auto saved_options = _execution->executionOptions();
2194 if (file_compiled_model.good())
2197 status = loadModelFile(_codegen_manager->exportModelPath(), compiled_model_type);
2200 _autoCompilationState = nnfw_session::AutoCompilationState::COMPILED_MODEL_LOADED;
2209 _model_path = _quant_manager->exportModelPath();
2212 status =
codegen(target, pref);
2215 _autoCompilationState = nnfw_session::AutoCompilationState::COMPILED_MODEL_LOADED;
2221 if (_autoCompilationState != nnfw_session::AutoCompilationState::COMPILED_MODEL_LOADED)
2224 status = loadModelFile(_quant_manager->exportModelPath(), quantized_model_type);
2228 _autoCompilationState = nnfw_session::AutoCompilationState::QUANTIZED_MODEL_LOADED;
2236 _execution->executionOptions() = saved_options;
2239 for (uint32_t input_index = 0; input_index < _input_buffers.size(); input_index++)
2247 auto input_size_in_bytes = getBufSize(&ti);
2249 status =
set_input(input_index, ti.
dtype, _input_buffers[input_index], input_size_in_bytes);
2256 for (uint32_t output_index = 0; output_index < _output_buffers.size(); output_index++)
2266 uint64_t output_size_in_bytes = getBufSize(&ti);
2269 set_output(output_index, ti.
dtype, _output_buffers[output_index], output_size_in_bytes);
2276 if (!isStatePreparedOrFinishedRun())
2278 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : "
2279 <<
"run should be run after prepare" << std::endl;
2285 _execution->execute();
2290 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : " << e.
what()
2294 catch (
const std::exception &e)
2296 std::cerr <<
"Error during nnfw_session::run_with_auto_compilation : " << e.
what()
2301 _state = State::FINISHED_RUN;
const char * what() const noexcept override
static CompilerFactory & get()
std::unique_ptr< ICompiler > create(const std::shared_ptr< ir::NNPkg > &nnpkg, CompilerOptions *copts, const ir::train::TrainingInfo *training_info=nullptr)
void updateMetadata(const std::unique_ptr< onert::ir::train::TrainingInfo > &training_info)
void updateWeight(const std::unique_ptr< onert::exec::Execution > &exec)
static uint16_t max()
Return max index value.
size_t size() const
Return the number of objects that the manager contains.
volatile const char info[]
SessionID session(const coco::Module *m)
std::unique_ptr< mir::Graph > loadModel(std::string predict_net, std::string init_net, const std::vector< std::vector< int > > &input_shapes)
std::string join(InputIt first, InputIt last, const std::string &concat)
std::vector< std::string > split(const std::string &s, char delim)
nnfw::cker::train::LossReductionType convertLossReductionType(ir::train::LossReductionType type)
convert loss reduction type
void exportCheckpoint(const std::string &filename, const std::unique_ptr< ir::train::TrainingInfo > &train_info, const std::unique_ptr< exec::Execution > &exec)
@ CategoricalCrossentropy
std::tuple< ModelIndex, SubgraphIndex, IOIndex > IODesc
::onert::util::Index< uint32_t, IOIndexTag > IOIndex
void loadCheckpoint(const std::string &filename, const std::unique_ptr< ir::train::TrainingInfo > &train_info, const std::unique_ptr< exec::Execution > &exec)
std::unique_ptr< ir::train::TrainingInfo > loadTrainingInfo(const uint8_t *buffer, const size_t size)
std::unique_ptr< ir::Model > loadCircleModel(const std::string &filename)
const char *const TRAININFO_METADATA_NAME
std::unique_ptr< ir::Model > loadTFLiteModel(const std::string &filename)
std::unique_ptr< ir::Model > loadModel(const std::string &filename, const std::string &type)
Create custom loader and load model from file.
@ CODEGEN_PREF_PERFORMANCE_FIRST
@ CODEGEN_PREF_MEMORY_FIRST
@ CODEGEN_PREF_COMPILE_TIME_FIRST
std::unordered_map< std::string, std::string > CfgKeyValues
void setConfigKeyValues(const CfgKeyValues &keyValues)
@ NNFW_TYPE_TENSOR_QUANT16_SYMM_SIGNED
@ NNFW_TYPE_TENSOR_QUANT8_ASYMM_SIGNED
@ NNFW_TYPE_TENSOR_QUANT8_ASYMM
NNFW_LAYOUT
Data format of a tensor.
@ NNFW_LAYOUT_CHANNELS_LAST
@ NNFW_LAYOUT_CHANNELS_FIRST
void(* nnfw_custom_eval)(nnfw_custom_kernel_params *params, char *userdata, size_t userdata_size)
NNFW_CODEGEN_PREF
Preference for target-dependent code generation.
@ NNFW_CODEGEN_PREF_DEFAULT
@ NNFW_CODEGEN_PREF_MEMORY_FIRST
@ NNFW_CODEGEN_PREF_COMPILE_TIME_FIRST
@ NNFW_CODEGEN_PREF_PERFORMANCE_FIRST
@ NNFW_TRAIN_TRAINABLE_NONE
@ NNFW_TRAIN_TRAINABLE_ALL
@ NNFW_TRAIN_TRAINABLE_INCORRECT_STATE
NNFW_QUANTIZE_TYPE
Convert between training mode and inference mode.
@ NNFW_QUANTIZE_TYPE_WO_I16_SYM
@ NNFW_QUANTIZE_TYPE_U8_ASYM
@ NNFW_QUANTIZE_TYPE_I16_SYM
@ NNFW_QUANTIZE_TYPE_WO_I8_SYM
NNFW_RUN_CONFIG
Configuration key for execution.
@ NNFW_RUN_CONFIG_PROFILE
@ NNFW_RUN_CONFIG_DUMP_MINMAX
NNFW_PREPARE_CONFIG
Configuration key for prepare (compile and schedule)
@ NNFW_PREPARE_CONFIG_PROFILE
#define MAX_TENSOR_NAME_LENGTH
#define MAX_BACKEND_NAME_LENGTH
NNFW_STATUS
Result values returned from a call to an API function.
@ NNFW_STATUS_INVALID_STATE
@ NNFW_STATUS_UNEXPECTED_NULL
@ NNFW_STATUS_DEPRECATED_API
@ NNFW_STATUS_INSUFFICIENT_OUTPUT_SIZE
@ NNFW_STATUS_OUT_OF_MEMORY
NNFW_TRAIN_LOSS_REDUCTION
@ NNFW_TRAIN_LOSS_REDUCTION_UNDEFINED
@ NNFW_TRAIN_LOSS_REDUCTION_SUM
@ NNFW_TRAIN_LOSS_REDUCTION_SUM_OVER_BATCH_SIZE
@ NNFW_TRAIN_OPTIMIZER_ADAM
@ NNFW_TRAIN_OPTIMIZER_SGD
@ NNFW_TRAIN_OPTIMIZER_UNDEFINED
@ NNFW_TRAIN_LOSS_MEAN_SQUARED_ERROR
@ NNFW_TRAIN_LOSS_UNDEFINED
@ NNFW_TRAIN_LOSS_CATEGORICAL_CROSSENTROPY
@ NNFW_TYPE_TENSOR_FLOAT32
#define NNFW_MAX_RANK
Maximum rank expressible with nnfw.
This file contains helper functions for std::string.
NNFW_STATUS train_prepare()
NNFW_STATUS train_set_output(uint32_t index, NNFW_TYPE type, void *buffer, size_t length)
NNFW_STATUS train_get_traininfo(nnfw_train_info *info)
NNFW_STATUS set_config(const char *key, const char *value)
NNFW_STATUS train_set_expected(uint32_t index, void *expected)
NNFW_STATUS delete_odc_minmax_file()
NNFW_STATUS set_odc_param_minmax_records_count(int minmax_records_count)
NNFW_STATUS train_run(bool update_weights)
NNFW_STATUS input_tensorinfo(uint32_t index, nnfw_tensorinfo *ti)
NNFW_STATUS output_tensorinfo(uint32_t index, nnfw_tensorinfo *ti)
NNFW_STATUS set_input_tensorinfo(uint32_t index, const nnfw_tensorinfo *ti)
NNFW_STATUS input_tensorindex(const char *tensorname, uint32_t *index)
NNFW_STATUS train_export_checkpoint(const char *path)
NNFW_STATUS set_output(uint32_t index, NNFW_TYPE type, void *buffer, size_t length)
NNFW_STATUS train_import_checkpoint(const char *path)
NNFW_STATUS set_workspace(const char *dir)
static NNFW_STATUS deprecated(const char *msg)
NNFW_STATUS train_expected_tensorinfo(uint32_t index, nnfw_tensorinfo *ti)
NNFW_STATUS reset_prepare_config()
NNFW_STATUS set_codegen_model_path(const char *path)
NNFW_STATUS train_set_input(uint32_t index, void *input)
NNFW_STATUS reset_execute_config()
NNFW_STATUS set_input(uint32_t index, NNFW_TYPE type, const void *buffer, size_t length)
NNFW_STATUS output_size(uint32_t *number)
NNFW_STATUS train_get_loss(uint32_t index, float *loss)
NNFW_STATUS load_model_from_path(const char *path)
NNFW_STATUS set_backends_per_operation(const char *backend_settings)
Set backends with string-encoded mapping from operation index to backend type (cpu,...
NNFW_STATUS set_quantization_type(NNFW_QUANTIZE_TYPE qtype)
NNFW_STATUS input_size(uint32_t *number)
NNFW_STATUS set_prepare_config(const NNFW_PREPARE_CONFIG key, const char *value)
NNFW_STATUS set_available_backends(const char *backends)
NNFW_STATUS get_config(const char *key, char *value, size_t value_size)
NNFW_STATUS codegen(const char *target, NNFW_CODEGEN_PREF pref)
NNFW_STATUS set_execute_config(const NNFW_RUN_CONFIG key, const char *value)
NNFW_STATUS run_with_auto_compilation(const char *target, NNFW_CODEGEN_PREF pref)
NNFW_STATUS set_output_layout(uint32_t index, NNFW_LAYOUT layout)
NNFW_STATUS train_input_tensorinfo(uint32_t index, nnfw_tensorinfo *ti)
NNFW_STATUS register_custom_operation(const std::string &id, nnfw_custom_eval eval_func)
NNFW_STATUS train_export_circle(const char *path)
NNFW_STATUS output_tensorindex(const char *tensorname, uint32_t *index)
NNFW_STATUS set_quantized_model_path(const char *path)
static NNFW_STATUS create(nnfw_session **session)
Factory method. It creates and initialize nnfw_session.
NNFW_STATUS load_circle_from_buffer(uint8_t *buffer, size_t size)
NNFW_STATUS train_export_circleplus(const char *path)
NNFW_STATUS set_input_layout(uint32_t index, NNFW_LAYOUT layout)
NNFW_STATUS train_set_traininfo(const nnfw_train_info *info)
tensor info describes the type and shape of tensors
int32_t dims[NNFW_MAX_RANK]
Training information to prepare training.
virtual const Operations & operations() const =0
LossReductionType reduction_type