blob: 4eeb414dc880075be6f172274250c3397b896faf [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.3/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>
29#include <nnapi/hal/1.2/Conversions.h>
30#include <nnapi/hal/CommonUtils.h>
31
32#include <algorithm>
33#include <chrono>
34#include <functional>
35#include <iterator>
36#include <limits>
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
Michael Butler382d5132021-03-18 21:15:09 -070044std::chrono::nanoseconds makeNanosFromUint64(uint64_t nanoseconds) {
45 constexpr auto kMaxCount = std::chrono::nanoseconds::max().count();
46 using CommonType = std::common_type_t<std::chrono::nanoseconds::rep, uint64_t>;
47 const auto count = std::min<CommonType>(kMaxCount, nanoseconds);
48 return std::chrono::nanoseconds{static_cast<std::chrono::nanoseconds::rep>(count)};
49}
50
51uint64_t makeUint64FromNanos(std::chrono::nanoseconds nanoseconds) {
52 if (nanoseconds < std::chrono::nanoseconds::zero()) {
53 return 0;
54 }
55 constexpr auto kMaxCount = std::numeric_limits<uint64_t>::max();
56 using CommonType = std::common_type_t<std::chrono::nanoseconds::rep, uint64_t>;
57 const auto count = std::min<CommonType>(kMaxCount, nanoseconds.count());
58 return static_cast<uint64_t>(count);
59}
60
Michael Butlerb98aa6d2020-02-22 22:37:59 -080061template <typename Type>
62constexpr std::underlying_type_t<Type> underlyingType(Type value) {
63 return static_cast<std::underlying_type_t<Type>>(value);
64}
65
66} // namespace
67
68namespace android::nn {
69namespace {
70
Michael Butlerb98aa6d2020-02-22 22:37:59 -080071using hardware::hidl_vec;
72
73template <typename Input>
Michael Butler388bceb2021-02-03 15:15:43 -080074using UnvalidatedConvertOutput =
Michael Butler6547b2a2020-11-22 19:36:30 -080075 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlerb98aa6d2020-02-22 22:37:59 -080076
77template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080078GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -080079 const hidl_vec<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -080080 std::vector<UnvalidatedConvertOutput<Type>> canonical;
Michael Butlerb98aa6d2020-02-22 22:37:59 -080081 canonical.reserve(arguments.size());
82 for (const auto& argument : arguments) {
Michael Butler6547b2a2020-11-22 19:36:30 -080083 canonical.push_back(NN_TRY(nn::unvalidatedConvert(argument)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -080084 }
85 return canonical;
86}
87
88template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080089GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& halObject) {
Michael Butler6547b2a2020-11-22 19:36:30 -080090 auto canonical = NN_TRY(nn::unvalidatedConvert(halObject));
Michael Butler388bceb2021-02-03 15:15:43 -080091 NN_TRY(hal::V1_3::utils::compliantVersion(canonical));
Michael Butler6547b2a2020-11-22 19:36:30 -080092 return canonical;
93}
94
95template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -080096GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -080097 const hidl_vec<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -080098 std::vector<UnvalidatedConvertOutput<Type>> canonical;
Michael Butler6547b2a2020-11-22 19:36:30 -080099 canonical.reserve(arguments.size());
100 for (const auto& argument : arguments) {
101 canonical.push_back(NN_TRY(validatedConvert(argument)));
102 }
103 return canonical;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800104}
105
106} // anonymous namespace
107
Michael Butler6547b2a2020-11-22 19:36:30 -0800108GeneralResult<OperandType> unvalidatedConvert(const hal::V1_3::OperandType& operandType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800109 return static_cast<OperandType>(operandType);
110}
111
Michael Butler6547b2a2020-11-22 19:36:30 -0800112GeneralResult<OperationType> unvalidatedConvert(const hal::V1_3::OperationType& operationType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800113 return static_cast<OperationType>(operationType);
114}
115
Michael Butler6547b2a2020-11-22 19:36:30 -0800116GeneralResult<Priority> unvalidatedConvert(const hal::V1_3::Priority& priority) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800117 return static_cast<Priority>(priority);
118}
119
Michael Butler6547b2a2020-11-22 19:36:30 -0800120GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_3::Capabilities& capabilities) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800121 const bool validOperandTypes = std::all_of(
122 capabilities.operandPerformance.begin(), capabilities.operandPerformance.end(),
123 [](const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler388bceb2021-02-03 15:15:43 -0800124 return validatedConvert(operandPerformance.type).has_value();
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800125 });
126 if (!validOperandTypes) {
Michael Butler4b276a72020-08-06 23:22:35 -0700127 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
Michael Butler6547b2a2020-11-22 19:36:30 -0800128 << "Invalid OperandType when unvalidatedConverting OperandPerformance in "
129 "Capabilities";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800130 }
131
Michael Butler6547b2a2020-11-22 19:36:30 -0800132 auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance));
Michael Butlerff9a5a52021-10-15 16:23:20 -0700133 auto table =
134 NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800135
Michael Butler7ecc2902022-04-25 22:36:51 -0700136 const auto relaxedFloat32toFloat16PerformanceScalar =
137 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
138 const auto relaxedFloat32toFloat16PerformanceTensor =
139 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
140 const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
141 const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800142 return Capabilities{
Michael Butler7ecc2902022-04-25 22:36:51 -0700143 .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
144 .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800145 .operandPerformance = std::move(table),
Michael Butler7ecc2902022-04-25 22:36:51 -0700146 .ifPerformance = ifPerformance,
147 .whilePerformance = whilePerformance,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800148 };
149}
150
Michael Butler6547b2a2020-11-22 19:36:30 -0800151GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800152 const hal::V1_3::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700153 const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
154 const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800155 return Capabilities::OperandPerformance{
Michael Butler7ecc2902022-04-25 22:36:51 -0700156 .type = type,
157 .info = info,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800158 };
159}
160
Michael Butler6547b2a2020-11-22 19:36:30 -0800161GeneralResult<Operation> unvalidatedConvert(const hal::V1_3::Operation& operation) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700162 const auto type = NN_TRY(unvalidatedConvert(operation.type));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800163 return Operation{
Michael Butler7ecc2902022-04-25 22:36:51 -0700164 .type = type,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800165 .inputs = operation.inputs,
166 .outputs = operation.outputs,
167 };
168}
169
Michael Butler6547b2a2020-11-22 19:36:30 -0800170GeneralResult<Operand::LifeTime> unvalidatedConvert(
171 const hal::V1_3::OperandLifeTime& operandLifeTime) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800172 return static_cast<Operand::LifeTime>(operandLifeTime);
173}
174
Michael Butler6547b2a2020-11-22 19:36:30 -0800175GeneralResult<Operand> unvalidatedConvert(const hal::V1_3::Operand& operand) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700176 const auto type = NN_TRY(unvalidatedConvert(operand.type));
177 const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
178 const auto location = NN_TRY(unvalidatedConvert(operand.location));
179 auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800180 return Operand{
Michael Butler7ecc2902022-04-25 22:36:51 -0700181 .type = type,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800182 .dimensions = operand.dimensions,
183 .scale = operand.scale,
184 .zeroPoint = operand.zeroPoint,
Michael Butler7ecc2902022-04-25 22:36:51 -0700185 .lifetime = lifetime,
186 .location = location,
187 .extraParams = std::move(extraParams),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800188 };
189}
190
Michael Butler6547b2a2020-11-22 19:36:30 -0800191GeneralResult<Model> unvalidatedConvert(const hal::V1_3::Model& model) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700192 auto main = NN_TRY(unvalidatedConvert(model.main));
193 auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
194 auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
195 auto pools = NN_TRY(unvalidatedConvert(model.pools));
196 auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800197 return Model{
Michael Butler7ecc2902022-04-25 22:36:51 -0700198 .main = std::move(main),
199 .referenced = std::move(referenced),
200 .operandValues = std::move(operandValues),
201 .pools = std::move(pools),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800202 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
Michael Butler7ecc2902022-04-25 22:36:51 -0700203 .extensionNameToPrefix = std::move(extensionNameToPrefix),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800204 };
205}
206
Michael Butler6547b2a2020-11-22 19:36:30 -0800207GeneralResult<Model::Subgraph> unvalidatedConvert(const hal::V1_3::Subgraph& subgraph) {
208 auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800209
210 // Verify number of consumers.
211 const auto numberOfConsumers =
Michael Butler301ef062021-10-14 22:04:59 -0700212 NN_TRY(countNumberOfConsumers(subgraph.operands.size(), operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800213 CHECK(subgraph.operands.size() == numberOfConsumers.size());
214 for (size_t i = 0; i < subgraph.operands.size(); ++i) {
215 if (subgraph.operands[i].numberOfConsumers != numberOfConsumers[i]) {
Michael Butler4b276a72020-08-06 23:22:35 -0700216 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
217 << "Invalid numberOfConsumers for operand " << i << ", expected "
218 << numberOfConsumers[i] << " but found "
219 << subgraph.operands[i].numberOfConsumers;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800220 }
221 }
222
Michael Butler7ecc2902022-04-25 22:36:51 -0700223 auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800224 return Model::Subgraph{
Michael Butler7ecc2902022-04-25 22:36:51 -0700225 .operands = std::move(operands),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800226 .operations = std::move(operations),
227 .inputIndexes = subgraph.inputIndexes,
228 .outputIndexes = subgraph.outputIndexes,
229 };
230}
231
Michael Butler6547b2a2020-11-22 19:36:30 -0800232GeneralResult<BufferDesc> unvalidatedConvert(const hal::V1_3::BufferDesc& bufferDesc) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800233 return BufferDesc{.dimensions = bufferDesc.dimensions};
234}
235
Michael Butler6547b2a2020-11-22 19:36:30 -0800236GeneralResult<BufferRole> unvalidatedConvert(const hal::V1_3::BufferRole& bufferRole) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800237 return BufferRole{
238 .modelIndex = bufferRole.modelIndex,
239 .ioIndex = bufferRole.ioIndex,
Xusong Wang3633d072021-03-19 13:58:24 -0700240 .probability = bufferRole.frequency,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800241 };
242}
243
Michael Butler6547b2a2020-11-22 19:36:30 -0800244GeneralResult<Request> unvalidatedConvert(const hal::V1_3::Request& request) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700245 auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
246 auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
247 auto pools = NN_TRY(unvalidatedConvert(request.pools));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800248 return Request{
Michael Butler7ecc2902022-04-25 22:36:51 -0700249 .inputs = std::move(inputs),
250 .outputs = std::move(outputs),
251 .pools = std::move(pools),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800252 };
253}
254
Michael Butler6547b2a2020-11-22 19:36:30 -0800255GeneralResult<Request::MemoryPool> unvalidatedConvert(
256 const hal::V1_3::Request::MemoryPool& memoryPool) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800257 using Discriminator = hal::V1_3::Request::MemoryPool::hidl_discriminator;
258 switch (memoryPool.getDiscriminator()) {
259 case Discriminator::hidlMemory:
Michael Butlere52a77e2021-06-07 13:10:58 -0700260 return unvalidatedConvert(memoryPool.hidlMemory());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800261 case Discriminator::token:
262 return static_cast<Request::MemoryDomainToken>(memoryPool.token());
263 }
Michael Butler4b276a72020-08-06 23:22:35 -0700264 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
265 << "Invalid Request::MemoryPool discriminator "
266 << underlyingType(memoryPool.getDiscriminator());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800267}
268
Michael Butler6547b2a2020-11-22 19:36:30 -0800269GeneralResult<OptionalTimePoint> unvalidatedConvert(
270 const hal::V1_3::OptionalTimePoint& optionalTimePoint) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800271 using Discriminator = hal::V1_3::OptionalTimePoint::hidl_discriminator;
272 switch (optionalTimePoint.getDiscriminator()) {
273 case Discriminator::none:
Michael Butler4024d8f2020-12-04 17:38:20 -0800274 return {};
Michael Butler382d5132021-03-18 21:15:09 -0700275 case Discriminator::nanosecondsSinceEpoch: {
276 const auto currentSteadyTime = std::chrono::steady_clock::now();
277 const auto currentBootTime = Clock::now();
278
279 const auto timeSinceEpoch =
280 makeNanosFromUint64(optionalTimePoint.nanosecondsSinceEpoch());
281 const auto steadyTimePoint = std::chrono::steady_clock::time_point{timeSinceEpoch};
282
283 // Both steadyTimePoint and currentSteadyTime are guaranteed to be non-negative, so this
284 // subtraction will never overflow or underflow.
285 const auto timeRemaining = steadyTimePoint - currentSteadyTime;
286
287 // currentBootTime is guaranteed to be non-negative, so this code only protects against
288 // an overflow.
289 nn::TimePoint bootTimePoint;
290 constexpr auto kZeroNano = std::chrono::nanoseconds::zero();
291 constexpr auto kMaxTime = nn::TimePoint::max();
292 if (timeRemaining > kZeroNano && currentBootTime > kMaxTime - timeRemaining) {
293 bootTimePoint = kMaxTime;
294 } else {
295 bootTimePoint = currentBootTime + timeRemaining;
296 }
297
298 constexpr auto kZeroTime = nn::TimePoint{};
299 return std::max(bootTimePoint, kZeroTime);
300 }
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800301 }
Michael Butler4b276a72020-08-06 23:22:35 -0700302 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
303 << "Invalid OptionalTimePoint discriminator "
304 << underlyingType(optionalTimePoint.getDiscriminator());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800305}
306
Michael Butler4024d8f2020-12-04 17:38:20 -0800307GeneralResult<OptionalDuration> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800308 const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800309 using Discriminator = hal::V1_3::OptionalTimeoutDuration::hidl_discriminator;
310 switch (optionalTimeoutDuration.getDiscriminator()) {
311 case Discriminator::none:
Michael Butler4024d8f2020-12-04 17:38:20 -0800312 return {};
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800313 case Discriminator::nanoseconds:
Michael Butler4024d8f2020-12-04 17:38:20 -0800314 return Duration(optionalTimeoutDuration.nanoseconds());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800315 }
Michael Butler4b276a72020-08-06 23:22:35 -0700316 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
317 << "Invalid OptionalTimeoutDuration discriminator "
318 << underlyingType(optionalTimeoutDuration.getDiscriminator());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800319}
320
Michael Butler6547b2a2020-11-22 19:36:30 -0800321GeneralResult<ErrorStatus> unvalidatedConvert(const hal::V1_3::ErrorStatus& status) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800322 switch (status) {
323 case hal::V1_3::ErrorStatus::NONE:
324 case hal::V1_3::ErrorStatus::DEVICE_UNAVAILABLE:
325 case hal::V1_3::ErrorStatus::GENERAL_FAILURE:
326 case hal::V1_3::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE:
327 case hal::V1_3::ErrorStatus::INVALID_ARGUMENT:
328 case hal::V1_3::ErrorStatus::MISSED_DEADLINE_TRANSIENT:
329 case hal::V1_3::ErrorStatus::MISSED_DEADLINE_PERSISTENT:
330 case hal::V1_3::ErrorStatus::RESOURCE_EXHAUSTED_TRANSIENT:
331 case hal::V1_3::ErrorStatus::RESOURCE_EXHAUSTED_PERSISTENT:
332 return static_cast<ErrorStatus>(status);
333 }
Michael Butler4b276a72020-08-06 23:22:35 -0700334 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
335 << "Invalid ErrorStatus " << underlyingType(status);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800336}
337
Michael Butler6547b2a2020-11-22 19:36:30 -0800338GeneralResult<Priority> convert(const hal::V1_3::Priority& priority) {
339 return validatedConvert(priority);
340}
341
342GeneralResult<Capabilities> convert(const hal::V1_3::Capabilities& capabilities) {
343 return validatedConvert(capabilities);
344}
345
346GeneralResult<Model> convert(const hal::V1_3::Model& model) {
347 return validatedConvert(model);
348}
349
350GeneralResult<BufferDesc> convert(const hal::V1_3::BufferDesc& bufferDesc) {
351 return validatedConvert(bufferDesc);
352}
353
354GeneralResult<Request> convert(const hal::V1_3::Request& request) {
355 return validatedConvert(request);
356}
357
358GeneralResult<OptionalTimePoint> convert(const hal::V1_3::OptionalTimePoint& optionalTimePoint) {
359 return validatedConvert(optionalTimePoint);
360}
361
Michael Butler4024d8f2020-12-04 17:38:20 -0800362GeneralResult<OptionalDuration> convert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800363 const hal::V1_3::OptionalTimeoutDuration& optionalTimeoutDuration) {
364 return validatedConvert(optionalTimeoutDuration);
365}
366
367GeneralResult<ErrorStatus> convert(const hal::V1_3::ErrorStatus& errorStatus) {
368 return validatedConvert(errorStatus);
369}
370
371GeneralResult<SharedHandle> convert(const hardware::hidl_handle& handle) {
372 return validatedConvert(handle);
373}
374
Michael Butler4b276a72020-08-06 23:22:35 -0700375GeneralResult<std::vector<BufferRole>> convert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800376 const hardware::hidl_vec<hal::V1_3::BufferRole>& bufferRoles) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800377 return validatedConvert(bufferRoles);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800378}
379
380} // namespace android::nn
381
382namespace android::hardware::neuralnetworks::V1_3::utils {
383namespace {
384
Michael Butler6547b2a2020-11-22 19:36:30 -0800385using utils::unvalidatedConvert;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800386
Michael Butler6547b2a2020-11-22 19:36:30 -0800387nn::GeneralResult<V1_0::PerformanceInfo> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800388 const nn::Capabilities::PerformanceInfo& performanceInfo) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800389 return V1_0::utils::unvalidatedConvert(performanceInfo);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800390}
391
Michael Butler6547b2a2020-11-22 19:36:30 -0800392nn::GeneralResult<V1_0::DataLocation> unvalidatedConvert(const nn::DataLocation& dataLocation) {
393 return V1_0::utils::unvalidatedConvert(dataLocation);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800394}
395
Michael Butler6547b2a2020-11-22 19:36:30 -0800396nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
397 const nn::Model::OperandValues& operandValues) {
398 return V1_0::utils::unvalidatedConvert(operandValues);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800399}
400
Michael Butler6547b2a2020-11-22 19:36:30 -0800401nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle) {
Michael Butler15965822021-10-14 23:45:11 -0700402 return V1_0::utils::unvalidatedConvert(handle);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800403}
404
Michael Butlerfadeb8a2021-02-07 00:11:13 -0800405nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::SharedMemory& memory) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800406 return V1_0::utils::unvalidatedConvert(memory);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800407}
408
Michael Butler6547b2a2020-11-22 19:36:30 -0800409nn::GeneralResult<V1_0::RequestArgument> unvalidatedConvert(const nn::Request::Argument& argument) {
410 return V1_0::utils::unvalidatedConvert(argument);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800411}
412
Michael Butler6547b2a2020-11-22 19:36:30 -0800413nn::GeneralResult<V1_2::Operand::ExtraParams> unvalidatedConvert(
414 const nn::Operand::ExtraParams& extraParams) {
415 return V1_2::utils::unvalidatedConvert(extraParams);
416}
417
418nn::GeneralResult<V1_2::Model::ExtensionNameAndPrefix> unvalidatedConvert(
Miao Wang0e671f32021-10-26 20:03:05 +0000419 const nn::ExtensionNameAndPrefix& extensionNameAndPrefix) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800420 return V1_2::utils::unvalidatedConvert(extensionNameAndPrefix);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800421}
422
423template <typename Input>
Michael Butler388bceb2021-02-03 15:15:43 -0800424using UnvalidatedConvertOutput =
Michael Butler6547b2a2020-11-22 19:36:30 -0800425 std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800426
427template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800428nn::GeneralResult<hidl_vec<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800429 const std::vector<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -0800430 hidl_vec<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800431 for (size_t i = 0; i < arguments.size(); ++i) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800432 halObject[i] = NN_TRY(unvalidatedConvert(arguments[i]));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800433 }
434 return halObject;
435}
436
Michael Butlerfadeb8a2021-02-07 00:11:13 -0800437nn::GeneralResult<Request::MemoryPool> makeMemoryPool(const nn::SharedMemory& memory) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800438 Request::MemoryPool ret;
Michael Butler6547b2a2020-11-22 19:36:30 -0800439 ret.hidlMemory(NN_TRY(unvalidatedConvert(memory)));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800440 return ret;
441}
442
Michael Butler4b276a72020-08-06 23:22:35 -0700443nn::GeneralResult<Request::MemoryPool> makeMemoryPool(const nn::Request::MemoryDomainToken& token) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800444 Request::MemoryPool ret;
445 ret.token(underlyingType(token));
446 return ret;
447}
448
Michael Butler4b276a72020-08-06 23:22:35 -0700449nn::GeneralResult<Request::MemoryPool> makeMemoryPool(const nn::SharedBuffer& /*buffer*/) {
450 return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE) << "Unable to make memory pool from IBuffer";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800451}
452
Michael Butler6547b2a2020-11-22 19:36:30 -0800453using utils::unvalidatedConvert;
454
455template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800456nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) {
457 NN_TRY(compliantVersion(canonical));
Michael Butler6547b2a2020-11-22 19:36:30 -0800458 return unvalidatedConvert(canonical);
459}
460
461template <typename Type>
Michael Butler388bceb2021-02-03 15:15:43 -0800462nn::GeneralResult<hidl_vec<UnvalidatedConvertOutput<Type>>> validatedConvert(
Michael Butler6547b2a2020-11-22 19:36:30 -0800463 const std::vector<Type>& arguments) {
Michael Butler388bceb2021-02-03 15:15:43 -0800464 hidl_vec<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
Michael Butler6547b2a2020-11-22 19:36:30 -0800465 for (size_t i = 0; i < arguments.size(); ++i) {
466 halObject[i] = NN_TRY(validatedConvert(arguments[i]));
467 }
468 return halObject;
469}
470
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800471} // anonymous namespace
472
Michael Butler6547b2a2020-11-22 19:36:30 -0800473nn::GeneralResult<OperandType> unvalidatedConvert(const nn::OperandType& operandType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800474 return static_cast<OperandType>(operandType);
475}
476
Michael Butler6547b2a2020-11-22 19:36:30 -0800477nn::GeneralResult<OperationType> unvalidatedConvert(const nn::OperationType& operationType) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800478 return static_cast<OperationType>(operationType);
479}
480
Michael Butler6547b2a2020-11-22 19:36:30 -0800481nn::GeneralResult<Priority> unvalidatedConvert(const nn::Priority& priority) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800482 return static_cast<Priority>(priority);
483}
484
Michael Butler6547b2a2020-11-22 19:36:30 -0800485nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700486 std::vector<nn::Capabilities::OperandPerformance> filteredOperandPerformances;
487 filteredOperandPerformances.reserve(capabilities.operandPerformance.asVector().size());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800488 std::copy_if(capabilities.operandPerformance.asVector().begin(),
489 capabilities.operandPerformance.asVector().end(),
Michael Butler7ecc2902022-04-25 22:36:51 -0700490 std::back_inserter(filteredOperandPerformances),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800491 [](const nn::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler388bceb2021-02-03 15:15:43 -0800492 return compliantVersion(operandPerformance.type).has_value();
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800493 });
494
Michael Butler7ecc2902022-04-25 22:36:51 -0700495 const auto relaxedFloat32toFloat16PerformanceScalar =
496 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
497 const auto relaxedFloat32toFloat16PerformanceTensor =
498 NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
499 auto operandPerformance = NN_TRY(unvalidatedConvert(filteredOperandPerformances));
500 const auto ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance));
501 const auto whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800502 return Capabilities{
Michael Butler7ecc2902022-04-25 22:36:51 -0700503 .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
504 .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
505 .operandPerformance = std::move(operandPerformance),
506 .ifPerformance = ifPerformance,
507 .whilePerformance = whilePerformance,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800508 };
509}
510
Michael Butler6547b2a2020-11-22 19:36:30 -0800511nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800512 const nn::Capabilities::OperandPerformance& operandPerformance) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700513 const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
514 const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800515 return Capabilities::OperandPerformance{
Michael Butler7ecc2902022-04-25 22:36:51 -0700516 .type = type,
517 .info = info,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800518 };
519}
520
Michael Butler6547b2a2020-11-22 19:36:30 -0800521nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700522 const auto type = NN_TRY(unvalidatedConvert(operation.type));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800523 return Operation{
Michael Butler7ecc2902022-04-25 22:36:51 -0700524 .type = type,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800525 .inputs = operation.inputs,
526 .outputs = operation.outputs,
527 };
528}
529
Michael Butler6547b2a2020-11-22 19:36:30 -0800530nn::GeneralResult<OperandLifeTime> unvalidatedConvert(
531 const nn::Operand::LifeTime& operandLifeTime) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800532 if (operandLifeTime == nn::Operand::LifeTime::POINTER) {
Michael Butler4b276a72020-08-06 23:22:35 -0700533 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler6547b2a2020-11-22 19:36:30 -0800534 << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800535 }
536 return static_cast<OperandLifeTime>(operandLifeTime);
537}
538
Michael Butler6547b2a2020-11-22 19:36:30 -0800539nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
Michael Butler7ecc2902022-04-25 22:36:51 -0700540 const auto type = NN_TRY(unvalidatedConvert(operand.type));
541 const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
542 const auto location = NN_TRY(unvalidatedConvert(operand.location));
543 auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800544 return Operand{
Michael Butler7ecc2902022-04-25 22:36:51 -0700545 .type = type,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800546 .dimensions = operand.dimensions,
547 .numberOfConsumers = 0,
548 .scale = operand.scale,
549 .zeroPoint = operand.zeroPoint,
Michael Butler7ecc2902022-04-25 22:36:51 -0700550 .lifetime = lifetime,
551 .location = location,
552 .extraParams = std::move(extraParams),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800553 };
554}
555
Michael Butler6547b2a2020-11-22 19:36:30 -0800556nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800557 if (!hal::utils::hasNoPointerData(model)) {
Michael Butler4b276a72020-08-06 23:22:35 -0700558 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler6547b2a2020-11-22 19:36:30 -0800559 << "Model cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800560 }
561
Michael Butler7ecc2902022-04-25 22:36:51 -0700562 auto main = NN_TRY(unvalidatedConvert(model.main));
563 auto referenced = NN_TRY(unvalidatedConvert(model.referenced));
564 auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
565 auto pools = NN_TRY(unvalidatedConvert(model.pools));
566 auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800567 return Model{
Michael Butler7ecc2902022-04-25 22:36:51 -0700568 .main = std::move(main),
569 .referenced = std::move(referenced),
570 .operandValues = std::move(operandValues),
571 .pools = std::move(pools),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800572 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
Michael Butler7ecc2902022-04-25 22:36:51 -0700573 .extensionNameToPrefix = std::move(extensionNameToPrefix),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800574 };
575}
576
Michael Butler6547b2a2020-11-22 19:36:30 -0800577nn::GeneralResult<Subgraph> unvalidatedConvert(const nn::Model::Subgraph& subgraph) {
578 auto operands = NN_TRY(unvalidatedConvert(subgraph.operands));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800579
580 // Update number of consumers.
581 const auto numberOfConsumers =
Michael Butler301ef062021-10-14 22:04:59 -0700582 NN_TRY(countNumberOfConsumers(operands.size(), subgraph.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800583 CHECK(operands.size() == numberOfConsumers.size());
584 for (size_t i = 0; i < operands.size(); ++i) {
585 operands[i].numberOfConsumers = numberOfConsumers[i];
586 }
587
Michael Butler7ecc2902022-04-25 22:36:51 -0700588 auto operations = NN_TRY(unvalidatedConvert(subgraph.operations));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800589 return Subgraph{
590 .operands = std::move(operands),
Michael Butler7ecc2902022-04-25 22:36:51 -0700591 .operations = std::move(operations),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800592 .inputIndexes = subgraph.inputIndexes,
593 .outputIndexes = subgraph.outputIndexes,
594 };
595}
596
Michael Butler6547b2a2020-11-22 19:36:30 -0800597nn::GeneralResult<BufferDesc> unvalidatedConvert(const nn::BufferDesc& bufferDesc) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800598 return BufferDesc{.dimensions = bufferDesc.dimensions};
599}
600
Michael Butler6547b2a2020-11-22 19:36:30 -0800601nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRole) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800602 return BufferRole{
603 .modelIndex = bufferRole.modelIndex,
604 .ioIndex = bufferRole.ioIndex,
Xusong Wang3633d072021-03-19 13:58:24 -0700605 .frequency = bufferRole.probability,
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800606 };
607}
608
Michael Butler6547b2a2020-11-22 19:36:30 -0800609nn::GeneralResult<Request> unvalidatedConvert(const nn::Request& request) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800610 if (!hal::utils::hasNoPointerData(request)) {
Michael Butler4b276a72020-08-06 23:22:35 -0700611 return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
Michael Butler6547b2a2020-11-22 19:36:30 -0800612 << "Request cannot be unvalidatedConverted because it contains pointer-based memory";
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800613 }
614
Michael Butler7ecc2902022-04-25 22:36:51 -0700615 auto inputs = NN_TRY(unvalidatedConvert(request.inputs));
616 auto outputs = NN_TRY(unvalidatedConvert(request.outputs));
617 auto pools = NN_TRY(unvalidatedConvert(request.pools));
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800618 return Request{
Michael Butler7ecc2902022-04-25 22:36:51 -0700619 .inputs = std::move(inputs),
620 .outputs = std::move(outputs),
621 .pools = std::move(pools),
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800622 };
623}
624
Michael Butler6547b2a2020-11-22 19:36:30 -0800625nn::GeneralResult<Request::MemoryPool> unvalidatedConvert(
626 const nn::Request::MemoryPool& memoryPool) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800627 return std::visit([](const auto& o) { return makeMemoryPool(o); }, memoryPool);
628}
629
Michael Butler6547b2a2020-11-22 19:36:30 -0800630nn::GeneralResult<OptionalTimePoint> unvalidatedConvert(
631 const nn::OptionalTimePoint& optionalTimePoint) {
Michael Butler382d5132021-03-18 21:15:09 -0700632 const auto currentSteadyTime = std::chrono::steady_clock::now();
633 const auto currentBootTime = nn::Clock::now();
634
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800635 OptionalTimePoint ret;
636 if (optionalTimePoint.has_value()) {
Michael Butler382d5132021-03-18 21:15:09 -0700637 const auto bootTimePoint = optionalTimePoint.value();
638
639 if (bootTimePoint < nn::TimePoint{}) {
640 return NN_ERROR() << "Trying to cast invalid time point";
641 }
642
643 // Both bootTimePoint and currentBootTime are guaranteed to be non-negative, so this
644 // subtraction will never overflow or underflow.
645 const auto timeRemaining = bootTimePoint - currentBootTime;
646
647 // currentSteadyTime is guaranteed to be non-negative, so this code only protects against an
648 // overflow.
649 std::chrono::steady_clock::time_point steadyTimePoint;
650 constexpr auto kZeroNano = std::chrono::nanoseconds::zero();
651 constexpr auto kMaxTime = std::chrono::steady_clock::time_point::max();
652 if (timeRemaining > kZeroNano && currentSteadyTime > kMaxTime - timeRemaining) {
653 steadyTimePoint = kMaxTime;
654 } else {
655 steadyTimePoint = currentSteadyTime + timeRemaining;
656 }
657
658 const uint64_t count = makeUint64FromNanos(steadyTimePoint.time_since_epoch());
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800659 ret.nanosecondsSinceEpoch(count);
660 }
661 return ret;
662}
663
Michael Butler6547b2a2020-11-22 19:36:30 -0800664nn::GeneralResult<OptionalTimeoutDuration> unvalidatedConvert(
Michael Butler4024d8f2020-12-04 17:38:20 -0800665 const nn::OptionalDuration& optionalTimeoutDuration) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800666 OptionalTimeoutDuration ret;
667 if (optionalTimeoutDuration.has_value()) {
668 const auto count = optionalTimeoutDuration.value().count();
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800669 ret.nanoseconds(count);
670 }
671 return ret;
672}
673
Michael Butler6547b2a2020-11-22 19:36:30 -0800674nn::GeneralResult<ErrorStatus> unvalidatedConvert(const nn::ErrorStatus& errorStatus) {
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800675 switch (errorStatus) {
676 case nn::ErrorStatus::NONE:
677 case nn::ErrorStatus::DEVICE_UNAVAILABLE:
678 case nn::ErrorStatus::GENERAL_FAILURE:
679 case nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE:
680 case nn::ErrorStatus::INVALID_ARGUMENT:
681 case nn::ErrorStatus::MISSED_DEADLINE_TRANSIENT:
682 case nn::ErrorStatus::MISSED_DEADLINE_PERSISTENT:
683 case nn::ErrorStatus::RESOURCE_EXHAUSTED_TRANSIENT:
684 case nn::ErrorStatus::RESOURCE_EXHAUSTED_PERSISTENT:
685 return static_cast<ErrorStatus>(errorStatus);
686 default:
687 return ErrorStatus::GENERAL_FAILURE;
688 }
689}
690
Michael Butler6547b2a2020-11-22 19:36:30 -0800691nn::GeneralResult<Priority> convert(const nn::Priority& priority) {
692 return validatedConvert(priority);
693}
694
695nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
696 return validatedConvert(capabilities);
697}
698
699nn::GeneralResult<Model> convert(const nn::Model& model) {
700 return validatedConvert(model);
701}
702
703nn::GeneralResult<BufferDesc> convert(const nn::BufferDesc& bufferDesc) {
704 return validatedConvert(bufferDesc);
705}
706
707nn::GeneralResult<Request> convert(const nn::Request& request) {
708 return validatedConvert(request);
709}
710
711nn::GeneralResult<OptionalTimePoint> convert(const nn::OptionalTimePoint& optionalTimePoint) {
712 return validatedConvert(optionalTimePoint);
713}
714
715nn::GeneralResult<OptionalTimeoutDuration> convert(
Michael Butler4024d8f2020-12-04 17:38:20 -0800716 const nn::OptionalDuration& optionalTimeoutDuration) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800717 return validatedConvert(optionalTimeoutDuration);
718}
719
720nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& errorStatus) {
721 return validatedConvert(errorStatus);
722}
723
724nn::GeneralResult<hidl_handle> convert(const nn::SharedHandle& handle) {
725 return validatedConvert(handle);
726}
727
Michael Butlerfadeb8a2021-02-07 00:11:13 -0800728nn::GeneralResult<hidl_memory> convert(const nn::SharedMemory& memory) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800729 return validatedConvert(memory);
730}
731
Michael Butler4b276a72020-08-06 23:22:35 -0700732nn::GeneralResult<hidl_vec<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles) {
Michael Butler6547b2a2020-11-22 19:36:30 -0800733 return validatedConvert(bufferRoles);
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800734}
735
Michael Butler7fd03c22020-12-06 21:50:59 -0800736nn::GeneralResult<V1_0::DeviceStatus> convert(const nn::DeviceStatus& deviceStatus) {
737 return V1_2::utils::convert(deviceStatus);
738}
739
740nn::GeneralResult<V1_1::ExecutionPreference> convert(
741 const nn::ExecutionPreference& executionPreference) {
742 return V1_2::utils::convert(executionPreference);
743}
744
745nn::GeneralResult<hidl_vec<V1_2::Extension>> convert(const std::vector<nn::Extension>& extensions) {
746 return V1_2::utils::convert(extensions);
747}
748
749nn::GeneralResult<hidl_vec<hidl_handle>> convert(const std::vector<nn::SharedHandle>& handles) {
750 return V1_2::utils::convert(handles);
751}
752
753nn::GeneralResult<hidl_vec<V1_2::OutputShape>> convert(
754 const std::vector<nn::OutputShape>& outputShapes) {
755 return V1_2::utils::convert(outputShapes);
756}
757
758nn::GeneralResult<V1_2::DeviceType> convert(const nn::DeviceType& deviceType) {
759 return V1_2::utils::convert(deviceType);
760}
761
762nn::GeneralResult<V1_2::MeasureTiming> convert(const nn::MeasureTiming& measureTiming) {
763 return V1_2::utils::convert(measureTiming);
764}
765
766nn::GeneralResult<V1_2::Timing> convert(const nn::Timing& timing) {
767 return V1_2::utils::convert(timing);
768}
769
Michael Butler15965822021-10-14 23:45:11 -0700770nn::GeneralResult<hidl_vec<hidl_handle>> convertSyncFences(
771 const std::vector<nn::SyncFence>& syncFences) {
772 std::vector<nn::SharedHandle> handles;
773 handles.reserve(syncFences.size());
774 std::transform(syncFences.begin(), syncFences.end(), std::back_inserter(handles),
775 [](const nn::SyncFence& syncFence) { return syncFence.getSharedHandle(); });
776 return convert(handles);
777}
778
Michael Butlerb98aa6d2020-02-22 22:37:59 -0800779} // namespace android::hardware::neuralnetworks::V1_3::utils