aboutsummaryrefslogtreecommitdiff
path: root/include/armnn/backends/IBackendInternal.hpp
blob: 626746465f6bddfeadc96ea82e0b0b042c88aaa2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include <armnn/Types.hpp>
#include <armnn/IRuntime.hpp>
#include <armnn/Deprecated.hpp>

#include <ISubgraphViewConverter.hpp>
#include <SubgraphView.hpp>
#include <optimizations/Optimization.hpp>

#include "IBackendContext.hpp"
#include "armnn/backends/profiling/IBackendProfiling.hpp"
#include "armnn/backends/profiling/IBackendProfilingContext.hpp"
#include "IMemoryManager.hpp"
#include "ITensorHandleFactory.hpp"
#include "OptimizationViews.hpp"

#include <vector>
#include <memory>

namespace armnn
{
class IWorkloadFactory;
class IMemoryManager;
class ILayerSupport;

struct BackendVersion
{
    uint32_t m_Major;
    uint32_t m_Minor;

    constexpr BackendVersion()
        : m_Major(0)
        , m_Minor(0)
    {}
    constexpr BackendVersion(uint32_t major, uint32_t minor)
        : m_Major(major)
        , m_Minor(minor)
    {}

    bool operator==(const BackendVersion& other) const
    {
        return this == &other ||
               (this->m_Major == other.m_Major &&
                this->m_Minor == other.m_Minor);
    }

    bool operator<=(const BackendVersion& other) const
    {
        return this->m_Major < other.m_Major ||
               (this->m_Major == other.m_Major &&
                this->m_Minor <= other.m_Minor);
    }

    bool operator>=(const BackendVersion& other) const
    {
        return this->m_Major > other.m_Major ||
               (this->m_Major == other.m_Major &&
                this->m_Minor >= other.m_Minor);
    }
};

inline std::ostream& operator<<(std::ostream& os, const BackendVersion& backendVersion)
{
    os << "[" << backendVersion.m_Major << "." << backendVersion.m_Minor << "]";

    return os;
}

class IBackendInternal : public IBackend
{
protected:
    /// Creation must be done through a specific
    /// backend interface.
    IBackendInternal() = default;

public:
    /// Allow backends created by the factory function
    /// to be destroyed through IBackendInternal.
    ~IBackendInternal() override = default;

    using IWorkloadFactoryPtr = std::unique_ptr<IWorkloadFactory>;
    using IBackendContextPtr = std::unique_ptr<IBackendContext>;
    /// This is the bridge between backend and backend profiling we'll keep it in the backend namespace.
    using IBackendProfilingContextPtr = std::shared_ptr<armnn::profiling::IBackendProfilingContext>;
    using IBackendProfilingPtr = std::unique_ptr<armnn::profiling::IBackendProfiling>;
    using OptimizationPtr = std::unique_ptr<Optimization>;
    using Optimizations = std::vector<OptimizationPtr>;
    using ILayerSupportSharedPtr = std::shared_ptr<ILayerSupport>;

    using IBackendSpecificModelContextPtr = std::shared_ptr<IBackendModelContext>;

    using IMemoryManagerUniquePtr = std::unique_ptr<IMemoryManager>;
    using IMemoryManagerSharedPtr = std::shared_ptr<IMemoryManager>;

    using GraphUniquePtr = std::unique_ptr<Graph>;
    using SubgraphViewUniquePtr = std::unique_ptr<SubgraphView>;

    ARMNN_NO_DEPRECATE_WARN_BEGIN
    using ISubGraphConverterPtr ARMNN_DEPRECATED_MSG("This type is no longer supported")
        = std::unique_ptr<ISubGraphConverter>;
    using SubGraphUniquePtr ARMNN_DEPRECATED_MSG("SubGraph is deprecated, use SubgraphView instead")
        = std::unique_ptr<SubGraph>;

    ARMNN_DEPRECATED_MSG("This method is no longer supported")
    virtual ISubGraphConverterPtr CreateSubGraphConverter(const std::shared_ptr<SubGraph>& subGraph) const;

    ARMNN_DEPRECATED_MSG("Use \"OptimizationViews OptimizeSubgraphView(const SubgraphView&)\" instead")
    virtual Optimizations GetOptimizations() const;

    ARMNN_DEPRECATED_MSG("Use \"OptimizationViews OptimizeSubgraphView(const SubgraphView&)\" instead")
    virtual SubGraphUniquePtr OptimizeSubGraph(const SubGraph& subGraph, bool& optimizationAttempted) const;
    ARMNN_NO_DEPRECATE_WARN_END

    virtual IMemoryManagerUniquePtr CreateMemoryManager() const;

