blob: f9b4f6edbcb5f2c207708d752357e9cb97716c14 [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
Michael Butlerf03ebd92021-03-25 15:27:38 -070019#include <aidl/android/hardware/common/Ashmem.h>
20#include <aidl/android/hardware/common/MappableFile.h>
21#include <aidl/android/hardware/graphics/common/HardwareBuffer.h>
22#include <android/binder_auto_utils.h>
Lev Proleev900c28a2021-01-26 19:40:20 +000023#include <android/binder_status.h>
Lev Proleev6b6dfcd2020-11-11 18:28:50 +000024#include <nnapi/Result.h>
Michael Butlerf03ebd92021-03-25 15:27:38 -070025#include <nnapi/SharedMemory.h>
Lev Proleev6b6dfcd2020-11-11 18:28:50 +000026
27namespace aidl::android::hardware::neuralnetworks::utils {
Lev Proleevc185e882020-12-15 19:25:32 +000028namespace {
Lev Proleev6b6dfcd2020-11-11 18:28:50 +000029
Michael Butlerf03ebd92021-03-25 15:27:38 -070030nn::GeneralResult<ndk::ScopedFileDescriptor> clone(const ndk::ScopedFileDescriptor& fd);
31using utils::clone;
32
Lev Proleevc185e882020-12-15 19:25:32 +000033template <typename Type>
34nn::GeneralResult<std::vector<Type>> cloneVec(const std::vector<Type>& arguments) {
35 std::vector<Type> clonedObjects;
36 clonedObjects.reserve(arguments.size());
37 for (const auto& argument : arguments) {
38 clonedObjects.push_back(NN_TRY(clone(argument)));
39 }
40 return clonedObjects;
41}
42
43template <typename Type>
Lev Proleev900c28a2021-01-26 19:40:20 +000044nn::GeneralResult<std::vector<Type>> clone(const std::vector<Type>& arguments) {
Lev Proleevc185e882020-12-15 19:25:32 +000045 return cloneVec(arguments);
46}
47
Michael Butlerf03ebd92021-03-25 15:27:38 -070048nn::GeneralResult<ndk::ScopedFileDescriptor> clone(const ndk::ScopedFileDescriptor& fd) {
49 auto duplicatedFd = NN_TRY(nn::dupFd(fd.get()));
50 return ndk::ScopedFileDescriptor(duplicatedFd.release());
51}
52
53nn::GeneralResult<common::NativeHandle> clone(const common::NativeHandle& handle) {
Michael Butlerad643b62022-04-25 22:36:51 -070054 auto fds = NN_TRY(cloneVec(handle.fds));
Michael Butlerf03ebd92021-03-25 15:27:38 -070055 return common::NativeHandle{
Michael Butlerad643b62022-04-25 22:36:51 -070056 .fds = std::move(fds),
Michael Butlerf03ebd92021-03-25 15:27:38 -070057 .ints = handle.ints,
58 };
59}
60
Lev Proleevc185e882020-12-15 19:25:32 +000061} // namespace
62
Lev Proleev900c28a2021-01-26 19:40:20 +000063nn::GeneralResult<Memory> clone(const Memory& memory) {
Michael Butlerf03ebd92021-03-25 15:27:38 -070064 switch (memory.getTag()) {
65 case Memory::Tag::ashmem: {
66 const auto& ashmem = memory.get<Memory::Tag::ashmem>();
Michael Butlerad643b62022-04-25 22:36:51 -070067 auto fd = NN_TRY(clone(ashmem.fd));
Michael Butlerf03ebd92021-03-25 15:27:38 -070068 auto handle = common::Ashmem{
Michael Butlerad643b62022-04-25 22:36:51 -070069 .fd = std::move(fd),
Michael Butlerf03ebd92021-03-25 15:27:38 -070070 .size = ashmem.size,
71 };
72 return Memory::make<Memory::Tag::ashmem>(std::move(handle));
Lev Proleevc185e882020-12-15 19:25:32 +000073 }
Michael Butlerf03ebd92021-03-25 15:27:38 -070074 case Memory::Tag::mappableFile: {
75 const auto& memFd = memory.get<Memory::Tag::mappableFile>();
Michael Butlerad643b62022-04-25 22:36:51 -070076 auto fd = NN_TRY(clone(memFd.fd));
Michael Butlerf03ebd92021-03-25 15:27:38 -070077 auto handle = common::MappableFile{
78 .length = memFd.length,
79 .prot = memFd.prot,
Michael Butlerad643b62022-04-25 22:36:51 -070080 .fd = std::move(fd),
Michael Butlerf03ebd92021-03-25 15:27:38 -070081 .offset = memFd.offset,
82 };
83 return Memory::make<Memory::Tag::mappableFile>(std::move(handle));
84 }
85 case Memory::Tag::hardwareBuffer: {
86 const auto& hardwareBuffer = memory.get<Memory::Tag::hardwareBuffer>();
Michael Butlerad643b62022-04-25 22:36:51 -070087 auto handle = NN_TRY(clone(hardwareBuffer.handle));
88 auto ahwbHandle = graphics::common::HardwareBuffer{
Michael Butlerf03ebd92021-03-25 15:27:38 -070089 .description = hardwareBuffer.description,
Michael Butlerad643b62022-04-25 22:36:51 -070090 .handle = std::move(handle),
Michael Butlerf03ebd92021-03-25 15:27:38 -070091 };
Michael Butlerad643b62022-04-25 22:36:51 -070092 return Memory::make<Memory::Tag::hardwareBuffer>(std::move(ahwbHandle));
Michael Butlerf03ebd92021-03-25 15:27:38 -070093 }
Lev Proleevc185e882020-12-15 19:25:32 +000094 }
Jooyung Han0bdded62022-02-26 21:10:12 +090095 return (NN_ERROR() << "Unrecognized Memory::Tag: " << underlyingType(memory.getTag()))
Michael Butlerf03ebd92021-03-25 15:27:38 -070096 .
97 operator nn::GeneralResult<Memory>();
Lev Proleevc185e882020-12-15 19:25:32 +000098}
99
Lev Proleev900c28a2021-01-26 19:40:20 +0000100nn::GeneralResult<RequestMemoryPool> clone(const RequestMemoryPool& requestPool) {
Lev Proleevc185e882020-12-15 19:25:32 +0000101 using Tag = RequestMemoryPool::Tag;
102 switch (requestPool.getTag()) {
103 case Tag::pool:
104 return RequestMemoryPool::make<Tag::pool>(NN_TRY(clone(requestPool.get<Tag::pool>())));
105 case Tag::token:
106 return RequestMemoryPool::make<Tag::token>(requestPool.get<Tag::token>());
107 }
108 // Using explicit type conversion because std::variant inside the RequestMemoryPool confuses the
109 // compiler.
Jooyung Han0bdded62022-02-26 21:10:12 +0900110 return (NN_ERROR() << "Unrecognized request pool tag: " << underlyingType(requestPool.getTag()))
Lev Proleevc185e882020-12-15 19:25:32 +0000111 .
Lev Proleev900c28a2021-01-26 19:40:20 +0000112 operator nn::GeneralResult<RequestMemoryPool>();
Lev Proleevc185e882020-12-15 19:25:32 +0000113}
114
Lev Proleev900c28a2021-01-26 19:40:20 +0000115nn::GeneralResult<Request> clone(const Request& request) {
Michael Butlerad643b62022-04-25 22:36:51 -0700116 auto pools = NN_TRY(clone(request.pools));
Lev Proleevc185e882020-12-15 19:25:32 +0000117 return Request{
118 .inputs = request.inputs,
119 .outputs = request.outputs,
Michael Butlerad643b62022-04-25 22:36:51 -0700120 .pools = std::move(pools),
Lev Proleevc185e882020-12-15 19:25:32 +0000121 };
122}
123
Lev Proleev900c28a2021-01-26 19:40:20 +0000124nn::GeneralResult<Model> clone(const Model& model) {
Michael Butlerad643b62022-04-25 22:36:51 -0700125 auto pools = NN_TRY(clone(model.pools));
Lev Proleevc185e882020-12-15 19:25:32 +0000126 return Model{
Lev Proleev6b6dfcd2020-11-11 18:28:50 +0000127 .main = model.main,
128 .referenced = model.referenced,
129 .operandValues = model.operandValues,
Michael Butlerad643b62022-04-25 22:36:51 -0700130 .pools = std::move(pools),
Lev Proleev6b6dfcd2020-11-11 18:28:50 +0000131 .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
132 .extensionNameToPrefix = model.extensionNameToPrefix,
133 };
Lev Proleev6b6dfcd2020-11-11 18:28:50 +0000134}
135
Lev Proleev900c28a2021-01-26 19:40:20 +0000136nn::GeneralResult<void> handleTransportError(const ndk::ScopedAStatus& ret) {
137 if (ret.getStatus() == STATUS_DEAD_OBJECT) {
138 return nn::error(nn::ErrorStatus::DEAD_OBJECT)
139 << "Binder transaction returned STATUS_DEAD_OBJECT: " << ret.getDescription();
140 }
141 if (ret.isOk()) {
142 return {};
143 }
144 if (ret.getExceptionCode() != EX_SERVICE_SPECIFIC) {
145 return nn::error(nn::ErrorStatus::GENERAL_FAILURE)
146 << "Binder transaction returned exception: " << ret.getDescription();
147 }
148 return nn::error(static_cast<nn::ErrorStatus>(ret.getServiceSpecificError()))
149 << ret.getMessage();
150}
151
Lev Proleev6b6dfcd2020-11-11 18:28:50 +0000152} // namespace aidl::android::hardware::neuralnetworks::utils