summaryrefslogtreecommitdiff
path: root/runtimes/neurun/core/src/backend/BackendManager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtimes/neurun/core/src/backend/BackendManager.cc')
-rw-r--r--runtimes/neurun/core/src/backend/BackendManager.cc124
1 files changed, 124 insertions, 0 deletions
diff --git a/runtimes/neurun/core/src/backend/BackendManager.cc b/runtimes/neurun/core/src/backend/BackendManager.cc
new file mode 100644
index 000000000..155f7f51a
--- /dev/null
+++ b/runtimes/neurun/core/src/backend/BackendManager.cc
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+#include <dlfcn.h>
+#include "BackendManager.h"
+
+#include "backend/Backend.h"
+#include "backend/IConfig.h"
+#include "util/logging.h"
+#include "util/ConfigSource.h"
+
+namespace neurun
+{
+namespace backend
+{
+
+BackendManager &BackendManager::instance()
+{
+ static BackendManager object;
+ return object;
+}
+
+template <typename T, class... Types>
+void BackendManager::loadObjectFromPlugin(std::shared_ptr<T> &object_of_plugin_class,
+ const std::string obj_creator_func_name, void *handle,
+ Types &&... args)
+{
+ T *(*allocate_obj)(Types && ... Args);
+ // load object creator function
+ allocate_obj = (T * (*)(Types && ... Args))dlsym(handle, obj_creator_func_name.c_str());
+ if (allocate_obj == nullptr)
+ {
+ fprintf(stderr, "BackendManager: unable to open function %s: %s\n",
+ obj_creator_func_name.c_str(), dlerror());
+ abort();
+ }
+
+ object_of_plugin_class.reset(allocate_obj(args...));
+}
+
+void BackendManager::loadBackend(const std::string &backend)
+{
+ const std::string backend_plugin = "libbackend_" + backend + ".so";
+ void *handle = dlopen(backend_plugin.c_str(), RTLD_LAZY | RTLD_LOCAL);
+ if (handle == nullptr)
+ {
+ fprintf(stderr, "BackendManager::loadBackend failed to load plugin of %s backend: %s\n",
+ backend.c_str(), dlerror());
+ abort();
+ }
+ VERBOSE(BackendManager::loadBackend) << "loaded " << backend_plugin << " as a plugin of "
+ << backend << " backend\n";
+
+ {
+ // load object creator function
+ auto backend_create = (backend_create_t)dlsym(handle, "neurun_backend_create");
+ if (backend_create == nullptr)
+ {
+ fprintf(stderr, "BackendManager: unable to open function neurun_backend_create : %s\n",
+ dlerror());
+ abort();
+ }
+
+ // load object creator function
+ auto backend_destroy = (backend_destroy_t)dlsym(handle, "neurun_backend_destroy");
+ if (backend_destroy == nullptr)
+ {
+ fprintf(stderr, "BackendManager: unable to open function neurun_backend_destroy : %s\n",
+ dlerror());
+ abort();
+ }
+
+ auto backend_object =
+ std::unique_ptr<backend::Backend, backend_destroy_t>(backend_create(), backend_destroy);
+ auto backend_object_raw = backend_object.get();
+ backend_object->config()->initialize(); // Call initialize here?
+ _gen_map.emplace(backend_object->config()->id(), std::move(backend_object));
+ _available_backends.push_back(backend_object_raw);
+ }
+
+ // Save backend handle (avoid warning by handle lost without dlclose())
+ _handle_map.emplace(backend, handle);
+}
+
+BackendManager::BackendManager()
+{
+ const auto backends = util::getConfigString(util::config::BACKENDS);
+ size_t prev_pos = 0;
+ auto pos = backends.find(";");
+ while (pos != std::string::npos)
+ {
+ loadBackend(backends.substr(prev_pos, pos - prev_pos));
+ prev_pos = pos + 1;
+ pos = backends.find(";", prev_pos);
+ }
+ // if backends doesn't terminate with ";"
+ if (prev_pos < backends.size())
+ {
+ loadBackend(backends.substr(prev_pos));
+ }
+}
+
+Backend *BackendManager::get(const std::string &key) { return _gen_map.at(key).get(); }
+
+const Backend *BackendManager::get(const std::string &key) const { return _gen_map.at(key).get(); }
+
+const Backend *BackendManager::getDefault() const { return get("cpu"); }
+
+} // namespace backend
+} // namespace neurun