blob: 08c94dec33522f8aaf339ad8a5af16d99ed44c59 [file] [log] [blame]
Michael Butlera685c3d2020-02-22 22:37:59 -08001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Conversions.h"
18
19#include <android-base/logging.h>
20#include <android/hardware/neuralnetworks/1.2/types.h>
21#include <nnapi/OperandTypes.h>
22#include <nnapi/OperationTypes.h>
23#include <nnapi/Result.h>
24#include <nnapi/SharedMemory.h>
25#include <nnapi/TypeUtils.h>
26#include <nnapi/Types.h>
27#include <nnapi/hal/1.0/Conversions.h>
28#include <nnapi/hal/CommonUtils.h>
Michael Butler3670c382020-08-06 23:22:35 -070029#include <nnapi/hal/HandleError.h>
Michael Butlera685c3d2020-02-22 22:37:59 -080030
31#include <algorithm>
32#include <functional>
33#include <iterator>
34#include <memory>
35#include <type_traits>
36#include <utility>
37
38namespace {
39
40template <typename Type>
41constexpr std::underlying_type_t<Type> underlyingType(Type value) {
42 return static_cast<std::underlying_type_t<Type>>(value);
43}
44
45} // namespace
46
47namespace android::nn {
48namespace {
49
50constexpr bool validOperandType(OperandType operandType) {
51 switch (operandType) {
52 case OperandType::FLOAT32:
53 case OperandType::INT32:
54 case OperandType::UINT32:
55 case OperandType::TENSOR_FLOAT32:
56 case OperandType::TENSOR_INT32:
57 case OperandType::TENSOR_QUANT8_ASYMM:
58 case OperandType::BOOL:
59 case OperandType::TENSOR_QUANT16_SYMM:
60 case OperandType::TENSOR_FLOAT16:
61 case OperandType::TENSOR_BOOL8:
62 case OperandType::FLOAT16:
63 case OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL:
64 case OperandType::TENSOR_QUANT16_ASYMM:
65 case OperandType::TENSOR_QUANT8_SYMM:
66 case OperandType::OEM:
67 case OperandType::TENSOR_OEM_BYTE:
68 return true;
69 default:
70 break;
71 }
72 return isExtension(operandType);
73}
74
75using hardware::hidl_handle;
76using hardware::hidl_vec;
77
78template <typename Input>
79using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
80
81template <typename Type>
Michael Butler3670c382020-08-06 23:22:35 -070082GeneralResult<std::vector<ConvertOutput<Type>>> convertVec(const hidl_vec<Type>& arguments) {
Michael Butlera685c3d2020-02-22 22:37:59 -080083 std::vector<ConvertOutput<Type>> canonical;
84 canonical.reserve(arguments.size());
85 for (const auto& argument : arguments) {
86 canonical.push_back(NN_TRY(nn::convert(argument)));
87 }
88 return canonical;
89}
90
91template <typename Type>
Michael Butler3670c382020-08-06 23:22:35 -070092GeneralResult<std::vector<ConvertOutput<Type>>> convert(const hidl_vec<Type>& arguments) {
Michael Butlera685c3d2020-02-22 22:37:59 -080093 return convertVec(arguments);
94}
95
96} // anonymous namespace
97
Michael Butler3670c382020-08-06 23:22:35 -070098GeneralResult<OperandType> convert(const hal::V1_2::OperandType& operandType) {
Michael Butlera685c3d2020-02-22 22:37:59 -080099 return static_cast<OperandType>(operandType);
100}
101
Michael Butler3670c382020-08-06 23:22:35 -0700102GeneralResult<OperationType> convert(const hal::V1_2::OperationType& operationType) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800103 return static_cast<OperationType>(operationType);
104}
105
Michael Butler3670c382020-08-06 23:22:35 -0700106GeneralResult<DeviceType> convert(const hal::V1_2::DeviceType& deviceType) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800107 return static_cast<DeviceType>(deviceType);
108}
109
Michael Butler3670c382020-08-06 23:22:35 -0700110GeneralResult<Capabilities> convert(const hal::V1_2::Capabilities& capabilities) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800111 const bool validOperandTypes = std::all_of(
112 capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(),
113 [](const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
114 const auto maybeType = convert(operandPerformance.type);
115 return !maybeType.has_value() ? false : validOperandType(maybeType.value());
116 });
117 if (!validOperandTypes) {
Michael Butler3670c382020-08-06 23:22:35 -0700118 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
Michael Butlera685c3d2020-02-22 22:37:59 -0800119 << "Invalid OperandType when converting OperandPerformance in Capabilities";
120 }
121
122 const auto relaxedFloat32toFloat16PerformanceScalar =
123 NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
124 const auto relaxedFloat32toFloat16PerformanceTensor =
125 NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
126 auto operandPerformance = NN_TRY(convert(capabilities.operandPerformance));
127
Michael Butler3670c382020-08-06 23:22:35 -0700128 auto table = NN_TRY(hal::utils::makeGeneralFailure(
129 Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)),
130 nn::ErrorStatus::GENERAL_FAILURE));
Michael Butlera685c3d2020-02-22 22:37:59 -0800131
132 return Capabilities{
133 .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
134 .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
135 .operandPerformance = std::move(table),
136 };
137}
138
Michael Butler3670c382020-08-06 23:22:35 -0700139GeneralResult<Capabilities::OperandPerformance> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800140 const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
141 return Capabilities::OperandPerformance{
142 .type = NN_TRY(convert(operandPerformance.type)),
143 .info = NN_TRY(convert(operandPerformance.info)),
144 };
145}
146
Michael Butler3670c382020-08-06 23:22:35 -0700147GeneralResult<Operation> convert(const hal::V1_2::Operation& operation) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800148 return Operation{
149 .type = NN_TRY(convert(operation.type)),
150 .inputs = operation.inputs,
151 .outputs = operation.outputs,
152 };
153}
154
Michael Butler3670c382020-08-06 23:22:35 -0700155GeneralResult<Operand::SymmPerChannelQuantParams> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800156 const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
157 return Operand::SymmPerChannelQuantParams{
158 .scales = symmPerChannelQuantParams.scales,
159 .channelDim = symmPerChannelQuantParams.channelDim,
160 };
161}
162
Michael Butler3670c382020-08-06 23:22:35 -0700163GeneralResult<Operand> convert(const hal::V1_2::Operand& operand) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800164 return Operand{
165 .type = NN_TRY(convert(operand.type)),
166 .dimensions = operand.dimensions,
167 .scale = operand.scale,
168 .zeroPoint = operand.zeroPoint,
169 .lifetime = NN_TRY(convert(operand.lifetime)),
170 .location = NN_TRY(convert(operand.location)),
171 .extraParams = NN_TRY(convert(operand.extraParams)),
172 };
173}
174
Michael Butler3670c382020-08-06 23:22:35 -0700175GeneralResult<Operand::ExtraParams> convert(const hal::V1_2::Operand::ExtraParams& extraParams) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800176 using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator;
177 switch (extraParams.getDiscriminator()) {
178 case Discriminator::none:
179 return Operand::NoParams{};
180 case Discriminator::channelQuant:
181 return convert(extraParams.channelQuant());
182 case Discriminator::extension:
183 return extraParams.extension();
184 }
Michael Butler3670c382020-08-06 23:22:35 -0700185 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
186 << "Unrecognized Operand::ExtraParams discriminator: "
187 << underlyingType(extraParams.getDiscriminator());
Michael Butlera685c3d2020-02-22 22:37:59 -0800188}
189
Michael Butler3670c382020-08-06 23:22:35 -0700190GeneralResult<Model> convert(const hal::V1_2::Model& model) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800191 auto operations = NN_TRY(convert(model.operations));
192
193 // Verify number of consumers.
194 const auto numberOfConsumers =
195 hal::utils::countNumberOfConsumers(model.operands.size(), operations);
196 CHECK(model.operands.size() == numberOfConsumers.size());
197 for (size_t i = 0; i < model.operands.size(); ++i) {
198 if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
Michael Butler3670c382020-08-06 23:22:35 -0700199 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
200 << "Invalid numberOfConsumers for operand " << i << ", expected "
201 << numberOfConsumers[i] << " but found " << model.operands[i].numberOfConsumers;
Michael Butlera685c3d2020-02-22 22:37:59 -0800202 }
203 }
204
205 auto main = Model::Subgraph{
206 .operands = NN_TRY(convert(model.operands)),
207 .operations = std::move(operations),
208 .inputIndexes = model.inputIndexes,
209 .outputIndexes = model.outputIndexes,
210 };
211
212 return Model{
213 .main = std::move(main),
214 .operandValues = NN_TRY(convert(model.operandValues)),
215 .pools = NN_TRY(convert(model.pools)),
216 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
217 .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
218 };
219}
220
Michael Butler3670c382020-08-06 23:22:35 -0700221GeneralResult<Model::ExtensionNameAndPrefix> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800222 const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
223 return Model::ExtensionNameAndPrefix{
224 .name = extensionNameAndPrefix.name,
225 .prefix = extensionNameAndPrefix.prefix,
226 };
227}
228
Michael Butler3670c382020-08-06 23:22:35 -0700229GeneralResult<OutputShape> convert(const hal::V1_2::OutputShape& outputShape) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800230 return OutputShape{
231 .dimensions = outputShape.dimensions,
232 .isSufficient = outputShape.isSufficient,
233 };
234}
235
Michael Butler3670c382020-08-06 23:22:35 -0700236GeneralResult<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800237 return static_cast<MeasureTiming>(measureTiming);
238}
239
Michael Butler3670c382020-08-06 23:22:35 -0700240GeneralResult<Timing> convert(const hal::V1_2::Timing& timing) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800241 return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver};
242}
243
Michael Butler3670c382020-08-06 23:22:35 -0700244GeneralResult<Extension> convert(const hal::V1_2::Extension& extension) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800245 return Extension{
246 .name = extension.name,
247 .operandTypes = NN_TRY(convert(extension.operandTypes)),
248 };
249}
250
Michael Butler3670c382020-08-06 23:22:35 -0700251GeneralResult<Extension::OperandTypeInformation> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800252 const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) {
253 return Extension::OperandTypeInformation{
254 .type = operandTypeInformation.type,
255 .isTensor = operandTypeInformation.isTensor,
256 .byteSize = operandTypeInformation.byteSize,
257 };
258}
259
Slava Shklyaevd4290b82020-10-27 18:44:01 +0000260GeneralResult<SharedHandle> convert(const hidl_handle& hidlHandle) {
261 return hal::utils::sharedHandleFromNativeHandle(hidlHandle.getNativeHandle());
Michael Butlera685c3d2020-02-22 22:37:59 -0800262}
263
Michael Butler3670c382020-08-06 23:22:35 -0700264GeneralResult<std::vector<Extension>> convert(const hidl_vec<hal::V1_2::Extension>& extensions) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800265 return convertVec(extensions);
266}
267
Slava Shklyaevd4290b82020-10-27 18:44:01 +0000268GeneralResult<std::vector<SharedHandle>> convert(const hidl_vec<hidl_handle>& handles) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800269 return convertVec(handles);
270}
271
Michael Butler3670c382020-08-06 23:22:35 -0700272GeneralResult<std::vector<OutputShape>> convert(
273 const hidl_vec<hal::V1_2::OutputShape>& outputShapes) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800274 return convertVec(outputShapes);
275}
276
277} // namespace android::nn
278
279namespace android::hardware::neuralnetworks::V1_2::utils {
280namespace {
281
282using utils::convert;
283
Michael Butler3670c382020-08-06 23:22:35 -0700284nn::GeneralResult<V1_0::OperandLifeTime> convert(const nn::Operand::LifeTime& lifetime) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800285 return V1_0::utils::convert(lifetime);
286}
287
Michael Butler3670c382020-08-06 23:22:35 -0700288nn::GeneralResult<V1_0::PerformanceInfo> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800289 const nn::Capabilities::PerformanceInfo& performanceInfo) {
290 return V1_0::utils::convert(performanceInfo);
291}
292
Michael Butler3670c382020-08-06 23:22:35 -0700293nn::GeneralResult<V1_0::DataLocation> convert(const nn::DataLocation& location) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800294 return V1_0::utils::convert(location);
295}
296
Michael Butler3670c382020-08-06 23:22:35 -0700297nn::GeneralResult<hidl_vec<uint8_t>> convert(const nn::Model::OperandValues& operandValues) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800298 return V1_0::utils::convert(operandValues);
299}
300
Michael Butler3670c382020-08-06 23:22:35 -0700301nn::GeneralResult<hidl_memory> convert(const nn::Memory& memory) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800302 return V1_0::utils::convert(memory);
303}
304
305template <typename Input>
306using ConvertOutput = std::decay_t<decltype(convert(std::declval<Input>()).value())>;
307
308template <typename Type>
Michael Butler3670c382020-08-06 23:22:35 -0700309nn::GeneralResult<hidl_vec<ConvertOutput<Type>>> convertVec(const std::vector<Type>& arguments) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800310 hidl_vec<ConvertOutput<Type>> halObject(arguments.size());
311 for (size_t i = 0; i < arguments.size(); ++i) {
312 halObject[i] = NN_TRY(convert(arguments[i]));
313 }
314 return halObject;
315}
316
317template <typename Type>
Michael Butler3670c382020-08-06 23:22:35 -0700318nn::GeneralResult<hidl_vec<ConvertOutput<Type>>> convert(const std::vector<Type>& arguments) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800319 return convertVec(arguments);
320}
321
Michael Butler3670c382020-08-06 23:22:35 -0700322nn::GeneralResult<Operand::ExtraParams> makeExtraParams(nn::Operand::NoParams /*noParams*/) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800323 return Operand::ExtraParams{};
324}
325
Michael Butler3670c382020-08-06 23:22:35 -0700326nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
Michael Butlera685c3d2020-02-22 22:37:59 -0800327 const nn::Operand::SymmPerChannelQuantParams& channelQuant) {
328 Operand::ExtraParams ret;
329 ret.channelQuant(NN_TRY(convert(channelQuant)));
330 return ret;
331}
332
Michael Butler3670c382020-08-06 23:22:35 -0700333nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
334 const nn::Operand::ExtensionParams& extension) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800335 Operand::ExtraParams ret;
336 ret.extension(extension);
337 return ret;
338}
339
340} // anonymous namespace
341
Michael Butler3670c382020-08-06 23:22:35 -0700342nn::GeneralResult<OperandType> convert(const nn::OperandType& operandType) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800343 return static_cast<OperandType>(operandType);
344}
345
Michael Butler3670c382020-08-06 23:22:35 -0700346nn::GeneralResult<OperationType> convert(const nn::OperationType& operationType) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800347 return static_cast<OperationType>(operationType);
348}
349
Michael Butler3670c382020-08-06 23:22:35 -0700350nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800351 switch (deviceType) {
352 case nn::DeviceType::UNKNOWN:
Michael Butler3670c382020-08-06 23:22:35 -0700353 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid DeviceType UNKNOWN";
Michael Butlera685c3d2020-02-22 22:37:59 -0800354 case nn::DeviceType::OTHER:
355 case nn::DeviceType::CPU:
356 case nn::DeviceType::GPU:
357 case nn::DeviceType::ACCELERATOR:
358 return static_cast<DeviceType>(deviceType);
359 }
Michael Butler3670c382020-08-06 23:22:35 -0700360 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
361 << "Invalid DeviceType " << underlyingType(deviceType);
Michael Butlera685c3d2020-02-22 22:37:59 -0800362}
363
Michael Butler3670c382020-08-06 23:22:35 -0700364nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800365 std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
366 operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
367 std::copy_if(capabilities.operandPerformance.asVector().begin(),
368 capabilities.operandPerformance.asVector().end(),
369 std::back_inserter(operandPerformance),
370 [](const nn::Capabilities::OperandPerformance& operandPerformance) {
371 return nn::validOperandType(operandPerformance.type);
372 });
373
374 return Capabilities{
375 .relaxedFloat32toFloat16PerformanceScalar =
376 NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
377 .relaxedFloat32toFloat16PerformanceTensor =
378 NN_TRY(convert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
379 .operandPerformance = NN_TRY(convert(operandPerformance)),
380 };
381}
382
Michael Butler3670c382020-08-06 23:22:35 -0700383nn::GeneralResult<Capabilities::OperandPerformance> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800384 const nn::Capabilities::OperandPerformance& operandPerformance) {
385 return Capabilities::OperandPerformance{
386 .type = NN_TRY(convert(operandPerformance.type)),
387 .info = NN_TRY(convert(operandPerformance.info)),
388 };
389}
390
Michael Butler3670c382020-08-06 23:22:35 -0700391nn::GeneralResult<Operation> convert(const nn::Operation& operation) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800392 return Operation{
393 .type = NN_TRY(convert(operation.type)),
394 .inputs = operation.inputs,
395 .outputs = operation.outputs,
396 };
397}
398
Michael Butler3670c382020-08-06 23:22:35 -0700399nn::GeneralResult<SymmPerChannelQuantParams> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800400 const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
401 return SymmPerChannelQuantParams{
402 .scales = symmPerChannelQuantParams.scales,
403 .channelDim = symmPerChannelQuantParams.channelDim,
404 };
405}
406
Michael Butler3670c382020-08-06 23:22:35 -0700407nn::GeneralResult<Operand> convert(const nn::Operand& operand) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800408 return Operand{
409 .type = NN_TRY(convert(operand.type)),
410 .dimensions = operand.dimensions,
411 .numberOfConsumers = 0,
412 .scale = operand.scale,
413 .zeroPoint = operand.zeroPoint,
414 .lifetime = NN_TRY(convert(operand.lifetime)),
415 .location = NN_TRY(convert(operand.location)),
416 .extraParams = NN_TRY(convert(operand.extraParams)),
417 };
418}
419
Michael Butler3670c382020-08-06 23:22:35 -0700420nn::GeneralResult<Operand::ExtraParams> convert(const nn::Operand::ExtraParams& extraParams) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800421 return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams);
422}
423
Michael Butler3670c382020-08-06 23:22:35 -0700424nn::GeneralResult<Model> convert(const nn::Model& model) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800425 if (!hal::utils::hasNoPointerData(model)) {
Michael Butler3670c382020-08-06 23:22:35 -0700426 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
427 << "Model cannot be converted because it contains pointer-based memory";
Michael Butlera685c3d2020-02-22 22:37:59 -0800428 }
429
430 auto operands = NN_TRY(convert(model.main.operands));
431
432 // Update number of consumers.
433 const auto numberOfConsumers =
434 hal::utils::countNumberOfConsumers(operands.size(), model.main.operations);
435 CHECK(operands.size() == numberOfConsumers.size());
436 for (size_t i = 0; i < operands.size(); ++i) {
437 operands[i].numberOfConsumers = numberOfConsumers[i];
438 }
439
440 return Model{
441 .operands = std::move(operands),
442 .operations = NN_TRY(convert(model.main.operations)),
443 .inputIndexes = model.main.inputIndexes,
444 .outputIndexes = model.main.outputIndexes,
445 .operandValues = NN_TRY(convert(model.operandValues)),
446 .pools = NN_TRY(convert(model.pools)),
447 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
448 .extensionNameToPrefix = NN_TRY(convert(model.extensionNameToPrefix)),
449 };
450}
451
Michael Butler3670c382020-08-06 23:22:35 -0700452nn::GeneralResult<Model::ExtensionNameAndPrefix> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800453 const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
454 return Model::ExtensionNameAndPrefix{
455 .name = extensionNameAndPrefix.name,
456 .prefix = extensionNameAndPrefix.prefix,
457 };
458}
459
Michael Butler3670c382020-08-06 23:22:35 -0700460nn::GeneralResult<OutputShape> convert(const nn::OutputShape& outputShape) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800461 return OutputShape{.dimensions = outputShape.dimensions,
462 .isSufficient = outputShape.isSufficient};
463}
464
Michael Butler3670c382020-08-06 23:22:35 -0700465nn::GeneralResult<MeasureTiming> convert(const nn::MeasureTiming& measureTiming) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800466 return static_cast<MeasureTiming>(measureTiming);
467}
468
Michael Butler3670c382020-08-06 23:22:35 -0700469nn::GeneralResult<Timing> convert(const nn::Timing& timing) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800470 return Timing{.timeOnDevice = timing.timeOnDevice, .timeInDriver = timing.timeInDriver};
471}
472
Michael Butler3670c382020-08-06 23:22:35 -0700473nn::GeneralResult<Extension> convert(const nn::Extension& extension) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800474 return Extension{
475 .name = extension.name,
476 .operandTypes = NN_TRY(convert(extension.operandTypes)),
477 };
478}
479
Michael Butler3670c382020-08-06 23:22:35 -0700480nn::GeneralResult<Extension::OperandTypeInformation> convert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800481 const nn::Extension::OperandTypeInformation& operandTypeInformation) {
482 return Extension::OperandTypeInformation{
483 .type = operandTypeInformation.type,
484 .isTensor = operandTypeInformation.isTensor,
485 .byteSize = operandTypeInformation.byteSize,
486 };
487}
488
Slava Shklyaevd4290b82020-10-27 18:44:01 +0000489nn::GeneralResult<hidl_handle> convert(const nn::SharedHandle& handle) {
490 return hal::utils::hidlHandleFromSharedHandle(handle);
Michael Butlera685c3d2020-02-22 22:37:59 -0800491}
492
Michael Butler3670c382020-08-06 23:22:35 -0700493nn::GeneralResult<hidl_vec<Extension>> convert(const std::vector<nn::Extension>& extensions) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800494 return convertVec(extensions);
495}
496
Slava Shklyaevd4290b82020-10-27 18:44:01 +0000497nn::GeneralResult<hidl_vec<hidl_handle>> convert(const std::vector<nn::SharedHandle>& handles) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800498 return convertVec(handles);
499}
500
Michael Butler3670c382020-08-06 23:22:35 -0700501nn::GeneralResult<hidl_vec<OutputShape>> convert(const std::vector<nn::OutputShape>& outputShapes) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800502 return convertVec(outputShapes);
503}
504
505} // namespace android::hardware::neuralnetworks::V1_2::utils