1 /*
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 "Buffer.h"
18
19 #include <android-base/logging.h>
20 #include <android/hardware/neuralnetworks/1.3/IBuffer.h>
21 #include <android/hardware/neuralnetworks/1.3/types.h>
22 #include <nnapi/IBuffer.h>
23 #include <nnapi/TypeUtils.h>
24 #include <nnapi/Types.h>
25 #include <nnapi/hal/1.3/Utils.h>
26 #include <memory>
27
28 // See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface
29 // lifetimes across processes and for protecting asynchronous calls across HIDL.
30
31 namespace android::hardware::neuralnetworks::adapter {
32 namespace {
33
34 template <typename Type>
convertInput(const Type & object)35 auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
36 auto result = nn::convert(object);
37 if (!result.has_value()) {
38 result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
39 }
40 return result;
41 }
42
copyTo(const nn::SharedBuffer & buffer,const hidl_memory & dst)43 nn::GeneralResult<void> copyTo(const nn::SharedBuffer& buffer, const hidl_memory& dst) {
44 const auto memory = NN_TRY(convertInput(dst));
45 NN_TRY(buffer->copyTo(memory));
46 return {};
47 }
48
copyFrom(const nn::SharedBuffer & buffer,const hidl_memory & src,const hidl_vec<uint32_t> & dimensions)49 nn::GeneralResult<void> copyFrom(const nn::SharedBuffer& buffer, const hidl_memory& src,
50 const hidl_vec<uint32_t>& dimensions) {
51 const auto memory = NN_TRY(convertInput(src));
52 NN_TRY(buffer->copyFrom(memory, dimensions));
53 return {};
54 }
55
56 } // namespace
57
Buffer(nn::SharedBuffer buffer)58 Buffer::Buffer(nn::SharedBuffer buffer) : kBuffer(std::move(buffer)) {
59 CHECK(kBuffer != nullptr);
60 }
61
copyTo(const hidl_memory & dst)62 Return<V1_3::ErrorStatus> Buffer::copyTo(const hidl_memory& dst) {
63 auto result = adapter::copyTo(kBuffer, dst);
64 if (!result.has_value()) {
65 const auto [message, code] = std::move(result).error();
66 LOG(ERROR) << "adapter::Buffer::copyTo failed with " << code << ": " << message;
67 return V1_3::utils::convert(code).value();
68 }
69 return V1_3::ErrorStatus::NONE;
70 }
71
copyFrom(const hidl_memory & src,const hidl_vec<uint32_t> & dimensions)72 Return<V1_3::ErrorStatus> Buffer::copyFrom(const hidl_memory& src,
73 const hidl_vec<uint32_t>& dimensions) {
74 auto result = adapter::copyFrom(kBuffer, src, dimensions);
75 if (!result.has_value()) {
76 const auto [message, code] = std::move(result).error();
77 LOG(ERROR) << "adapter::Buffer::copyFrom failed with " << code << ": " << message;
78 return V1_3::utils::convert(code).value();
79 }
80 return V1_3::ErrorStatus::NONE;
81 }
82
83 } // namespace android::hardware::neuralnetworks::adapter
84