    virtual IWorkloadFactoryPtr CreateWorkloadFactory(
        const IMemoryManagerSharedPtr& memoryManager = nullptr) const = 0;

    virtual IWorkloadFactoryPtr CreateWorkloadFactory(
        class TensorHandleFactoryRegistry& tensorHandleFactoryRegistry) const;

    virtual IWorkloadFactoryPtr CreateWorkloadFactory(
        const IMemoryManagerSharedPtr& memoryManager,
        const ModelOptions& modelOptions) const;

    virtual IWorkloadFactoryPtr CreateWorkloadFactory(
        class TensorHandleFactoryRegistry& tensorHandleFactoryRegistry,
        const ModelOptions& modelOptions) const;

    virtual IWorkloadFactoryPtr CreateWorkloadFactory(
        class TensorHandleFactoryRegistry& tensorHandleFactoryRegistry,
        const ModelOptions& modelOptions,
        MemorySourceFlags inputFlags,
        MemorySourceFlags outputFlags) const;

    /// Create the runtime context of the backend
    ///
    /// Implementations may return a default-constructed IBackendContextPtr if
    /// no context is needed at runtime.
    /// Implementations must throw BackendUnavailableException if the backend
    /// cannot be used (for example, necessary accelerator hardware is not present).
    /// The default implementation always returns a default-constructed pointer.
    virtual IBackendContextPtr CreateBackendContext(const IRuntime::CreationOptions&) const;

    virtual IBackendSpecificModelContextPtr CreateBackendSpecificModelContext(const ModelOptions& modelOptions) const;

    /// Create context specifically used for profiling interaction from backends.
    virtual IBackendProfilingContextPtr CreateBackendProfilingContext(const IRuntime::CreationOptions& creationOptions,
                                                                      IBackendProfilingPtr& backendProfiling);

    virtual ILayerSupportSharedPtr GetLayerSupport() const = 0;

    virtual ILayerSupportSharedPtr GetLayerSupport(const ModelOptions& modelOptions) const;

    virtual OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph) const;

    virtual OptimizationViews OptimizeSubgraphView(const SubgraphView& subgraph,
                                                   const ModelOptions& modelOptions) const;

    bool SupportsTensorAllocatorAPI() const;

    ITensorHandleFactory::FactoryId GetBackwardCompatibleFavoriteHandleFactory();

    /// (Optional) Returns a vector of supported TensorHandleFactory ids in preference order.
    virtual std::vector<ITensorHandleFactory::FactoryId> GetHandleFactoryPreferences() const;

    /// (Optional) Register TensorHandleFactories
    /// Either this method or CreateMemoryManager() and
    /// IWorkloadFactory::CreateTensor()/IWorkloadFactory::CreateSubtensor() methods must be implemented.
    virtual void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& /*registry*/) {}

    /// (Optional) Register TensorHandleFactories
    /// Either this method or CreateMemoryManager() and
    /// IWorkloadFactory::CreateTensor()/IWorkloadFactory::CreateSubtensor() methods must be implemented.
    virtual void RegisterTensorHandleFactories(class TensorHandleFactoryRegistry& registry,
                                               MemorySourceFlags inputFlags,
                                               MemorySourceFlags outputFlags);

    /// Returns the version of the Backend API
    static constexpr BackendVersion GetApiVersion() { return BackendVersion(1, 1); }

    /// Returns a BackendCapability if the backend lists the capability
    /// The BackendCapability must then be inspected to check whether or not that BackendCapability is supported
    /// Otherwise returns an EmptyOptional if the BackendCapability is unlisted
    virtual BackendCapabilities GetCapabilities() const
    {
        return BackendCapabilities("IBackendInternal NullCapabilities");
    };

    /// Returns true if backend support the capability false otherwise
    ARMNN_DEPRECATED_MSG("This function has been deprecated in favour of GetCapability")
    virtual bool HasCapability(BackendCapability /*capabilityClass*/) const { return false; }

    /// Signals the backend to use a custom memory allocator provided by the user
    ///
    /// \param allocator - a pointer to the provided ICustomAllocator to use with this backend
    /// \param errMsg - Optional string variable to return error messages
    /// \return - Returns true if switching to custom allocator was successful
    virtual bool UseCustomMemoryAllocator(std::shared_ptr<ICustomAllocator> allocator,
                                          armnn::Optional<std::string&> errMsg)
    {
        IgnoreUnused(allocator);
        if (errMsg)
        {
            std::stringstream message;
            message << "The backend " << GetId() << " doesn't support using a custom allocator. This error might"
                                                    " be related with the protected mode if the backend doesn't"
                                                    " fully support it.";

            errMsg.value() = message.str();
        }
        return false;
    }
};

using IBackendInternalUniquePtr = std::unique_ptr<IBackendInternal>;

} // namespace armnn