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 #ifndef ANDROID_ML_NN_RUNTIME_MANAGER_H
18 #define ANDROID_ML_NN_RUNTIME_MANAGER_H
19 
20 #include "HalInterfaces.h"
21 #include "Utils.h"
22 #include "VersionedIDevice.h"
23 
24 #include <android-base/macros.h>
25 #include <map>
26 #include <unordered_set>
27 #include <vector>
28 
29 namespace android {
30 namespace nn {
31 
32 class ModelBuilder;
33 
34 class Device {
35     DISALLOW_IMPLICIT_CONSTRUCTORS(Device);
36 public:
37     Device(std::string name, const sp<V1_0::IDevice>& device);
getInterface()38     VersionedIDevice* getInterface() { return &mInterface; }
getName()39     const std::string& getName() const { return mName; }
40     // Returns true if succesfully initialized.
41     bool initialize();
42 
43     void getSupportedOperations(const Model& hidlModel, hidl_vec<bool>* supportedOperations);
44 
getFloat32Performance()45     PerformanceInfo getFloat32Performance() const { return mFloat32Performance; }
getQuantized8Performance()46     PerformanceInfo getQuantized8Performance() const { return mQuantized8Performance; }
getRelaxedFloat32toFloat16Performance()47     PerformanceInfo getRelaxedFloat32toFloat16Performance() const {
48         return mRelaxedFloat32toFloat16Performance;
49     }
50 
51 private:
52     std::string mName;
53     VersionedIDevice mInterface;
54     PerformanceInfo mFloat32Performance;
55     PerformanceInfo mQuantized8Performance;
56     PerformanceInfo mRelaxedFloat32toFloat16Performance;
57 
58 #ifdef NN_DEBUGGABLE
59     // For debugging: behavior of IDevice::getSupportedOperations for SampleDriver.
60     // 0 - all operations reported by IDevice::getSupportedOperations() supported
61     // 1 - some operations reported by IDevice::getSupportedOperations() supported
62     uint32_t mSupported = 0;
63 #endif  // NN_DEBUGGABLE
64 };
65 
66 // Manages the NN HAL devices.  Only one instance of this class will exist.
67 // Use get() to retrieve it.
68 class DeviceManager {
69 public:
getDrivers()70     const std::vector<std::shared_ptr<Device>>& getDrivers() const {
71         if (mSetCpuOnly || mDebugNNCpuOnly) {
72             return mNoDevices;
73         }
74         return mDevices;
75     }
76 
77     // For testing only:
setUseCpuOnly(bool useCpuOnly)78     void setUseCpuOnly(bool useCpuOnly) { mSetCpuOnly = useCpuOnly; }
79 
80     // How to handle graph partitioning?
81     // 0 - Don't do graph partitioning.
82     // 1 - Do graph partitioning; but fall back to non-partitioned
83     //     execution if there is a partitioning failure.
84     // 2 - Do graph partitioning, and rely on it; there is no fallback.
85     enum {
86         kPartitioningNo              = 0,
87         kPartitioningWithFallback    = 1,
88         kPartitioningWithoutFallback = 2
89     };
getPartitioning()90     uint32_t getPartitioning() const { return mPartitioning; }
partitioningAllowsFallback(uint32_t partitioning)91     static bool partitioningAllowsFallback(uint32_t partitioning) {
92         return partitioning == kPartitioningWithFallback;
93     }
94 
95     // Returns the singleton manager.
96     static DeviceManager* get();
97 
98 private:
99     // Builds the list of available drivers and queries their capabilities.
100     DeviceManager();
101 
102     // Adds a device for the manager to use.
103     void registerDevice(const char* name, const sp<V1_0::IDevice>& device);
104 
105     void findAvailableDevices();
106 
107     // List of all the devices we discovered.
108     std::vector<std::shared_ptr<Device>> mDevices;
109 
110     // We leave this one always empty. To be used when mUseCpuOnly is true.
111     std::vector<std::shared_ptr<Device>> mNoDevices;
112 
113     // If either of these is true, we'll ignore the drivers that are
114     // on the device and run everything on the CPU.
115     bool mSetCpuOnly = false;      // set by setUseCpuOnly()
116     bool mDebugNNCpuOnly = false;  // derived from system property debug.nn.cpuonly
117 
118     static const uint32_t kPartitioningDefault = kPartitioningWithFallback;
119     uint32_t mPartitioning = kPartitioningDefault;
120 };
121 
122 } // namespace nn
123 } // namespace android
124 
125 #endif // ANDROID_ML_NN_RUNTIME_MANAGER_H
126