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 // TODO Remove indentation
73 // Workaround If backend have dynamic library with "-boost" suffix naming,
74 // BackendManager load library with "-boost" suffix instead of library without suffix
75 // This feature is used for custom backend extension to support additional operations
77 const std::string backend_boost_so = "libbackend_" + backend + "-boost" + SHARED_LIB_EXT;
78 const std::string backend_so = "libbackend_" + backend + SHARED_LIB_EXT;
80 void *handle = dlopen(backend_boost_so.c_str(), RTLD_LAZY | RTLD_LOCAL);
81 if (handle == nullptr)
83 handle = dlopen(backend_so.c_str(), RTLD_LAZY | RTLD_LOCAL);
85 if (handle == nullptr)
87 VERBOSE_F() << "Failed to load backend '" << backend << "' - " << dlerror() << std::endl;
91 VERBOSE_F() << "Successfully loaded '" << backend << "' - " << backend_so << "\n";
95 VERBOSE_F() << "Successfully loaded '" << backend << "' - " << backend_boost_so << "\n";
99 // load object creator function
100 auto backend_create = (backend_create_t)dlsym(handle, "onert_backend_create");
101 if (backend_create == nullptr)
103 fprintf(stderr, "BackendManager: unable to open function onert_backend_create : %s\n",
108 // load object creator function
109 auto backend_destroy = (backend_destroy_t)dlsym(handle, "onert_backend_destroy");
110 if (backend_destroy == nullptr)
112 fprintf(stderr, "BackendManager: unable to open function onert_backend_destroy : %s\n",
117 auto backend_object =
118 std::unique_ptr<backend::Backend, backend_destroy_t>(backend_create(), backend_destroy);
119 bool initialized = backend_object->config()->initialize(); // Call initialize here?
122 VERBOSE_F() << backend.c_str() << " backend initialization failed. Don't use this backend"
127 _gen_map.emplace(backend_object->config()->id(), std::move(backend_object));
130 // Save backend handle (avoid warning by handle lost without dlclose())
131 auto u_handle = std::unique_ptr<void, dlhandle_destroy_t>{handle, [](void *h) { dlclose(h); }};
132 _handle_map.emplace(backend, std::move(u_handle));
136 backend::Backend *BackendManager::get(const std::string &key)
138 if (_gen_map.find(key) != _gen_map.end())
140 return _gen_map.at(key).get();
146 const backend::Backend *BackendManager::get(const std::string &key) const
148 if (_gen_map.find(key) != _gen_map.end())
150 return _gen_map.at(key).get();
156 const backend::controlflow::Backend *BackendManager::getControlflow() const { return _controlflow; }
158 } // namespace compiler