/* * 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 #include #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 mInputOperand; std::vector mOutputOperand; // ---------------------------Model------------------------------------ int err = NEURON_NO_ERROR; err |= NeuronModel_create(&model); CHECK_NO_ERROR(err); mModel = std::unique_ptr(model); std::vector 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 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(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(execution); return NEURON_NO_ERROR; } } // namespace neuron } // namespace backends } // namespace executorch