1 /*
2 * Copyright (c) 2024 MediaTek Inc.
3 *
4 * Licensed under the BSD License (the "License"); you may not use this file
5 * except in compliance with the License. See the license file in the root
6 * directory of this source tree for more details.
7 */
8
9 #include "NeuronExecutor.h"
10 #include "NeuronLog.h"
11 #include "api/NeuronAdapter.h"
12
13 #include <string>
14 #include <vector>
15
16 #define RESTORE_DLA_EXTENSION_OPERAND_TYPE 0x0100
17 #define RESTORE_DLA_EXTENSION_OPERATION_TYPE 0x0000
18 #define RESTORE_DLA_EXTENSION_NAME "com.mediatek.compiled_network"
19
20 namespace executorch {
21 namespace backends {
22 namespace neuron {
23
NeuronExecutor()24 NeuronExecutor::NeuronExecutor(){};
25
LoadFromCompiledNetwork(const void * buffer,size_t size,int inputCount,int outputCount,std::string & runtimeOption)26 int NeuronExecutor::LoadFromCompiledNetwork(
27 const void* buffer,
28 size_t size,
29 int inputCount,
30 int outputCount,
31 std::string& runtimeOption) {
32 NeuronModel* model = nullptr;
33 NeuronCompilation* compilation = nullptr;
34 NeuronExecution* execution = nullptr;
35
36 std::vector<NeuronOperandType> mInputOperand;
37 std::vector<NeuronOperandType> mOutputOperand;
38 // ---------------------------Model------------------------------------
39 int err = NEURON_NO_ERROR;
40 err |= NeuronModel_create(&model);
41 CHECK_NO_ERROR(err);
42
43 mModel = std::unique_ptr<NeuronModel, NeuronDeleter>(model);
44
45 std::vector<uint32_t> input_op_number;
46 // fake input, the real outputs are loaded by compiled network.
47 NeuronOperandType fakeInputOperandType{
48 .type = NEURON_TENSOR_FLOAT32,
49 .dimensionCount = 0,
50 .scale = 0.0f,
51 .zeroPoint = 0,
52 };
53
54 for (int i = 0; i < inputCount; i++) {
55 mInputOperand.push_back(fakeInputOperandType);
56 }
57 for (int i = 0; i < mInputOperand.size(); i++) {
58 err |= NeuronModel_addOperand(model, &mInputOperand[i]);
59 input_op_number.emplace_back(i);
60 }
61
62 int32_t operandType = 0;
63 const uint16_t network_operand_restore_data =
64 RESTORE_DLA_EXTENSION_OPERAND_TYPE;
65 const char* extensionRestoreCompiledNetwork = RESTORE_DLA_EXTENSION_NAME;
66 err |= NeuronModel_getExtensionOperandType(
67 model,
68 extensionRestoreCompiledNetwork,
69 network_operand_restore_data,
70 &operandType);
71 CHECK_NO_ERROR(err);
72
73 NeuronOperandType extenOperandType{
74 .type = operandType,
75 .dimensionCount = 0,
76 .scale = 0.0f,
77 .zeroPoint = 0,
78 };
79
80 err |= NeuronModel_addOperand(model, &extenOperandType);
81 CHECK_NO_ERROR(err);
82 input_op_number.emplace_back(input_op_number.size());
83
84 // fake output, the real outputs are loaded by compiled network.
85 NeuronOperandType fakeOutputOperandType{
86 .type = NEURON_TENSOR_FLOAT32,
87 .dimensionCount = 0,
88 .scale = 0.0f,
89 .zeroPoint = 0,
90 };
91
92 for (int i = 0; i < outputCount; i++) {
93 mOutputOperand.push_back(fakeOutputOperandType);
94 }
95
96 std::vector<uint32_t> output_op_number;
97 for (int i = 0; i < mOutputOperand.size(); i++) {
98 err |= NeuronModel_addOperand(model, &mOutputOperand[i]);
99 output_op_number.emplace_back(i + input_op_number.size());
100 }
101
102 CHECK_NO_ERROR(err);
103
104 err |=
105 NeuronModel_setOperandValue(model, input_op_number.back(), buffer, size);
106
107 int32_t operationType = 0;
108 const uint16_t network_operation_type_restore =
109 RESTORE_DLA_EXTENSION_OPERATION_TYPE;
110 err |= NeuronModel_getExtensionOperationType(
111 model,
112 extensionRestoreCompiledNetwork,
113 network_operation_type_restore,
114 &operationType);
115
116 CHECK_NO_ERROR(err);
117
118 // Add extension operation
119 err |= NeuronModel_addOperation(
120 model,
121 (NeuronOperationType)operationType,
122 input_op_number.size(),
123 input_op_number.data(),
124 output_op_number.size(),
125 output_op_number.data());
126
127 CHECK_NO_ERROR(err);
128
129 // Identify input and output
130 err |= NeuronModel_identifyInputsAndOutputs(
131 model,
132 input_op_number.size() - 1,
133 input_op_number.data(),
134 output_op_number.size(),
135 output_op_number.data());
136
137 CHECK_NO_ERROR(err);
138
139 err |= NeuronModel_finish(model);
140 CHECK_NO_ERROR(err);
141 // ---------------------------Compilation------------------------------------
142 // err = NeuronCompilation_e(model, &compilation) != NEURON_NO_ERROR;
143 err = NeuronCompilation_createWithOptions(
144 model, &compilation, runtimeOption.c_str());
145 CHECK_NO_ERROR(err);
146
147 mCompilation = std::unique_ptr<NeuronCompilation, NeuronDeleter>(compilation);
148
149 err |=
150 NeuronCompilation_setPreference(compilation, NEURON_PREFER_TURBO_BOOST);
151 err |= NeuronCompilation_setPriority(compilation, NEURON_PRIORITY_HIGH);
152 CHECK_NO_ERROR(err);
153
154 err = NeuronCompilation_finish(compilation);
155 CHECK_NO_ERROR(err);
156
157 // ---------------------------Execution------------------------------------
158 // Create Neuron executor instance.
159 err = NeuronExecution_create(compilation, &execution);
160 CHECK_NO_ERROR(err);
161 mExecution = std::unique_ptr<NeuronExecution, NeuronDeleter>(execution);
162
163 return NEURON_NO_ERROR;
164 }
165
166 } // namespace neuron
167 } // namespace backends
168 } // namespace executorch
169