• 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 "CompilationBuilder"
18 
19 #include "CompilationBuilder.h"
20 
21 #include "ExecutionBuilder.h"
22 #include "ExecutionPlan.h"
23 #include "Manager.h"
24 #include "ModelBuilder.h"
25 #include "Utils.h"
26 
27 namespace android {
28 namespace nn {
29 
CompilationBuilder(const ModelBuilder * model)30 CompilationBuilder::CompilationBuilder(const ModelBuilder* model) :
31         mModel(model), mPartitioning(DeviceManager::get()->getPartitioning()) {
32     VLOG(COMPILATION) << "CompilationBuilder::CompilationBuilder";
33 }
34 
finish()35 int CompilationBuilder::finish() {
36     // Get the list of HAL devices.
37     return finish(DeviceManager::get()->getDrivers());
38 }
39 
finish(const std::vector<std::shared_ptr<Device>> & devices)40 int CompilationBuilder::finish(const std::vector<std::shared_ptr<Device>>& devices) {
41     if (mFinished) {
42         LOG(ERROR) << "ANeuralNetworksCompilation_finish called more than once";
43         return ANEURALNETWORKS_BAD_STATE;
44     }
45     // TODO validate the rest
46 
47     mFinished = true;
48 
49     if (mPartitioning) {
50         int n = mModel->partitionTheWork(devices, mPreference, &mPlan);
51         switch (n) {
52             case ANEURALNETWORKS_NO_ERROR:
53                 break;
54             case ANEURALNETWORKS_UNEXPECTED_NULL:
55             case ANEURALNETWORKS_BAD_DATA:
56                 // The two error codes above should only be used for errors in the user's
57                 // request. In case of a user error, we won't try any fallback.
58                 // TODO: Document this in NeuralNetworks.h and in the HAL. Make sure
59                 // driver writers know which code they can return.
60                 return n;
61             default:
62                 // The error might be recoverable. Return the error only if falling back
63                 // is not allowed.
64                 if (!DeviceManager::partitioningAllowsFallback(mPartitioning)) {
65                     return n;
66                 }
67                 break;
68         }
69     }
70 
71     return ANEURALNETWORKS_NO_ERROR;
72 }
73 
setPreference(int32_t preference)74 int CompilationBuilder::setPreference(int32_t preference) {
75     if (mFinished) {
76         LOG(ERROR) <<
77                 "ANeuralNetworksCompilation_setPreference can't modify after compilation finished";
78         return ANEURALNETWORKS_BAD_STATE;
79     }
80     if (preference >= kNumberOfPreferences) {
81         LOG(ERROR) << "ANeuralNetworksCompilation_setPreference invalid preference " << preference;
82         return ANEURALNETWORKS_BAD_DATA;
83     }
84 
85     mPreference = preference;
86     return ANEURALNETWORKS_NO_ERROR;
87 }
88 
setPartitioning(uint32_t partitioning)89 int CompilationBuilder::setPartitioning(uint32_t partitioning) {
90     if (mFinished) {
91         LOG(ERROR) <<
92                 "ANeuralNetworksCompilation_setPartitioning can't modify after compilation finished";
93         return ANEURALNETWORKS_BAD_STATE;
94     }
95 
96     mPartitioning = partitioning;
97     return ANEURALNETWORKS_NO_ERROR;
98 }
99 
createExecution(ExecutionBuilder ** execution)100 int CompilationBuilder::createExecution(ExecutionBuilder **execution) {
101     if (!mFinished) {
102         LOG(ERROR) << "ANeuralNetworksExecution_create passed an unfinished compilation";
103         *execution = nullptr;
104         return ANEURALNETWORKS_BAD_STATE;
105     }
106     *execution = new (std::nothrow) ExecutionBuilder(this);
107     return (*execution ? ANEURALNETWORKS_NO_ERROR : ANEURALNETWORKS_OUT_OF_MEMORY);
108 }
109 
110 }  // namespace nn
111 }  // namespace android
112