blob: ef5056b5fed2408e0eefe28c80802eda4a8da9d3 [file] [log] [blame]
Michael Butlerb98aa6d2020-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>
Michael Butler6547b2a2020-11-22 19:36:30 -080027#include <nnapi/Validation.h>
Michael Butlerb98aa6d2020-02-22 22:37:59 -080028#include <nnapi/hal/1.0/Conversions.h>
Michael Butler7fd03c22020-12-06 21:50:59 -080029#include <nnapi/hal/1.1/Conversions.h>
Michael Butlerb98aa6d2020-02-22 22:37:59 -080030#include <nnapi/hal/CommonUtils.h>
Michael Butler4b276a72020-08-06 23:22:35 -070031#include <nnapi/hal/HandleError.h>
Michael Butlerb98aa6d2020-02-22 22:37:59 -080032
33#include <algorithm>
34#include <functional>
35#include <iterator>
36#include <memory>
37#include <type_traits>
38#include <utility>
39
Michael Butler388bceb2021-02-03 15:15:43 -080040#include "Utils.h"
41
Michael Butlerb98aa6d2020-02-22 22:37:59 -080042namespace {
43
44template <typename Type>
45constexpr std::underlying_type_t<Type> underlyingType(Type value) {
46 return static_cast<std::underlying_type_t<Type>>(value);
47}
48
Michael Butler4024d8f2020-12-04 17:38:20 -080049using HalDuration = std::chrono::duration<uint64_t, std::micro>;
Michael Butler6547b2a2020-11-22 19:36:30 -080050
Michael Butlerb98aa6d2020-02-22 22:37:59 -080051} // namespace
52
53namespace android::nn {
54namespace {
55
Michael Butlerb98aa6d2020-02-22 22:37:59 -080056using hardware::hidl_handle;
57using hardware::hidl_vec;
58
59template <typename Input>
Michael Butler388bceb2021-02-03 15:15:43 -080060using UnvalidatedConvertOutput =
Michael Butler6547b2a2020-11-22 19:36:30 -080061 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlerb98aa6d2020-02-22 22:37:59 -080062
63template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080064GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -080065 const hidl_vec<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -080066 std::vector<UnvalidatedConvertOutput<Type>> canonical;
Michael Butlerb98aa6d2020-02-22 22:37:59 -080067 canonical.reserve(arguments.size());
68 for (const auto& argument : arguments) {
Michael Butler6547b2a2020-11-22 19:36:30 -080069 canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -080070 }
71 return canonical;
72}
73
74template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080075GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& halObject) {
Michael Butler6547b2a2020-11-22 19:36:30 -080076 auto canonical = NN_TRY(nn::unvalidatedConvert(halObject));
Michael Butler388bceb2021-02-03 15:15:43 -080077 NN_TRY(hal::V1_2::utils::compliantVersion(canonical));
Michael Butler6547b2a2020-11-22 19:36:30 -080078 return canonical;
79}
80
81template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080082GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -080083 const hidl_vec<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -080084 std::vector<UnvalidatedConvertOutput<Type>> canonical;
Michael Butler6547b2a2020-11-22 19:36:30 -080085 canonical.reserve(arguments.size());
86 for (const auto& argument : arguments) {
87 canonical.push_back(NN_TRY(validatedConvert(argument)));
88 }
89 return canonical;
Michael Butlerb98aa6d2020-02-22 22:37:59 -080090}
91
92} // anonymous namespace
93
Michael Butler6547b2a2020-11-22 19:36:30 -080094GeneralResult<OperandType> unvalidatedConvert(const hal::V1_2::OperandType& operandType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -080095 return static_cast<OperandType>(operandType);
96}
97
Michael Butler6547b2a2020-11-22 19:36:30 -080098GeneralResult<OperationType> unvalidatedConvert(const hal::V1_2::OperationType& operationType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -080099 return static_cast<OperationType>(operationType);
100}
101
Michael Butler6547b2a2020-11-22 19:36:30 -0800102GeneralResult<DeviceType> unvalidatedConvert(const hal::V1_2::DeviceType& deviceType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800103 return static_cast<DeviceType>(deviceType);
104}
105
Michael Butler6547b2a2020-11-22 19:36:30 -0800106GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_2::Capabilities& capabilities) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800107 const bool validOperandTypes = std::all_of(
108 capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(),
109 [](const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler388bceb2021-02-03 15:15:43 -0800110 return validatedConvert(operandPerformance.type).has_value();
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800111 });
112 if (!validOperandTypes) {
Michael Butler4b276a72020-08-06 23:22:35 -0700113 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800114 << "Invalid OperandType when converting OperandPerformance in Capabilities";
115 }
116
117 const auto relaxedFloat32toFloat16PerformanceScalar =
Michael Butler6547b2a2020-11-22 19:36:30 -0800118 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800119 const auto relaxedFloat32toFloat16PerformanceTensor =
Michael Butler6547b2a2020-11-22 19:36:30 -0800120 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
121 auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800122
Michael Butlerff9a5a52021-10-15 16:23:20 -0700123 auto table =
124 NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800125
126 return Capabilities{
127 .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
128 .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
129 .operandPerformance = std::move(table),
130 };
131}
132
Michael Butler6547b2a2020-11-22 19:36:30 -0800133GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800134 const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
135 return Capabilities::OperandPerformance{
Michael Butler6547b2a2020-11-22 19:36:30 -0800136 .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
137 .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800138 };
139}
140
Michael Butler6547b2a2020-11-22 19:36:30 -0800141GeneralResult<Operation> unvalidatedConvert(const hal::V1_2::Operation& operation) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800142 return Operation{
Michael Butler6547b2a2020-11-22 19:36:30 -0800143 .type = NN_TRY(unvalidatedConvert(operation.type)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800144 .inputs = operation.inputs,
145 .outputs = operation.outputs,
146 };
147}
148
Michael Butler6547b2a2020-11-22 19:36:30 -0800149GeneralResult<Operand::SymmPerChannelQuantParams> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800150 const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
151 return Operand::SymmPerChannelQuantParams{
152 .scales = symmPerChannelQuantParams.scales,
153 .channelDim = symmPerChannelQuantParams.channelDim,
154 };
155}
156
Michael Butler6547b2a2020-11-22 19:36:30 -0800157GeneralResult<Operand> unvalidatedConvert(const hal::V1_2::Operand& operand) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800158 return Operand{
Michael Butler6547b2a2020-11-22 19:36:30 -0800159 .type = NN_TRY(unvalidatedConvert(operand.type)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800160 .dimensions = operand.dimensions,
161 .scale = operand.scale,
162 .zeroPoint = operand.zeroPoint,
Michael Butler6547b2a2020-11-22 19:36:30 -0800163 .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
164 .location = NN_TRY(unvalidatedConvert(operand.location)),
165 .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800166 };
167}
168
Michael Butler6547b2a2020-11-22 19:36:30 -0800169GeneralResult<Operand::ExtraParams> unvalidatedConvert(
170 const hal::V1_2::Operand::ExtraParams& extraParams) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800171 using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator;
172 switch (extraParams.getDiscriminator()) {
173 case Discriminator::none:
174 return Operand::NoParams{};
175 case Discriminator::channelQuant:
Michael Butler6547b2a2020-11-22 19:36:30 -0800176 return unvalidatedConvert(extraParams.channelQuant());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800177 case Discriminator::extension:
178 return extraParams.extension();
179 }
Michael Butler4b276a72020-08-06 23:22:35 -0700180 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
181 << "Unrecognized Operand::ExtraParams discriminator: "
182 << underlyingType(extraParams.getDiscriminator());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800183}
184
Michael Butler6547b2a2020-11-22 19:36:30 -0800185GeneralResult<Model> unvalidatedConvert(const hal::V1_2::Model& model) {
186 auto operations = NN_TRY(unvalidatedConvert(model.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800187
188 // Verify number of consumers.
189 const auto numberOfConsumers =
Michael Butler301ef062021-10-14 22:04:59 -0700190 NN_TRY(countNumberOfConsumers(model.operands.size(), operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800191 CHECK(model.operands.size() == numberOfConsumers.size());
192 for (size_t i = 0; i < model.operands.size(); ++i) {
193 if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
Michael Butler4b276a72020-08-06 23:22:35 -0700194 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
195 << "Invalid numberOfConsumers for operand " << i << ", expected "
196 << numberOfConsumers[i] << " but found " << model.operands[i].numberOfConsumers;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800197 }
198 }
199
200 auto main = Model::Subgraph{
Michael Butler6547b2a2020-11-22 19:36:30 -0800201 .operands = NN_TRY(unvalidatedConvert(model.operands)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800202 .operations = std::move(operations),
203 .inputIndexes = model.inputIndexes,
204 .outputIndexes = model.outputIndexes,
205 };
206
207 return Model{
208 .main = std::move(main),
Michael Butler6547b2a2020-11-22 19:36:30 -0800209 .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
210 .pools = NN_TRY(unvalidatedConvert(model.pools)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800211 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
Michael Butler6547b2a2020-11-22 19:36:30 -0800212 .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800213 };
214}
215
Michael Butler6547b2a2020-11-22 19:36:30 -0800216GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800217 const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
218 return Model::ExtensionNameAndPrefix{
219 .name = extensionNameAndPrefix.name,
220 .prefix = extensionNameAndPrefix.prefix,
221 };
222}
223
Michael Butler6547b2a2020-11-22 19:36:30 -0800224GeneralResult<OutputShape> unvalidatedConvert(const hal::V1_2::OutputShape& outputShape) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800225 return OutputShape{
226 .dimensions = outputShape.dimensions,
227 .isSufficient = outputShape.isSufficient,
228 };
229}
230
Michael Butler6547b2a2020-11-22 19:36:30 -0800231GeneralResult<MeasureTiming> unvalidatedConvert(const hal::V1_2::MeasureTiming& measureTiming) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800232 return static_cast<MeasureTiming>(measureTiming);
233}
234
Michael Butler6547b2a2020-11-22 19:36:30 -0800235GeneralResult<Timing> unvalidatedConvert(const hal::V1_2::Timing& timing) {
Michael Butler4024d8f2020-12-04 17:38:20 -0800236 constexpr uint64_t kMaxTiming = std::chrono::floor<HalDuration>(Duration::max()).count();
237 constexpr auto convertTiming = [](uint64_t halTiming) -> OptionalDuration {
Michael Butler388bceb2021-02-03 15:15:43 -0800238 constexpr uint64_t kNoTiming = std::numeric_limits<uint64_t>::max();
Michael Butler4024d8f2020-12-04 17:38:20 -0800239 if (halTiming == kNoTiming) {
240 return {};
241 }
242 if (halTiming > kMaxTiming) {
243 return Duration::max();
244 }
245 return HalDuration{halTiming};
246 };
247 return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice),
248 .timeInDriver = convertTiming(timing.timeInDriver)};
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800249}
250
Michael Butler6547b2a2020-11-22 19:36:30 -0800251GeneralResult<Extension> unvalidatedConvert(const hal::V1_2::Extension& extension) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800252 return Extension{
253 .name = extension.name,
Michael Butler6547b2a2020-11-22 19:36:30 -0800254 .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800255 };
256}
257
Michael Butler6547b2a2020-11-22 19:36:30 -0800258GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800259 const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) {
260 return Extension::OperandTypeInformation{
261 .type = operandTypeInformation.type,
262 .isTensor = operandTypeInformation.isTensor,
263 .byteSize = operandTypeInformation.byteSize,
264 };
265}
266
Michael Butler6547b2a2020-11-22 19:36:30 -0800267GeneralResult<DeviceType> convert(const hal::V1_2::DeviceType& deviceType) {
268 return validatedConvert(deviceType);
269}
270
271GeneralResult<Capabilities> convert(const hal::V1_2::Capabilities& capabilities) {
272 return validatedConvert(capabilities);
273}
274
275GeneralResult<Model> convert(const hal::V1_2::Model& model) {
276 return validatedConvert(model);
277}
278
279GeneralResult<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming) {
280 return validatedConvert(measureTiming);
281}
282
283GeneralResult<Timing> convert(const hal::V1_2::Timing& timing) {
284 return validatedConvert(timing);
285}
286
Michael Butler76e491f2020-12-19 01:55:32 -0800287GeneralResult<SharedMemory> convert(const hardware::hidl_memory& memory) {
288 return validatedConvert(memory);
289}
290
Michael Butler4b276a72020-08-06 23:22:35 -0700291GeneralResult<std::vector<Extension>> convert(const hidl_vec<hal::V1_2::Extension>& extensions) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800292 return validatedConvert(extensions);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800293}
294
Slava Shklyaev49817a02020-10-27 18:44:01 +0000295GeneralResult<std::vector<SharedHandle>> convert(const hidl_vec<hidl_handle>& handles) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800296 return validatedConvert(handles);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800297}
298
Michael Butler4b276a72020-08-06 23:22:35 -0700299GeneralResult<std::vector<OutputShape>> convert(
300 const hidl_vec<hal::V1_2::OutputShape>& outputShapes) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800301 return validatedConvert(outputShapes);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800302}
303
304} // namespace android::nn
305
306namespace android::hardware::neuralnetworks::V1_2::utils {
307namespace {
308
Michael Butler6547b2a2020-11-22 19:36:30 -0800309using utils::unvalidatedConvert;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800310
Michael Butler6547b2a2020-11-22 19:36:30 -0800311nn::GeneralResult<V1_0::OperandLifeTime> unvalidatedConvert(const nn::Operand::LifeTime& lifetime) {
312 return V1_0::utils::unvalidatedConvert(lifetime);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800313}
314
Michael Butler6547b2a2020-11-22 19:36:30 -0800315nn::GeneralResult<V1_0::PerformanceInfo> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800316 const nn::Capabilities::PerformanceInfo& performanceInfo) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800317 return V1_0::utils::unvalidatedConvert(performanceInfo);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800318}
319
Michael Butler6547b2a2020-11-22 19:36:30 -0800320nn::GeneralResult<V1_0::DataLocation> unvalidatedConvert(const nn::DataLocation& location) {
321 return V1_0::utils::unvalidatedConvert(location);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800322}
323
Michael Butler6547b2a2020-11-22 19:36:30 -0800324nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
325 const nn::Model::OperandValues& operandValues) {
326 return V1_0::utils::unvalidatedConvert(operandValues);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800327}
328
Michael Butler15965822021-10-14 23:45:11 -0700329nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle) {
330 return V1_0::utils::unvalidatedConvert(handle);
331}
332
Michael Butlerfadeb8a2021-02-07 00:11:13 -0800333nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::SharedMemory& memory) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800334 return V1_0::utils::unvalidatedConvert(memory);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800335}
336
337template <typename Input>
Michael Butler388bceb2021-02-03 15:15:43 -0800338using UnvalidatedConvertOutput =
Michael Butler6547b2a2020-11-22 19:36:30 -0800339 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800340
341template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800342nn::GeneralResult<hidl_vec<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800343 const std::vector<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -0800344 hidl_vec<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800345 for (size_t i = 0; i < arguments.size(); ++i) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800346 halObject[i] = NN_TRY(unvalidatedConvert(arguments[i]));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800347 }
348 return halObject;
349}
350
Michael Butler4b276a72020-08-06 23:22:35 -0700351nn::GeneralResult<Operand::ExtraParams> makeExtraParams(nn::Operand::NoParams /*noParams*/) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800352 return Operand::ExtraParams{};
353}
354
Michael Butler4b276a72020-08-06 23:22:35 -0700355nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800356 const nn::Operand::SymmPerChannelQuantParams& channelQuant) {
357 Operand::ExtraParams ret;
Michael Butler6547b2a2020-11-22 19:36:30 -0800358 ret.channelQuant(NN_TRY(unvalidatedConvert(channelQuant)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800359 return ret;
360}
361
Michael Butler4b276a72020-08-06 23:22:35 -0700362nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
363 const nn::Operand::ExtensionParams& extension) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800364 Operand::ExtraParams ret;
365 ret.extension(extension);
366 return ret;
367}
368
Michael Butler6547b2a2020-11-22 19:36:30 -0800369template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800370nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) {
371 NN_TRY(compliantVersion(canonical));
372 return unvalidatedConvert(canonical);
Michael Butler6547b2a2020-11-22 19:36:30 -0800373}
374
375template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800376nn::GeneralResult<hidl_vec<UnvalidatedConvertOutput<Type>>> validatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800377 const std::vector<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -0800378 hidl_vec<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butler6547b2a2020-11-22 19:36:30 -0800379 for (size_t i = 0; i < arguments.size(); ++i) {
380 halObject[i] = NN_TRY(validatedConvert(arguments[i]));
381 }
382 return halObject;
383}
384
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800385} // anonymous namespace
386
Michael Butler6547b2a2020-11-22 19:36:30 -0800387nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800388 return static_cast<OperandType>(operandType);
389}
390
Michael Butler6547b2a2020-11-22 19:36:30 -0800391nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800392 return static_cast<OperationType>(operationType);
393}
394
Michael Butler6547b2a2020-11-22 19:36:30 -0800395nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800396 switch (deviceType) {
397 case nn::DeviceType::UNKNOWN:
Michael Butler4b276a72020-08-06 23:22:35 -0700398 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid DeviceType UNKNOWN";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800399 case nn::DeviceType::OTHER:
400 case nn::DeviceType::CPU:
401 case nn::DeviceType::GPU:
402 case nn::DeviceType::ACCELERATOR:
403 return static_cast<DeviceType>(deviceType);
404 }
Michael Butler4b276a72020-08-06 23:22:35 -0700405 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
406 << "Invalid DeviceType " << underlyingType(deviceType);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800407}
408
Michael Butler6547b2a2020-11-22 19:36:30 -0800409nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800410 std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
411 operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
412 std::copy_if(capabilities.operandPerformance.asVector().begin(),
413 capabilities.operandPerformance.asVector().end(),
414 std::back_inserter(operandPerformance),
415 [](const nn::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler388bceb2021-02-03 15:15:43 -0800416 return compliantVersion(operandPerformance.type).has_value();
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800417 });
418
419 return Capabilities{
Michael Butler6547b2a2020-11-22 19:36:30 -0800420 .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
421 unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
422 .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
423 unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
424 .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800425 };
426}
427
Michael Butler6547b2a2020-11-22 19:36:30 -0800428nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800429 const nn::Capabilities::OperandPerformance& operandPerformance) {
430 return Capabilities::OperandPerformance{
Michael Butler6547b2a2020-11-22 19:36:30 -0800431 .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
432 .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800433 };
434}
435
Michael Butler6547b2a2020-11-22 19:36:30 -0800436nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800437 return Operation{
Michael Butler6547b2a2020-11-22 19:36:30 -0800438 .type = NN_TRY(unvalidatedConvert(operation.type)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800439 .inputs = operation.inputs,
440 .outputs = operation.outputs,
441 };
442}
443
Michael Butler6547b2a2020-11-22 19:36:30 -0800444nn::GeneralResult<SymmPerChannelQuantParams> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800445 const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
446 return SymmPerChannelQuantParams{
447 .scales = symmPerChannelQuantParams.scales,
448 .channelDim = symmPerChannelQuantParams.channelDim,
449 };
450}
451
Michael Butler6547b2a2020-11-22 19:36:30 -0800452nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800453 return Operand{
Michael Butler6547b2a2020-11-22 19:36:30 -0800454 .type = NN_TRY(unvalidatedConvert(operand.type)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800455 .dimensions = operand.dimensions,
456 .numberOfConsumers = 0,
457 .scale = operand.scale,
458 .zeroPoint = operand.zeroPoint,
Michael Butler6547b2a2020-11-22 19:36:30 -0800459 .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
460 .location = NN_TRY(unvalidatedConvert(operand.location)),
461 .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800462 };
463}
464
Michael Butler6547b2a2020-11-22 19:36:30 -0800465nn::GeneralResult<Operand::ExtraParams> unvalidatedConvert(
466 const nn::Operand::ExtraParams& extraParams) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800467 return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams);
468}
469
Michael Butler6547b2a2020-11-22 19:36:30 -0800470nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800471 if (!hal::utils::hasNoPointerData(model)) {
Michael Butler4b276a72020-08-06 23:22:35 -0700472 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler6547b2a2020-11-22 19:36:30 -0800473 << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800474 }
475
Michael Butler6547b2a2020-11-22 19:36:30 -0800476 auto operands = NN_TRY(unvalidatedConvert(model.main.operands));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800477
478 // Update number of consumers.
479 const auto numberOfConsumers =
Michael Butler301ef062021-10-14 22:04:59 -0700480 NN_TRY(countNumberOfConsumers(operands.size(), model.main.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800481 CHECK(operands.size() == numberOfConsumers.size());
482 for (size_t i = 0; i < operands.size(); ++i) {
483 operands[i].numberOfConsumers = numberOfConsumers[i];
484 }
485
486 return Model{
487 .operands = std::move(operands),
Michael Butler6547b2a2020-11-22 19:36:30 -0800488 .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800489 .inputIndexes = model.main.inputIndexes,
490 .outputIndexes = model.main.outputIndexes,
Michael Butler6547b2a2020-11-22 19:36:30 -0800491 .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
492 .pools = NN_TRY(unvalidatedConvert(model.pools)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800493 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
Michael Butler6547b2a2020-11-22 19:36:30 -0800494 .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800495 };
496}
497
Michael Butler6547b2a2020-11-22 19:36:30 -0800498nn::GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800499 const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
500 return Model::ExtensionNameAndPrefix{
501 .name = extensionNameAndPrefix.name,
502 .prefix = extensionNameAndPrefix.prefix,
503 };
504}
505
Michael Butler6547b2a2020-11-22 19:36:30 -0800506nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800507 return OutputShape{.dimensions = outputShape.dimensions,
508 .isSufficient = outputShape.isSufficient};
509}
510
Michael Butler6547b2a2020-11-22 19:36:30 -0800511nn::GeneralResult<MeasureTiming> unvalidatedConvert(const nn::MeasureTiming& measureTiming) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800512 return static_cast<MeasureTiming>(measureTiming);
513}
514
Michael Butler6547b2a2020-11-22 19:36:30 -0800515nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) {
Michael Butler4024d8f2020-12-04 17:38:20 -0800516 constexpr auto convertTiming = [](nn::OptionalDuration canonicalTiming) -> uint64_t {
Michael Butler388bceb2021-02-03 15:15:43 -0800517 constexpr uint64_t kNoTiming = std::numeric_limits<uint64_t>::max();
Michael Butler4024d8f2020-12-04 17:38:20 -0800518 if (!canonicalTiming.has_value()) {
519 return kNoTiming;
520 }
521 return std::chrono::ceil<HalDuration>(*canonicalTiming).count();
522 };
523 return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice),
524 .timeInDriver = convertTiming(timing.timeInDriver)};
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800525}
526
Michael Butler6547b2a2020-11-22 19:36:30 -0800527nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800528 return Extension{
529 .name = extension.name,
Michael Butler6547b2a2020-11-22 19:36:30 -0800530 .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800531 };
532}
533
Michael Butler6547b2a2020-11-22 19:36:30 -0800534nn::GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800535 const nn::Extension::OperandTypeInformation& operandTypeInformation) {
536 return Extension::OperandTypeInformation{
537 .type = operandTypeInformation.type,
538 .isTensor = operandTypeInformation.isTensor,
539 .byteSize = operandTypeInformation.byteSize,
540 };
541}
542
Michael Butler6547b2a2020-11-22 19:36:30 -0800543nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
544 return validatedConvert(deviceType);
545}
546
547nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
548 return validatedConvert(capabilities);
549}
550
551nn::GeneralResult<Model> convert(const nn::Model& model) {
552 return validatedConvert(model);
553}
554
555nn::GeneralResult<MeasureTiming> convert(const nn::MeasureTiming& measureTiming) {
556 return validatedConvert(measureTiming);
557}
558
559nn::GeneralResult<Timing> convert(const nn::Timing& timing) {
560 return validatedConvert(timing);
561}
562
Michael Butler4b276a72020-08-06 23:22:35 -0700563nn::GeneralResult<hidl_vec<Extension>> convert(const std::vector<nn::Extension>& extensions) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800564 return validatedConvert(extensions);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800565}
566
Slava Shklyaev49817a02020-10-27 18:44:01 +0000567nn::GeneralResult<hidl_vec<hidl_handle>> convert(const std::vector<nn::SharedHandle>& handles) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800568 return validatedConvert(handles);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800569}
570
Michael Butler4b276a72020-08-06 23:22:35 -0700571nn::GeneralResult<hidl_vec<OutputShape>> convert(const std::vector<nn::OutputShape>& outputShapes) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800572 return validatedConvert(outputShapes);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800573}
574
Michael Butler7fd03c22020-12-06 21:50:59 -0800575nn::GeneralResult<V1_0::DeviceStatus> convert(const nn::DeviceStatus& deviceStatus) {
576 return V1_1::utils::convert(deviceStatus);
577}
578
579nn::GeneralResult<V1_0::Request> convert(const nn::Request& request) {
580 return V1_1::utils::convert(request);
581}
582
583nn::GeneralResult<V1_0::ErrorStatus> convert(const nn::ErrorStatus& status) {
584 return V1_1::utils::convert(status);
585}
586
587nn::GeneralResult<V1_1::ExecutionPreference> convert(
588 const nn::ExecutionPreference& executionPreference) {
589 return V1_1::utils::convert(executionPreference);
590}
591
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800592} // namespace android::hardware::neuralnetworks::V1_2::utils