blob: 95516c854b2a5018de3b1a8a779447a2de9e3757 [file] [log] [blame]
Lev Proleev6b6dfcd2020-11-11 18:28:50 +00001/*
2 * Copyright (C) 2021 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 "Utils.h"
18
Lev Proleev900c28a2021-01-26 19:40:20 +000019#include <android/binder_status.h>
Lev Proleev6b6dfcd2020-11-11 18:28:50 +000020#include <nnapi/Result.h>
21
22namespace aidl::android::hardware::neuralnetworks::utils {
Lev Proleevc185e882020-12-15 19:25:32 +000023namespace {
Lev Proleev6b6dfcd2020-11-11 18:28:50 +000024
Lev Proleevc185e882020-12-15 19:25:32 +000025template <typename Type>
26nn::GeneralResult<std::vector<Type>> cloneVec(const std::vector<Type>& arguments) {
27 std::vector<Type> clonedObjects;
28 clonedObjects.reserve(arguments.size());
29 for (const auto& argument : arguments) {
30 clonedObjects.push_back(NN_TRY(clone(argument)));
31 }
32 return clonedObjects;
33}
34
35template <typename Type>
Lev Proleev900c28a2021-01-26 19:40:20 +000036nn::GeneralResult<std::vector<Type>> clone(const std::vector<Type>& arguments) {
Lev Proleevc185e882020-12-15 19:25:32 +000037 return cloneVec(arguments);
38}
39
40} // namespace
41
Lev Proleev900c28a2021-01-26 19:40:20 +000042nn::GeneralResult<Memory> clone(const Memory& memory) {
Lev Proleevc185e882020-12-15 19:25:32 +000043 common::NativeHandle nativeHandle;
44 nativeHandle.ints = memory.handle.ints;
45 nativeHandle.fds.reserve(memory.handle.fds.size());
46 for (const auto& fd : memory.handle.fds) {
47 const int newFd = dup(fd.get());
48 if (newFd < 0) {
49 return NN_ERROR() << "Couldn't dup a file descriptor";
50 }
51 nativeHandle.fds.emplace_back(newFd);
52 }
53 return Memory{
54 .handle = std::move(nativeHandle),
55 .size = memory.size,
56 .name = memory.name,
57 };
58}
59
Lev Proleev900c28a2021-01-26 19:40:20 +000060nn::GeneralResult<RequestMemoryPool> clone(const RequestMemoryPool& requestPool) {
Lev Proleevc185e882020-12-15 19:25:32 +000061 using Tag = RequestMemoryPool::Tag;
62 switch (requestPool.getTag()) {
63 case Tag::pool:
64 return RequestMemoryPool::make<Tag::pool>(NN_TRY(clone(requestPool.get<Tag::pool>())));
65 case Tag::token:
66 return RequestMemoryPool::make<Tag::token>(requestPool.get<Tag::token>());
67 }
68 // Using explicit type conversion because std::variant inside the RequestMemoryPool confuses the
69 // compiler.
70 return (NN_ERROR() << "Unrecognized request pool tag: " << requestPool.getTag())
71 .
Lev Proleev900c28a2021-01-26 19:40:20 +000072 operator nn::GeneralResult<RequestMemoryPool>();
Lev Proleevc185e882020-12-15 19:25:32 +000073}
74
Lev Proleev900c28a2021-01-26 19:40:20 +000075nn::GeneralResult<Request> clone(const Request& request) {
Lev Proleevc185e882020-12-15 19:25:32 +000076 return Request{
77 .inputs = request.inputs,
78 .outputs = request.outputs,
79 .pools = NN_TRY(clone(request.pools)),
80 };
81}
82
Lev Proleev900c28a2021-01-26 19:40:20 +000083nn::GeneralResult<Model> clone(const Model& model) {
Lev Proleevc185e882020-12-15 19:25:32 +000084 return Model{
Lev Proleev6b6dfcd2020-11-11 18:28:50 +000085 .main = model.main,
86 .referenced = model.referenced,
87 .operandValues = model.operandValues,
Lev Proleevc185e882020-12-15 19:25:32 +000088 .pools = NN_TRY(clone(model.pools)),
Lev Proleev6b6dfcd2020-11-11 18:28:50 +000089 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
90 .extensionNameToPrefix = model.extensionNameToPrefix,
91 };
Lev Proleev6b6dfcd2020-11-11 18:28:50 +000092}
93
Lev Proleev900c28a2021-01-26 19:40:20 +000094nn::GeneralResult<void> handleTransportError(const ndk::ScopedAStatus& ret) {
95 if (ret.getStatus() == STATUS_DEAD_OBJECT) {
96 return nn::error(nn::ErrorStatus::DEAD_OBJECT)
97 << "Binder transaction returned STATUS_DEAD_OBJECT: " << ret.getDescription();
98 }
99 if (ret.isOk()) {
100 return {};
101 }
102 if (ret.getExceptionCode() != EX_SERVICE_SPECIFIC) {
103 return nn::error(nn::ErrorStatus::GENERAL_FAILURE)
104 << "Binder transaction returned exception: " << ret.getDescription();
105 }
106 return nn::error(static_cast<nn::ErrorStatus>(ret.getServiceSpecificError()))
107 << ret.getMessage();
108}
109
Lev Proleev6b6dfcd2020-11-11 18:28:50 +0000110} // namespace aidl::android::hardware::neuralnetworks::utils