summaryrefslogtreecommitdiff
path: root/neuralnetworks/aidl/utils/src/Utils.cpp
blob: 95516c854b2a5018de3b1a8a779447a2de9e3757 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Utils.h"

#include <android/binder_status.h>
#include <nnapi/Result.h>

namespace aidl::android::hardware::neuralnetworks::utils {
namespace {

template <typename Type>
nn::GeneralResult<std::vector<Type>> cloneVec(const std::vector<Type>& arguments) {
    std::vector<Type> clonedObjects;
    clonedObjects.reserve(arguments.size());
    for (const auto& argument : arguments) {
        clonedObjects.push_back(NN_TRY(clone(argument)));
    }
    return clonedObjects;
}

template <typename Type>
nn::GeneralResult<std::vector<Type>> clone(const std::vector<Type>& arguments) {
    return cloneVec(arguments);
}

}  // namespace

nn::GeneralResult<Memory> clone(const Memory& memory) {
    common::NativeHandle nativeHandle;
    nativeHandle.ints = memory.handle.ints;
    nativeHandle.fds.reserve(memory.handle.fds.size());
    for (const auto& fd : memory.handle.fds) {
        const int newFd = dup(fd.get());
        if (newFd < 0) {
            return NN_ERROR() << "Couldn't dup a file descriptor";
        }
        nativeHandle.fds.emplace_back(newFd);
    }
    return Memory{
            .handle = std::move(nativeHandle),
            .size = memory.size,
            .name = memory.name,
    };
}

nn::GeneralResult<RequestMemoryPool> clone(const RequestMemoryPool& requestPool) {
    using Tag = RequestMemoryPool::Tag;
    switch (requestPool.getTag()) {
        case Tag::pool:
            return RequestMemoryPool::make<Tag::pool>(NN_TRY(clone(requestPool.get<Tag::pool>())));
        case Tag::token:
            return RequestMemoryPool::make<Tag::token>(requestPool.get<Tag::token>());
    }
    // Using explicit type conversion because std::variant inside the RequestMemoryPool confuses the
    // compiler.
    return (NN_ERROR() << "Unrecognized request pool tag: " << requestPool.getTag())
            .
            operator nn::GeneralResult<RequestMemoryPool>();
}

nn::GeneralResult<Request> clone(const Request& request) {
    return Request{
            .inputs = request.inputs,
            .outputs = request.outputs,
            .pools = NN_TRY(clone(request.pools)),
    };
}

nn::GeneralResult<Model> clone(const Model& model) {
    return Model{
            .main = model.main,
            .referenced = model.referenced,
            .operandValues = model.operandValues,
            .pools = NN_TRY(clone(model.pools)),
            .relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
            .extensionNameToPrefix = model.extensionNameToPrefix,
    };
}

nn::GeneralResult<void> handleTransportError(const ndk::ScopedAStatus& ret) {
    if (ret.getStatus() == STATUS_DEAD_OBJECT) {
        return nn::error(nn::ErrorStatus::DEAD_OBJECT)
               << "Binder transaction returned STATUS_DEAD_OBJECT: " << ret.getDescription();
    }
    if (ret.isOk()) {
        return {};
    }
    if (ret.getExceptionCode() != EX_SERVICE_SPECIFIC) {
        return nn::error(nn::ErrorStatus::GENERAL_FAILURE)
               << "Binder transaction returned exception: " << ret.getDescription();
    }
    return nn::error(static_cast<nn::ErrorStatus>(ret.getServiceSpecificError()))
           << ret.getMessage();
}

}  // namespace aidl::android::hardware::neuralnetworks::utils