• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 #define LOG_TAG "SampleDriver"
18 
19 #include "SampleDriver.h"
20 
21 #include "CpuExecutor.h"
22 #include "HalInterfaces.h"
23 
24 #include <android-base/logging.h>
25 #include <hidl/LegacySupport.h>
26 #include <thread>
27 
28 namespace android {
29 namespace nn {
30 namespace sample_driver {
31 
prepareModel(const Model & model,const sp<IPreparedModelCallback> & callback)32 Return<ErrorStatus> SampleDriver::prepareModel(const Model& model,
33                                                const sp<IPreparedModelCallback>& callback) {
34     if (VLOG_IS_ON(DRIVER)) {
35         VLOG(DRIVER) << "prepareModel";
36         logModelToInfo(model);
37     }
38     if (callback.get() == nullptr) {
39         LOG(ERROR) << "invalid callback passed to prepareModel";
40         return ErrorStatus::INVALID_ARGUMENT;
41     }
42     if (!validateModel(model)) {
43         callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
44         return ErrorStatus::INVALID_ARGUMENT;
45     }
46 
47     // TODO: make asynchronous later
48     sp<SamplePreparedModel> preparedModel = new SamplePreparedModel(model);
49     if (!preparedModel->initialize()) {
50        callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr);
51        return ErrorStatus::INVALID_ARGUMENT;
52     }
53     callback->notify(ErrorStatus::NONE, preparedModel);
54     return ErrorStatus::NONE;
55 }
56 
getStatus()57 Return<DeviceStatus> SampleDriver::getStatus() {
58     VLOG(DRIVER) << "getStatus()";
59     return DeviceStatus::AVAILABLE;
60 }
61 
run()62 int SampleDriver::run() {
63     android::hardware::configureRpcThreadpool(4, true);
64     if (registerAsService(mName) != android::OK) {
65         LOG(ERROR) << "Could not register service";
66         return 1;
67     }
68     android::hardware::joinRpcThreadpool();
69     LOG(ERROR) << "Service exited!";
70     return 1;
71 }
72 
initialize()73 bool SamplePreparedModel::initialize() {
74     return setRunTimePoolInfosFromHidlMemories(&mPoolInfos, mModel.pools);
75 }
76 
asyncExecute(const Request & request,const sp<IExecutionCallback> & callback)77 void SamplePreparedModel::asyncExecute(const Request& request,
78                                        const sp<IExecutionCallback>& callback) {
79     std::vector<RunTimePoolInfo> requestPoolInfos;
80     if (!setRunTimePoolInfosFromHidlMemories(&requestPoolInfos, request.pools)) {
81         callback->notify(ErrorStatus::GENERAL_FAILURE);
82         return;
83     }
84 
85     CpuExecutor executor;
86     int n = executor.run(mModel, request, mPoolInfos, requestPoolInfos);
87     VLOG(DRIVER) << "executor.run returned " << n;
88     ErrorStatus executionStatus =
89             n == ANEURALNETWORKS_NO_ERROR ? ErrorStatus::NONE : ErrorStatus::GENERAL_FAILURE;
90     Return<void> returned = callback->notify(executionStatus);
91     if (!returned.isOk()) {
92         LOG(ERROR) << " hidl callback failed to return properly: " << returned.description();
93     }
94 }
95 
execute(const Request & request,const sp<IExecutionCallback> & callback)96 Return<ErrorStatus> SamplePreparedModel::execute(const Request& request,
97                                                  const sp<IExecutionCallback>& callback) {
98     VLOG(DRIVER) << "execute(" << toString(request) << ")";
99     if (callback.get() == nullptr) {
100         LOG(ERROR) << "invalid callback passed to execute";
101         return ErrorStatus::INVALID_ARGUMENT;
102     }
103     if (!validateRequest(request, mModel)) {
104         callback->notify(ErrorStatus::INVALID_ARGUMENT);
105         return ErrorStatus::INVALID_ARGUMENT;
106     }
107 
108     // This thread is intentionally detached because the sample driver service
109     // is expected to live forever.
110     std::thread([this, request, callback]{ asyncExecute(request, callback); }).detach();
111 
112     return ErrorStatus::NONE;
113 }
114 
115 } // namespace sample_driver
116 } // namespace nn
117 } // namespace android
118