blob: 62ec2ed6c6f2e13748f796b40a3bf0bc1f0b776b [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>
31
32#include <algorithm>
33#include <functional>
34#include <iterator>
35#include <memory>
36#include <type_traits>
37#include <utility>
38
Michael Butler388bceb2021-02-03 15:15:43 -080039#include "Utils.h"
40
Michael Butlerb98aa6d2020-02-22 22:37:59 -080041namespace {
42
43template <typename Type>
44constexpr std::underlying_type_t<Type> underlyingType(Type value) {
45 return static_cast<std::underlying_type_t<Type>>(value);
46}
47
Michael Butler4024d8f2020-12-04 17:38:20 -080048using HalDuration = std::chrono::duration<uint64_t, std::micro>;
Michael Butler6547b2a2020-11-22 19:36:30 -080049
Michael Butlerb98aa6d2020-02-22 22:37:59 -080050} // namespace
51
52namespace android::nn {
53namespace {
54
Michael Butlerb98aa6d2020-02-22 22:37:59 -080055using hardware::hidl_handle;
56using hardware::hidl_vec;
57
58template <typename Input>
Michael Butler388bceb2021-02-03 15:15:43 -080059using UnvalidatedConvertOutput =
Michael Butler6547b2a2020-11-22 19:36:30 -080060 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlerb98aa6d2020-02-22 22:37:59 -080061
62template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080063GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -080064 const hidl_vec<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -080065 std::vector<UnvalidatedConvertOutput<Type>> canonical;
Michael Butlerb98aa6d2020-02-22 22:37:59 -080066 canonical.reserve(arguments.size());
67 for (const auto& argument : arguments) {
Michael Butler6547b2a2020-11-22 19:36:30 -080068 canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -080069 }
70 return canonical;
71}
72
73template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080074GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& halObject) {
Michael Butler6547b2a2020-11-22 19:36:30 -080075 auto canonical = NN_TRY(nn::unvalidatedConvert(halObject));
Michael Butler388bceb2021-02-03 15:15:43 -080076 NN_TRY(hal::V1_2::utils::compliantVersion(canonical));
Michael Butler6547b2a2020-11-22 19:36:30 -080077 return canonical;
78}
79
80template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080081GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -080082 const hidl_vec<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -080083 std::vector<UnvalidatedConvertOutput<Type>> canonical;
Michael Butler6547b2a2020-11-22 19:36:30 -080084 canonical.reserve(arguments.size());
85 for (const auto& argument : arguments) {
86 canonical.push_back(NN_TRY(validatedConvert(argument)));
87 }
88 return canonical;
Michael Butlerb98aa6d2020-02-22 22:37:59 -080089}
90
91} // anonymous namespace
92
Michael Butler6547b2a2020-11-22 19:36:30 -080093GeneralResult<OperandType> unvalidatedConvert(const hal::V1_2::OperandType& operandType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -080094 return static_cast<OperandType>(operandType);
95}
96
Michael Butler6547b2a2020-11-22 19:36:30 -080097GeneralResult<OperationType> unvalidatedConvert(const hal::V1_2::OperationType& operationType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -080098 return static_cast<OperationType>(operationType);
99}
100
Michael Butler6547b2a2020-11-22 19:36:30 -0800101GeneralResult<DeviceType> unvalidatedConvert(const hal::V1_2::DeviceType& deviceType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800102 return static_cast<DeviceType>(deviceType);
103}
104
Michael Butler6547b2a2020-11-22 19:36:30 -0800105GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_2::Capabilities& capabilities) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800106 const bool validOperandTypes = std::all_of(
107 capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(),
108 [](const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler388bceb2021-02-03 15:15:43 -0800109 return validatedConvert(operandPerformance.type).has_value();
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800110 });
111 if (!validOperandTypes) {
Michael Butler4b276a72020-08-06 23:22:35 -0700112 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800113 << "Invalid OperandType when converting OperandPerformance in Capabilities";
114 }
115
116 const auto relaxedFloat32toFloat16PerformanceScalar =
Michael Butler6547b2a2020-11-22 19:36:30 -0800117 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800118 const auto relaxedFloat32toFloat16PerformanceTensor =
Michael Butler6547b2a2020-11-22 19:36:30 -0800119 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
120 auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800121
Michael Butlerff9a5a52021-10-15 16:23:20 -0700122 auto table =
123 NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800124
125 return Capabilities{
126 .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
127 .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
128 .operandPerformance = std::move(table),
129 };
130}
131
Michael Butler6547b2a2020-11-22 19:36:30 -0800132GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800133 const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
134 return Capabilities::OperandPerformance{
Michael Butler6547b2a2020-11-22 19:36:30 -0800135 .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
136 .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800137 };
138}
139
Michael Butler6547b2a2020-11-22 19:36:30 -0800140GeneralResult<Operation> unvalidatedConvert(const hal::V1_2::Operation& operation) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800141 return Operation{
Michael Butler6547b2a2020-11-22 19:36:30 -0800142 .type = NN_TRY(unvalidatedConvert(operation.type)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800143 .inputs = operation.inputs,
144 .outputs = operation.outputs,
145 };
146}
147
Michael Butler6547b2a2020-11-22 19:36:30 -0800148GeneralResult<Operand::SymmPerChannelQuantParams> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800149 const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
150 return Operand::SymmPerChannelQuantParams{
151 .scales = symmPerChannelQuantParams.scales,
152 .channelDim = symmPerChannelQuantParams.channelDim,
153 };
154}
155
Michael Butler6547b2a2020-11-22 19:36:30 -0800156GeneralResult<Operand> unvalidatedConvert(const hal::V1_2::Operand& operand) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800157 return Operand{
Michael Butler6547b2a2020-11-22 19:36:30 -0800158 .type = NN_TRY(unvalidatedConvert(operand.type)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800159 .dimensions = operand.dimensions,
160 .scale = operand.scale,
161 .zeroPoint = operand.zeroPoint,
Michael Butler6547b2a2020-11-22 19:36:30 -0800162 .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
163 .location = NN_TRY(unvalidatedConvert(operand.location)),
164 .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800165 };
166}
167
Michael Butler6547b2a2020-11-22 19:36:30 -0800168GeneralResult<Operand::ExtraParams> unvalidatedConvert(
169 const hal::V1_2::Operand::ExtraParams& extraParams) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800170 using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator;
171 switch (extraParams.getDiscriminator()) {
172 case Discriminator::none:
173 return Operand::NoParams{};
174 case Discriminator::channelQuant:
Michael Butler6547b2a2020-11-22 19:36:30 -0800175 return unvalidatedConvert(extraParams.channelQuant());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800176 case Discriminator::extension:
177 return extraParams.extension();
178 }
Michael Butler4b276a72020-08-06 23:22:35 -0700179 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
180 << "Unrecognized Operand::ExtraParams discriminator: "
181 << underlyingType(extraParams.getDiscriminator());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800182}
183
Michael Butler6547b2a2020-11-22 19:36:30 -0800184GeneralResult<Model> unvalidatedConvert(const hal::V1_2::Model& model) {
185 auto operations = NN_TRY(unvalidatedConvert(model.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800186
187 // Verify number of consumers.
188 const auto numberOfConsumers =
Michael Butler301ef062021-10-14 22:04:59 -0700189 NN_TRY(countNumberOfConsumers(model.operands.size(), operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800190 CHECK(model.operands.size() == numberOfConsumers.size());
191 for (size_t i = 0; i < model.operands.size(); ++i) {
192 if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
Michael Butler4b276a72020-08-06 23:22:35 -0700193 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
194 << "Invalid numberOfConsumers for operand " << i << ", expected "
195 << numberOfConsumers[i] << " but found " << model.operands[i].numberOfConsumers;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800196 }
197 }
198
199 auto main = Model::Subgraph{
Michael Butler6547b2a2020-11-22 19:36:30 -0800200 .operands = NN_TRY(unvalidatedConvert(model.operands)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800201 .operations = std::move(operations),
202 .inputIndexes = model.inputIndexes,
203 .outputIndexes = model.outputIndexes,
204 };
205
206 return Model{
207 .main = std::move(main),
Michael Butler6547b2a2020-11-22 19:36:30 -0800208 .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
209 .pools = NN_TRY(unvalidatedConvert(model.pools)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800210 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
Michael Butler6547b2a2020-11-22 19:36:30 -0800211 .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800212 };
213}
214
Miao Wang0e671f32021-10-26 20:03:05 +0000215GeneralResult<ExtensionNameAndPrefix> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800216 const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
Miao Wang0e671f32021-10-26 20:03:05 +0000217 return ExtensionNameAndPrefix{
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800218 .name = extensionNameAndPrefix.name,
219 .prefix = extensionNameAndPrefix.prefix,
220 };
221}
222
Michael Butler6547b2a2020-11-22 19:36:30 -0800223GeneralResult<OutputShape> unvalidatedConvert(const hal::V1_2::OutputShape& outputShape) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800224 return OutputShape{
225 .dimensions = outputShape.dimensions,
226 .isSufficient = outputShape.isSufficient,
227 };
228}
229
Michael Butler6547b2a2020-11-22 19:36:30 -0800230GeneralResult<MeasureTiming> unvalidatedConvert(const hal::V1_2::MeasureTiming& measureTiming) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800231 return static_cast<MeasureTiming>(measureTiming);
232}
233
Michael Butler6547b2a2020-11-22 19:36:30 -0800234GeneralResult<Timing> unvalidatedConvert(const hal::V1_2::Timing& timing) {
Michael Butler4024d8f2020-12-04 17:38:20 -0800235 constexpr uint64_t kMaxTiming = std::chrono::floor<HalDuration>(Duration::max()).count();
236 constexpr auto convertTiming = [](uint64_t halTiming) -> OptionalDuration {
Michael Butler388bceb2021-02-03 15:15:43 -0800237 constexpr uint64_t kNoTiming = std::numeric_limits<uint64_t>::max();
Michael Butler4024d8f2020-12-04 17:38:20 -0800238 if (halTiming == kNoTiming) {
239 return {};
240 }
241 if (halTiming > kMaxTiming) {
242 return Duration::max();
243 }
244 return HalDuration{halTiming};
245 };
246 return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice),
247 .timeInDriver = convertTiming(timing.timeInDriver)};
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800248}
249
Michael Butler6547b2a2020-11-22 19:36:30 -0800250GeneralResult<Extension> unvalidatedConvert(const hal::V1_2::Extension& extension) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800251 return Extension{
252 .name = extension.name,
Michael Butler6547b2a2020-11-22 19:36:30 -0800253 .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800254 };
255}
256
Michael Butler6547b2a2020-11-22 19:36:30 -0800257GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800258 const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) {
259 return Extension::OperandTypeInformation{
260 .type = operandTypeInformation.type,
261 .isTensor = operandTypeInformation.isTensor,
262 .byteSize = operandTypeInformation.byteSize,
263 };
264}
265
Michael Butler6547b2a2020-11-22 19:36:30 -0800266GeneralResult<DeviceType> convert(const hal::V1_2::DeviceType& deviceType) {
267 return validatedConvert(deviceType);
268}
269
270GeneralResult<Capabilities> convert(const hal::V1_2::Capabilities& capabilities) {
271 return validatedConvert(capabilities);
272}
273
274GeneralResult<Model> convert(const hal::V1_2::Model& model) {
275 return validatedConvert(model);
276}
277
278GeneralResult<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming) {
279 return validatedConvert(measureTiming);
280}
281
282GeneralResult<Timing> convert(const hal::V1_2::Timing& timing) {
283 return validatedConvert(timing);
284}
285
Michael Butler76e491f2020-12-19 01:55:32 -0800286GeneralResult<SharedMemory> convert(const hardware::hidl_memory& memory) {
287 return validatedConvert(memory);
288}
289
Michael Butler4b276a72020-08-06 23:22:35 -0700290GeneralResult<std::vector<Extension>> convert(const hidl_vec<hal::V1_2::Extension>& extensions) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800291 return validatedConvert(extensions);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800292}
293
Slava Shklyaev49817a02020-10-27 18:44:01 +0000294GeneralResult<std::vector<SharedHandle>> convert(const hidl_vec<hidl_handle>& handles) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800295 return validatedConvert(handles);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800296}
297
Michael Butler4b276a72020-08-06 23:22:35 -0700298GeneralResult<std::vector<OutputShape>> convert(
299 const hidl_vec<hal::V1_2::OutputShape>& outputShapes) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800300 return validatedConvert(outputShapes);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800301}
302
303} // namespace android::nn
304
305namespace android::hardware::neuralnetworks::V1_2::utils {
306namespace {
307
Michael Butler6547b2a2020-11-22 19:36:30 -0800308using utils::unvalidatedConvert;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800309
Michael Butler6547b2a2020-11-22 19:36:30 -0800310nn::GeneralResult<V1_0::OperandLifeTime> unvalidatedConvert(const nn::Operand::LifeTime& lifetime) {
311 return V1_0::utils::unvalidatedConvert(lifetime);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800312}
313
Michael Butler6547b2a2020-11-22 19:36:30 -0800314nn::GeneralResult<V1_0::PerformanceInfo> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800315 const nn::Capabilities::PerformanceInfo& performanceInfo) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800316 return V1_0::utils::unvalidatedConvert(performanceInfo);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800317}
318
Michael Butler6547b2a2020-11-22 19:36:30 -0800319nn::GeneralResult<V1_0::DataLocation> unvalidatedConvert(const nn::DataLocation& location) {
320 return V1_0::utils::unvalidatedConvert(location);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800321}
322
Michael Butler6547b2a2020-11-22 19:36:30 -0800323nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
324 const nn::Model::OperandValues& operandValues) {
325 return V1_0::utils::unvalidatedConvert(operandValues);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800326}
327
Michael Butler15965822021-10-14 23:45:11 -0700328nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle) {
329 return V1_0::utils::unvalidatedConvert(handle);
330}
331
Michael Butlerfadeb8a2021-02-07 00:11:13 -0800332nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::SharedMemory& memory) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800333 return V1_0::utils::unvalidatedConvert(memory);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800334}
335
336template <typename Input>
Michael Butler388bceb2021-02-03 15:15:43 -0800337using UnvalidatedConvertOutput =
Michael Butler6547b2a2020-11-22 19:36:30 -0800338 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800339
340template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800341nn::GeneralResult<hidl_vec<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800342 const std::vector<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -0800343 hidl_vec<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800344 for (size_t i = 0; i < arguments.size(); ++i) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800345 halObject[i] = NN_TRY(unvalidatedConvert(arguments[i]));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800346 }
347 return halObject;
348}
349
Michael Butler4b276a72020-08-06 23:22:35 -0700350nn::GeneralResult<Operand::ExtraParams> makeExtraParams(nn::Operand::NoParams /*noParams*/) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800351 return Operand::ExtraParams{};
352}
353
Michael Butler4b276a72020-08-06 23:22:35 -0700354nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800355 const nn::Operand::SymmPerChannelQuantParams& channelQuant) {
356 Operand::ExtraParams ret;
Michael Butler6547b2a2020-11-22 19:36:30 -0800357 ret.channelQuant(NN_TRY(unvalidatedConvert(channelQuant)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800358 return ret;
359}
360
Michael Butler4b276a72020-08-06 23:22:35 -0700361nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
362 const nn::Operand::ExtensionParams& extension) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800363 Operand::ExtraParams ret;
364 ret.extension(extension);
365 return ret;
366}
367
Michael Butler6547b2a2020-11-22 19:36:30 -0800368template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800369nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) {
370 NN_TRY(compliantVersion(canonical));
371 return unvalidatedConvert(canonical);
Michael Butler6547b2a2020-11-22 19:36:30 -0800372}
373
374template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800375nn::GeneralResult<hidl_vec<UnvalidatedConvertOutput<Type>>> validatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800376 const std::vector<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -0800377 hidl_vec<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butler6547b2a2020-11-22 19:36:30 -0800378 for (size_t i = 0; i < arguments.size(); ++i) {
379 halObject[i] = NN_TRY(validatedConvert(arguments[i]));
380 }
381 return halObject;
382}
383
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800384} // anonymous namespace
385
Michael Butler6547b2a2020-11-22 19:36:30 -0800386nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800387 return static_cast<OperandType>(operandType);
388}
389
Michael Butler6547b2a2020-11-22 19:36:30 -0800390nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800391 return static_cast<OperationType>(operationType);
392}
393
Michael Butler6547b2a2020-11-22 19:36:30 -0800394nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800395 switch (deviceType) {
396 case nn::DeviceType::UNKNOWN:
Michael Butler4b276a72020-08-06 23:22:35 -0700397 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid DeviceType UNKNOWN";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800398 case nn::DeviceType::OTHER:
399 case nn::DeviceType::CPU:
400 case nn::DeviceType::GPU:
401 case nn::DeviceType::ACCELERATOR:
402 return static_cast<DeviceType>(deviceType);
403 }
Michael Butler4b276a72020-08-06 23:22:35 -0700404 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
405 << "Invalid DeviceType " << underlyingType(deviceType);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800406}
407
Michael Butler6547b2a2020-11-22 19:36:30 -0800408nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800409 std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
410 operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
411 std::copy_if(capabilities.operandPerformance.asVector().begin(),
412 capabilities.operandPerformance.asVector().end(),
413 std::back_inserter(operandPerformance),
414 [](const nn::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler388bceb2021-02-03 15:15:43 -0800415 return compliantVersion(operandPerformance.type).has_value();
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800416 });
417
418 return Capabilities{
Michael Butler6547b2a2020-11-22 19:36:30 -0800419 .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
420 unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
421 .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
422 unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
423 .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800424 };
425}
426
Michael Butler6547b2a2020-11-22 19:36:30 -0800427nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800428 const nn::Capabilities::OperandPerformance& operandPerformance) {
429 return Capabilities::OperandPerformance{
Michael Butler6547b2a2020-11-22 19:36:30 -0800430 .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
431 .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800432 };
433}
434
Michael Butler6547b2a2020-11-22 19:36:30 -0800435nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800436 return Operation{
Michael Butler6547b2a2020-11-22 19:36:30 -0800437 .type = NN_TRY(unvalidatedConvert(operation.type)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800438 .inputs = operation.inputs,
439 .outputs = operation.outputs,
440 };
441}
442
Michael Butler6547b2a2020-11-22 19:36:30 -0800443nn::GeneralResult<SymmPerChannelQuantParams> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800444 const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
445 return SymmPerChannelQuantParams{
446 .scales = symmPerChannelQuantParams.scales,
447 .channelDim = symmPerChannelQuantParams.channelDim,
448 };
449}
450
Michael Butler6547b2a2020-11-22 19:36:30 -0800451nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800452 return Operand{
Michael Butler6547b2a2020-11-22 19:36:30 -0800453 .type = NN_TRY(unvalidatedConvert(operand.type)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800454 .dimensions = operand.dimensions,
455 .numberOfConsumers = 0,
456 .scale = operand.scale,
457 .zeroPoint = operand.zeroPoint,
Michael Butler6547b2a2020-11-22 19:36:30 -0800458 .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
459 .location = NN_TRY(unvalidatedConvert(operand.location)),
460 .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800461 };
462}
463
Michael Butler6547b2a2020-11-22 19:36:30 -0800464nn::GeneralResult<Operand::ExtraParams> unvalidatedConvert(
465 const nn::Operand::ExtraParams& extraParams) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800466 return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams);
467}
468
Michael Butler6547b2a2020-11-22 19:36:30 -0800469nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800470 if (!hal::utils::hasNoPointerData(model)) {
Michael Butler4b276a72020-08-06 23:22:35 -0700471 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler6547b2a2020-11-22 19:36:30 -0800472 << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800473 }
474
Michael Butler6547b2a2020-11-22 19:36:30 -0800475 auto operands = NN_TRY(unvalidatedConvert(model.main.operands));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800476
477 // Update number of consumers.
478 const auto numberOfConsumers =
Michael Butler301ef062021-10-14 22:04:59 -0700479 NN_TRY(countNumberOfConsumers(operands.size(), model.main.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800480 CHECK(operands.size() == numberOfConsumers.size());
481 for (size_t i = 0; i < operands.size(); ++i) {
482 operands[i].numberOfConsumers = numberOfConsumers[i];
483 }
484
485 return Model{
486 .operands = std::move(operands),
Michael Butler6547b2a2020-11-22 19:36:30 -0800487 .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800488 .inputIndexes = model.main.inputIndexes,
489 .outputIndexes = model.main.outputIndexes,
Michael Butler6547b2a2020-11-22 19:36:30 -0800490 .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
491 .pools = NN_TRY(unvalidatedConvert(model.pools)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800492 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
Michael Butler6547b2a2020-11-22 19:36:30 -0800493 .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800494 };
495}
496
Michael Butler6547b2a2020-11-22 19:36:30 -0800497nn::GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
Miao Wang0e671f32021-10-26 20:03:05 +0000498 const nn::ExtensionNameAndPrefix& extensionNameAndPrefix) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800499 return Model::ExtensionNameAndPrefix{
500 .name = extensionNameAndPrefix.name,
501 .prefix = extensionNameAndPrefix.prefix,
502 };
503}
504
Michael Butler6547b2a2020-11-22 19:36:30 -0800505nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800506 return OutputShape{.dimensions = outputShape.dimensions,
507 .isSufficient = outputShape.isSufficient};
508}
509
Michael Butler6547b2a2020-11-22 19:36:30 -0800510nn::GeneralResult<MeasureTiming> unvalidatedConvert(const nn::MeasureTiming& measureTiming) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800511 return static_cast<MeasureTiming>(measureTiming);
512}
513
Michael Butler6547b2a2020-11-22 19:36:30 -0800514nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) {
Michael Butler4024d8f2020-12-04 17:38:20 -0800515 constexpr auto convertTiming = [](nn::OptionalDuration canonicalTiming) -> uint64_t {
Michael Butler388bceb2021-02-03 15:15:43 -0800516 constexpr uint64_t kNoTiming = std::numeric_limits<uint64_t>::max();
Michael Butler4024d8f2020-12-04 17:38:20 -0800517 if (!canonicalTiming.has_value()) {
518 return kNoTiming;
519 }
520 return std::chrono::ceil<HalDuration>(*canonicalTiming).count();
521 };
522 return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice),
523 .timeInDriver = convertTiming(timing.timeInDriver)};
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800524}
525
Michael Butler6547b2a2020-11-22 19:36:30 -0800526nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800527 return Extension{
528 .name = extension.name,
Michael Butler6547b2a2020-11-22 19:36:30 -0800529 .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800530 };
531}
532
Michael Butler6547b2a2020-11-22 19:36:30 -0800533nn::GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800534 const nn::Extension::OperandTypeInformation& operandTypeInformation) {
535 return Extension::OperandTypeInformation{
536 .type = operandTypeInformation.type,
537 .isTensor = operandTypeInformation.isTensor,
538 .byteSize = operandTypeInformation.byteSize,
539 };
540}
541
Michael Butler6547b2a2020-11-22 19:36:30 -0800542nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
543 return validatedConvert(deviceType);
544}
545
546nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
547 return validatedConvert(capabilities);
548}
549
550nn::GeneralResult<Model> convert(const nn::Model& model) {
551 return validatedConvert(model);
552}
553
554nn::GeneralResult<MeasureTiming> convert(const nn::MeasureTiming& measureTiming) {
555 return validatedConvert(measureTiming);
556}
557
558nn::GeneralResult<Timing> convert(const nn::Timing& timing) {
559 return validatedConvert(timing);
560}
561
Michael Butler4b276a72020-08-06 23:22:35 -0700562nn::GeneralResult<hidl_vec<Extension>> convert(const std::vector<nn::Extension>& extensions) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800563 return validatedConvert(extensions);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800564}
565
Slava Shklyaev49817a02020-10-27 18:44:01 +0000566nn::GeneralResult<hidl_vec<hidl_handle>> convert(const std::vector<nn::SharedHandle>& handles) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800567 return validatedConvert(handles);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800568}
569
Michael Butler4b276a72020-08-06 23:22:35 -0700570nn::GeneralResult<hidl_vec<OutputShape>> convert(const std::vector<nn::OutputShape>& outputShapes) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800571 return validatedConvert(outputShapes);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800572}
573
Michael Butler7fd03c22020-12-06 21:50:59 -0800574nn::GeneralResult<V1_0::DeviceStatus> convert(const nn::DeviceStatus& deviceStatus) {
575 return V1_1::utils::convert(deviceStatus);
576}
577
578nn::GeneralResult<V1_0::Request> convert(const nn::Request& request) {
579 return V1_1::utils::convert(request);
580}
581
582nn::GeneralResult<V1_0::ErrorStatus> convert(const nn::ErrorStatus& status) {
583 return V1_1::utils::convert(status);
584}
585
586nn::GeneralResult<V1_1::ExecutionPreference> convert(
587 const nn::ExecutionPreference& executionPreference) {
588 return V1_1::utils::convert(executionPreference);
589}
590
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800591} // namespace android::hardware::neuralnetworks::V1_2::utils