blob: 2a6ea549f289fa9839734f8cd5f2527c240a43af [file]
/*
* Copyright (c) 2024 MediaTek Inc.
*
* Licensed under the BSD License (the "License"); you may not use this file
* except in compliance with the License. See the license file in the root
* directory of this source tree for more details.
*/
#include "NeuronExecutor.h"
#include "NeuronLog.h"
#include "api/NeuronAdapter.h"
#include <string>
#include <vector>
#define RESTORE_DLA_EXTENSION_OPERAND_TYPE 0x0100
#define RESTORE_DLA_EXTENSION_OPERATION_TYPE 0x0000
#define RESTORE_DLA_EXTENSION_NAME "com.mediatek.compiled_network"
namespace executorch {
namespace backends {
namespace neuron {
NeuronExecutor::NeuronExecutor(){};
int NeuronExecutor::LoadFromCompiledNetwork(
const void* buffer,
size_t size,
int inputCount,
int outputCount,
std::string& runtimeOption) {
NeuronModel* model = nullptr;
NeuronCompilation* compilation = nullptr;
NeuronExecution* execution = nullptr;
std::vector<NeuronOperandType> mInputOperand;
std::vector<NeuronOperandType> mOutputOperand;
// ---------------------------Model------------------------------------
int err = NEURON_NO_ERROR;
err |= NeuronModel_create(&model);
CHECK_NO_ERROR(err);
mModel = std::unique_ptr<NeuronModel, NeuronDeleter>(model);
std::vector<uint32_t> input_op_number;
// fake input, the real outputs are loaded by compiled network.
NeuronOperandType fakeInputOperandType{
.type = NEURON_TENSOR_FLOAT32,
.dimensionCount = 0,
.scale = 0.0f,
.zeroPoint = 0,
};
for (int i = 0; i < inputCount; i++) {
mInputOperand.push_back(fakeInputOperandType);
}
for (int i = 0; i < mInputOperand.size(); i++) {
err |= NeuronModel_addOperand(model, &mInputOperand[i]);
input_op_number.emplace_back(i);
}
int32_t operandType = 0;
const uint16_t network_operand_restore_data =
RESTORE_DLA_EXTENSION_OPERAND_TYPE;
const char* extensionRestoreCompiledNetwork = RESTORE_DLA_EXTENSION_NAME;
err |= NeuronModel_getExtensionOperandType(
model,
extensionRestoreCompiledNetwork,
network_operand_restore_data,
&operandType);
CHECK_NO_ERROR(err);
NeuronOperandType extenOperandType{
.type = operandType,
.dimensionCount = 0,
.scale = 0.0f,
.zeroPoint = 0,
};
err |= NeuronModel_addOperand(model, &extenOperandType);
CHECK_NO_ERROR(err);
input_op_number.emplace_back(input_op_number.size());
// fake output, the real outputs are loaded by compiled network.
NeuronOperandType fakeOutputOperandType{
.type = NEURON_TENSOR_FLOAT32,
.dimensionCount = 0,
.scale = 0.0f,
.zeroPoint = 0,
};
for (int i = 0; i < outputCount; i++) {
mOutputOperand.push_back(fakeOutputOperandType);
}
std::vector<uint32_t> output_op_number;
for (int i = 0; i < mOutputOperand.size(); i++) {
err |= NeuronModel_addOperand(model, &mOutputOperand[i]);
output_op_number.emplace_back(i + input_op_number.size());
}
CHECK_NO_ERROR(err);
err |=
NeuronModel_setOperandValue(model, input_op_number.back(), buffer, size);
int32_t operationType = 0;
const uint16_t network_operation_type_restore =
RESTORE_DLA_EXTENSION_OPERATION_TYPE;
err |= NeuronModel_getExtensionOperationType(
model,
extensionRestoreCompiledNetwork,
network_operation_type_restore,
&operationType);
CHECK_NO_ERROR(err);
// Add extension operation
err |= NeuronModel_addOperation(
model,
(NeuronOperationType)operationType,
input_op_number.size(),
input_op_number.data(),
output_op_number.size(),
output_op_number.data());
CHECK_NO_ERROR(err);
// Identify input and output
err |= NeuronModel_identifyInputsAndOutputs(
model,
input_op_number.size() - 1,
input_op_number.data(),
output_op_number.size(),
output_op_number.data());
CHECK_NO_ERROR(err);
err |= NeuronModel_finish(model);
CHECK_NO_ERROR(err);
// ---------------------------Compilation------------------------------------
// err = NeuronCompilation_e(model, &compilation) != NEURON_NO_ERROR;
err = NeuronCompilation_createWithOptions(
model, &compilation, runtimeOption.c_str());
CHECK_NO_ERROR(err);
mCompilation = std::unique_ptr<NeuronCompilation, NeuronDeleter>(compilation);
err |=
NeuronCompilation_setPreference(compilation, NEURON_PREFER_TURBO_BOOST);
err |= NeuronCompilation_setPriority(compilation, NEURON_PRIORITY_HIGH);
CHECK_NO_ERROR(err);
err = NeuronCompilation_finish(compilation);
CHECK_NO_ERROR(err);
// ---------------------------Execution------------------------------------
// Create Neuron executor instance.
err = NeuronExecution_create(compilation, &execution);
CHECK_NO_ERROR(err);
mExecution = std::unique_ptr<NeuronExecution, NeuronDeleter>(execution);
return NEURON_NO_ERROR;
}
} // namespace neuron
} // namespace backends
} // namespace executorch