2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "compiler/BackendManager.h"
22 #include "backend/Backend.h"
23 #include "backend/controlflow/Backend.h"
24 #include "backend/controlflow/Config.h"
25 #include "backend/IConfig.h"
26 #include "util/logging.h"
27 #include "util/ConfigSource.h"
28 #include "misc/string_helpers.h"
30 static const char *SHARED_LIB_EXT =
31 #if defined(__APPLE__) && defined(__MACH__)
42 BackendManager &BackendManager::get()
44 static BackendManager object;
48 BackendManager::BackendManager() { loadControlflowBackend(); }
50 void BackendManager::loadControlflowBackend()
52 auto backend_object = std::unique_ptr<backend::controlflow::Backend, backend_destroy_t>(
53 new backend::controlflow::Backend, [](backend::Backend *backend) { delete backend; });
55 bool initialized = backend_object->config()->initialize(); // Call initialize here?
58 throw std::runtime_error(backend::controlflow::Config::ID + " backend initialization failed");
60 _controlflow = backend_object.get(); // Save the controlflow backend implementation pointer
62 _gen_map.emplace(backend_object->config()->id(), std::move(backend_object));
65 void BackendManager::loadBackend(const std::string &backend)
67 if (get(backend) != nullptr)
72 const std::string backend_so = "libbackend_" + backend + SHARED_LIB_EXT;
73 void *handle = dlopen(backend_so.c_str(), RTLD_LAZY | RTLD_LOCAL);
75 if (handle == nullptr)
77 VERBOSE(BackendManager) << "Failed to load backend '" << backend << "' - " << dlerror() << "\n";
81 VERBOSE(BackendManager) << "Successfully loaded '" << backend << "'(" << backend_so << ")\n";
84 // load object creator function
85 auto backend_create = (backend_create_t)dlsym(handle, "onert_backend_create");
86 if (backend_create == nullptr)
88 // TODO replace `fprintf` with `VERBOSE`
89 fprintf(stderr, "BackendManager: unable to find function `onert_backend_create` : %s\n",
95 // load object creator function
96 auto backend_destroy = (backend_destroy_t)dlsym(handle, "onert_backend_destroy");
97 if (backend_destroy == nullptr)
99 // TODO replace `fprintf` with `VERBOSE`
100 fprintf(stderr, "BackendManager: unable to find `function onert_backend_destroy` : %s\n",
106 auto backend_object =
107 std::unique_ptr<backend::Backend, backend_destroy_t>(backend_create(), backend_destroy);
108 bool initialized = backend_object->config()->initialize(); // Call initialize here?
111 VERBOSE(BackendManager) << backend.c_str()
112 << " backend initialization failed. Don't use this backend"
117 _gen_map.emplace(backend_object->config()->id(), std::move(backend_object));
120 // Save backend handle (avoid warning by handle lost without dlclose())
122 // NOTE This is a workaround for clang-format3.9 (seems like it does not understand
123 // "by-copy capture with an initializer"
125 auto u_handle = std::unique_ptr<void, dlhandle_destroy_t>{
126 handle, [id = backend, filename = backend_so](void *h) {
129 VERBOSE(BackendManager) << "Successfully unloaded '" << id << "'(" << filename << ")\n";
133 VERBOSE(BackendManager)
134 << "Failed to unload backend '" << id << "'- " << dlerror() << "\n";
138 _handle_map.emplace(backend, std::move(u_handle));
141 backend::Backend *BackendManager::get(const std::string &key)
143 if (_gen_map.find(key) != _gen_map.end())
145 return _gen_map.at(key).get();
151 const backend::Backend *BackendManager::get(const std::string &key) const
153 if (_gen_map.find(key) != _gen_map.end())
155 return _gen_map.at(key).get();
161 const backend::controlflow::Backend *BackendManager::getControlflow() const { return _controlflow; }
163 } // namespace compiler