blob: 34862c00cbfd5b00910a3f3233e38b6d7d33ac8e [file] [log] [blame]
Michael Butlera685c3d2020-02-22 22:37:59 -08001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Conversions.h"
18
19#include <android-base/logging.h>
20#include <android/hardware/neuralnetworks/1.0/types.h>
21#include <nnapi/OperandTypes.h>
22#include <nnapi/OperationTypes.h>
23#include <nnapi/Result.h>
24#include <nnapi/SharedMemory.h>
Michael Butler32acc062020-11-22 19:36:30 -080025#include <nnapi/TypeUtils.h>
Michael Butlera685c3d2020-02-22 22:37:59 -080026#include <nnapi/Types.h>
Michael Butler32acc062020-11-22 19:36:30 -080027#include <nnapi/Validation.h>
Michael Butlera685c3d2020-02-22 22:37:59 -080028#include <nnapi/hal/CommonUtils.h>
29
30#include <algorithm>
31#include <functional>
32#include <iterator>
33#include <memory>
34#include <type_traits>
35#include <utility>
36#include <variant>
37
38namespace {
39
40template <typename Type>
41constexpr std::underlying_type_t<Type> underlyingType(Type value) {
42 return static_cast<std::underlying_type_t<Type>>(value);
43}
44
Michael Butler32acc062020-11-22 19:36:30 -080045constexpr auto kVersion = android::nn::Version::ANDROID_OC_MR1;
46
Michael Butlera685c3d2020-02-22 22:37:59 -080047} // namespace
48
49namespace android::nn {
50namespace {
51
52using hardware::hidl_memory;
53using hardware::hidl_vec;
54
55template <typename Input>
Michael Butler32acc062020-11-22 19:36:30 -080056using unvalidatedConvertOutput =
57 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlera685c3d2020-02-22 22:37:59 -080058
59template <typename Type>
Michael Butler32acc062020-11-22 19:36:30 -080060GeneralResult<std::vector<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
61 const hidl_vec<Type>& arguments) {
62 std::vector<unvalidatedConvertOutput<Type>> canonical;
Michael Butlera685c3d2020-02-22 22:37:59 -080063 canonical.reserve(arguments.size());
64 for (const auto& argument : arguments) {
Michael Butler32acc062020-11-22 19:36:30 -080065 canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument)));
66 }
67 return canonical;
68}
69
70template <typename Type>
71decltype(nn::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& halObject) {
72 auto canonical = NN_TRY(nn::unvalidatedConvert(halObject));
73 const auto maybeVersion = validate(canonical);
74 if (!maybeVersion.has_value()) {
75 return error() << maybeVersion.error();
76 }
77 const auto version = maybeVersion.value();
78 if (version > kVersion) {
79 return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
Michael Butlera685c3d2020-02-22 22:37:59 -080080 }
81 return canonical;
82}
83
84} // anonymous namespace
85
Michael Butler32acc062020-11-22 19:36:30 -080086GeneralResult<OperandType> unvalidatedConvert(const hal::V1_0::OperandType& operandType) {
Michael Butlera685c3d2020-02-22 22:37:59 -080087 return static_cast<OperandType>(operandType);
88}
89
Michael Butler32acc062020-11-22 19:36:30 -080090GeneralResult<OperationType> unvalidatedConvert(const hal::V1_0::OperationType& operationType) {
Michael Butlera685c3d2020-02-22 22:37:59 -080091 return static_cast<OperationType>(operationType);
92}
93
Michael Butler32acc062020-11-22 19:36:30 -080094GeneralResult<Operand::LifeTime> unvalidatedConvert(const hal::V1_0::OperandLifeTime& lifetime) {
Michael Butlera685c3d2020-02-22 22:37:59 -080095 return static_cast<Operand::LifeTime>(lifetime);
96}
97
Michael Butler32acc062020-11-22 19:36:30 -080098GeneralResult<DeviceStatus> unvalidatedConvert(const hal::V1_0::DeviceStatus& deviceStatus) {
Michael Butlera685c3d2020-02-22 22:37:59 -080099 return static_cast<DeviceStatus>(deviceStatus);
100}
101
Michael Butler32acc062020-11-22 19:36:30 -0800102GeneralResult<Capabilities::PerformanceInfo> unvalidatedConvert(
Michael Butler3670c382020-08-06 23:22:35 -0700103 const hal::V1_0::PerformanceInfo& performanceInfo) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800104 return Capabilities::PerformanceInfo{
105 .execTime = performanceInfo.execTime,
106 .powerUsage = performanceInfo.powerUsage,
107 };
108}
109
Michael Butler32acc062020-11-22 19:36:30 -0800110GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_0::Capabilities& capabilities) {
111 const auto quantized8Performance =
112 NN_TRY(unvalidatedConvert(capabilities.quantized8Performance));
113 const auto float32Performance = NN_TRY(unvalidatedConvert(capabilities.float32Performance));
Michael Butlera685c3d2020-02-22 22:37:59 -0800114
115 auto table = hal::utils::makeQuantized8PerformanceConsistentWithP(float32Performance,
116 quantized8Performance);
117
118 return Capabilities{
119 .relaxedFloat32toFloat16PerformanceScalar = float32Performance,
120 .relaxedFloat32toFloat16PerformanceTensor = float32Performance,
121 .operandPerformance = std::move(table),
122 };
123}
124
Michael Butler32acc062020-11-22 19:36:30 -0800125GeneralResult<DataLocation> unvalidatedConvert(const hal::V1_0::DataLocation& location) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800126 return DataLocation{
127 .poolIndex = location.poolIndex,
128 .offset = location.offset,
129 .length = location.length,
130 };
131}
132
Michael Butler32acc062020-11-22 19:36:30 -0800133GeneralResult<Operand> unvalidatedConvert(const hal::V1_0::Operand& operand) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800134 return Operand{
Michael Butler32acc062020-11-22 19:36:30 -0800135 .type = NN_TRY(unvalidatedConvert(operand.type)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800136 .dimensions = operand.dimensions,
137 .scale = operand.scale,
138 .zeroPoint = operand.zeroPoint,
Michael Butler32acc062020-11-22 19:36:30 -0800139 .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
140 .location = NN_TRY(unvalidatedConvert(operand.location)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800141 };
142}
143
Michael Butler32acc062020-11-22 19:36:30 -0800144GeneralResult<Operation> unvalidatedConvert(const hal::V1_0::Operation& operation) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800145 return Operation{
Michael Butler32acc062020-11-22 19:36:30 -0800146 .type = NN_TRY(unvalidatedConvert(operation.type)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800147 .inputs = operation.inputs,
148 .outputs = operation.outputs,
149 };
150}
151
Michael Butler32acc062020-11-22 19:36:30 -0800152GeneralResult<Model::OperandValues> unvalidatedConvert(const hidl_vec<uint8_t>& operandValues) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800153 return Model::OperandValues(operandValues.data(), operandValues.size());
154}
155
Michael Butler79a16eb2021-02-07 00:11:13 -0800156GeneralResult<SharedMemory> unvalidatedConvert(const hidl_memory& memory) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800157 return createSharedMemoryFromHidlMemory(memory);
158}
159
Michael Butler32acc062020-11-22 19:36:30 -0800160GeneralResult<Model> unvalidatedConvert(const hal::V1_0::Model& model) {
161 auto operations = NN_TRY(unvalidatedConvert(model.operations));
Michael Butlera685c3d2020-02-22 22:37:59 -0800162
163 // Verify number of consumers.
164 const auto numberOfConsumers =
165 hal::utils::countNumberOfConsumers(model.operands.size(), operations);
166 CHECK(model.operands.size() == numberOfConsumers.size());
167 for (size_t i = 0; i < model.operands.size(); ++i) {
168 if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
Michael Butler3670c382020-08-06 23:22:35 -0700169 return NN_ERROR(ErrorStatus::GENERAL_FAILURE)
170 << "Invalid numberOfConsumers for operand " << i << ", expected "
171 << numberOfConsumers[i] << " but found " << model.operands[i].numberOfConsumers;
Michael Butlera685c3d2020-02-22 22:37:59 -0800172 }
173 }
174
175 auto main = Model::Subgraph{
Michael Butler32acc062020-11-22 19:36:30 -0800176 .operands = NN_TRY(unvalidatedConvert(model.operands)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800177 .operations = std::move(operations),
178 .inputIndexes = model.inputIndexes,
179 .outputIndexes = model.outputIndexes,
180 };
181
182 return Model{
183 .main = std::move(main),
Michael Butler32acc062020-11-22 19:36:30 -0800184 .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
185 .pools = NN_TRY(unvalidatedConvert(model.pools)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800186 };
187}
188
Michael Butler32acc062020-11-22 19:36:30 -0800189GeneralResult<Request::Argument> unvalidatedConvert(const hal::V1_0::RequestArgument& argument) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800190 const auto lifetime = argument.hasNoValue ? Request::Argument::LifeTime::NO_VALUE
191 : Request::Argument::LifeTime::POOL;
192 return Request::Argument{
193 .lifetime = lifetime,
Michael Butler32acc062020-11-22 19:36:30 -0800194 .location = NN_TRY(unvalidatedConvert(argument.location)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800195 .dimensions = argument.dimensions,
196 };
197}
198
Michael Butler32acc062020-11-22 19:36:30 -0800199GeneralResult<Request> unvalidatedConvert(const hal::V1_0::Request& request) {
200 auto memories = NN_TRY(unvalidatedConvert(request.pools));
Michael Butlera685c3d2020-02-22 22:37:59 -0800201 std::vector<Request::MemoryPool> pools;
202 pools.reserve(memories.size());
203 std::move(memories.begin(), memories.end(), std::back_inserter(pools));
204
205 return Request{
Michael Butler32acc062020-11-22 19:36:30 -0800206 .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
207 .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800208 .pools = std::move(pools),
209 };
210}
211
Michael Butler32acc062020-11-22 19:36:30 -0800212GeneralResult<ErrorStatus> unvalidatedConvert(const hal::V1_0::ErrorStatus& status) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800213 switch (status) {
214 case hal::V1_0::ErrorStatus::NONE:
215 case hal::V1_0::ErrorStatus::DEVICE_UNAVAILABLE:
216 case hal::V1_0::ErrorStatus::GENERAL_FAILURE:
217 case hal::V1_0::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE:
218 case hal::V1_0::ErrorStatus::INVALID_ARGUMENT:
219 return static_cast<ErrorStatus>(status);
220 }
Michael Butler3670c382020-08-06 23:22:35 -0700221 return NN_ERROR(ErrorStatus::GENERAL_FAILURE)
222 << "Invalid ErrorStatus " << underlyingType(status);
Michael Butlera685c3d2020-02-22 22:37:59 -0800223}
224
Michael Butler32acc062020-11-22 19:36:30 -0800225GeneralResult<DeviceStatus> convert(const hal::V1_0::DeviceStatus& deviceStatus) {
226 return validatedConvert(deviceStatus);
227}
228
229GeneralResult<Capabilities> convert(const hal::V1_0::Capabilities& capabilities) {
230 return validatedConvert(capabilities);
231}
232
233GeneralResult<Model> convert(const hal::V1_0::Model& model) {
234 return validatedConvert(model);
235}
236
237GeneralResult<Request> convert(const hal::V1_0::Request& request) {
238 return validatedConvert(request);
239}
240
241GeneralResult<ErrorStatus> convert(const hal::V1_0::ErrorStatus& status) {
242 return validatedConvert(status);
243}
244
Michael Butlera685c3d2020-02-22 22:37:59 -0800245} // namespace android::nn
246
247namespace android::hardware::neuralnetworks::V1_0::utils {
248namespace {
249
250template <typename Input>
Michael Butler32acc062020-11-22 19:36:30 -0800251using unvalidatedConvertOutput =
252 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlera685c3d2020-02-22 22:37:59 -0800253
254template <typename Type>
Michael Butler32acc062020-11-22 19:36:30 -0800255nn::GeneralResult<hidl_vec<unvalidatedConvertOutput<Type>>> unvalidatedConvert(
256 const std::vector<Type>& arguments) {
257 hidl_vec<unvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butlera685c3d2020-02-22 22:37:59 -0800258 for (size_t i = 0; i < arguments.size(); ++i) {
Michael Butler32acc062020-11-22 19:36:30 -0800259 halObject[i] = NN_TRY(utils::unvalidatedConvert(arguments[i]));
Michael Butlera685c3d2020-02-22 22:37:59 -0800260 }
261 return halObject;
262}
263
Michael Butler32acc062020-11-22 19:36:30 -0800264template <typename Type>
265decltype(utils::unvalidatedConvert(std::declval<Type>())) validatedConvert(const Type& canonical) {
266 const auto maybeVersion = nn::validate(canonical);
267 if (!maybeVersion.has_value()) {
268 return nn::error() << maybeVersion.error();
269 }
270 const auto version = maybeVersion.value();
271 if (version > kVersion) {
272 return NN_ERROR() << "Insufficient version: " << version << " vs required " << kVersion;
273 }
274 return utils::unvalidatedConvert(canonical);
275}
276
Michael Butlera685c3d2020-02-22 22:37:59 -0800277} // anonymous namespace
278
Michael Butler32acc062020-11-22 19:36:30 -0800279nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800280 return static_cast<OperandType>(operandType);
281}
282
Michael Butler32acc062020-11-22 19:36:30 -0800283nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800284 return static_cast<OperationType>(operationType);
285}
286
Michael Butler32acc062020-11-22 19:36:30 -0800287nn::GeneralResult<OperandLifeTime> unvalidatedConvert(const nn::Operand::LifeTime& lifetime) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800288 if (lifetime == nn::Operand::LifeTime::POINTER) {
Michael Butler3670c382020-08-06 23:22:35 -0700289 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler32acc062020-11-22 19:36:30 -0800290 << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlera685c3d2020-02-22 22:37:59 -0800291 }
292 return static_cast<OperandLifeTime>(lifetime);
293}
294
Michael Butler32acc062020-11-22 19:36:30 -0800295nn::GeneralResult<DeviceStatus> unvalidatedConvert(const nn::DeviceStatus& deviceStatus) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800296 return static_cast<DeviceStatus>(deviceStatus);
297}
298
Michael Butler32acc062020-11-22 19:36:30 -0800299nn::GeneralResult<PerformanceInfo> unvalidatedConvert(
Michael Butler3670c382020-08-06 23:22:35 -0700300 const nn::Capabilities::PerformanceInfo& performanceInfo) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800301 return PerformanceInfo{
302 .execTime = performanceInfo.execTime,
303 .powerUsage = performanceInfo.powerUsage,
304 };
305}
306
Michael Butler32acc062020-11-22 19:36:30 -0800307nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800308 return Capabilities{
Michael Butler32acc062020-11-22 19:36:30 -0800309 .float32Performance = NN_TRY(unvalidatedConvert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800310 capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_FLOAT32))),
Michael Butler32acc062020-11-22 19:36:30 -0800311 .quantized8Performance = NN_TRY(unvalidatedConvert(
Michael Butlera685c3d2020-02-22 22:37:59 -0800312 capabilities.operandPerformance.lookup(nn::OperandType::TENSOR_QUANT8_ASYMM))),
313 };
314}
315
Michael Butler32acc062020-11-22 19:36:30 -0800316nn::GeneralResult<DataLocation> unvalidatedConvert(const nn::DataLocation& location) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800317 return DataLocation{
318 .poolIndex = location.poolIndex,
319 .offset = location.offset,
320 .length = location.length,
321 };
322}
323
Michael Butler32acc062020-11-22 19:36:30 -0800324nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800325 return Operand{
Michael Butler32acc062020-11-22 19:36:30 -0800326 .type = NN_TRY(unvalidatedConvert(operand.type)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800327 .dimensions = operand.dimensions,
328 .numberOfConsumers = 0,
329 .scale = operand.scale,
330 .zeroPoint = operand.zeroPoint,
Michael Butler32acc062020-11-22 19:36:30 -0800331 .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
332 .location = NN_TRY(unvalidatedConvert(operand.location)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800333 };
334}
335
Michael Butler32acc062020-11-22 19:36:30 -0800336nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800337 return Operation{
Michael Butler32acc062020-11-22 19:36:30 -0800338 .type = NN_TRY(unvalidatedConvert(operation.type)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800339 .inputs = operation.inputs,
340 .outputs = operation.outputs,
341 };
342}
343
Michael Butler32acc062020-11-22 19:36:30 -0800344nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
345 const nn::Model::OperandValues& operandValues) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800346 return hidl_vec<uint8_t>(operandValues.data(), operandValues.data() + operandValues.size());
347}
348
Michael Butler79a16eb2021-02-07 00:11:13 -0800349nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::SharedMemory& memory) {
350 CHECK(memory != nullptr);
351 return hidl_memory(memory->name, NN_TRY(hal::utils::hidlHandleFromSharedHandle(memory->handle)),
352 memory->size);
Michael Butlera685c3d2020-02-22 22:37:59 -0800353}
354
Michael Butler32acc062020-11-22 19:36:30 -0800355nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800356 if (!hal::utils::hasNoPointerData(model)) {
Michael Butler3670c382020-08-06 23:22:35 -0700357 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler32acc062020-11-22 19:36:30 -0800358 << "Mdoel cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlera685c3d2020-02-22 22:37:59 -0800359 }
360
Michael Butler32acc062020-11-22 19:36:30 -0800361 auto operands = NN_TRY(unvalidatedConvert(model.main.operands));
Michael Butlera685c3d2020-02-22 22:37:59 -0800362
363 // Update number of consumers.
364 const auto numberOfConsumers =
365 hal::utils::countNumberOfConsumers(operands.size(), model.main.operations);
366 CHECK(operands.size() == numberOfConsumers.size());
367 for (size_t i = 0; i < operands.size(); ++i) {
368 operands[i].numberOfConsumers = numberOfConsumers[i];
369 }
370
371 return Model{
372 .operands = std::move(operands),
Michael Butler32acc062020-11-22 19:36:30 -0800373 .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800374 .inputIndexes = model.main.inputIndexes,
375 .outputIndexes = model.main.outputIndexes,
Michael Butler32acc062020-11-22 19:36:30 -0800376 .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
377 .pools = NN_TRY(unvalidatedConvert(model.pools)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800378 };
379}
380
Michael Butler32acc062020-11-22 19:36:30 -0800381nn::GeneralResult<RequestArgument> unvalidatedConvert(
382 const nn::Request::Argument& requestArgument) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800383 if (requestArgument.lifetime == nn::Request::Argument::LifeTime::POINTER) {
Michael Butler3670c382020-08-06 23:22:35 -0700384 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler32acc062020-11-22 19:36:30 -0800385 << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlera685c3d2020-02-22 22:37:59 -0800386 }
387 const bool hasNoValue = requestArgument.lifetime == nn::Request::Argument::LifeTime::NO_VALUE;
388 return RequestArgument{
389 .hasNoValue = hasNoValue,
Michael Butler32acc062020-11-22 19:36:30 -0800390 .location = NN_TRY(unvalidatedConvert(requestArgument.location)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800391 .dimensions = requestArgument.dimensions,
392 };
393}
394
Michael Butler32acc062020-11-22 19:36:30 -0800395nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::Request::MemoryPool& memoryPool) {
Michael Butler79a16eb2021-02-07 00:11:13 -0800396 return unvalidatedConvert(std::get<nn::SharedMemory>(memoryPool));
Michael Butlera685c3d2020-02-22 22:37:59 -0800397}
398
Michael Butler32acc062020-11-22 19:36:30 -0800399nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800400 if (!hal::utils::hasNoPointerData(request)) {
Michael Butler3670c382020-08-06 23:22:35 -0700401 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler32acc062020-11-22 19:36:30 -0800402 << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlera685c3d2020-02-22 22:37:59 -0800403 }
404
405 return Request{
Michael Butler32acc062020-11-22 19:36:30 -0800406 .inputs = NN_TRY(unvalidatedConvert(request.inputs)),
407 .outputs = NN_TRY(unvalidatedConvert(request.outputs)),
408 .pools = NN_TRY(unvalidatedConvert(request.pools)),
Michael Butlera685c3d2020-02-22 22:37:59 -0800409 };
410}
411
Michael Butler32acc062020-11-22 19:36:30 -0800412nn::GeneralResult<ErrorStatus> unvalidatedConvert(const nn::ErrorStatus& status) {
Michael Butlera685c3d2020-02-22 22:37:59 -0800413 switch (status) {
414 case nn::ErrorStatus::NONE:
415 case nn::ErrorStatus::DEVICE_UNAVAILABLE:
416 case nn::ErrorStatus::GENERAL_FAILURE:
417 case nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE:
418 case nn::ErrorStatus::INVALID_ARGUMENT:
419 return static_cast<ErrorStatus>(status);
420 default:
421 return ErrorStatus::GENERAL_FAILURE;
422 }
423}
424
Michael Butler32acc062020-11-22 19:36:30 -0800425nn::GeneralResult<DeviceStatus> convert(const nn::DeviceStatus& deviceStatus) {
426 return validatedConvert(deviceStatus);
427}
428
429nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
430 return validatedConvert(capabilities);
431}
432
433nn::GeneralResult<Model> convert(const nn::Model& model) {
434 return validatedConvert(model);
435}
436
437nn::GeneralResult<Request> convert(const nn::Request& request) {
438 return validatedConvert(request);
439}
440
441nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& status) {
442 return validatedConvert(status);
443}
444
Michael Butlera685c3d2020-02-22 22:37:59 -0800445} // namespace android::hardware::neuralnetworks::V1_0::utils