1/**
2 * Copyright (c) Glow Contributors. See CONTRIBUTORS file.
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#ifndef GLOW_BACKENDS_INLINEDEVICEMANAGER_H
17#define GLOW_BACKENDS_INLINEDEVICEMANAGER_H
18
19#include "glow/Backends/DeviceManager.h"
20#include "glow/Runtime/RuntimeTypes.h"
21#include "llvm/Support/FormatVariadic.h"
22
23#include <atomic>
24
25namespace glow {
26namespace runtime {
27
28/// The DummyDeviceManager is a simple DeviceManager implementation that
29/// provides execution for backends that are in development. It is explicitly
30/// not threadsafe and runs provided CompiledFunction's in the caller thread.
31class DummyDeviceManager : public DeviceManager {
32 /// Compiled function list by name.
33 FunctionMapTy functions_;
34
35public:
36 DummyDeviceManager(const DeviceConfig &config) : DeviceManager(config) {}
37
38 /// The DummyDeviceManager is a simple wrapper for testing, if you need
39 /// memory guards you should implement a DeviceManager for your device.
40 uint64_t getMaximumMemory() const override {
41 return std::numeric_limits<uint64_t>::max();
42 }
43 uint64_t getAvailableMemory() const override {
44 return std::numeric_limits<uint64_t>::max();
45 }
46 bool isMemoryAvailable(uint64_t) const override { return true; }
47
48 /// Load the provided module into the device, readyCB will be called when
49 /// ready to use.
50 /// \p functions contains the list of functions to load, keyed by their name
51 /// (as used in runFunction).
52 void addNetwork(const Module *module, FunctionMapTy functions,
53 ReadyCBTy callback) override {
54 for (const auto &func : functions) {
55 if (functions_.count(func.first) != 0) {
56 callback(
57 module,
58 MAKE_ERR(
59 ErrorValue::ErrorCode::RUNTIME_NET_NOT_FOUND,
60 llvm::formatv("Function {0} not found", func.first).str()));
61 return;
62 }
63 }
64
65 for (const auto &func : functions) {
66 if (func.second->getRuntimeBundle().getConstants() == nullptr) {
67 func.second->getRuntimeBundle().collectConstants(module);
68 }
69 functions_.emplace(func.first, func.second);
70 }
71
72 // Fire the ready CB.
73 callback(module, Error::success());
74 }
75
76 /// Remove (and delete) the provided function, freeing
77 /// up space on the device.
78 void evictNetwork(std::string functionName,
79 EvictFunctionCBTy evictCB) override {
80 functions_.erase(functionName);
81 evictCB(functionName, Error::success());
82 }
83
84 /// Execute the named Function in an already provided network on the device.
85 /// functionName must match the name of a function already added.
86 /// The ExecutionContext's PlaceholderBindings should have all Placeholders
87 /// allocated. resultCB will be called with the ExecutionContext containing
88 /// output tensors filled, and any generated TraceEvents.
89 RunIdentifierTy runFunction(std::string functionName,
90 std::unique_ptr<ExecutionContext> context,
91 ResultCBTy callback) override {
92 auto funcIt = functions_.find(functionName);
93 if (funcIt == functions_.end()) {
94 callback(
95 0,
96 MAKE_ERR(ErrorValue::ErrorCode::RUNTIME_NET_NOT_FOUND,
97 llvm::formatv("Function {0} not found", functionName).str()),
98 std::move(context));
99 return 0;
100 }
101
102 CompiledFunction *func = funcIt->second;
103
104 auto executeErr = func->execute(context.get());
105
106 // Fire the resultCB.
107 callback(0, std::move(executeErr), std::move(context));
108
109 return 0;
110 }
111};
112
113} // namespace runtime
114} // namespace glow
115
116#endif // GLOW_BACKENDS_INLINEDEVICEMANAGER_H
117