blob: 78d71cf990614dadf78b0613a9169db53a7c1352 [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) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700134 const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
135 const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800136 return Capabilities::OperandPerformance{
Michael Butler7ecc2902022-04-25 22:36:51 -0700137 .type = type,
138 .info = info,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800139 };
140}
141
Michael Butler6547b2a2020-11-22 19:36:30 -0800142GeneralResult<Operation> unvalidatedConvert(const hal::V1_2::Operation& operation) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700143 const auto type = NN_TRY(unvalidatedConvert(operation.type));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800144 return Operation{
Michael Butler7ecc2902022-04-25 22:36:51 -0700145 .type = type,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800146 .inputs = operation.inputs,
147 .outputs = operation.outputs,
148 };
149}
150
Michael Butler6547b2a2020-11-22 19:36:30 -0800151GeneralResult<Operand::SymmPerChannelQuantParams> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800152 const hal::V1_2::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
153 return Operand::SymmPerChannelQuantParams{
154 .scales = symmPerChannelQuantParams.scales,
155 .channelDim = symmPerChannelQuantParams.channelDim,
156 };
157}
158
Michael Butler6547b2a2020-11-22 19:36:30 -0800159GeneralResult<Operand> unvalidatedConvert(const hal::V1_2::Operand& operand) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700160 const auto type = NN_TRY(unvalidatedConvert(operand.type));
161 const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
162 const auto location = NN_TRY(unvalidatedConvert(operand.location));
163 auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800164 return Operand{
Michael Butler7ecc2902022-04-25 22:36:51 -0700165 .type = type,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800166 .dimensions = operand.dimensions,
167 .scale = operand.scale,
168 .zeroPoint = operand.zeroPoint,
Michael Butler7ecc2902022-04-25 22:36:51 -0700169 .lifetime = lifetime,
170 .location = location,
171 .extraParams = std::move(extraParams),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800172 };
173}
174
Michael Butler6547b2a2020-11-22 19:36:30 -0800175GeneralResult<Operand::ExtraParams> unvalidatedConvert(
176 const hal::V1_2::Operand::ExtraParams& extraParams) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800177 using Discriminator = hal::V1_2::Operand::ExtraParams::hidl_discriminator;
178 switch (extraParams.getDiscriminator()) {
179 case Discriminator::none:
180 return Operand::NoParams{};
181 case Discriminator::channelQuant:
Michael Butler6547b2a2020-11-22 19:36:30 -0800182 return unvalidatedConvert(extraParams.channelQuant());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800183 case Discriminator::extension:
184 return extraParams.extension();
185 }
Michael Butler4b276a72020-08-06 23:22:35 -0700186 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
187 << "Unrecognized Operand::ExtraParams discriminator: "
188 << underlyingType(extraParams.getDiscriminator());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800189}
190
Michael Butler6547b2a2020-11-22 19:36:30 -0800191GeneralResult<Model> unvalidatedConvert(const hal::V1_2::Model& model) {
192 auto operations = NN_TRY(unvalidatedConvert(model.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800193
194 // Verify number of consumers.
195 const auto numberOfConsumers =
Michael Butler301ef062021-10-14 22:04:59 -0700196 NN_TRY(countNumberOfConsumers(model.operands.size(), operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800197 CHECK(model.operands.size() == numberOfConsumers.size());
198 for (size_t i = 0; i < model.operands.size(); ++i) {
199 if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
Michael Butler4b276a72020-08-06 23:22:35 -0700200 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
201 << "Invalid numberOfConsumers for operand " << i << ", expected "
202 << numberOfConsumers[i] << " but found " << model.operands[i].numberOfConsumers;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800203 }
204 }
205
Michael Butler7ecc2902022-04-25 22:36:51 -0700206 auto operands = NN_TRY(unvalidatedConvert(model.operands));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800207 auto main = Model::Subgraph{
Michael Butler7ecc2902022-04-25 22:36:51 -0700208 .operands = std::move(operands),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800209 .operations = std::move(operations),
210 .inputIndexes = model.inputIndexes,
211 .outputIndexes = model.outputIndexes,
212 };
213
Michael Butler7ecc2902022-04-25 22:36:51 -0700214 auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
215 auto pools = NN_TRY(unvalidatedConvert(model.pools));
216 auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800217 return Model{
218 .main = std::move(main),
Michael Butler7ecc2902022-04-25 22:36:51 -0700219 .operandValues = std::move(operandValues),
220 .pools = std::move(pools),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800221 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
Michael Butler7ecc2902022-04-25 22:36:51 -0700222 .extensionNameToPrefix = std::move(extensionNameToPrefix),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800223 };
224}
225
Miao Wang0e671f32021-10-26 20:03:05 +0000226GeneralResult<ExtensionNameAndPrefix> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800227 const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
Miao Wang0e671f32021-10-26 20:03:05 +0000228 return ExtensionNameAndPrefix{
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800229 .name = extensionNameAndPrefix.name,
230 .prefix = extensionNameAndPrefix.prefix,
231 };
232}
233
Michael Butler6547b2a2020-11-22 19:36:30 -0800234GeneralResult<OutputShape> unvalidatedConvert(const hal::V1_2::OutputShape& outputShape) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800235 return OutputShape{
236 .dimensions = outputShape.dimensions,
237 .isSufficient = outputShape.isSufficient,
238 };
239}
240
Michael Butler6547b2a2020-11-22 19:36:30 -0800241GeneralResult<MeasureTiming> unvalidatedConvert(const hal::V1_2::MeasureTiming& measureTiming) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800242 return static_cast<MeasureTiming>(measureTiming);
243}
244
Michael Butler6547b2a2020-11-22 19:36:30 -0800245GeneralResult<Timing> unvalidatedConvert(const hal::V1_2::Timing& timing) {
Michael Butler4024d8f2020-12-04 17:38:20 -0800246 constexpr uint64_t kMaxTiming = std::chrono::floor<HalDuration>(Duration::max()).count();
247 constexpr auto convertTiming = [](uint64_t halTiming) -> OptionalDuration {
Michael Butler388bceb2021-02-03 15:15:43 -0800248 constexpr uint64_t kNoTiming = std::numeric_limits<uint64_t>::max();
Michael Butler4024d8f2020-12-04 17:38:20 -0800249 if (halTiming == kNoTiming) {
250 return {};
251 }
252 if (halTiming > kMaxTiming) {
253 return Duration::max();
254 }
255 return HalDuration{halTiming};
256 };
257 return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice),
258 .timeInDriver = convertTiming(timing.timeInDriver)};
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800259}
260
Michael Butler6547b2a2020-11-22 19:36:30 -0800261GeneralResult<Extension> unvalidatedConvert(const hal::V1_2::Extension& extension) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700262 auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800263 return Extension{
264 .name = extension.name,
Michael Butler7ecc2902022-04-25 22:36:51 -0700265 .operandTypes = std::move(operandTypes),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800266 };
267}
268
Michael Butler6547b2a2020-11-22 19:36:30 -0800269GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800270 const hal::V1_2::Extension::OperandTypeInformation& operandTypeInformation) {
271 return Extension::OperandTypeInformation{
272 .type = operandTypeInformation.type,
273 .isTensor = operandTypeInformation.isTensor,
274 .byteSize = operandTypeInformation.byteSize,
275 };
276}
277
Michael Butler6547b2a2020-11-22 19:36:30 -0800278GeneralResult<DeviceType> convert(const hal::V1_2::DeviceType& deviceType) {
279 return validatedConvert(deviceType);
280}
281
282GeneralResult<Capabilities> convert(const hal::V1_2::Capabilities& capabilities) {
283 return validatedConvert(capabilities);
284}
285
286GeneralResult<Model> convert(const hal::V1_2::Model& model) {
287 return validatedConvert(model);
288}
289
290GeneralResult<MeasureTiming> convert(const hal::V1_2::MeasureTiming& measureTiming) {
291 return validatedConvert(measureTiming);
292}
293
294GeneralResult<Timing> convert(const hal::V1_2::Timing& timing) {
295 return validatedConvert(timing);
296}
297
Michael Butler76e491f2020-12-19 01:55:32 -0800298GeneralResult<SharedMemory> convert(const hardware::hidl_memory& memory) {
299 return validatedConvert(memory);
300}
301
Michael Butler4b276a72020-08-06 23:22:35 -0700302GeneralResult<std::vector<Extension>> convert(const hidl_vec<hal::V1_2::Extension>& extensions) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800303 return validatedConvert(extensions);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800304}
305
Slava Shklyaev49817a02020-10-27 18:44:01 +0000306GeneralResult<std::vector<SharedHandle>> convert(const hidl_vec<hidl_handle>& handles) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800307 return validatedConvert(handles);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800308}
309
Michael Butler4b276a72020-08-06 23:22:35 -0700310GeneralResult<std::vector<OutputShape>> convert(
311 const hidl_vec<hal::V1_2::OutputShape>& outputShapes) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800312 return validatedConvert(outputShapes);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800313}
314
315} // namespace android::nn
316
317namespace android::hardware::neuralnetworks::V1_2::utils {
318namespace {
319
Michael Butler6547b2a2020-11-22 19:36:30 -0800320using utils::unvalidatedConvert;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800321
Michael Butler6547b2a2020-11-22 19:36:30 -0800322nn::GeneralResult<V1_0::OperandLifeTime> unvalidatedConvert(const nn::Operand::LifeTime& lifetime) {
323 return V1_0::utils::unvalidatedConvert(lifetime);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800324}
325
Michael Butler6547b2a2020-11-22 19:36:30 -0800326nn::GeneralResult<V1_0::PerformanceInfo> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800327 const nn::Capabilities::PerformanceInfo& performanceInfo) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800328 return V1_0::utils::unvalidatedConvert(performanceInfo);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800329}
330
Michael Butler6547b2a2020-11-22 19:36:30 -0800331nn::GeneralResult<V1_0::DataLocation> unvalidatedConvert(const nn::DataLocation& location) {
332 return V1_0::utils::unvalidatedConvert(location);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800333}
334
Michael Butler6547b2a2020-11-22 19:36:30 -0800335nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
336 const nn::Model::OperandValues& operandValues) {
337 return V1_0::utils::unvalidatedConvert(operandValues);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800338}
339
Michael Butler15965822021-10-14 23:45:11 -0700340nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle) {
341 return V1_0::utils::unvalidatedConvert(handle);
342}
343
Michael Butlerfadeb8a2021-02-07 00:11:13 -0800344nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::SharedMemory& memory) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800345 return V1_0::utils::unvalidatedConvert(memory);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800346}
347
348template <typename Input>
Michael Butler388bceb2021-02-03 15:15:43 -0800349using UnvalidatedConvertOutput =
Michael Butler6547b2a2020-11-22 19:36:30 -0800350 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800351
352template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800353nn::GeneralResult<hidl_vec<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800354 const std::vector<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -0800355 hidl_vec<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800356 for (size_t i = 0; i < arguments.size(); ++i) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800357 halObject[i] = NN_TRY(unvalidatedConvert(arguments[i]));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800358 }
359 return halObject;
360}
361
Michael Butler4b276a72020-08-06 23:22:35 -0700362nn::GeneralResult<Operand::ExtraParams> makeExtraParams(nn::Operand::NoParams /*noParams*/) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800363 return Operand::ExtraParams{};
364}
365
Michael Butler4b276a72020-08-06 23:22:35 -0700366nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800367 const nn::Operand::SymmPerChannelQuantParams& channelQuant) {
368 Operand::ExtraParams ret;
Michael Butler6547b2a2020-11-22 19:36:30 -0800369 ret.channelQuant(NN_TRY(unvalidatedConvert(channelQuant)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800370 return ret;
371}
372
Michael Butler4b276a72020-08-06 23:22:35 -0700373nn::GeneralResult<Operand::ExtraParams> makeExtraParams(
374 const nn::Operand::ExtensionParams& extension) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800375 Operand::ExtraParams ret;
376 ret.extension(extension);
377 return ret;
378}
379
Michael Butler6547b2a2020-11-22 19:36:30 -0800380template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800381nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) {
382 NN_TRY(compliantVersion(canonical));
383 return unvalidatedConvert(canonical);
Michael Butler6547b2a2020-11-22 19:36:30 -0800384}
385
386template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800387nn::GeneralResult<hidl_vec<UnvalidatedConvertOutput<Type>>> validatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800388 const std::vector<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -0800389 hidl_vec<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butler6547b2a2020-11-22 19:36:30 -0800390 for (size_t i = 0; i < arguments.size(); ++i) {
391 halObject[i] = NN_TRY(validatedConvert(arguments[i]));
392 }
393 return halObject;
394}
395
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800396} // anonymous namespace
397
Michael Butler6547b2a2020-11-22 19:36:30 -0800398nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800399 return static_cast<OperandType>(operandType);
400}
401
Michael Butler6547b2a2020-11-22 19:36:30 -0800402nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800403 return static_cast<OperationType>(operationType);
404}
405
Michael Butler6547b2a2020-11-22 19:36:30 -0800406nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800407 switch (deviceType) {
408 case nn::DeviceType::UNKNOWN:
Michael Butler4b276a72020-08-06 23:22:35 -0700409 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Invalid DeviceType UNKNOWN";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800410 case nn::DeviceType::OTHER:
411 case nn::DeviceType::CPU:
412 case nn::DeviceType::GPU:
413 case nn::DeviceType::ACCELERATOR:
414 return static_cast<DeviceType>(deviceType);
415 }
Michael Butler4b276a72020-08-06 23:22:35 -0700416 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
417 << "Invalid DeviceType " << underlyingType(deviceType);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800418}
419
Michael Butler6547b2a2020-11-22 19:36:30 -0800420nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700421 std::vector<nn::Capabilities::OperandPerformance> filteredOperandPerformances;
422 filteredOperandPerformances.reserve(capabilities.operandPerformance.asVector().size());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800423 std::copy_if(capabilities.operandPerformance.asVector().begin(),
424 capabilities.operandPerformance.asVector().end(),
Michael Butler7ecc2902022-04-25 22:36:51 -0700425 std::back_inserter(filteredOperandPerformances),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800426 [](const nn::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler388bceb2021-02-03 15:15:43 -0800427 return compliantVersion(operandPerformance.type).has_value();
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800428 });
429
Michael Butler7ecc2902022-04-25 22:36:51 -0700430 const auto relaxedFloat32toFloat16PerformanceScalar =
431 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
432 const auto relaxedFloat32toFloat16PerformanceTensor =
433 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
434 auto operandPerformance = NN_TRY(unvalidatedConvert(filteredOperandPerformances));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800435 return Capabilities{
Michael Butler7ecc2902022-04-25 22:36:51 -0700436 .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
437 .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
438 .operandPerformance = std::move(operandPerformance),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800439 };
440}
441
Michael Butler6547b2a2020-11-22 19:36:30 -0800442nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800443 const nn::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700444 const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
445 const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800446 return Capabilities::OperandPerformance{
Michael Butler7ecc2902022-04-25 22:36:51 -0700447 .type = type,
448 .info = info,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800449 };
450}
451
Michael Butler6547b2a2020-11-22 19:36:30 -0800452nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700453 const auto type = NN_TRY(unvalidatedConvert(operation.type));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800454 return Operation{
Michael Butler7ecc2902022-04-25 22:36:51 -0700455 .type = type,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800456 .inputs = operation.inputs,
457 .outputs = operation.outputs,
458 };
459}
460
Michael Butler6547b2a2020-11-22 19:36:30 -0800461nn::GeneralResult<SymmPerChannelQuantParams> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800462 const nn::Operand::SymmPerChannelQuantParams& symmPerChannelQuantParams) {
463 return SymmPerChannelQuantParams{
464 .scales = symmPerChannelQuantParams.scales,
465 .channelDim = symmPerChannelQuantParams.channelDim,
466 };
467}
468
Michael Butler6547b2a2020-11-22 19:36:30 -0800469nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700470 const auto type = NN_TRY(unvalidatedConvert(operand.type));
471 const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
472 const auto location = NN_TRY(unvalidatedConvert(operand.location));
473 auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800474 return Operand{
Michael Butler7ecc2902022-04-25 22:36:51 -0700475 .type = type,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800476 .dimensions = operand.dimensions,
477 .numberOfConsumers = 0,
478 .scale = operand.scale,
479 .zeroPoint = operand.zeroPoint,
Michael Butler7ecc2902022-04-25 22:36:51 -0700480 .lifetime = lifetime,
481 .location = location,
482 .extraParams = std::move(extraParams),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800483 };
484}
485
Michael Butler6547b2a2020-11-22 19:36:30 -0800486nn::GeneralResult<Operand::ExtraParams> unvalidatedConvert(
487 const nn::Operand::ExtraParams& extraParams) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800488 return std::visit([](const auto& x) { return makeExtraParams(x); }, extraParams);
489}
490
Michael Butler6547b2a2020-11-22 19:36:30 -0800491nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800492 if (!hal::utils::hasNoPointerData(model)) {
Michael Butler4b276a72020-08-06 23:22:35 -0700493 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler6547b2a2020-11-22 19:36:30 -0800494 << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800495 }
496
Michael Butler6547b2a2020-11-22 19:36:30 -0800497 auto operands = NN_TRY(unvalidatedConvert(model.main.operands));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800498
499 // Update number of consumers.
500 const auto numberOfConsumers =
Michael Butler301ef062021-10-14 22:04:59 -0700501 NN_TRY(countNumberOfConsumers(operands.size(), model.main.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800502 CHECK(operands.size() == numberOfConsumers.size());
503 for (size_t i = 0; i < operands.size(); ++i) {
504 operands[i].numberOfConsumers = numberOfConsumers[i];
505 }
506
Michael Butler7ecc2902022-04-25 22:36:51 -0700507 auto operations = NN_TRY(unvalidatedConvert(model.main.operations));
508 auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
509 auto pools = NN_TRY(unvalidatedConvert(model.pools));
510 auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800511 return Model{
512 .operands = std::move(operands),
Michael Butler7ecc2902022-04-25 22:36:51 -0700513 .operations = std::move(operations),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800514 .inputIndexes = model.main.inputIndexes,
515 .outputIndexes = model.main.outputIndexes,
Michael Butler7ecc2902022-04-25 22:36:51 -0700516 .operandValues = std::move(operandValues),
517 .pools = std::move(pools),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800518 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
Michael Butler7ecc2902022-04-25 22:36:51 -0700519 .extensionNameToPrefix = std::move(extensionNameToPrefix),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800520 };
521}
522
Michael Butler6547b2a2020-11-22 19:36:30 -0800523nn::GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
Miao Wang0e671f32021-10-26 20:03:05 +0000524 const nn::ExtensionNameAndPrefix& extensionNameAndPrefix) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800525 return Model::ExtensionNameAndPrefix{
526 .name = extensionNameAndPrefix.name,
527 .prefix = extensionNameAndPrefix.prefix,
528 };
529}
530
Michael Butler6547b2a2020-11-22 19:36:30 -0800531nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800532 return OutputShape{.dimensions = outputShape.dimensions,
533 .isSufficient = outputShape.isSufficient};
534}
535
Michael Butler6547b2a2020-11-22 19:36:30 -0800536nn::GeneralResult<MeasureTiming> unvalidatedConvert(const nn::MeasureTiming& measureTiming) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800537 return static_cast<MeasureTiming>(measureTiming);
538}
539
Michael Butler6547b2a2020-11-22 19:36:30 -0800540nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) {
Michael Butler4024d8f2020-12-04 17:38:20 -0800541 constexpr auto convertTiming = [](nn::OptionalDuration canonicalTiming) -> uint64_t {
Michael Butler388bceb2021-02-03 15:15:43 -0800542 constexpr uint64_t kNoTiming = std::numeric_limits<uint64_t>::max();
Michael Butler4024d8f2020-12-04 17:38:20 -0800543 if (!canonicalTiming.has_value()) {
544 return kNoTiming;
545 }
546 return std::chrono::ceil<HalDuration>(*canonicalTiming).count();
547 };
548 return Timing{.timeOnDevice = convertTiming(timing.timeOnDevice),
549 .timeInDriver = convertTiming(timing.timeInDriver)};
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800550}
551
Michael Butler6547b2a2020-11-22 19:36:30 -0800552nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700553 auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800554 return Extension{
555 .name = extension.name,
Michael Butler7ecc2902022-04-25 22:36:51 -0700556 .operandTypes = std::move(operandTypes),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800557 };
558}
559
Michael Butler6547b2a2020-11-22 19:36:30 -0800560nn::GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800561 const nn::Extension::OperandTypeInformation& operandTypeInformation) {
562 return Extension::OperandTypeInformation{
563 .type = operandTypeInformation.type,
564 .isTensor = operandTypeInformation.isTensor,
565 .byteSize = operandTypeInformation.byteSize,
566 };
567}
568
Michael Butler6547b2a2020-11-22 19:36:30 -0800569nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
570 return validatedConvert(deviceType);
571}
572
573nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
574 return validatedConvert(capabilities);
575}
576
577nn::GeneralResult<Model> convert(const nn::Model& model) {
578 return validatedConvert(model);
579}
580
581nn::GeneralResult<MeasureTiming> convert(const nn::MeasureTiming& measureTiming) {
582 return validatedConvert(measureTiming);
583}
584
585nn::GeneralResult<Timing> convert(const nn::Timing& timing) {
586 return validatedConvert(timing);
587}
588
Michael Butler4b276a72020-08-06 23:22:35 -0700589nn::GeneralResult<hidl_vec<Extension>> convert(const std::vector<nn::Extension>& extensions) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800590 return validatedConvert(extensions);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800591}
592
Slava Shklyaev49817a02020-10-27 18:44:01 +0000593nn::GeneralResult<hidl_vec<hidl_handle>> convert(const std::vector<nn::SharedHandle>& handles) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800594 return validatedConvert(handles);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800595}
596
Michael Butler4b276a72020-08-06 23:22:35 -0700597nn::GeneralResult<hidl_vec<OutputShape>> convert(const std::vector<nn::OutputShape>& outputShapes) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800598 return validatedConvert(outputShapes);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800599}
600
Michael Butler7fd03c22020-12-06 21:50:59 -0800601nn::GeneralResult<V1_0::DeviceStatus> convert(const nn::DeviceStatus& deviceStatus) {
602 return V1_1::utils::convert(deviceStatus);
603}
604
605nn::GeneralResult<V1_0::Request> convert(const nn::Request& request) {
606 return V1_1::utils::convert(request);
607}
608
609nn::GeneralResult<V1_0::ErrorStatus> convert(const nn::ErrorStatus& status) {
610 return V1_1::utils::convert(status);
611}
612
613nn::GeneralResult<V1_1::ExecutionPreference> convert(
614 const nn::ExecutionPreference& executionPreference) {
615 return V1_1::utils::convert(executionPreference);
616}
617
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800618} // namespace android::hardware::neuralnetworks::V1_2::utils