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
29namespace android {
30namespace nn {
31
32class ModelBuilder;
33
34class Device {
35    DISALLOW_IMPLICIT_CONSTRUCTORS(Device);
36public:
37    Device(std::string name, const sp<V1_0::IDevice>& device);
38    VersionedIDevice* getInterface() { return &mInterface; }
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
45    PerformanceInfo getFloat32Performance() const { return mFloat32Performance; }
46    PerformanceInfo getQuantized8Performance() const { return mQuantized8Performance; }
47    PerformanceInfo getRelaxedFloat32toFloat16Performance() const {
48        return mRelaxedFloat32toFloat16Performance;
49    }
50
51private:
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.
68class DeviceManager {
69public:
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:
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    };
90    uint32_t getPartitioning() const { return mPartitioning; }
91    static bool partitioningAllowsFallback(uint32_t partitioning) {
92        return partitioning == kPartitioningWithFallback;
93    }
94
95    // Returns the singleton manager.
96    static DeviceManager* get();
97
98private:
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