• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 "VersionedIDevice.h"
18 
19 #include "Utils.h"
20 
21 #include <android-base/logging.h>
22 
23 namespace android {
24 namespace nn {
25 
26 // HIDL guarantees all V1_1 interfaces inherit from their corresponding V1_0 interfaces.
VersionedIDevice(sp<V1_0::IDevice> device)27 VersionedIDevice::VersionedIDevice(sp<V1_0::IDevice> device) :
28         mDeviceV1_0(device),
29         mDeviceV1_1(V1_1::IDevice::castFrom(mDeviceV1_0).withDefault(nullptr)) {}
30 
getCapabilities()31 std::pair<ErrorStatus, Capabilities> VersionedIDevice::getCapabilities() {
32     std::pair<ErrorStatus, Capabilities> result;
33 
34     if (mDeviceV1_1 != nullptr) {
35         Return<void> ret = mDeviceV1_1->getCapabilities_1_1(
36             [&result](ErrorStatus error, const Capabilities& capabilities) {
37                 result = std::make_pair(error, capabilities);
38             });
39         if (!ret.isOk()) {
40             LOG(ERROR) << "getCapabilities_1_1 failure: " << ret.description();
41             return {ErrorStatus::GENERAL_FAILURE, {}};
42         }
43     } else if (mDeviceV1_0 != nullptr) {
44         Return<void> ret = mDeviceV1_0->getCapabilities(
45             [&result](ErrorStatus error, const V1_0::Capabilities& capabilities) {
46                 result = std::make_pair(error, convertToV1_1(capabilities));
47             });
48         if (!ret.isOk()) {
49             LOG(ERROR) << "getCapabilities failure: " << ret.description();
50             return {ErrorStatus::GENERAL_FAILURE, {}};
51         }
52     } else {
53         LOG(ERROR) << "Device not available!";
54         return {ErrorStatus::DEVICE_UNAVAILABLE, {}};
55     }
56 
57     return result;
58 }
59 
getSupportedOperations(const Model & model)60 std::pair<ErrorStatus, hidl_vec<bool>> VersionedIDevice::getSupportedOperations(
61         const Model& model) {
62     std::pair<ErrorStatus, hidl_vec<bool>> result;
63 
64     if (mDeviceV1_1 != nullptr) {
65         Return<void> ret = mDeviceV1_1->getSupportedOperations_1_1(
66             model, [&result](ErrorStatus error, const hidl_vec<bool>& supported) {
67                 result = std::make_pair(error, supported);
68             });
69         if (!ret.isOk()) {
70             LOG(ERROR) << "getSupportedOperations_1_1 failure: " << ret.description();
71             return {ErrorStatus::GENERAL_FAILURE, {}};
72         }
73     } else if (mDeviceV1_0 != nullptr && compliantWithV1_0(model)) {
74         Return<void> ret = mDeviceV1_0->getSupportedOperations(
75             convertToV1_0(model), [&result](ErrorStatus error, const hidl_vec<bool>& supported) {
76                 result = std::make_pair(error, supported);
77             });
78         if (!ret.isOk()) {
79             LOG(ERROR) << "getSupportedOperations failure: " << ret.description();
80             return {ErrorStatus::GENERAL_FAILURE, {}};
81         }
82     } else {
83         // TODO: partition the model such that v1.1 ops are not passed to v1.0
84         // device
85         LOG(ERROR) << "Could not handle getSupportedOperations!";
86         return {ErrorStatus::GENERAL_FAILURE, {}};
87     }
88 
89     return result;
90 }
91 
prepareModel(const Model & model,ExecutionPreference preference,const sp<IPreparedModelCallback> & callback)92 ErrorStatus VersionedIDevice::prepareModel(const Model& model, ExecutionPreference preference,
93                                            const sp<IPreparedModelCallback>& callback) {
94     if (mDeviceV1_1 != nullptr) {
95         Return<ErrorStatus> ret = mDeviceV1_1->prepareModel_1_1(model, preference, callback);
96         if (!ret.isOk()) {
97             LOG(ERROR) << "prepareModel_1_1 failure: " << ret.description();
98             return ErrorStatus::GENERAL_FAILURE;
99         }
100         return static_cast<ErrorStatus>(ret);
101     } else if (mDeviceV1_0 != nullptr && compliantWithV1_0(model)) {
102         Return<ErrorStatus> ret = mDeviceV1_0->prepareModel(convertToV1_0(model), callback);
103         if (!ret.isOk()) {
104             LOG(ERROR) << "prepareModel failure: " << ret.description();
105             return ErrorStatus::GENERAL_FAILURE;
106         }
107         return static_cast<ErrorStatus>(ret);
108     } else {
109         // TODO: partition the model such that v1.1 ops are not passed to v1.0
110         // device
111         LOG(ERROR) << "Could not handle prepareModel!";
112         return ErrorStatus::GENERAL_FAILURE;
113     }
114 }
115 
getStatus()116 DeviceStatus VersionedIDevice::getStatus() {
117     if (mDeviceV1_0 == nullptr) {
118         LOG(ERROR) << "Device not available!";
119         return DeviceStatus::UNKNOWN;
120     }
121 
122     Return<DeviceStatus> ret = mDeviceV1_0->getStatus();
123 
124     if (!ret.isOk()) {
125         LOG(ERROR) << "getStatus failure: " << ret.description();
126         return DeviceStatus::UNKNOWN;
127     }
128     return static_cast<DeviceStatus>(ret);
129 }
130 
operator ==(nullptr_t)131 bool VersionedIDevice::operator==(nullptr_t) {
132     return mDeviceV1_0 == nullptr;
133 }
134 
operator !=(nullptr_t)135 bool VersionedIDevice::operator!=(nullptr_t) {
136     return mDeviceV1_0 != nullptr;
137 }
138 
139 }  // namespace nn
140 }  // namespace android
141