- /runtime/libs/misc
- /runtime/libs/ndarray
- /runtime/onert
- - /runtime/service/npud/tests
- /tests/nnfw_api
testFile:
option(GENERATE_RUNTIME_NNAPI_TESTS "Generate NNAPI operation gtest" ON)
option(ENVVAR_ONERT_CONFIG "Use environment variable for onert configuration" ON)
option(INSTALL_TEST_SCRIPTS "Install test scripts" ON)
-option(BUILD_NPUD "Build NPU daemon" OFF)
-option(ENVVAR_NPUD_CONFIG "Use environment variable for npud configuration" OFF)
option(BUILD_MINMAX_H5DUMPER "Build minmax h5dumper" OFF)
#
# Default build configuration for contrib
option(BUILD_MLAPSE "Build mlapse benchmark toolkit" OFF)
option(BUILD_GPU_CL "Build gpu_cl backend" OFF)
option(BUILD_TENSORFLOW_LITE_GPU "Build TensorFlow Lite GPU delegate from the downloaded source" OFF)
+option(BUILD_NPUD "Build NPU daemon" OFF)
+option(ENVVAR_NPUD_CONFIG "Use environment variable for npud configuration" OFF)
#
# Default build configuration for tools
#
option(GENERATE_RUNTIME_NNAPI_TESTS "Generate NNAPI operation gtest" OFF)
option(ENVVAR_ONERT_CONFIG "Use environment variable for onert configuration" OFF)
-option(BUILD_NPUD "Build NPU daemon" OFF)
-# Do not allow to use CONFIG option on Tizen
-option(ENVVAR_NPUD_CONFIG "Use environment variable for npud configuration" OFF)
# Tizen boost package does not have static library
option(Boost_USE_STATIC_LIBS "Determine whether or not static linking for Boost" OFF)
option(GENERATE_RUNTIME_NNAPI_TESTS "Generate NNAPI operation gtest" OFF)
option(ENVVAR_ONERT_CONFIG "Use environment variable for onert configuration" OFF)
-option(BUILD_NPUD "Build NPU daemon" OFF)
-# Do not allow to use CONFIG option on Tizen
-option(ENVVAR_NPUD_CONFIG "Use environment variable for npud configuration" OFF)
# Tizen boost package does not have static library
option(Boost_USE_STATIC_LIBS "Determine whether or not static linking for Boost" OFF)
option(GENERATE_RUNTIME_NNAPI_TESTS "Generate NNAPI operation gtest" OFF)
option(ENVVAR_ONERT_CONFIG "Use environment variable for onert configuration" OFF)
-option(BUILD_NPUD "Build NPU daemon" OFF)
-# Do not allow to use CONFIG option on Tizen
-option(ENVVAR_NPUD_CONFIG "Use environment variable for npud configuration" OFF)
# Tizen boost package does not have static library
option(Boost_USE_STATIC_LIBS "Determine whether or not static linking for Boost" OFF)
option(ENVVAR_ONERT_CONFIG "Use environment variable for onert configuration" OFF)
option(BUILD_XNNPACK "Build XNNPACK" OFF)
-
-option(BUILD_NPUD "Build NPU daemon" OFF)
-# Do not allow to use CONFIG option on Tizen
-option(ENVVAR_NPUD_CONFIG "Use environment variable for npud configuration" OFF)
option(BUILD_XNNPACK "Build XNNPACK" OFF)
-option(BUILD_NPUD "Build NPU daemon" OFF)
-# Do not allow to use CONFIG option on Tizen
-option(ENVVAR_NPUD_CONFIG "Use environment variable for npud configuration" OFF)
# Tizen boost package does not have static library
option(Boost_USE_STATIC_LIBS "Determine whether or not static linking for Boost" OFF)
option(BUILD_XNNPACK "Build XNNPACK" OFF)
-option(BUILD_NPUD "Build NPU daemon" OFF)
-# Do not allow to use CONFIG option on Tizen
-option(ENVVAR_NPUD_CONFIG "Use environment variable for npud configuration" OFF)
# Tizen boost package does not have static library
option(Boost_USE_STATIC_LIBS "Determine whether or not static linking for Boost" OFF)
#!/bin/bash
-set -eo pipefail
-
-CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-ROOT_PATH="$(cd ${CURRENT_PATH}/../../ && pwd)"
-
-# Install path on CI
-INSTALL_PATH="$ROOT_PATH/Product/out"
-MODEL_PATH="${INSTALL_PATH}/npud-gtest/models"
-
-# Install dbus configuration file
-DBUS_CONF="${INSTALL_PATH}/share/org.tizen.npud.conf"
-mkdir -p /usr/share/dbus-1/system.d/
-cp ${DBUS_CONF} /usr/share/dbus-1/system.d/
-
-service dbus restart
-
-function TestPrepared()
-{
- if [[ -z "${MODELFILE}" ]]; then
- echo "Model file is not set. Try to use default setting."
- exit 1
- fi
-
- mkdir -p ${MODEL_PATH}
- if [[ "${MODELFILE: -7}" == ".tar.gz" ]]; then
- curl -o model.tar.gz -kLsSO ${MODELFILE}
- tar -zxf model.tar.gz -C ${MODEL_PATH}
- else
- echo "The file format is not supported."
- echo "Supported format: tar.gz"
- exit 1
- fi
-}
-
-function TestCleanUp()
-{
- rm -rf ${MODEL_PATH}
-}
-
-function NpudTest()
-{
- pushd ${ROOT_PATH} > /dev/null
-
- $INSTALL_PATH/npud-gtest/npud_gtest
- EXITCODE=$?
- if [ ${EXITCODE} -ne 0 ]; then
- exit ${EXITCODE}
- fi
-
- popd > /dev/null
-}
-
-TestPrepared
-
-DEVICE_MODULE_PATH=${INSTALL_PATH}/lib GTEST_MODEL_PATH=${MODEL_PATH} NpudTest
-
-TestCleanUp
+# DO NOTHING
+# THIS FILE WILL BE REMOVED AFTER JENKINS SCRIPT IS UPDATED.
+exit 0
Source3016: XNNPACK.tar.gz
%{!?build_type: %define build_type Release}
-%{!?npud_build: %define npud_build 0}
%{!?trix_support: %define trix_support 1}
%{!?odc_build: %define odc_build 1}
%{!?coverage_build: %define coverage_build 0}
%define test_build 1
%endif
-%ifarch riscv64
-# Disable npud on risc-v
-# TODO Enable on risc-v
-%define npud_build 0
-%endif
-
BuildRequires: cmake
Requires(post): /sbin/ldconfig
BuildRequires: gtest-devel
%endif
-%if %{npud_build} == 1
-BuildRequires: pkgconfig(glib-2.0)
-%endif
-
%if %{trix_support} == 1
BuildRequires: pkgconfig(npu-engine)
%endif
# TODO Use release runtime pacakge for test
%endif
-%if %{npud_build} == 1
-%package npud
-Summary: NPU daemon
-
-%description npud
-NPU daemon for optimal management of NPU hardware
-%endif
-
%ifarch armv7l
%define target_arch armv7l
%endif
# Set option for configuration
%define option_config %{nil}
%if %{config_support} == 1
-%if %{npud_build} == 1
-# ENVVAR_NPUD_CONFIG: Use environment variable for npud configuration and debug
-%define option_config -DENVVAR_NPUD_CONFIG=ON
-%endif # npud_build
%endif # config_support
%if %{coverage_build} == 1
install -m 644 build/out/lib/nnfw/odc/*.so %{buildroot}%{_libdir}/nnfw/odc
%endif # odc_build
-%if %{npud_build} == 1
-install -m 755 build/out/bin/npud %{buildroot}%{_bindir}
-
-%if %{test_build} == 1
-mkdir -p %{test_install_path}/npud-gtest
-install -m 755 build/out/npud-gtest/* %{test_install_path}/npud-gtest
-%endif # test_build
-
-%endif # npud_build
-
%endif
%post -p /sbin/ldconfig
%endif # arm armv7l armv7hl aarch64
%endif # test_build
-%if %{npud_build} == 1
-%files npud
-%manifest %{name}.manifest
-%defattr(-,root,root,-)
-%ifarch arm armv7l armv7hl aarch64 x86_64 %ix86 riscv64
-%{_bindir}/npud
-%endif # arm armv7l armv7hl aarch64 x86_64 %ix86
-%endif # npud_build
-
%if %{odc_build} == 1
%files odc
%manifest %{name}.manifest
--- /dev/null
+if(NOT BUILD_NPUD)
+ return()
+endif(NOT BUILD_NPUD)
+
+set(NPUD_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
+
+nnfw_find_package(Gio2.0 REQUIRED)
+nnfw_find_package(Giounix2.0 REQUIRED)
+
+find_program(GDBUS_CODEGEN NAMES gdbus-codegen)
+if (NOT GDBUS_CODEGEN)
+ message(SEND_ERROR "Could not find gdbus-codegen")
+endif(NOT GDBUS_CODEGEN)
+
+set(DBUS_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}")
+set(DBUS_INTERFACE "org.tizen.npud")
+set(DBUS_NAMESPACE "Npud")
+set(DBUS_INTROSPECTION_XML "org.tizen.npud.xml")
+set(DBUS_CORE "dbus-core")
+set(DBUS_CORE_SOURCE "${DBUS_CORE}.c")
+set(DBUS_CONFIG_FILE "org.tizen.npud.conf")
+
+add_custom_command(OUTPUT ${DBUS_CORE_SOURCE}
+ COMMAND ${GDBUS_CODEGEN}
+ --generate-c-code ${DBUS_CORE}
+ --interface-prefix ${DBUS_INTERFACE}
+ --c-namespace ${DBUS_NAMESPACE}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${DBUS_INTROSPECTION_XML}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${DBUS_INTROSPECTION_XML})
+
+add_library(npud_dbus STATIC ${DBUS_CORE_SOURCE})
+
+target_include_directories(npud_dbus PUBLIC ${GIO2.0_INCLUDE_DIRS})
+target_include_directories(npud_dbus PUBLIC ${GIO_UNIX_2.0_INCLUDE_DIRS})
+target_link_libraries(npud_dbus PRIVATE ${GIO2.0_LIBRARIES})
+target_link_libraries(npud_dbus PRIVATE ${GIO_UNIX_2.0_LIBRARIES})
+
+install(FILES ${DBUS_CONFIG_FILE} DESTINATION share)
+
+add_subdirectory(core)
+add_subdirectory(tests)
+add_subdirectory(backend)
--- /dev/null
+# Backends
+add_subdirectory(trix)
--- /dev/null
+nnfw_find_package(TRIXEngine QUIET 2.5.0)
+
+if(NOT TRIXEngine_FOUND)
+ message(STATUS "NPUD backend: Failed to find TRIXEngine")
+ return()
+endif(NOT TRIXEngine_FOUND)
+message(STATUS "NPUD backend: Found TRIXEngine")
+
+file(GLOB_RECURSE SOURCES "*.cc")
+
+add_library(npud_backend_trix SHARED ${SOURCES})
+
+target_include_directories(npud_backend_trix PUBLIC ${NPUD_INCLUDE_DIRS})
+target_link_libraries(npud_backend_trix PRIVATE nnfw_lib_misc)
+target_link_libraries(npud_backend_trix PRIVATE trix_engine)
+
+if(ENVVAR_NPUD_CONFIG)
+ target_compile_definitions(npud_backend_trix PRIVATE ENVVAR_FOR_DEFAULT_CONFIG)
+endif(ENVVAR_NPUD_CONFIG)
+
+install(TARGETS npud_backend_trix DESTINATION lib)
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "TrixBackend.h"
+
+#include <algorithm>
+
+#if defined(__linux__)
+extern "C" {
+using namespace ::npud::backend::trix;
+
+TrixBackend *allocate() { return new TrixBackend(); }
+
+void deallocate(TrixBackend *trix) { delete trix; }
+}
+#endif
+
+namespace npud
+{
+namespace backend
+{
+namespace trix
+{
+
+TrixBackend::TrixBackend() : _devType(NPUCOND_TRIV2_CONN_SOCIP)
+{
+ auto coreNum = getnumNPUdeviceByType(_devType);
+ if (coreNum <= 0)
+ {
+ return;
+ }
+
+ std::vector<npudev_h> handles;
+ for (int i = 0; i < coreNum; ++i)
+ {
+ npudev_h handle;
+ if (getNPUdeviceByType(&handle, _devType, i) < 0)
+ {
+ // Note Run for all cores.
+ continue;
+ }
+ handles.emplace_back(handle);
+ }
+
+ if (handles.size() == 0)
+ {
+ return;
+ }
+
+ _dev = std::make_unique<TrixDevice>();
+ _dev->handles = std::move(handles);
+}
+
+TrixBackend::~TrixBackend()
+{
+ for (const auto &ctx : _dev->ctxs)
+ {
+ npudev_h handle = _dev->handles.at(ctx->defaultCore);
+ for (const auto id : ctx->requests)
+ {
+ removeNPU_request(handle, id);
+ }
+ }
+
+ for (const auto &handle : _dev->handles)
+ {
+ unregisterNPUmodel_all(handle);
+ putNPUdevice(handle);
+ }
+}
+
+NpuStatus TrixBackend::getVersion(std::string &version)
+{
+ // TODO Implement details
+ return NPU_STATUS_ERROR_NOT_SUPPORTED;
+}
+
+NpuStatus TrixBackend::createContext(int deviceId, int priority, NpuContext **ctx)
+{
+ if (deviceId >= _dev->handles.size())
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+ auto context = std::make_unique<NpuContext>();
+ context->defaultCore = deviceId;
+ // TODO Consider priority.
+ *ctx = context.get();
+ _dev->ctxs.emplace_back(std::move(context));
+ return NPU_STATUS_SUCCESS;
+}
+
+NpuStatus TrixBackend::destroyContext(NpuContext *ctx)
+{
+ if (ctx == nullptr)
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ auto citer = std::find_if(_dev->ctxs.begin(), _dev->ctxs.end(),
+ [&](std::unique_ptr<NpuContext> &c) { return c.get() == ctx; });
+ if (citer == _dev->ctxs.end())
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ npudev_h handle = _dev->handles.at(ctx->defaultCore);
+
+ for (auto &&rid : ctx->requests)
+ {
+ if (removeNPU_request(handle, rid) < 0)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+ _dev->requests.erase(rid);
+ }
+
+ for (auto &&mid : ctx->models)
+ {
+ auto &minfo = _dev->models.at(mid);
+ if (--minfo->refCount == 0)
+ {
+ if (unregisterNPUmodel(handle, mid) < 0)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+ _dev->models.erase(mid);
+ }
+ }
+
+ _dev->ctxs.erase(citer);
+ return NPU_STATUS_SUCCESS;
+}
+
+NpuStatus TrixBackend::createBuffer(NpuContext *ctx, GenericBuffer *buffer)
+{
+ // TODO Implement details
+ return NPU_STATUS_ERROR_NOT_SUPPORTED;
+}
+
+NpuStatus TrixBackend::destroyBuffer(NpuContext *ctx, GenericBuffer *buffer)
+{
+ // TODO Implement details
+ return NPU_STATUS_ERROR_NOT_SUPPORTED;
+}
+
+NpuStatus TrixBackend::registerModel(NpuContext *ctx, const std::string &modelPath,
+ ModelID *modelId)
+{
+ if (ctx == nullptr)
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ ModelID id = 0;
+ auto iter =
+ std::find_if(_dev->models.begin(), _dev->models.end(),
+ [&](const std::pair<const ModelID, std::unique_ptr<TrixModelInfo>> &p) {
+ return p.second->core == ctx->defaultCore && p.second->path == modelPath;
+ });
+ // Already registered model.
+ if (iter != _dev->models.end())
+ {
+ _dev->models.at(iter->first)->refCount++;
+ ctx->models.emplace_back(iter->first);
+ }
+ else
+ {
+ auto meta = getNPUmodel_metadata(modelPath.c_str(), false);
+ if (meta == nullptr)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+
+ generic_buffer fileInfo;
+ fileInfo.type = BUFFER_FILE;
+ fileInfo.filepath = modelPath.c_str();
+ fileInfo.size = meta->size;
+
+ npudev_h handle = _dev->handles.at(ctx->defaultCore);
+ if (registerNPUmodel(handle, &fileInfo, &id) < 0)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+
+ _dev->models.insert(std::make_pair(id, std::unique_ptr<TrixModelInfo>(new TrixModelInfo{
+ id, modelPath, ctx->defaultCore, meta, 1})));
+ ctx->models.emplace_back(id);
+ }
+
+ *modelId = id;
+ return NPU_STATUS_SUCCESS;
+}
+
+NpuStatus TrixBackend::unregisterModel(NpuContext *ctx, ModelID modelId)
+{
+ if (ctx == nullptr)
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ auto miter = std::find(ctx->models.begin(), ctx->models.end(), modelId);
+ if (miter == ctx->models.end())
+ {
+ return NPU_STATUS_ERROR_INVALID_MODEL;
+ }
+
+ npudev_h handle = _dev->handles.at(ctx->defaultCore);
+
+ for (auto riter = ctx->requests.begin(); riter != ctx->requests.end();)
+ {
+ auto &rinfo = _dev->requests.at(*riter);
+ if (rinfo->modelId == modelId)
+ {
+ if (removeNPU_request(handle, rinfo->id) < 0)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+ _dev->requests.erase(rinfo->id);
+ riter = ctx->requests.erase(riter);
+ }
+ else
+ {
+ ++riter;
+ }
+ }
+
+ auto &minfo = _dev->models.at(modelId);
+ if (--minfo->refCount == 0)
+ {
+ if (unregisterNPUmodel(handle, modelId) < 0)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+ _dev->models.erase(modelId);
+ }
+
+ ctx->models.erase(miter);
+ return NPU_STATUS_SUCCESS;
+}
+
+NpuStatus TrixBackend::createRequest(NpuContext *ctx, ModelID modelId, RequestID *requestId)
+{
+ if (ctx == nullptr)
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ auto miter = std::find(ctx->models.begin(), ctx->models.end(), modelId);
+ if (miter == ctx->models.end())
+ {
+ return NPU_STATUS_ERROR_INVALID_MODEL;
+ }
+
+ int id = 0;
+ npudev_h handle = _dev->handles.at(ctx->defaultCore);
+ if (createNPU_request(handle, modelId, &id) < 0)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+
+ _dev->requests.insert(std::make_pair(id, std::unique_ptr<TrixRequestInfo>(new TrixRequestInfo{
+ static_cast<RequestID>(id), modelId})));
+ ctx->requests.emplace_back(id);
+
+ *requestId = id;
+ return NPU_STATUS_SUCCESS;
+}
+
+NpuStatus TrixBackend::destroyRequest(NpuContext *ctx, RequestID requestId)
+{
+ if (ctx == nullptr)
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ auto riter = std::find(ctx->requests.begin(), ctx->requests.end(), requestId);
+ if (riter == ctx->requests.end())
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ npudev_h handle = _dev->handles.at(ctx->defaultCore);
+ if (removeNPU_request(handle, requestId) < 0)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+
+ _dev->requests.erase(requestId);
+ ctx->requests.erase(riter);
+ return NPU_STATUS_SUCCESS;
+}
+
+NpuStatus TrixBackend::setRequestData(NpuContext *ctx, RequestID requestId, InputBuffers *inputBufs,
+ TensorDataInfos *inputInfos, OutputBuffers *outputBufs,
+ TensorDataInfos *outputInfos)
+{
+ auto citer = std::find_if(_dev->ctxs.begin(), _dev->ctxs.end(),
+ [&](std::unique_ptr<NpuContext> &c) { return c.get() == ctx; });
+ if (citer == _dev->ctxs.end())
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ auto riter = std::find(ctx->requests.begin(), ctx->requests.end(), requestId);
+ if (riter == ctx->requests.end())
+ {
+ return NPU_STATUS_ERROR_INVALID_ARGUMENT;
+ }
+
+ auto &req = _dev->requests.at(requestId);
+ auto miter = std::find(ctx->models.begin(), ctx->models.end(), req->modelId);
+ if (miter == ctx->models.end())
+ {
+ return NPU_STATUS_ERROR_INVALID_MODEL;
+ }
+
+ // TODO Exception controll of `at`
+ auto &minfo = _dev->models.at(req->modelId);
+ if (minfo->meta->input_seg_num != inputBufs->numBuffers ||
+ minfo->meta->output_seg_num != outputBufs->numBuffers)
+ {
+ return NPU_STATUS_ERROR_INVALID_DATA;
+ }
+
+ auto &inInfos = req->inInfos;
+ auto &outInfos = req->outInfos;
+
+ inInfos->num_info = inputBufs->numBuffers;
+ for (auto i = 0; i < inInfos->num_info; ++i)
+ {
+ inInfos->info[i].layout = DATA_LAYOUT_MODEL;
+ inInfos->info[i].type = minfo->meta->input_seg_quant_type[i];
+ }
+
+ outInfos->num_info = outputBufs->numBuffers;
+ for (auto i = 0; i < outInfos->num_info; ++i)
+ {
+ outInfos->info[i].layout = DATA_LAYOUT_MODEL;
+ outInfos->info[i].type = minfo->meta->output_seg_quant_type[i];
+ }
+
+ auto &inBufs = req->inBufs;
+ auto &outBufs = req->outBufs;
+
+ inBufs->num_buffers = inputBufs->numBuffers;
+ for (auto i = 0; i < inBufs->num_buffers; ++i)
+ {
+ if (inputBufs->buffers[i].type == NPU_BUFFER_MAPPED)
+ {
+ inBufs->bufs[i].addr = inputBufs->buffers[i].addr;
+ }
+ else if (inputBufs->buffers[i].type == NPU_BUFFER_DMABUF)
+ {
+ // TODO Implement details
+ // inBufs.bufs[i].dmabuf = inputBufs->buffers[i].dmabuf;
+ // inBufs.bufs[i].offset = inputBufs->buffers[i].offset;
+ }
+ else
+ {
+ continue;
+ }
+ inBufs->bufs[i].size = inputBufs->buffers[i].size;
+ inBufs->bufs[i].type = static_cast<buffer_types>(inputBufs->buffers[i].type);
+ }
+
+ outBufs->num_buffers = outputBufs->numBuffers;
+ for (auto i = 0; i < outBufs->num_buffers; ++i)
+ {
+ if (outputBufs->buffers[i].type == NPU_BUFFER_MAPPED)
+ {
+ outBufs->bufs[i].addr = outputBufs->buffers[i].addr;
+ }
+ else if (outputBufs->buffers[i].type == NPU_BUFFER_DMABUF)
+ {
+ // TODO Implement details
+ // outBufs.bufs[i].dmabuf = outputBufs->buffers[i].dmabuf;
+ // outBufs.bufs[i].offset = outputBufs->buffers[i].offset;
+ }
+ else
+ {
+ continue;
+ }
+ outBufs->bufs[i].size = outputBufs->buffers[i].size;
+ outBufs->bufs[i].type = static_cast<buffer_types>(outputBufs->buffers[i].type);
+ }
+
+ npudev_h handle = _dev->handles.at(ctx->defaultCore);
+ if (setNPU_requestData(handle, requestId, inBufs.get(), inInfos.get(), outBufs.get(),
+ outInfos.get()) < 0)
+ {
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+
+ return NPU_STATUS_SUCCESS;
+}
+
+NpuStatus TrixBackend::submitRequest(NpuContext *ctx, RequestID requestId)
+{
+ // TODO Implement details
+ return NPU_STATUS_ERROR_NOT_SUPPORTED;
+}
+
+} // namespace trix
+} // namespace backend
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_BACKEND_TRIX_BACKEND_H__
+#define __ONE_SERVICE_NPUD_BACKEND_TRIX_BACKEND_H__
+
+#include <core/Backend.h>
+#include <libnpuhost.h>
+#include <memory>
+#include <vector>
+#include <map>
+
+namespace npud
+{
+namespace backend
+{
+namespace trix
+{
+
+using namespace ::npud::core;
+
+using Handle = void *;
+
+/**
+ * @brief Trix model information.
+ *
+ * @param id The model identifier.
+ * @param path The model path.
+ * @param core The core number where the model is registered.
+ * @param meta The meta data of model.
+ * @param refCount The reference count of model users.
+ */
+struct TrixModelInfo
+{
+ ModelID id;
+ std::string path;
+ int core;
+ npubin_meta *meta;
+ int refCount;
+
+ TrixModelInfo() : meta(nullptr), refCount(0) {}
+ TrixModelInfo(ModelID _id, const std::string &_path, int _core, npubin_meta *_meta, int _refCount)
+ : id(_id), path(_path), core(_core), meta(_meta), refCount(_refCount)
+ {
+ }
+ ~TrixModelInfo() { free(meta); }
+};
+
+/**
+ * @brief Trix request information
+ *
+ * @param id The request identifier.
+ * @param modelId The model id of request.
+ */
+struct TrixRequestInfo
+{
+ RequestID id;
+ ModelID modelId;
+ std::unique_ptr<input_buffers> inBufs;
+ std::unique_ptr<tensors_data_info> inInfos;
+ std::unique_ptr<output_buffers> outBufs;
+ std::unique_ptr<tensors_data_info> outInfos;
+ TrixRequestInfo(RequestID _id, ModelID _mid)
+ : id(_id), modelId(_mid), inBufs(std::make_unique<input_buffers>()),
+ inInfos(std::make_unique<tensors_data_info>()), outBufs(std::make_unique<output_buffers>()),
+ outInfos(std::make_unique<tensors_data_info>())
+ {
+ }
+};
+
+/**
+ * @brief Trix device information
+ *
+ * @param handles The device handle list.
+ * @param ctxs The NpuContext list.
+ * @param models The model map.
+ * @param requests The request map.
+ */
+struct TrixDevice
+{
+ std::vector<Handle> handles;
+ std::vector<std::unique_ptr<NpuContext>> ctxs;
+ std::map<ModelID, std::unique_ptr<TrixModelInfo>> models;
+ std::map<RequestID, std::unique_ptr<TrixRequestInfo>> requests;
+};
+
+class TrixBackend : public Backend
+{
+public:
+ TrixBackend();
+ ~TrixBackend();
+
+ NpuStatus getVersion(std::string &version) override;
+ NpuStatus createContext(int deviceId, int priority, NpuContext **ctx) override;
+ NpuStatus destroyContext(NpuContext *ctx) override;
+ NpuStatus createBuffer(NpuContext *ctx, GenericBuffer *buffer) override;
+ NpuStatus destroyBuffer(NpuContext *ctx, GenericBuffer *buffer) override;
+ // TODO Support to register model from buffer
+ NpuStatus registerModel(NpuContext *ctx, const std::string &modelPath, ModelID *modelId) override;
+ NpuStatus unregisterModel(NpuContext *ctx, ModelID modelId) override;
+ NpuStatus createRequest(NpuContext *ctx, ModelID modelId, RequestID *requestId) override;
+ NpuStatus destroyRequest(NpuContext *ctx, RequestID requestId) override;
+ NpuStatus setRequestData(NpuContext *ctx, RequestID requestId, InputBuffers *inputBufs,
+ TensorDataInfos *inputInfos, OutputBuffers *outputBufs,
+ TensorDataInfos *outputInfos) override;
+ NpuStatus submitRequest(NpuContext *ctx, RequestID requestId) override;
+
+private:
+ dev_type _devType;
+ std::unique_ptr<TrixDevice> _dev;
+};
+
+} // namespace trix
+} // namespace backend
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_BACKEND_TRIX_BACKEND_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_BACKEND_H__
+#define __ONE_SERVICE_NPUD_CORE_BACKEND_H__
+
+#include "ir/Layout.h"
+#include "ir/DataType.h"
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace npud
+{
+namespace core
+{
+
+#define NPU_TENSOR_MAX (16)
+
+/**
+ * @brief Npu model ID.
+ *
+ */
+using ModelID = uint32_t;
+
+/**
+ * @brief Npu request ID.
+ *
+ */
+using RequestID = uint32_t;
+
+/**
+ * @brief Npu buffer type
+ *
+ */
+enum BufferTypes
+{
+ NPU_BUFFER_MAPPED, /**< buffer is a memory-mapped ptr */
+ NPU_BUFFER_DMABUF, /**< buffer is a dmabuf fd, representing contiguous memory */
+ NPU_BUFFER_UNDEFINED /**< buffer type is undefined */
+};
+
+/**
+ * @brief Various kinds of buffer supported for input/output/model.
+ *
+ */
+struct GenericBuffer
+{
+ struct
+ { /** NPU_BUFFER_MAPPED/DMABUF */
+ void *addr; /**< Mapped address of the buffer */
+ struct
+ { /** NPU_BUFFER_DMABUF only */
+ int dmabuf; /**< The dma-buf fd handle of the memory allocated */
+ uint64_t offset; /**< Offset to be applied to the base memory address */
+ };
+ };
+ uint64_t size; /**< The size of the buffer in bytes */
+ BufferTypes type; /**< Type of memory in this buffer */
+};
+
+/**
+ * @brief Npu generic buffer array.
+ *
+ */
+struct GenericBuffers
+{
+ uint32_t numBuffers;
+ GenericBuffer buffers[NPU_TENSOR_MAX];
+};
+
+/**
+ * @brief Npu input/output buffers are compotible with GenericBuffers.
+ *
+ */
+typedef GenericBuffers InputBuffers;
+typedef GenericBuffers OutputBuffers;
+
+/**
+ * @brief Npu tensor data info description.
+ *
+ */
+struct TensorDataInfo
+{
+ ir::Layout layout;
+ ir::DataType type;
+};
+
+/**
+ * @brief Npu tensor data info array.
+ *
+ */
+struct TensorDataInfos
+{
+ uint32_t numInfos;
+ TensorDataInfo infos[NPU_TENSOR_MAX];
+};
+
+/**
+ * @brief Npu error status.
+ *
+ */
+enum NpuStatus
+{
+ NPU_STATUS_SUCCESS = 0,
+ NPU_STATUS_ERROR_OPERATION_FAILED,
+ NPU_STATUS_ERROR_NOT_SUPPORTED,
+ NPU_STATUS_ERROR_INVALID_ARGUMENT,
+ NPU_STATUS_ERROR_INVALID_MODEL,
+ NPU_STATUS_ERROR_INVALID_DATA,
+};
+
+/**
+ * @brief Npu context definition
+ *
+ * @param models The model lists.
+ * @param requests The request lists.
+ * @param defaultCore The core number to be used by default.
+ */
+struct NpuContext
+{
+ std::vector<ModelID> models;
+ std::vector<RequestID> requests;
+ int defaultCore;
+};
+
+/**
+ * @brief Npu backend interface
+ *
+ * Backend module should implement this Backend interface.
+ * Npu daemon will load this class symbol at runtime.
+ */
+class Backend
+{
+public:
+ virtual ~Backend() = default;
+
+ virtual NpuStatus getVersion(std::string &version) = 0;
+ virtual NpuStatus createContext(int deviceId, int priority, NpuContext **ctx) = 0;
+ virtual NpuStatus destroyContext(NpuContext *ctx) = 0;
+ virtual NpuStatus createBuffer(NpuContext *ctx, GenericBuffer *buffer) = 0;
+ virtual NpuStatus destroyBuffer(NpuContext *ctx, GenericBuffer *buffer) = 0;
+ // TODO Support to register model from buffer
+ virtual NpuStatus registerModel(NpuContext *ctx, const std::string &modelPath,
+ ModelID *modelId) = 0;
+ virtual NpuStatus unregisterModel(NpuContext *ctx, ModelID modelId) = 0;
+ virtual NpuStatus createRequest(NpuContext *ctx, ModelID modelId, RequestID *requestId) = 0;
+ virtual NpuStatus destroyRequest(NpuContext *ctx, RequestID requestId) = 0;
+ virtual NpuStatus setRequestData(NpuContext *ctx, RequestID requestId, InputBuffers *inputBufs,
+ TensorDataInfos *inputInfos, OutputBuffers *outputBufs,
+ TensorDataInfos *outputInfos) = 0;
+ virtual NpuStatus submitRequest(NpuContext *ctx, RequestID requestId) = 0;
+};
+
+typedef Backend *(*NpuAlloc)();
+typedef void (*NpuDealloc)(Backend *);
+
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_BACKEND_H__
--- /dev/null
+nnfw_find_package(GLib2.0 REQUIRED)
+
+file(GLOB_RECURSE SOURCES "*.cc")
+file(GLOB_RECURSE MAIN_SOURCE_FILE "main.cc")
+list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
+
+add_library(npud_core STATIC ${SOURCES})
+
+set_target_properties(npud_core PROPERTIES LINKER_LANGUAGE CXX)
+target_include_directories(npud_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(npud_core PUBLIC ${GLIB2.0_INCLUDE_DIRS})
+target_include_directories(npud_core PUBLIC ${DBUS_INCLUDE_DIRS})
+target_link_libraries(npud_core PRIVATE nnfw_lib_misc)
+target_link_libraries(npud_core PRIVATE ${GLIB2.0_LIBRARIES})
+target_link_libraries(npud_core PRIVATE ${LIB_PTHREAD})
+target_link_libraries(npud_core PRIVATE dl)
+target_link_libraries(npud_core PRIVATE npud_dbus)
+
+if(ENVVAR_NPUD_CONFIG)
+ target_compile_definitions(npud_core PRIVATE ENVVAR_FOR_DEFAULT_CONFIG)
+endif(ENVVAR_NPUD_CONFIG)
+
+# npud executable
+add_executable(npud ${MAIN_SOURCE_FILE})
+
+set_target_properties(npud PROPERTIES LINKER_LANGUAGE CXX)
+target_link_libraries(npud PRIVATE npud_core)
+
+install(TARGETS npud DESTINATION bin)
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "ContextManager.h"
+
+#include <algorithm>
+#include <util/Logging.h>
+
+namespace npud
+{
+namespace core
+{
+
+ContextManager::ContextManager() noexcept {}
+
+ContextManager::~ContextManager() noexcept { _contexts.clear(); }
+
+void ContextManager::newContext(NpuContext *npuContext, ContextID *contextId)
+{
+ auto context = std::make_unique<Context>();
+ // TODO Consider the possibility of reusing the same address.
+ context->contextId = reinterpret_cast<ContextID>(context.get());
+ context->npuContext = npuContext;
+ *contextId = context->contextId;
+ _contexts.emplace_back(std::move(context));
+
+ this->listContexts();
+}
+
+void ContextManager::deleteContext(ContextID contextId)
+{
+ const auto iter =
+ std::remove_if(_contexts.begin(), _contexts.end(),
+ [&](std::unique_ptr<Context> &c) { return c->contextId == contextId; });
+ if (iter == _contexts.end())
+ {
+ return;
+ }
+
+ _contexts.erase(iter, _contexts.end());
+
+ this->listContexts();
+}
+
+void ContextManager::listContexts()
+{
+#ifdef DEBUG
+ VERBOSE(ContextManager) << "Size: " << _contexts.size() << std::endl;
+ for (const auto &context : _contexts)
+ {
+ VERBOSE(ContextManager) << "==========================" << std::endl;
+ VERBOSE(ContextManager) << "contextId: " << context->contextId << std::endl;
+ }
+ VERBOSE(ContextManager) << "==========================" << std::endl;
+#endif
+}
+
+const std::vector<std::unique_ptr<Context>>::iterator
+ContextManager::getContext(ContextID contextId)
+{
+ const auto iter =
+ std::find_if(_contexts.begin(), _contexts.end(),
+ [&](std::unique_ptr<Context> &c) { return c->contextId == contextId; });
+ return iter;
+}
+
+NpuContext *ContextManager::getNpuContext(ContextID contextId)
+{
+ const auto iter = getContext(contextId);
+ if (iter == _contexts.end())
+ {
+ return nullptr;
+ }
+
+ return iter->get()->npuContext;
+}
+
+} // namespace core
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_CONTEXT_MANAGER_H__
+#define __ONE_SERVICE_NPUD_CORE_CONTEXT_MANAGER_H__
+
+#include "Backend.h"
+
+#include <vector>
+#include <memory>
+
+namespace npud
+{
+namespace core
+{
+
+using ContextID = uint64_t;
+struct Context
+{
+ // TODO Describe the variables
+ ContextID contextId;
+ NpuContext *npuContext;
+};
+
+class ContextManager
+{
+public:
+ ContextManager() noexcept;
+ ~ContextManager() noexcept;
+
+ ContextManager(const ContextManager &) = delete;
+ ContextManager &operator=(const ContextManager &) = delete;
+
+ void newContext(NpuContext *npuContext, ContextID *contextId);
+ void deleteContext(ContextID contextId);
+ const std::vector<std::unique_ptr<Context>>::iterator getContext(ContextID contextId);
+ NpuContext *getNpuContext(ContextID contextId);
+
+private:
+ void listContexts(void);
+
+private:
+ std::vector<std::unique_ptr<Context>> _contexts;
+};
+
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_CONTEXT_MANAGER_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "Core.h"
+#include "util/Logging.h"
+
+namespace npud
+{
+namespace core
+{
+
+Core::Core() noexcept
+ : _devManager(std::make_unique<DevManager>()), _contextManager(std::make_unique<ContextManager>())
+{
+}
+
+void Core::init() { _devManager->loadModules(); }
+
+void Core::deinit() { _devManager->releaseModules(); }
+
+int Core::getAvailableDeviceList(std::vector<std::string> &list) const { return 0; }
+
+int Core::createContext(int deviceId, int priority, ContextID *contextId) const
+{
+ VERBOSE(Core) << "createContext with " << deviceId << ", " << priority << std::endl;
+ NpuContext *npuContext;
+ int ret = _devManager->createContext(deviceId, priority, &npuContext);
+ if (ret != NPU_STATUS_SUCCESS)
+ {
+ VERBOSE(Core) << "Fail to create dev context" << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ ContextID _contextId;
+ _contextManager->newContext(npuContext, &_contextId);
+ *contextId = _contextId;
+ return 0;
+}
+
+int Core::destroyContext(ContextID contextId) const
+{
+ VERBOSE(Core) << "destroyContext with " << contextId << std::endl;
+ NpuContext *npuContext = _contextManager->getNpuContext(contextId);
+ if (!npuContext)
+ {
+ VERBOSE(Core) << "Invalid context id" << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ int ret = _devManager->destroyContext(npuContext);
+ if (ret != NPU_STATUS_SUCCESS)
+ {
+ VERBOSE(Core) << "Failed to destroy npu context: " << ret << std::endl;
+ return 1;
+ }
+
+ _contextManager->deleteContext(contextId);
+ return 0;
+}
+
+int Core::createNetwork(ContextID contextId, const std::string &modelPath, ModelID *modelId) const
+{
+ VERBOSE(Core) << "createNetwork with " << contextId << ", " << modelPath << std::endl;
+ NpuContext *npuContext = _contextManager->getNpuContext(contextId);
+ if (!npuContext)
+ {
+ VERBOSE(Core) << "Invalid context id" << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ ModelID id;
+ int ret = _devManager->registerModel(npuContext, modelPath, &id);
+ if (ret != NPU_STATUS_SUCCESS)
+ {
+ VERBOSE(Core) << "Failed to register model: " << ret << std::endl;
+ return 1;
+ }
+
+ *modelId = id;
+ return 0;
+}
+
+int Core::destroyNetwork(ContextID contextId, ModelID modelId) const
+{
+ VERBOSE(Core) << "destroyNetwork with " << contextId << std::endl;
+ NpuContext *npuContext = _contextManager->getNpuContext(contextId);
+ if (!npuContext)
+ {
+ VERBOSE(Core) << "Invalid context id" << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ int ret = _devManager->unregisterModel(npuContext, modelId);
+ if (ret != NPU_STATUS_SUCCESS)
+ {
+ VERBOSE(Core) << "Failed to unregister model: " << ret << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ return 0;
+}
+
+int Core::createRequest(ContextID contextId, ModelID modelId, RequestID *requestId) const
+{
+ VERBOSE(Core) << "createRequest with " << contextId << ", " << modelId << std::endl;
+ NpuContext *npuContext = _contextManager->getNpuContext(contextId);
+ if (!npuContext)
+ {
+ VERBOSE(Core) << "Invalid context id" << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ RequestID id;
+ int ret = _devManager->createRequest(npuContext, modelId, &id);
+ if (ret != NPU_STATUS_SUCCESS)
+ {
+ VERBOSE(Core) << "Failed to create request of model: " << ret << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ *requestId = id;
+ return 0;
+}
+
+int Core::destroyRequest(ContextID contextId, RequestID requestId) const
+{
+ VERBOSE(Core) << "destroyRequest with " << contextId << ", " << requestId << std::endl;
+ NpuContext *npuContext = _contextManager->getNpuContext(contextId);
+ if (!npuContext)
+ {
+ VERBOSE(Core) << "Invalid context id" << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ int ret = _devManager->destroyRequest(npuContext, requestId);
+ if (ret != NPU_STATUS_SUCCESS)
+ {
+ VERBOSE(Core) << "Failed to destroy request: " << ret << std::endl;
+ // TODO Define CoreStatus
+ return 1;
+ }
+
+ return 0;
+}
+
+} // namespace core
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_CORE_H__
+#define __ONE_SERVICE_NPUD_CORE_CORE_H__
+
+#include "DevManager.h"
+#include "ContextManager.h"
+
+#include <vector>
+#include <string>
+
+namespace npud
+{
+namespace core
+{
+
+// TODO Define error status
+
+class Core
+{
+public:
+ Core() noexcept;
+ ~Core() noexcept = default;
+
+ Core(const Core &) = delete;
+ Core &operator=(const Core &) = delete;
+
+ void init();
+ void deinit();
+
+ int getAvailableDeviceList(std::vector<std::string> &list) const;
+ int createContext(int deviceId, int priority, ContextID *contextId) const;
+ int destroyContext(ContextID contextId) const;
+ int createNetwork(ContextID contextId, const std::string &modelPath, ModelID *modelId) const;
+ int destroyNetwork(ContextID contextId, ModelID modelId) const;
+ int createRequest(ContextID contextId, ModelID modelId, RequestID *requestId) const;
+ int destroyRequest(ContextID contextId, RequestID requestId) const;
+
+private:
+ std::unique_ptr<DevManager> _devManager;
+ std::unique_ptr<ContextManager> _contextManager;
+};
+
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_CORE_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "DBus.h"
+#include "Server.h"
+
+#include <atomic>
+#include <util/Logging.h>
+
+namespace npud
+{
+namespace core
+{
+
+std::atomic_bool DBus::_isReady(false);
+
+DBus::DBus() noexcept
+{
+ VERBOSE(DBus) << "Starting dbus service" << std::endl;
+
+ _gdbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, "org.tizen.npud", G_BUS_NAME_OWNER_FLAGS_NONE,
+ (GBusAcquiredCallback)on_bus_acquired,
+ (GBusNameAcquiredCallback)on_name_acquired,
+ (GBusNameLostCallback)on_name_lost, NULL, NULL);
+}
+
+DBus::~DBus() noexcept
+{
+ VERBOSE(DBus) << "Stop dbus service" << std::endl;
+
+ g_bus_unown_name(_gdbus_id);
+}
+
+void DBus::on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
+{
+ VERBOSE(DBus) << name << " on bus acquired" << std::endl;
+
+ GError *error = NULL;
+ NpudCore *core = npud_core_skeleton_new();
+ NpudCoreIface *iface = NPUD_CORE_GET_IFACE(core);
+
+ iface->handle_device_get_available_list = &on_handle_device_get_available_list;
+ iface->handle_context_create = &on_handle_context_create;
+ iface->handle_context_destroy = &on_handle_context_destroy;
+ iface->handle_buffers_create = &on_handle_buffers_create;
+ iface->handle_buffers_destroy = &on_handle_buffers_destroy;
+ iface->handle_network_create = &on_handle_network_create;
+ iface->handle_network_destroy = &on_handle_network_destroy;
+ iface->handle_request_create = &on_handle_request_create;
+ iface->handle_request_destroy = &on_handle_request_destroy;
+ iface->handle_request_set_data = &on_handle_request_set_data;
+ iface->handle_execute_run = &on_handle_execute_run;
+
+ if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(core), conn, "/org/tizen/npud",
+ &error))
+ {
+ VERBOSE(DBus) << "Failed to export skeleton, Server will stop." << std::endl;
+ Server::instance().stop();
+ }
+
+ _isReady.exchange(true);
+}
+
+void DBus::on_name_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
+{
+ VERBOSE(DBus) << name << " on name acquired" << std::endl;
+}
+
+void DBus::on_name_lost(GDBusConnection *conn, const gchar *name, gpointer user_data)
+{
+ VERBOSE(DBus) << name << " on name lost, Server will stop." << std::endl;
+ Server::instance().stop();
+}
+
+gboolean DBus::on_handle_device_get_available_list(NpudCore *object,
+ GDBusMethodInvocation *invocation)
+{
+ VERBOSE(DBus) << __FUNCTION__ << std::endl;
+ std::vector<std::string> list;
+ int error = Server::instance().core().getAvailableDeviceList(list);
+ // TODO Implement variant outputs
+ npud_core_complete_device_get_available_list(object, invocation, error);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_context_create(NpudCore *object, GDBusMethodInvocation *invocation,
+ gint arg_device_id, gint arg_priority)
+{
+ VERBOSE(DBus) << "on_handle_context_create with " << arg_device_id << ", " << arg_priority
+ << std::endl;
+
+ guint64 out_ctx = 0;
+ int ret = Server::instance().core().createContext(arg_device_id, arg_priority, &out_ctx);
+ npud_core_complete_context_create(object, invocation, out_ctx, ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_context_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx)
+{
+ VERBOSE(DBus) << "on_handle_context_destroy with " << arg_ctx << std::endl;
+ int ret = Server::instance().core().destroyContext(arg_ctx);
+ npud_core_complete_context_destroy(object, invocation, ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_buffers_create(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, GVariant *arg_buffers)
+{
+ VERBOSE(DBus) << "on_handle_buffers_create with " << arg_ctx << std::endl;
+ GenericBuffers bufs;
+ GVariantIter *iter = NULL;
+ gint32 type;
+ guint64 addr;
+ guint32 size;
+ int index = 0;
+ g_variant_get(arg_buffers, "a(itu)", &iter);
+ while (iter != NULL && g_variant_iter_loop(iter, "(itu)", &type, &addr, &size))
+ {
+ VERBOSE(DBus) << "in [" << index << "] Type: " << type << ", Addr: " << addr
+ << ", Size: " << size << std::endl;
+ bufs.buffers[index].type = static_cast<BufferTypes>(type);
+ bufs.buffers[index].addr = reinterpret_cast<void *>(addr);
+ bufs.buffers[index].size = size;
+ index++;
+ }
+ bufs.numBuffers = index;
+ g_variant_iter_free(iter);
+
+ // TODO Invoke Core function.
+ int ret = -1;
+
+ GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("a(itu)"));
+
+ // TODO Enable below code when we can update ret value by core function
+ // if (ret == 0)
+ // {
+ // for (auto i = 0; i < bufs.numBuffers; ++i)
+ // {
+ // VERBOSE(DBus) << "out [" << index << "] Type: " << bufs.buffers[i].type
+ // << ", Addr: " << bufs.buffers[i].addr << ", Size: " << bufs.buffers[i].size
+ // << std::endl;
+ // g_variant_builder_add(builder, "(itu)", bufs.buffers[i].type, bufs.buffers[i].addr,
+ // bufs.buffers[i].size);
+ // }
+ // }
+ npud_core_complete_buffers_create(object, invocation, g_variant_builder_end(builder), ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_buffers_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, GVariant *arg_buffers)
+{
+ VERBOSE(DBus) << "on_handle_buffers_destroy with " << arg_ctx << std::endl;
+ GenericBuffers bufs;
+ GVariantIter *iter = NULL;
+ gint32 type;
+ guint64 addr;
+ guint32 size;
+ int index = 0;
+ g_variant_get(arg_buffers, "a(itu)", &iter);
+ while (iter != NULL && g_variant_iter_loop(iter, "(itu)", &type, &addr, &size))
+ {
+ VERBOSE(DBus) << "[" << index << "] Type: " << type << ", Addr: " << (void *)addr
+ << ", Size: " << size << std::endl;
+ bufs.buffers[index].type = static_cast<BufferTypes>(type);
+ bufs.buffers[index].addr = reinterpret_cast<void *>(addr);
+ bufs.buffers[index].size = size;
+ index++;
+ }
+ bufs.numBuffers = index;
+ g_variant_iter_free(iter);
+ // TODO Invoke Core function.
+ int ret = -1;
+ npud_core_complete_buffers_destroy(object, invocation, ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_network_create(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, const gchar *arg_model_path)
+{
+ VERBOSE(DBus) << "on_handle_network_create with " << arg_ctx << ", " << arg_model_path
+ << std::endl;
+ ModelID modelId = 0;
+ int ret = Server::instance().core().createNetwork(arg_ctx, arg_model_path, &modelId);
+ npud_core_complete_network_create(object, invocation, guint(modelId), ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_network_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_nw_handle)
+{
+ VERBOSE(DBus) << "on_handle_network_destroy with " << arg_ctx << ", " << arg_nw_handle
+ << std::endl;
+ int ret = Server::instance().core().destroyNetwork(arg_ctx, arg_nw_handle);
+ npud_core_complete_network_destroy(object, invocation, ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_request_create(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_nw_handle)
+{
+ VERBOSE(DBus) << "on_handle_request_create with " << arg_ctx << ", " << arg_nw_handle
+ << std::endl;
+ RequestID requestID = 0;
+ int ret = Server::instance().core().createRequest(arg_ctx, arg_nw_handle, &requestID);
+ npud_core_complete_request_create(object, invocation, guint(requestID), ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_request_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_rq_handle)
+{
+ VERBOSE(DBus) << "on_handle_request_destroy with " << arg_ctx << ", " << arg_rq_handle
+ << std::endl;
+ int ret = Server::instance().core().destroyRequest(arg_ctx, arg_rq_handle);
+ npud_core_complete_request_destroy(object, invocation, ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_request_set_data(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_rq_handle,
+ GVariant *arg_input_buffers, GVariant *arg_output_buffers)
+{
+ VERBOSE(DBus) << "on_handle_request_set_data with " << arg_ctx << ", " << arg_rq_handle
+ << std::endl;
+ GVariantIter *iter = NULL;
+ InputBuffers inBufs;
+ OutputBuffers outBufs;
+ gint32 type;
+ guint64 addr;
+ guint32 size;
+ int index = 0;
+
+ // inBufs
+ g_variant_get(arg_input_buffers, "a(itu)", &iter);
+ index = 0;
+ while (iter != NULL && g_variant_iter_loop(iter, "(itu)", &type, &addr, &size))
+ {
+ VERBOSE(DBus) << "in [" << index << "] Type: " << type << ", Addr: " << (void *)addr
+ << ", Size: " << size << std::endl;
+ if (type == 0) // NPU_BUFFER_MAPPED
+ {
+ inBufs.buffers[index].addr = reinterpret_cast<void *>(addr);
+ }
+ else if (type == 1) // NPU_BUFFER_DMABUF
+ {
+ // TODO Support dma buffer
+ VERBOSE(DBus) << "[NYI] NPU_BUFFER_DMABUF" << std::endl;
+ continue;
+ }
+ else
+ {
+ VERBOSE(DBus) << "Wrong buffer type. Ignored." << std::endl;
+ continue;
+ }
+ inBufs.buffers[index].size = size;
+ inBufs.buffers[index].type = static_cast<BufferTypes>(type);
+ index++;
+ }
+ inBufs.numBuffers = index;
+ g_variant_iter_free(iter);
+
+ // outBufs
+ g_variant_get(arg_output_buffers, "a(itu)", &iter);
+ index = 0;
+ while (iter != NULL && g_variant_iter_loop(iter, "(itu)", &type, &addr, &size))
+ {
+ VERBOSE(DBus) << "out [" << index << "] Type: " << type << ", Addr: " << (void *)addr
+ << ", Size: " << size << std::endl;
+ if (type == 0) // NPU_BUFFER_MAPPED
+ {
+ outBufs.buffers[index].addr = reinterpret_cast<void *>(addr);
+ }
+ else if (type == 1) // NPU_BUFFER_DMABUF
+ {
+ // TODO Support dma buffer
+ VERBOSE(DBus) << "[NYI] NPU_BUFFER_DMABUF" << std::endl;
+ continue;
+ }
+ else
+ {
+ VERBOSE(DBus) << "Wrong buffer type. Ignored." << std::endl;
+ continue;
+ }
+ outBufs.buffers[index].size = size;
+ outBufs.buffers[index].type = static_cast<BufferTypes>(type);
+ index++;
+ }
+ outBufs.numBuffers = index;
+ g_variant_iter_free(iter);
+
+ // TODO Invoke Core function.
+ int ret = -1;
+ npud_core_complete_request_set_data(object, invocation, ret);
+ return TRUE;
+}
+
+gboolean DBus::on_handle_execute_run(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_rq_handle)
+{
+ VERBOSE(DBus) << "on_handle_execute_run with " << arg_ctx << ", " << arg_rq_handle << std::endl;
+ // TODO Invoke Core function.
+ int ret = -1;
+ npud_core_complete_execute_run(object, invocation, ret);
+ return TRUE;
+}
+
+} // namespace core
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_DBUS_H__
+#define __ONE_SERVICE_NPUD_CORE_DBUS_H__
+
+#include <dbus-core.h>
+#include <gio/gio.h>
+#include <memory>
+#include <atomic>
+
+namespace npud
+{
+namespace core
+{
+
+class DBus
+{
+public:
+ DBus() noexcept;
+ ~DBus() noexcept;
+
+ DBus(const DBus &) = delete;
+ DBus &operator=(const DBus &) = delete;
+
+ bool isReady() { return _isReady.load(); }
+
+ static void on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data);
+ static void on_name_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data);
+ static void on_name_lost(GDBusConnection *conn, const gchar *name, gpointer user_data);
+
+ static gboolean on_handle_device_get_available_list(NpudCore *object,
+ GDBusMethodInvocation *invocation);
+ static gboolean on_handle_context_create(NpudCore *object, GDBusMethodInvocation *invocation,
+ gint arg_device_id, gint arg_priority);
+ static gboolean on_handle_context_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx);
+ static gboolean on_handle_buffers_create(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, GVariant *arg_buffers);
+ static gboolean on_handle_buffers_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, GVariant *arg_buffers);
+ static gboolean on_handle_network_create(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, const gchar *arg_model_path);
+ static gboolean on_handle_network_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_nw_handle);
+ static gboolean on_handle_request_create(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_nw_handle);
+ static gboolean on_handle_request_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_rq_handle);
+ static gboolean on_handle_request_set_data(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_rq_handle,
+ GVariant *arg_input_buffers,
+ GVariant *arg_output_buffers);
+ static gboolean on_handle_execute_run(NpudCore *object, GDBusMethodInvocation *invocation,
+ guint64 arg_ctx, guint arg_rq_handle);
+
+private:
+ guint _gdbus_id;
+ static std::atomic_bool _isReady;
+};
+
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_DBUS_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "DevManager.h"
+#include "util/Logging.h"
+
+#include <dirent.h>
+
+namespace npud
+{
+namespace core
+{
+
+DevManager::DevManager()
+{
+ const auto env = util::getConfigString(util::config::DEVICE_MODULE_PATH);
+ _module_dir = std::move(env);
+}
+
+void DevManager::loadModules()
+{
+ VERBOSE(DevManager) << "load modules from " << _module_dir << std::endl;
+
+ releaseModules();
+
+ DIR *dir;
+ struct dirent *entry;
+
+ // NOTE
+ // Return NULL(0) value when opendir or readdir error occurs.
+ // NULL should be used instead of nullptr.
+ dir = opendir(_module_dir.c_str());
+ if (dir == NULL)
+ {
+ VERBOSE(DevManager) << "Fail to open module directory" << std::endl;
+ return;
+ }
+
+ while ((entry = readdir(dir)) != NULL)
+ {
+ std::string modulePath(entry->d_name);
+ if (modulePath.find("npud_backend") == std::string::npos)
+ {
+ continue;
+ }
+
+ DynamicLoader *loader = nullptr;
+ try
+ {
+ loader = new DynamicLoader(modulePath.c_str());
+ }
+ catch (const std::exception &e)
+ {
+ VERBOSE(DevManager) << e.what() << std::endl;
+ continue;
+ }
+
+ std::unique_ptr<Device> dev = std::make_unique<Device>();
+ dev->modulePath = std::move(modulePath);
+ dev->loader = std::unique_ptr<DynamicLoader>(loader);
+
+ _dev = std::move(dev);
+ break;
+ }
+
+ closedir(dir);
+}
+
+void DevManager::releaseModules()
+{
+ if (_dev)
+ {
+ _dev.reset();
+ }
+}
+
+std::shared_ptr<Backend> DevManager::getBackend()
+{
+ if (!_dev)
+ {
+ throw std::runtime_error("No backend device.");
+ }
+ return _dev->loader->getInstance();
+}
+
+int DevManager::createContext(int deviceId, int priority, NpuContext **npuContext)
+{
+ try
+ {
+ return getBackend()->createContext(deviceId, priority, npuContext);
+ }
+ catch (const std::exception &e)
+ {
+ VERBOSE(DevManager) << e.what() << std::endl;
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+}
+
+int DevManager::destroyContext(NpuContext *npuContext)
+{
+ try
+ {
+ return getBackend()->destroyContext(npuContext);
+ }
+ catch (const std::exception &e)
+ {
+ VERBOSE(DevManager) << e.what() << std::endl;
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+}
+
+int DevManager::registerModel(NpuContext *npuContext, const std::string &modelPath,
+ ModelID *modelId)
+{
+ try
+ {
+ return getBackend()->registerModel(npuContext, modelPath, modelId);
+ }
+ catch (const std::exception &e)
+ {
+ VERBOSE(DevManager) << e.what() << std::endl;
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+}
+
+int DevManager::unregisterModel(NpuContext *npuContext, ModelID modelId)
+{
+ try
+ {
+ return getBackend()->unregisterModel(npuContext, modelId);
+ }
+ catch (const std::exception &e)
+ {
+ VERBOSE(DevManager) << e.what() << std::endl;
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+}
+
+int DevManager::createRequest(NpuContext *npuContext, ModelID modelId, RequestID *requestId)
+{
+ try
+ {
+ return getBackend()->createRequest(npuContext, modelId, requestId);
+ }
+ catch (const std::exception &e)
+ {
+ VERBOSE(DevManager) << e.what() << std::endl;
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+}
+
+int DevManager::destroyRequest(NpuContext *npuContext, RequestID requestId)
+{
+ try
+ {
+ return getBackend()->destroyRequest(npuContext, requestId);
+ }
+ catch (const std::exception &e)
+ {
+ VERBOSE(DevManager) << e.what() << std::endl;
+ return NPU_STATUS_ERROR_OPERATION_FAILED;
+ }
+}
+
+} // namespace core
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_DEV_MANAGER_H__
+#define __ONE_SERVICE_NPUD_CORE_DEV_MANAGER_H__
+
+#include "DynamicLoader.h"
+
+#include <memory>
+
+namespace npud
+{
+namespace core
+{
+
+struct Device
+{
+ std::string modulePath;
+ std::unique_ptr<DynamicLoader> loader;
+};
+
+class DevManager
+{
+public:
+ DevManager();
+ ~DevManager() = default;
+
+ DevManager(const DevManager &) = delete;
+ DevManager &operator=(const DevManager &) = delete;
+
+ void loadModules();
+ void releaseModules();
+ std::shared_ptr<Backend> getBackend();
+
+ int createContext(int deviceId, int priority, NpuContext **npuContext);
+ int destroyContext(NpuContext *npuContext);
+ int registerModel(NpuContext *npuContext, const std::string &modelPath, ModelID *modelId);
+ int unregisterModel(NpuContext *npuContext, ModelID modelId);
+ int createRequest(NpuContext *npuContext, ModelID modelId, RequestID *requestId);
+ int destroyRequest(NpuContext *npuContext, RequestID requestId);
+
+private:
+ std::unique_ptr<Device> _dev;
+ std::string _module_dir;
+};
+
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_DEV_MANAGER_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "DynamicLoader.h"
+
+#include "util/Logging.h"
+
+namespace npud
+{
+namespace core
+{
+
+DynamicLoader::DynamicLoader(const char *file, int flags)
+ : _handle(nullptr), _filepath(file), _allocSymbol("allocate"), _deallocSymbol("deallocate")
+{
+ if (!(_handle = dlopen(_filepath.c_str(), flags)))
+ {
+ VERBOSE(DynamicLoader) << "Fail to load " << _filepath << " module: " << dlerror() << std::endl;
+ throw std::runtime_error("Fail to load " + _filepath + " module");
+ }
+
+ NpuAlloc alloc;
+ NpuDealloc dealloc;
+
+ alloc = reinterpret_cast<NpuAlloc>(dlsym(_handle, _allocSymbol.c_str()));
+ dealloc = reinterpret_cast<NpuDealloc>(dlsym(_handle, _deallocSymbol.c_str()));
+ if (!alloc || !dealloc)
+ {
+ VERBOSE(DynamicLoader) << "Fail to load " << _filepath << " symbol: " << dlerror() << std::endl;
+ dlclose(_handle);
+ throw std::runtime_error("Fail to load " + _filepath + " module");
+ }
+
+ _backend = std::shared_ptr<Backend>(alloc(), [dealloc](Backend *b) { dealloc(b); });
+}
+
+DynamicLoader::~DynamicLoader()
+{
+ // NOTE
+ // The _backend shared_ptr must be explicitly deleted before
+ // the dynamic library handle is released.
+ _backend.reset();
+ dlclose(_handle);
+}
+
+std::shared_ptr<Backend> DynamicLoader::getInstance() { return _backend; }
+
+} // namespace core
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_DYNAMIC_LOADER_H__
+#define __ONE_SERVICE_NPUD_CORE_DYNAMIC_LOADER_H__
+
+#include "Backend.h"
+
+#include <dlfcn.h>
+#include <string>
+#include <memory>
+
+namespace npud
+{
+namespace core
+{
+
+using DLHandle = void *;
+
+class DynamicLoader
+{
+public:
+ DynamicLoader(const char *file, int flags = RTLD_LAZY);
+ ~DynamicLoader();
+
+ DynamicLoader(const DynamicLoader &) = delete;
+
+ std::shared_ptr<Backend> getInstance();
+
+private:
+ DLHandle _handle;
+ std::string _filepath;
+ std::string _allocSymbol;
+ std::string _deallocSymbol;
+ std::shared_ptr<Backend> _backend;
+};
+
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_DYNAMIC_LOADER_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "Server.h"
+#include "util/Logging.h"
+
+#include <thread>
+
+namespace npud
+{
+namespace core
+{
+
+std::atomic_bool Server::_isRunning(false);
+
+Server::Server() noexcept
+ : _mainloop(g_main_loop_new(NULL, FALSE), g_main_loop_unref), _signal(std::make_unique<Signal>()),
+ _core(std::make_unique<Core>()), _dbus(std::make_unique<DBus>())
+{
+}
+
+bool Server::isServiceReady()
+{
+ if (!_isRunning.load())
+ {
+ VERBOSE(Server) << "Server is not started." << std::endl;
+ return false;
+ }
+
+ if (!_dbus->isReady())
+ {
+ VERBOSE(Server) << "DBus service is not ready." << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+void Server::run(void)
+{
+ VERBOSE(Server) << "Starting Server\n";
+
+ if (_isRunning.exchange(true))
+ {
+ return;
+ }
+
+ _core->init();
+
+ g_main_loop_run(_mainloop.get());
+}
+
+void Server::stop(void)
+{
+ VERBOSE(Server) << "Stop Server\n";
+
+ if (!_isRunning.load())
+ {
+ return;
+ }
+
+ while (!g_main_loop_is_running(_mainloop.get()))
+ {
+ std::this_thread::yield();
+ }
+
+ _core->deinit();
+
+ g_main_loop_quit(_mainloop.get());
+ _isRunning = false;
+}
+
+} // namespace core
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_SERVER_H__
+#define __ONE_SERVICE_NPUD_CORE_SERVER_H__
+
+#include "Signal.h"
+#include "Core.h"
+#include "DBus.h"
+
+#include <glib.h>
+#include <memory>
+#include <atomic>
+
+namespace npud
+{
+namespace core
+{
+
+class Server
+{
+public:
+ Server(const Server &) = delete;
+ Server &operator=(const Server &) = delete;
+
+ void run(void);
+ void stop(void);
+
+ bool isRunning() { return _isRunning.load(); }
+ bool isServiceReady();
+
+ static Server &instance(void)
+ {
+ static Server server;
+ return server;
+ }
+
+ const Core &core(void) { return *_core.get(); }
+
+private:
+ Server() noexcept;
+
+ static std::atomic_bool _isRunning;
+
+ std::unique_ptr<GMainLoop, void (*)(GMainLoop *)> _mainloop;
+ std::unique_ptr<Signal> _signal;
+ std::unique_ptr<Core> _core;
+ std::unique_ptr<DBus> _dbus;
+};
+
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_SERVER_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "Signal.h"
+#include "Server.h"
+#include "util/Logging.h"
+
+#include <csignal>
+
+namespace npud
+{
+namespace core
+{
+
+Signal::Signal(void) noexcept { init(); }
+
+void Signal::init(void)
+{
+ // NOTE Types of signals
+ // SIGTERM: termination request, sent to the program
+ // SIGINT: external interrupt, usually initiated by the user
+ // SIGILL: invalid program image, such as invalid instruction
+ // SIGABRT: abnormal termination condition, as is e.g. initiated by std::abort()
+ // SIGFPE: erroneous arithmetic operation such as divide by zero
+ // from https://en.cppreference.com/w/cpp/utility/program/SIG_types
+ std::signal(SIGTERM, handleSignal);
+ std::signal(SIGINT, handleSignal);
+ std::signal(SIGILL, handleSignal);
+ std::signal(SIGABRT, handleSignal);
+ std::signal(SIGFPE, handleSignal);
+}
+
+void Signal::handleSignal(int signum)
+{
+ VERBOSE(signal) << "Signal received: " << strsignal(signum) << "(" << signum << ")\n";
+ Server::instance().stop();
+}
+
+} // namespace core
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_SIGNAL_H__
+#define __ONE_SERVICE_NPUD_CORE_SIGNAL_H__
+
+namespace npud
+{
+namespace core
+{
+
+class Signal
+{
+public:
+ Signal() noexcept;
+
+ void init(void);
+ static void handleSignal(int signum);
+};
+
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_SIGNAL_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_IR_DATATYPE_H__
+#define __ONE_SERVICE_NPUD_CORE_IR_DATATYPE_H__
+
+#include <cstdlib>
+
+namespace npud
+{
+namespace core
+{
+namespace ir
+{
+
+enum class DataType
+{
+ INT8 = 0,
+ UINT8,
+ QUANT_UINT8_ASYMM,
+ INT16,
+ UINT16,
+ QUANT_INT16_SYMM,
+ INT32,
+ UINT32,
+ FLOAT32,
+ INT64,
+ UINT64,
+ FLOAT64,
+};
+
+} // namespace ir
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_IR_DATATYPE_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_CORE_IR_LAYOUT_H__
+#define __ONE_SERVICE_NPUD_CORE_IR_LAYOUT_H__
+
+#include <functional>
+#include <stdexcept>
+#include <string>
+
+namespace npud
+{
+namespace core
+{
+namespace ir
+{
+
+enum class Layout
+{
+ UNKNOWN = 0,
+ NHWC,
+ NCHW
+};
+
+} // namespace ir
+} // namespace core
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_CORE_IR_LAYOUT_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "Server.h"
+#include "util/Logging.h"
+
+using namespace npud;
+
+int main(int argc, const char *argv[])
+{
+ auto &server = core::Server::instance();
+
+ VERBOSE(main) << "Starting npud\n";
+ try
+ {
+ server.run();
+ }
+ catch (const std::runtime_error &err)
+ {
+ std::cerr << err.what() << std::endl;
+ return 1;
+ }
+
+ VERBOSE(main) << "Finished npud\n";
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef CONFIG
+#error Define CONFIG before including this file
+#endif
+
+// Name | Type | Default
+CONFIG(NPUD_LOG_ENABLE , bool , "0")
+CONFIG(DEVICE_MODULE_PATH , std::string , "/usr/lib/npud/devices")
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "ConfigSource.h"
+
+#include <misc/EnvConfigSource.h>
+#include <misc/GeneralConfigSource.h>
+#include <misc/IConfigSource.h>
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <memory>
+
+namespace npud
+{
+namespace util
+{
+
+using namespace nnfw::misc;
+
+static std::unique_ptr<IConfigSource> _source;
+
+void config_source(std::unique_ptr<IConfigSource> &&source) { _source = std::move(source); }
+
+static IConfigSource *config_source()
+{
+ if (!_source)
+ {
+#ifdef ENVVAR_FOR_DEFAULT_CONFIG
+ // Default ConfigSource is EnvConfigSource
+ _source = std::make_unique<EnvConfigSource>();
+#else
+ _source = std::make_unique<GeneralConfigSource>();
+#endif // ENVVAR_FOR_DEFAULT_CONFIG
+ }
+ return _source.get();
+}
+
+static std::string getConfigOrDefault(const std::string &key)
+{
+ static std::unordered_map<std::string, std::string> defaults;
+ if (defaults.empty())
+ {
+#define CONFIG(Name, Type, Default) \
+ { \
+ auto name = std::string{#Name}; \
+ defaults.emplace(name, std::string{Default}); \
+ }
+
+#include "Config.lst"
+
+#undef CONFIG
+ }
+
+ // Treat empty string and absence of the value to be the same
+ auto ret = config_source()->get(key);
+ // if not found search from defaults
+ if (ret.empty())
+ {
+ auto itr = defaults.find(key);
+ if (itr != defaults.end())
+ {
+ // Return the default value if exists
+ ret = itr->second;
+ }
+ }
+
+ return ret;
+}
+
+bool toBool(const std::string &val)
+{
+ static const std::array<std::string, 5> false_list{"0", "OFF", "FALSE", "N", "NO"};
+ auto false_found = std::find(false_list.begin(), false_list.end(), val);
+ return false_found == false_list.end();
+}
+
+int toInt(const std::string &val) { return std::stoi(val); }
+
+bool getConfigBool(const std::string &key)
+{
+ auto raw = getConfigOrDefault(key);
+ return toBool(raw);
+}
+
+int getConfigInt(const std::string &key)
+{
+ auto raw = getConfigOrDefault(key);
+ return toInt(raw);
+}
+
+std::string getConfigString(const std::string &key) { return getConfigOrDefault(key); }
+
+} // namespace util
+} // namespace npud
+
+namespace npud
+{
+namespace util
+{
+namespace config
+{
+
+#define CONFIG(Name, Type, Default) const char *Name = #Name;
+
+#include "Config.lst"
+
+#undef CONFIG
+
+} // namespace config
+} // namespace util
+} // namespace npud
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_UTIL_CONFIG_SOURCE_H__
+#define __ONE_SERVICE_NPUD_UTIL_CONFIG_SOURCE_H__
+
+#include <string>
+
+namespace npud
+{
+namespace util
+{
+
+bool getConfigBool(const std::string &key);
+int getConfigInt(const std::string &key);
+std::string getConfigString(const std::string &key);
+
+} // namespace util
+} // namespace npud
+
+namespace npud
+{
+namespace util
+{
+namespace config
+{
+
+#define CONFIG(Name, Type, Default) extern const char *Name;
+
+#include "Config.lst"
+
+#undef CONFIG
+
+} // namespace config
+} // namespace util
+} // namespace npud
+
+#endif // __ONE_SERVICE_NPUD_UTIL_CONFIG_SOURCE_H__
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef __ONE_SERVICE_NPUD_UTIL_LOGGING_H__
+#define __ONE_SERVICE_NPUD_UTIL_LOGGING_H__
+
+#include <iostream>
+#include <cstring>
+
+#include "ConfigSource.h"
+
+namespace npud
+{
+namespace util
+{
+namespace logging
+{
+class Context
+{
+public:
+ Context() noexcept : _enabled{false}
+ {
+ const auto env = util::getConfigBool(util::config::NPUD_LOG_ENABLE);
+
+ if (env)
+ {
+ _enabled = true;
+ }
+ }
+
+ static Context &get() noexcept
+ {
+ static Context ctx;
+ return ctx;
+ }
+
+public:
+ bool enabled(void) const { return _enabled; }
+
+private:
+ bool _enabled;
+};
+
+static Context &ctx = Context::get();
+
+inline std::string decorated_name(const char *input)
+{
+ const int min_prefix = 16;
+ std::string prefix(input);
+ auto len_prefix = prefix.size();
+ if (len_prefix > min_prefix)
+ return "[" + prefix + "] ";
+ std::string spaces((min_prefix - len_prefix) / 2, ' ');
+ return (len_prefix % 2 ? "[ " : "[") + spaces + prefix + spaces + "] ";
+}
+} // namespace logging
+} // namespace util
+} // namespace npud
+
+#define VERBOSE(name) \
+ if (::npud::util::logging::ctx.enabled()) \
+ std::cout << ::npud::util::logging::decorated_name(#name)
+
+#define VERBOSE_F() \
+ if (::npud::util::logging::ctx.enabled()) \
+ std::cout << ::npud::util::logging::decorated_name(__func__)
+
+#define WHEN_LOG_ENABLED(METHOD) \
+ if (::npud::util::logging::ctx.enabled()) \
+ do \
+ { \
+ METHOD; \
+ } while (0)
+
+#endif // __ONE_SERVICE_NPUD_UTIL_LOGGING_H__
--- /dev/null
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<busconfig>
+ <policy context="default">
+ <allow own="org.tizen.npud"/>
+ <allow send_destination="org.tizen.npud"/>
+ <allow receive_sender="org.tizen.npud"/>
+ </policy>
+</busconfig>
--- /dev/null
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/">
+ <!-- org.tizen.npud.core:
+ @short_description: Npud interface
+
+ The interface used to run AI models on npu devices.
+ -->
+ <interface name="org.tizen.npud.core">
+ <!--
+ device_get_available_list:
+ @error: The error status of the function.
+
+ Get all available npu device lists.
+ -->
+ <method name="device_get_available_list">
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ context_create:
+ @device_id: The device numger to use.
+ @priority: The device priority.
+ @ctx: The Context handle.
+ @error: The error status of the function.
+
+ Create context.
+ -->
+ <method name="context_create">
+ <arg name="device_id" type="i" direction="in" />
+ <arg name="priority" type="i" direction="in" />
+ <arg name="ctx" type="t" direction="out" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ context_destroy:
+ @ctx: The Context handle to destroy.
+ @error: The error status of the function.
+
+ Destroy context.
+ -->
+ <method name="context_destroy">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ buffers_create:
+ @ctx: The Context handle.
+ @buffers: The array of buffer structure. (i:type, t:address, u:size)
+ @out_buffers: The array of buffer sturcture containing created buffer address.
+ @error: The error status of the function.
+
+ Create buffer array.
+ -->
+ <method name="buffers_create">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="buffers" type="a(itu)" direction="in" />
+ <arg name="out_buffers" type="a(itu)" direction="out" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ buffers_destroy:
+ @ctx: The Context handle.
+ @buffers: The array of buffer structure. (i:type, t:address, u:size)
+ @error: The error status of the function.
+
+ Destroy buffer array.
+ -->
+ <method name="buffers_destroy">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="buffers" type="a(itu)" direction="in" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ network_create:
+ @ctx: The context handle.
+ @model_path: The model path to run.
+ @nw_handle: The Network handle.
+ @error: The error status of the function.
+
+ Create network.
+
+ TODO Support file descriptor input
+ -->
+ <method name="network_create">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="model_path" type="s" direction="in" />
+ <arg name="nw_handle" type="u" direction="out" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ network_destroy:
+ @ctx: The context handle.
+ @nw_handle: The Network handle.
+ @error: The error status of the function.
+
+ Destroy network.
+ -->
+ <method name="network_destroy">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="nw_handle" type="u" direction="in" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ request_create:
+ @ctx: The context handle.
+ @nw_handle: The Network handle.
+ @rq_handle: The Request handle.
+ @error: The error status of the function.
+
+ Create request.
+ -->
+ <method name="request_create">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="nw_handle" type="u" direction="in" />
+ <arg name="rq_handle" type="u" direction="out" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ request_destroy:
+ @ctx: The context handle.
+ @rq_handle: The Request handle.
+ @error: The error status of the function.
+
+ Destroy request.
+ -->
+ <method name="request_destroy">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="rq_handle" type="u" direction="in" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ request_set_data:
+ @ctx: The context handle.
+ @rq_handle: The Request handle.
+ @input_buffers: The input buffer datas.
+ @output_buffers: The output buffer datas.
+ @error: The error status of the function.
+
+ Set request data.
+ -->
+ <method name="request_set_data">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="rq_handle" type="u" direction="in" />
+ <arg name="input_buffers" type="a(itu)" direction="in" />
+ <arg name="output_buffers" type="a(itu)" direction="in" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ <!--
+ execute_run:
+ @ctx: The context handle.
+ @rq_handle: The Request handle.
+ @error: The error status of the function.
+
+ Execute run.
+ -->
+ <method name="execute_run">
+ <arg name="ctx" type="t" direction="in" />
+ <arg name="rq_handle" type="u" direction="in" />
+ <arg name="error" type="i" direction="out" />
+ </method>
+ </interface>
+</node>
--- /dev/null
+if(NOT ENABLE_TEST)
+ return()
+endif(NOT ENABLE_TEST)
+
+file(GLOB_RECURSE TESTS "*.cc")
+
+add_executable(npud_gtest ${TESTS})
+
+set_target_properties(npud_gtest PROPERTIES LINKER_LANGUAGE CXX)
+target_include_directories(npud_gtest PUBLIC ${NPUD_INCLUDE_DIRS})
+target_include_directories(npud_gtest PUBLIC ${GLIB2.0_INCLUDE_DIRS})
+target_link_libraries(npud_gtest PRIVATE ${GLIB2.0_LIBRARIES})
+target_link_libraries(npud_gtest PRIVATE ${LIB_PTHREAD})
+target_link_libraries(npud_gtest PRIVATE npud_core)
+target_link_libraries(npud_gtest PRIVATE gtest_main dl)
+
+install(TARGETS npud_gtest DESTINATION npud-gtest)
--- /dev/null
+/*
+ * Copyright (c) 2022 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 <core/Server.h>
+#include <gtest/gtest.h>
+#include <thread>
+#include <gio/gio.h>
+#include <dbus-core.h>
+#include <iostream>
+
+namespace
+{
+using namespace npud;
+using namespace core;
+
+//
+// DBusTest setup/teardown
+//
+class DBusTest : public ::testing::Test
+{
+protected:
+ static void runTask()
+ {
+ auto &server = Server::instance();
+ server.run();
+ }
+
+ void SetUp() override
+ {
+ std::thread child = std::thread(runTask);
+ child.detach();
+ auto &server = Server::instance();
+ while (server.isServiceReady() != true)
+ {
+ }
+ }
+
+ void TearDown() override
+ {
+ auto &server = Server::instance();
+ if (server.isRunning())
+ {
+ server.stop();
+ }
+ }
+
+ NpudCore *getProxy()
+ {
+ GError *error = nullptr;
+ NpudCore *proxy = nullptr;
+ proxy = npud_core_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.npud", "/org/tizen/npud", NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ return proxy;
+ }
+
+ const std::string &getModel()
+ {
+ if (model.empty())
+ {
+ auto model_path = std::getenv("GTEST_MODEL_PATH");
+ model = model_path + std::string("/mv1.q8/mv1.q8.tvn");
+ }
+ if (access(model.c_str(), F_OK) != 0)
+ {
+ model.clear();
+ }
+ return model;
+ }
+
+private:
+ std::string model;
+};
+
+//
+// DBusTest
+//
+TEST_F(DBusTest, get_proxy)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+}
+
+TEST_F(DBusTest, device_get_available_list)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ npud_core_call_device_get_available_list_sync(proxy, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+}
+
+TEST_F(DBusTest, context_create)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+}
+
+TEST_F(DBusTest, context_destroy)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+
+ npud_core_call_context_destroy_sync(proxy, out_ctx, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_context_destroy_invalid_ctx)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ guint64 out_ctx = 0;
+ npud_core_call_context_destroy_sync(proxy, out_ctx, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+TEST_F(DBusTest, network_create)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ const gchar *model_path = this->getModel().c_str();
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_network_create_invalid_ctx)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ guint64 out_ctx = -1;
+ const gchar *model_path = this->getModel().c_str();
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_network_create_invalid_model)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ // Invalid model
+ const gchar *model_path = "invalid.tvn";
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+TEST_F(DBusTest, network_destroy)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ const gchar *model_path = this->getModel().c_str();
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ npud_core_call_network_destroy_sync(proxy, out_ctx, out_nw_handle, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_network_destroy_invalid_ctx)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ const gchar *model_path = this->getModel().c_str();
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ // Invalid ctx
+ out_ctx = -1;
+ npud_core_call_network_destroy_sync(proxy, out_ctx, out_nw_handle, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_network_destroy_invalid_nw_handle)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ guint out_nw_handle = -1;
+ npud_core_call_network_destroy_sync(proxy, out_ctx, out_nw_handle, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+TEST_F(DBusTest, request_create)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ const gchar *model_path = this->getModel().c_str();
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ guint out_rq_handle = 0;
+ npud_core_call_request_create_sync(proxy, out_ctx, out_nw_handle, &out_rq_handle, &out_error,
+ NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_request_create_invalid_ctx)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ const gchar *model_path = this->getModel().c_str();
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ guint out_rq_handle = 0;
+ npud_core_call_request_create_sync(proxy, 0, out_nw_handle, &out_rq_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_request_create_invalid_nw)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ guint out_rq_handle = 0;
+ npud_core_call_request_create_sync(proxy, out_ctx, 0, &out_rq_handle, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+TEST_F(DBusTest, request_destroy)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ const gchar *model_path = this->getModel().c_str();
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ guint out_rq_handle = 0;
+ npud_core_call_request_create_sync(proxy, out_ctx, out_nw_handle, &out_rq_handle, &out_error,
+ NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ npud_core_call_request_destroy_sync(proxy, out_ctx, out_rq_handle, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_request_destroy_invalid_ctx)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ const gchar *model_path = this->getModel().c_str();
+ guint out_nw_handle = 0;
+ npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ guint out_rq_handle = 0;
+ npud_core_call_request_create_sync(proxy, out_ctx, out_nw_handle, &out_rq_handle, &out_error,
+ NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ npud_core_call_request_destroy_sync(proxy, 0, out_rq_handle, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+TEST_F(DBusTest, neg_request_destroy_invalid_rq)
+{
+ NpudCore *proxy = this->getProxy();
+ ASSERT_NE(proxy, nullptr);
+
+ GError *error = NULL;
+ gint out_error = -1;
+ gint arg_device_id = 0;
+ gint arg_priority = 0;
+ guint64 out_ctx = 0;
+ npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
+ &error);
+ if (error)
+ {
+ g_error_free(error);
+ error = NULL;
+ }
+ ASSERT_EQ(out_error, 0);
+
+ out_error = -1;
+ npud_core_call_request_destroy_sync(proxy, out_ctx, 0, &out_error, NULL, &error);
+ if (error)
+ {
+ g_error_free(error);
+ }
+ ASSERT_NE(out_error, 0);
+}
+
+} // unnamed namespace
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "core/Server.h"
+
+#include <gtest/gtest.h>
+#include <thread>
+
+namespace
+{
+using namespace npud;
+using namespace core;
+
+//
+// ServerTest setup/teardown
+//
+class ServerTest : public ::testing::Test
+{
+protected:
+ static void runTask()
+ {
+ auto &server = Server::instance();
+ server.run();
+ }
+
+ void SetUp() override
+ {
+ std::thread child = std::thread(runTask);
+ child.detach();
+ auto &server = Server::instance();
+ while (server.isRunning() != true)
+ {
+ }
+ }
+
+ void TearDown() override
+ {
+ auto &server = Server::instance();
+ if (server.isRunning())
+ {
+ server.stop();
+ }
+ }
+};
+
+//
+// ServerTest
+//
+TEST_F(ServerTest, run)
+{
+ auto &server = Server::instance();
+ ASSERT_EQ(server.isRunning(), true);
+}
+
+TEST_F(ServerTest, stop)
+{
+ auto &server = Server::instance();
+ server.stop();
+ ASSERT_EQ(server.isRunning(), false);
+}
+
+} // unnamed namespace
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "core/Server.h"
+#include "core/Signal.h"
+
+#include <gtest/gtest.h>
+#include <thread>
+#include <csignal>
+
+namespace
+{
+using namespace npud;
+using namespace core;
+
+//
+// SignalTest setup/teardown
+//
+class SignalTest : public ::testing::Test
+{
+protected:
+ static void runTask()
+ {
+ auto &server = Server::instance();
+ server.run();
+ }
+
+ void SetUp() override
+ {
+ std::thread child = std::thread(runTask);
+ child.detach();
+ auto &server = Server::instance();
+ while (server.isRunning() != true)
+ {
+ }
+ }
+
+ void TearDown() override
+ {
+ auto &server = Server::instance();
+ if (server.isRunning())
+ {
+ server.stop();
+ }
+ }
+};
+
+//
+// SignalTest
+//
+TEST_F(SignalTest, raise_SIGTERM)
+{
+ auto &server = Server::instance();
+ ASSERT_EQ(server.isRunning(), true);
+ std::raise(SIGTERM);
+ ASSERT_EQ(server.isRunning(), false);
+}
+
+TEST_F(SignalTest, raise_SIGINT)
+{
+ auto &server = Server::instance();
+ ASSERT_EQ(server.isRunning(), true);
+ std::raise(SIGINT);
+ ASSERT_EQ(server.isRunning(), false);
+}
+
+TEST_F(SignalTest, raise_SIGILL)
+{
+ auto &server = Server::instance();
+ ASSERT_EQ(server.isRunning(), true);
+ std::raise(SIGILL);
+ ASSERT_EQ(server.isRunning(), false);
+}
+
+TEST_F(SignalTest, raise_SIGABRT)
+{
+ auto &server = Server::instance();
+ ASSERT_EQ(server.isRunning(), true);
+ std::raise(SIGABRT);
+ ASSERT_EQ(server.isRunning(), false);
+}
+
+TEST_F(SignalTest, raise_SIGFPE)
+{
+ auto &server = Server::instance();
+ ASSERT_EQ(server.isRunning(), true);
+ std::raise(SIGFPE);
+ ASSERT_EQ(server.isRunning(), false);
+}
+
+} // unnamed namespace
+++ /dev/null
-add_subdirectories()
+++ /dev/null
-if(NOT BUILD_NPUD)
- return()
-endif(NOT BUILD_NPUD)
-
-set(NPUD_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
-
-nnfw_find_package(Gio2.0 REQUIRED)
-nnfw_find_package(Giounix2.0 REQUIRED)
-
-find_program(GDBUS_CODEGEN NAMES gdbus-codegen)
-if (NOT GDBUS_CODEGEN)
- message(SEND_ERROR "Could not find gdbus-codegen")
-endif(NOT GDBUS_CODEGEN)
-
-set(DBUS_INCLUDE_DIRS "${CMAKE_CURRENT_BINARY_DIR}")
-set(DBUS_INTERFACE "org.tizen.npud")
-set(DBUS_NAMESPACE "Npud")
-set(DBUS_INTROSPECTION_XML "org.tizen.npud.xml")
-set(DBUS_CORE "dbus-core")
-set(DBUS_CORE_SOURCE "${DBUS_CORE}.c")
-set(DBUS_CONFIG_FILE "org.tizen.npud.conf")
-
-add_custom_command(OUTPUT ${DBUS_CORE_SOURCE}
- COMMAND ${GDBUS_CODEGEN}
- --generate-c-code ${DBUS_CORE}
- --interface-prefix ${DBUS_INTERFACE}
- --c-namespace ${DBUS_NAMESPACE}
- ${CMAKE_CURRENT_SOURCE_DIR}/${DBUS_INTROSPECTION_XML}
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${DBUS_INTROSPECTION_XML})
-
-add_library(npud_dbus STATIC ${DBUS_CORE_SOURCE})
-
-target_include_directories(npud_dbus PUBLIC ${GIO2.0_INCLUDE_DIRS})
-target_include_directories(npud_dbus PUBLIC ${GIO_UNIX_2.0_INCLUDE_DIRS})
-target_link_libraries(npud_dbus PRIVATE ${GIO2.0_LIBRARIES})
-target_link_libraries(npud_dbus PRIVATE ${GIO_UNIX_2.0_LIBRARIES})
-
-install(FILES ${DBUS_CONFIG_FILE} DESTINATION share)
-
-add_subdirectory(core)
-add_subdirectory(tests)
-add_subdirectory(backend)
+++ /dev/null
-# Backends
-add_subdirectory(trix)
+++ /dev/null
-nnfw_find_package(TRIXEngine QUIET 2.5.0)
-
-if(NOT TRIXEngine_FOUND)
- message(STATUS "NPUD backend: Failed to find TRIXEngine")
- return()
-endif(NOT TRIXEngine_FOUND)
-message(STATUS "NPUD backend: Found TRIXEngine")
-
-file(GLOB_RECURSE SOURCES "*.cc")
-
-add_library(npud_backend_trix SHARED ${SOURCES})
-
-target_include_directories(npud_backend_trix PUBLIC ${NPUD_INCLUDE_DIRS})
-target_link_libraries(npud_backend_trix PRIVATE nnfw_lib_misc)
-target_link_libraries(npud_backend_trix PRIVATE trix_engine)
-
-if(ENVVAR_NPUD_CONFIG)
- target_compile_definitions(npud_backend_trix PRIVATE ENVVAR_FOR_DEFAULT_CONFIG)
-endif(ENVVAR_NPUD_CONFIG)
-
-install(TARGETS npud_backend_trix DESTINATION lib)
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "TrixBackend.h"
-
-#include <algorithm>
-
-#if defined(__linux__)
-extern "C" {
-using namespace ::npud::backend::trix;
-
-TrixBackend *allocate() { return new TrixBackend(); }
-
-void deallocate(TrixBackend *trix) { delete trix; }
-}
-#endif
-
-namespace npud
-{
-namespace backend
-{
-namespace trix
-{
-
-TrixBackend::TrixBackend() : _devType(NPUCOND_TRIV2_CONN_SOCIP)
-{
- auto coreNum = getnumNPUdeviceByType(_devType);
- if (coreNum <= 0)
- {
- return;
- }
-
- std::vector<npudev_h> handles;
- for (int i = 0; i < coreNum; ++i)
- {
- npudev_h handle;
- if (getNPUdeviceByType(&handle, _devType, i) < 0)
- {
- // Note Run for all cores.
- continue;
- }
- handles.emplace_back(handle);
- }
-
- if (handles.size() == 0)
- {
- return;
- }
-
- _dev = std::make_unique<TrixDevice>();
- _dev->handles = std::move(handles);
-}
-
-TrixBackend::~TrixBackend()
-{
- for (const auto &ctx : _dev->ctxs)
- {
- npudev_h handle = _dev->handles.at(ctx->defaultCore);
- for (const auto id : ctx->requests)
- {
- removeNPU_request(handle, id);
- }
- }
-
- for (const auto &handle : _dev->handles)
- {
- unregisterNPUmodel_all(handle);
- putNPUdevice(handle);
- }
-}
-
-NpuStatus TrixBackend::getVersion(std::string &version)
-{
- // TODO Implement details
- return NPU_STATUS_ERROR_NOT_SUPPORTED;
-}
-
-NpuStatus TrixBackend::createContext(int deviceId, int priority, NpuContext **ctx)
-{
- if (deviceId >= _dev->handles.size())
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
- auto context = std::make_unique<NpuContext>();
- context->defaultCore = deviceId;
- // TODO Consider priority.
- *ctx = context.get();
- _dev->ctxs.emplace_back(std::move(context));
- return NPU_STATUS_SUCCESS;
-}
-
-NpuStatus TrixBackend::destroyContext(NpuContext *ctx)
-{
- if (ctx == nullptr)
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- auto citer = std::find_if(_dev->ctxs.begin(), _dev->ctxs.end(),
- [&](std::unique_ptr<NpuContext> &c) { return c.get() == ctx; });
- if (citer == _dev->ctxs.end())
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- npudev_h handle = _dev->handles.at(ctx->defaultCore);
-
- for (auto &&rid : ctx->requests)
- {
- if (removeNPU_request(handle, rid) < 0)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
- _dev->requests.erase(rid);
- }
-
- for (auto &&mid : ctx->models)
- {
- auto &minfo = _dev->models.at(mid);
- if (--minfo->refCount == 0)
- {
- if (unregisterNPUmodel(handle, mid) < 0)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
- _dev->models.erase(mid);
- }
- }
-
- _dev->ctxs.erase(citer);
- return NPU_STATUS_SUCCESS;
-}
-
-NpuStatus TrixBackend::createBuffer(NpuContext *ctx, GenericBuffer *buffer)
-{
- // TODO Implement details
- return NPU_STATUS_ERROR_NOT_SUPPORTED;
-}
-
-NpuStatus TrixBackend::destroyBuffer(NpuContext *ctx, GenericBuffer *buffer)
-{
- // TODO Implement details
- return NPU_STATUS_ERROR_NOT_SUPPORTED;
-}
-
-NpuStatus TrixBackend::registerModel(NpuContext *ctx, const std::string &modelPath,
- ModelID *modelId)
-{
- if (ctx == nullptr)
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- ModelID id = 0;
- auto iter =
- std::find_if(_dev->models.begin(), _dev->models.end(),
- [&](const std::pair<const ModelID, std::unique_ptr<TrixModelInfo>> &p) {
- return p.second->core == ctx->defaultCore && p.second->path == modelPath;
- });
- // Already registered model.
- if (iter != _dev->models.end())
- {
- _dev->models.at(iter->first)->refCount++;
- ctx->models.emplace_back(iter->first);
- }
- else
- {
- auto meta = getNPUmodel_metadata(modelPath.c_str(), false);
- if (meta == nullptr)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-
- generic_buffer fileInfo;
- fileInfo.type = BUFFER_FILE;
- fileInfo.filepath = modelPath.c_str();
- fileInfo.size = meta->size;
-
- npudev_h handle = _dev->handles.at(ctx->defaultCore);
- if (registerNPUmodel(handle, &fileInfo, &id) < 0)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-
- _dev->models.insert(std::make_pair(id, std::unique_ptr<TrixModelInfo>(new TrixModelInfo{
- id, modelPath, ctx->defaultCore, meta, 1})));
- ctx->models.emplace_back(id);
- }
-
- *modelId = id;
- return NPU_STATUS_SUCCESS;
-}
-
-NpuStatus TrixBackend::unregisterModel(NpuContext *ctx, ModelID modelId)
-{
- if (ctx == nullptr)
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- auto miter = std::find(ctx->models.begin(), ctx->models.end(), modelId);
- if (miter == ctx->models.end())
- {
- return NPU_STATUS_ERROR_INVALID_MODEL;
- }
-
- npudev_h handle = _dev->handles.at(ctx->defaultCore);
-
- for (auto riter = ctx->requests.begin(); riter != ctx->requests.end();)
- {
- auto &rinfo = _dev->requests.at(*riter);
- if (rinfo->modelId == modelId)
- {
- if (removeNPU_request(handle, rinfo->id) < 0)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
- _dev->requests.erase(rinfo->id);
- riter = ctx->requests.erase(riter);
- }
- else
- {
- ++riter;
- }
- }
-
- auto &minfo = _dev->models.at(modelId);
- if (--minfo->refCount == 0)
- {
- if (unregisterNPUmodel(handle, modelId) < 0)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
- _dev->models.erase(modelId);
- }
-
- ctx->models.erase(miter);
- return NPU_STATUS_SUCCESS;
-}
-
-NpuStatus TrixBackend::createRequest(NpuContext *ctx, ModelID modelId, RequestID *requestId)
-{
- if (ctx == nullptr)
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- auto miter = std::find(ctx->models.begin(), ctx->models.end(), modelId);
- if (miter == ctx->models.end())
- {
- return NPU_STATUS_ERROR_INVALID_MODEL;
- }
-
- int id = 0;
- npudev_h handle = _dev->handles.at(ctx->defaultCore);
- if (createNPU_request(handle, modelId, &id) < 0)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-
- _dev->requests.insert(std::make_pair(id, std::unique_ptr<TrixRequestInfo>(new TrixRequestInfo{
- static_cast<RequestID>(id), modelId})));
- ctx->requests.emplace_back(id);
-
- *requestId = id;
- return NPU_STATUS_SUCCESS;
-}
-
-NpuStatus TrixBackend::destroyRequest(NpuContext *ctx, RequestID requestId)
-{
- if (ctx == nullptr)
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- auto riter = std::find(ctx->requests.begin(), ctx->requests.end(), requestId);
- if (riter == ctx->requests.end())
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- npudev_h handle = _dev->handles.at(ctx->defaultCore);
- if (removeNPU_request(handle, requestId) < 0)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-
- _dev->requests.erase(requestId);
- ctx->requests.erase(riter);
- return NPU_STATUS_SUCCESS;
-}
-
-NpuStatus TrixBackend::setRequestData(NpuContext *ctx, RequestID requestId, InputBuffers *inputBufs,
- TensorDataInfos *inputInfos, OutputBuffers *outputBufs,
- TensorDataInfos *outputInfos)
-{
- auto citer = std::find_if(_dev->ctxs.begin(), _dev->ctxs.end(),
- [&](std::unique_ptr<NpuContext> &c) { return c.get() == ctx; });
- if (citer == _dev->ctxs.end())
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- auto riter = std::find(ctx->requests.begin(), ctx->requests.end(), requestId);
- if (riter == ctx->requests.end())
- {
- return NPU_STATUS_ERROR_INVALID_ARGUMENT;
- }
-
- auto &req = _dev->requests.at(requestId);
- auto miter = std::find(ctx->models.begin(), ctx->models.end(), req->modelId);
- if (miter == ctx->models.end())
- {
- return NPU_STATUS_ERROR_INVALID_MODEL;
- }
-
- // TODO Exception controll of `at`
- auto &minfo = _dev->models.at(req->modelId);
- if (minfo->meta->input_seg_num != inputBufs->numBuffers ||
- minfo->meta->output_seg_num != outputBufs->numBuffers)
- {
- return NPU_STATUS_ERROR_INVALID_DATA;
- }
-
- auto &inInfos = req->inInfos;
- auto &outInfos = req->outInfos;
-
- inInfos->num_info = inputBufs->numBuffers;
- for (auto i = 0; i < inInfos->num_info; ++i)
- {
- inInfos->info[i].layout = DATA_LAYOUT_MODEL;
- inInfos->info[i].type = minfo->meta->input_seg_quant_type[i];
- }
-
- outInfos->num_info = outputBufs->numBuffers;
- for (auto i = 0; i < outInfos->num_info; ++i)
- {
- outInfos->info[i].layout = DATA_LAYOUT_MODEL;
- outInfos->info[i].type = minfo->meta->output_seg_quant_type[i];
- }
-
- auto &inBufs = req->inBufs;
- auto &outBufs = req->outBufs;
-
- inBufs->num_buffers = inputBufs->numBuffers;
- for (auto i = 0; i < inBufs->num_buffers; ++i)
- {
- if (inputBufs->buffers[i].type == NPU_BUFFER_MAPPED)
- {
- inBufs->bufs[i].addr = inputBufs->buffers[i].addr;
- }
- else if (inputBufs->buffers[i].type == NPU_BUFFER_DMABUF)
- {
- // TODO Implement details
- // inBufs.bufs[i].dmabuf = inputBufs->buffers[i].dmabuf;
- // inBufs.bufs[i].offset = inputBufs->buffers[i].offset;
- }
- else
- {
- continue;
- }
- inBufs->bufs[i].size = inputBufs->buffers[i].size;
- inBufs->bufs[i].type = static_cast<buffer_types>(inputBufs->buffers[i].type);
- }
-
- outBufs->num_buffers = outputBufs->numBuffers;
- for (auto i = 0; i < outBufs->num_buffers; ++i)
- {
- if (outputBufs->buffers[i].type == NPU_BUFFER_MAPPED)
- {
- outBufs->bufs[i].addr = outputBufs->buffers[i].addr;
- }
- else if (outputBufs->buffers[i].type == NPU_BUFFER_DMABUF)
- {
- // TODO Implement details
- // outBufs.bufs[i].dmabuf = outputBufs->buffers[i].dmabuf;
- // outBufs.bufs[i].offset = outputBufs->buffers[i].offset;
- }
- else
- {
- continue;
- }
- outBufs->bufs[i].size = outputBufs->buffers[i].size;
- outBufs->bufs[i].type = static_cast<buffer_types>(outputBufs->buffers[i].type);
- }
-
- npudev_h handle = _dev->handles.at(ctx->defaultCore);
- if (setNPU_requestData(handle, requestId, inBufs.get(), inInfos.get(), outBufs.get(),
- outInfos.get()) < 0)
- {
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-
- return NPU_STATUS_SUCCESS;
-}
-
-NpuStatus TrixBackend::submitRequest(NpuContext *ctx, RequestID requestId)
-{
- // TODO Implement details
- return NPU_STATUS_ERROR_NOT_SUPPORTED;
-}
-
-} // namespace trix
-} // namespace backend
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_BACKEND_TRIX_BACKEND_H__
-#define __ONE_SERVICE_NPUD_BACKEND_TRIX_BACKEND_H__
-
-#include <core/Backend.h>
-#include <libnpuhost.h>
-#include <memory>
-#include <vector>
-#include <map>
-
-namespace npud
-{
-namespace backend
-{
-namespace trix
-{
-
-using namespace ::npud::core;
-
-using Handle = void *;
-
-/**
- * @brief Trix model information.
- *
- * @param id The model identifier.
- * @param path The model path.
- * @param core The core number where the model is registered.
- * @param meta The meta data of model.
- * @param refCount The reference count of model users.
- */
-struct TrixModelInfo
-{
- ModelID id;
- std::string path;
- int core;
- npubin_meta *meta;
- int refCount;
-
- TrixModelInfo() : meta(nullptr), refCount(0) {}
- TrixModelInfo(ModelID _id, const std::string &_path, int _core, npubin_meta *_meta, int _refCount)
- : id(_id), path(_path), core(_core), meta(_meta), refCount(_refCount)
- {
- }
- ~TrixModelInfo() { free(meta); }
-};
-
-/**
- * @brief Trix request information
- *
- * @param id The request identifier.
- * @param modelId The model id of request.
- */
-struct TrixRequestInfo
-{
- RequestID id;
- ModelID modelId;
- std::unique_ptr<input_buffers> inBufs;
- std::unique_ptr<tensors_data_info> inInfos;
- std::unique_ptr<output_buffers> outBufs;
- std::unique_ptr<tensors_data_info> outInfos;
- TrixRequestInfo(RequestID _id, ModelID _mid)
- : id(_id), modelId(_mid), inBufs(std::make_unique<input_buffers>()),
- inInfos(std::make_unique<tensors_data_info>()), outBufs(std::make_unique<output_buffers>()),
- outInfos(std::make_unique<tensors_data_info>())
- {
- }
-};
-
-/**
- * @brief Trix device information
- *
- * @param handles The device handle list.
- * @param ctxs The NpuContext list.
- * @param models The model map.
- * @param requests The request map.
- */
-struct TrixDevice
-{
- std::vector<Handle> handles;
- std::vector<std::unique_ptr<NpuContext>> ctxs;
- std::map<ModelID, std::unique_ptr<TrixModelInfo>> models;
- std::map<RequestID, std::unique_ptr<TrixRequestInfo>> requests;
-};
-
-class TrixBackend : public Backend
-{
-public:
- TrixBackend();
- ~TrixBackend();
-
- NpuStatus getVersion(std::string &version) override;
- NpuStatus createContext(int deviceId, int priority, NpuContext **ctx) override;
- NpuStatus destroyContext(NpuContext *ctx) override;
- NpuStatus createBuffer(NpuContext *ctx, GenericBuffer *buffer) override;
- NpuStatus destroyBuffer(NpuContext *ctx, GenericBuffer *buffer) override;
- // TODO Support to register model from buffer
- NpuStatus registerModel(NpuContext *ctx, const std::string &modelPath, ModelID *modelId) override;
- NpuStatus unregisterModel(NpuContext *ctx, ModelID modelId) override;
- NpuStatus createRequest(NpuContext *ctx, ModelID modelId, RequestID *requestId) override;
- NpuStatus destroyRequest(NpuContext *ctx, RequestID requestId) override;
- NpuStatus setRequestData(NpuContext *ctx, RequestID requestId, InputBuffers *inputBufs,
- TensorDataInfos *inputInfos, OutputBuffers *outputBufs,
- TensorDataInfos *outputInfos) override;
- NpuStatus submitRequest(NpuContext *ctx, RequestID requestId) override;
-
-private:
- dev_type _devType;
- std::unique_ptr<TrixDevice> _dev;
-};
-
-} // namespace trix
-} // namespace backend
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_BACKEND_TRIX_BACKEND_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_BACKEND_H__
-#define __ONE_SERVICE_NPUD_CORE_BACKEND_H__
-
-#include "ir/Layout.h"
-#include "ir/DataType.h"
-
-#include <cstdint>
-#include <string>
-#include <vector>
-
-namespace npud
-{
-namespace core
-{
-
-#define NPU_TENSOR_MAX (16)
-
-/**
- * @brief Npu model ID.
- *
- */
-using ModelID = uint32_t;
-
-/**
- * @brief Npu request ID.
- *
- */
-using RequestID = uint32_t;
-
-/**
- * @brief Npu buffer type
- *
- */
-enum BufferTypes
-{
- NPU_BUFFER_MAPPED, /**< buffer is a memory-mapped ptr */
- NPU_BUFFER_DMABUF, /**< buffer is a dmabuf fd, representing contiguous memory */
- NPU_BUFFER_UNDEFINED /**< buffer type is undefined */
-};
-
-/**
- * @brief Various kinds of buffer supported for input/output/model.
- *
- */
-struct GenericBuffer
-{
- struct
- { /** NPU_BUFFER_MAPPED/DMABUF */
- void *addr; /**< Mapped address of the buffer */
- struct
- { /** NPU_BUFFER_DMABUF only */
- int dmabuf; /**< The dma-buf fd handle of the memory allocated */
- uint64_t offset; /**< Offset to be applied to the base memory address */
- };
- };
- uint64_t size; /**< The size of the buffer in bytes */
- BufferTypes type; /**< Type of memory in this buffer */
-};
-
-/**
- * @brief Npu generic buffer array.
- *
- */
-struct GenericBuffers
-{
- uint32_t numBuffers;
- GenericBuffer buffers[NPU_TENSOR_MAX];
-};
-
-/**
- * @brief Npu input/output buffers are compotible with GenericBuffers.
- *
- */
-typedef GenericBuffers InputBuffers;
-typedef GenericBuffers OutputBuffers;
-
-/**
- * @brief Npu tensor data info description.
- *
- */
-struct TensorDataInfo
-{
- ir::Layout layout;
- ir::DataType type;
-};
-
-/**
- * @brief Npu tensor data info array.
- *
- */
-struct TensorDataInfos
-{
- uint32_t numInfos;
- TensorDataInfo infos[NPU_TENSOR_MAX];
-};
-
-/**
- * @brief Npu error status.
- *
- */
-enum NpuStatus
-{
- NPU_STATUS_SUCCESS = 0,
- NPU_STATUS_ERROR_OPERATION_FAILED,
- NPU_STATUS_ERROR_NOT_SUPPORTED,
- NPU_STATUS_ERROR_INVALID_ARGUMENT,
- NPU_STATUS_ERROR_INVALID_MODEL,
- NPU_STATUS_ERROR_INVALID_DATA,
-};
-
-/**
- * @brief Npu context definition
- *
- * @param models The model lists.
- * @param requests The request lists.
- * @param defaultCore The core number to be used by default.
- */
-struct NpuContext
-{
- std::vector<ModelID> models;
- std::vector<RequestID> requests;
- int defaultCore;
-};
-
-/**
- * @brief Npu backend interface
- *
- * Backend module should implement this Backend interface.
- * Npu daemon will load this class symbol at runtime.
- */
-class Backend
-{
-public:
- virtual ~Backend() = default;
-
- virtual NpuStatus getVersion(std::string &version) = 0;
- virtual NpuStatus createContext(int deviceId, int priority, NpuContext **ctx) = 0;
- virtual NpuStatus destroyContext(NpuContext *ctx) = 0;
- virtual NpuStatus createBuffer(NpuContext *ctx, GenericBuffer *buffer) = 0;
- virtual NpuStatus destroyBuffer(NpuContext *ctx, GenericBuffer *buffer) = 0;
- // TODO Support to register model from buffer
- virtual NpuStatus registerModel(NpuContext *ctx, const std::string &modelPath,
- ModelID *modelId) = 0;
- virtual NpuStatus unregisterModel(NpuContext *ctx, ModelID modelId) = 0;
- virtual NpuStatus createRequest(NpuContext *ctx, ModelID modelId, RequestID *requestId) = 0;
- virtual NpuStatus destroyRequest(NpuContext *ctx, RequestID requestId) = 0;
- virtual NpuStatus setRequestData(NpuContext *ctx, RequestID requestId, InputBuffers *inputBufs,
- TensorDataInfos *inputInfos, OutputBuffers *outputBufs,
- TensorDataInfos *outputInfos) = 0;
- virtual NpuStatus submitRequest(NpuContext *ctx, RequestID requestId) = 0;
-};
-
-typedef Backend *(*NpuAlloc)();
-typedef void (*NpuDealloc)(Backend *);
-
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_BACKEND_H__
+++ /dev/null
-nnfw_find_package(GLib2.0 REQUIRED)
-
-file(GLOB_RECURSE SOURCES "*.cc")
-file(GLOB_RECURSE MAIN_SOURCE_FILE "main.cc")
-list(REMOVE_ITEM SOURCES ${MAIN_SOURCE_FILE})
-
-add_library(npud_core STATIC ${SOURCES})
-
-set_target_properties(npud_core PROPERTIES LINKER_LANGUAGE CXX)
-target_include_directories(npud_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-target_include_directories(npud_core PUBLIC ${GLIB2.0_INCLUDE_DIRS})
-target_include_directories(npud_core PUBLIC ${DBUS_INCLUDE_DIRS})
-target_link_libraries(npud_core PRIVATE nnfw_lib_misc)
-target_link_libraries(npud_core PRIVATE ${GLIB2.0_LIBRARIES})
-target_link_libraries(npud_core PRIVATE ${LIB_PTHREAD})
-target_link_libraries(npud_core PRIVATE dl)
-target_link_libraries(npud_core PRIVATE npud_dbus)
-
-if(ENVVAR_NPUD_CONFIG)
- target_compile_definitions(npud_core PRIVATE ENVVAR_FOR_DEFAULT_CONFIG)
-endif(ENVVAR_NPUD_CONFIG)
-
-# npud executable
-add_executable(npud ${MAIN_SOURCE_FILE})
-
-set_target_properties(npud PROPERTIES LINKER_LANGUAGE CXX)
-target_link_libraries(npud PRIVATE npud_core)
-
-install(TARGETS npud DESTINATION bin)
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "ContextManager.h"
-
-#include <algorithm>
-#include <util/Logging.h>
-
-namespace npud
-{
-namespace core
-{
-
-ContextManager::ContextManager() noexcept {}
-
-ContextManager::~ContextManager() noexcept { _contexts.clear(); }
-
-void ContextManager::newContext(NpuContext *npuContext, ContextID *contextId)
-{
- auto context = std::make_unique<Context>();
- // TODO Consider the possibility of reusing the same address.
- context->contextId = reinterpret_cast<ContextID>(context.get());
- context->npuContext = npuContext;
- *contextId = context->contextId;
- _contexts.emplace_back(std::move(context));
-
- this->listContexts();
-}
-
-void ContextManager::deleteContext(ContextID contextId)
-{
- const auto iter =
- std::remove_if(_contexts.begin(), _contexts.end(),
- [&](std::unique_ptr<Context> &c) { return c->contextId == contextId; });
- if (iter == _contexts.end())
- {
- return;
- }
-
- _contexts.erase(iter, _contexts.end());
-
- this->listContexts();
-}
-
-void ContextManager::listContexts()
-{
-#ifdef DEBUG
- VERBOSE(ContextManager) << "Size: " << _contexts.size() << std::endl;
- for (const auto &context : _contexts)
- {
- VERBOSE(ContextManager) << "==========================" << std::endl;
- VERBOSE(ContextManager) << "contextId: " << context->contextId << std::endl;
- }
- VERBOSE(ContextManager) << "==========================" << std::endl;
-#endif
-}
-
-const std::vector<std::unique_ptr<Context>>::iterator
-ContextManager::getContext(ContextID contextId)
-{
- const auto iter =
- std::find_if(_contexts.begin(), _contexts.end(),
- [&](std::unique_ptr<Context> &c) { return c->contextId == contextId; });
- return iter;
-}
-
-NpuContext *ContextManager::getNpuContext(ContextID contextId)
-{
- const auto iter = getContext(contextId);
- if (iter == _contexts.end())
- {
- return nullptr;
- }
-
- return iter->get()->npuContext;
-}
-
-} // namespace core
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_CONTEXT_MANAGER_H__
-#define __ONE_SERVICE_NPUD_CORE_CONTEXT_MANAGER_H__
-
-#include "Backend.h"
-
-#include <vector>
-#include <memory>
-
-namespace npud
-{
-namespace core
-{
-
-using ContextID = uint64_t;
-struct Context
-{
- // TODO Describe the variables
- ContextID contextId;
- NpuContext *npuContext;
-};
-
-class ContextManager
-{
-public:
- ContextManager() noexcept;
- ~ContextManager() noexcept;
-
- ContextManager(const ContextManager &) = delete;
- ContextManager &operator=(const ContextManager &) = delete;
-
- void newContext(NpuContext *npuContext, ContextID *contextId);
- void deleteContext(ContextID contextId);
- const std::vector<std::unique_ptr<Context>>::iterator getContext(ContextID contextId);
- NpuContext *getNpuContext(ContextID contextId);
-
-private:
- void listContexts(void);
-
-private:
- std::vector<std::unique_ptr<Context>> _contexts;
-};
-
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_CONTEXT_MANAGER_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "Core.h"
-#include "util/Logging.h"
-
-namespace npud
-{
-namespace core
-{
-
-Core::Core() noexcept
- : _devManager(std::make_unique<DevManager>()), _contextManager(std::make_unique<ContextManager>())
-{
-}
-
-void Core::init() { _devManager->loadModules(); }
-
-void Core::deinit() { _devManager->releaseModules(); }
-
-int Core::getAvailableDeviceList(std::vector<std::string> &list) const { return 0; }
-
-int Core::createContext(int deviceId, int priority, ContextID *contextId) const
-{
- VERBOSE(Core) << "createContext with " << deviceId << ", " << priority << std::endl;
- NpuContext *npuContext;
- int ret = _devManager->createContext(deviceId, priority, &npuContext);
- if (ret != NPU_STATUS_SUCCESS)
- {
- VERBOSE(Core) << "Fail to create dev context" << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- ContextID _contextId;
- _contextManager->newContext(npuContext, &_contextId);
- *contextId = _contextId;
- return 0;
-}
-
-int Core::destroyContext(ContextID contextId) const
-{
- VERBOSE(Core) << "destroyContext with " << contextId << std::endl;
- NpuContext *npuContext = _contextManager->getNpuContext(contextId);
- if (!npuContext)
- {
- VERBOSE(Core) << "Invalid context id" << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- int ret = _devManager->destroyContext(npuContext);
- if (ret != NPU_STATUS_SUCCESS)
- {
- VERBOSE(Core) << "Failed to destroy npu context: " << ret << std::endl;
- return 1;
- }
-
- _contextManager->deleteContext(contextId);
- return 0;
-}
-
-int Core::createNetwork(ContextID contextId, const std::string &modelPath, ModelID *modelId) const
-{
- VERBOSE(Core) << "createNetwork with " << contextId << ", " << modelPath << std::endl;
- NpuContext *npuContext = _contextManager->getNpuContext(contextId);
- if (!npuContext)
- {
- VERBOSE(Core) << "Invalid context id" << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- ModelID id;
- int ret = _devManager->registerModel(npuContext, modelPath, &id);
- if (ret != NPU_STATUS_SUCCESS)
- {
- VERBOSE(Core) << "Failed to register model: " << ret << std::endl;
- return 1;
- }
-
- *modelId = id;
- return 0;
-}
-
-int Core::destroyNetwork(ContextID contextId, ModelID modelId) const
-{
- VERBOSE(Core) << "destroyNetwork with " << contextId << std::endl;
- NpuContext *npuContext = _contextManager->getNpuContext(contextId);
- if (!npuContext)
- {
- VERBOSE(Core) << "Invalid context id" << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- int ret = _devManager->unregisterModel(npuContext, modelId);
- if (ret != NPU_STATUS_SUCCESS)
- {
- VERBOSE(Core) << "Failed to unregister model: " << ret << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- return 0;
-}
-
-int Core::createRequest(ContextID contextId, ModelID modelId, RequestID *requestId) const
-{
- VERBOSE(Core) << "createRequest with " << contextId << ", " << modelId << std::endl;
- NpuContext *npuContext = _contextManager->getNpuContext(contextId);
- if (!npuContext)
- {
- VERBOSE(Core) << "Invalid context id" << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- RequestID id;
- int ret = _devManager->createRequest(npuContext, modelId, &id);
- if (ret != NPU_STATUS_SUCCESS)
- {
- VERBOSE(Core) << "Failed to create request of model: " << ret << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- *requestId = id;
- return 0;
-}
-
-int Core::destroyRequest(ContextID contextId, RequestID requestId) const
-{
- VERBOSE(Core) << "destroyRequest with " << contextId << ", " << requestId << std::endl;
- NpuContext *npuContext = _contextManager->getNpuContext(contextId);
- if (!npuContext)
- {
- VERBOSE(Core) << "Invalid context id" << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- int ret = _devManager->destroyRequest(npuContext, requestId);
- if (ret != NPU_STATUS_SUCCESS)
- {
- VERBOSE(Core) << "Failed to destroy request: " << ret << std::endl;
- // TODO Define CoreStatus
- return 1;
- }
-
- return 0;
-}
-
-} // namespace core
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_CORE_H__
-#define __ONE_SERVICE_NPUD_CORE_CORE_H__
-
-#include "DevManager.h"
-#include "ContextManager.h"
-
-#include <vector>
-#include <string>
-
-namespace npud
-{
-namespace core
-{
-
-// TODO Define error status
-
-class Core
-{
-public:
- Core() noexcept;
- ~Core() noexcept = default;
-
- Core(const Core &) = delete;
- Core &operator=(const Core &) = delete;
-
- void init();
- void deinit();
-
- int getAvailableDeviceList(std::vector<std::string> &list) const;
- int createContext(int deviceId, int priority, ContextID *contextId) const;
- int destroyContext(ContextID contextId) const;
- int createNetwork(ContextID contextId, const std::string &modelPath, ModelID *modelId) const;
- int destroyNetwork(ContextID contextId, ModelID modelId) const;
- int createRequest(ContextID contextId, ModelID modelId, RequestID *requestId) const;
- int destroyRequest(ContextID contextId, RequestID requestId) const;
-
-private:
- std::unique_ptr<DevManager> _devManager;
- std::unique_ptr<ContextManager> _contextManager;
-};
-
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_CORE_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "DBus.h"
-#include "Server.h"
-
-#include <atomic>
-#include <util/Logging.h>
-
-namespace npud
-{
-namespace core
-{
-
-std::atomic_bool DBus::_isReady(false);
-
-DBus::DBus() noexcept
-{
- VERBOSE(DBus) << "Starting dbus service" << std::endl;
-
- _gdbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, "org.tizen.npud", G_BUS_NAME_OWNER_FLAGS_NONE,
- (GBusAcquiredCallback)on_bus_acquired,
- (GBusNameAcquiredCallback)on_name_acquired,
- (GBusNameLostCallback)on_name_lost, NULL, NULL);
-}
-
-DBus::~DBus() noexcept
-{
- VERBOSE(DBus) << "Stop dbus service" << std::endl;
-
- g_bus_unown_name(_gdbus_id);
-}
-
-void DBus::on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
-{
- VERBOSE(DBus) << name << " on bus acquired" << std::endl;
-
- GError *error = NULL;
- NpudCore *core = npud_core_skeleton_new();
- NpudCoreIface *iface = NPUD_CORE_GET_IFACE(core);
-
- iface->handle_device_get_available_list = &on_handle_device_get_available_list;
- iface->handle_context_create = &on_handle_context_create;
- iface->handle_context_destroy = &on_handle_context_destroy;
- iface->handle_buffers_create = &on_handle_buffers_create;
- iface->handle_buffers_destroy = &on_handle_buffers_destroy;
- iface->handle_network_create = &on_handle_network_create;
- iface->handle_network_destroy = &on_handle_network_destroy;
- iface->handle_request_create = &on_handle_request_create;
- iface->handle_request_destroy = &on_handle_request_destroy;
- iface->handle_request_set_data = &on_handle_request_set_data;
- iface->handle_execute_run = &on_handle_execute_run;
-
- if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(core), conn, "/org/tizen/npud",
- &error))
- {
- VERBOSE(DBus) << "Failed to export skeleton, Server will stop." << std::endl;
- Server::instance().stop();
- }
-
- _isReady.exchange(true);
-}
-
-void DBus::on_name_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
-{
- VERBOSE(DBus) << name << " on name acquired" << std::endl;
-}
-
-void DBus::on_name_lost(GDBusConnection *conn, const gchar *name, gpointer user_data)
-{
- VERBOSE(DBus) << name << " on name lost, Server will stop." << std::endl;
- Server::instance().stop();
-}
-
-gboolean DBus::on_handle_device_get_available_list(NpudCore *object,
- GDBusMethodInvocation *invocation)
-{
- VERBOSE(DBus) << __FUNCTION__ << std::endl;
- std::vector<std::string> list;
- int error = Server::instance().core().getAvailableDeviceList(list);
- // TODO Implement variant outputs
- npud_core_complete_device_get_available_list(object, invocation, error);
- return TRUE;
-}
-
-gboolean DBus::on_handle_context_create(NpudCore *object, GDBusMethodInvocation *invocation,
- gint arg_device_id, gint arg_priority)
-{
- VERBOSE(DBus) << "on_handle_context_create with " << arg_device_id << ", " << arg_priority
- << std::endl;
-
- guint64 out_ctx = 0;
- int ret = Server::instance().core().createContext(arg_device_id, arg_priority, &out_ctx);
- npud_core_complete_context_create(object, invocation, out_ctx, ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_context_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx)
-{
- VERBOSE(DBus) << "on_handle_context_destroy with " << arg_ctx << std::endl;
- int ret = Server::instance().core().destroyContext(arg_ctx);
- npud_core_complete_context_destroy(object, invocation, ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_buffers_create(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, GVariant *arg_buffers)
-{
- VERBOSE(DBus) << "on_handle_buffers_create with " << arg_ctx << std::endl;
- GenericBuffers bufs;
- GVariantIter *iter = NULL;
- gint32 type;
- guint64 addr;
- guint32 size;
- int index = 0;
- g_variant_get(arg_buffers, "a(itu)", &iter);
- while (iter != NULL && g_variant_iter_loop(iter, "(itu)", &type, &addr, &size))
- {
- VERBOSE(DBus) << "in [" << index << "] Type: " << type << ", Addr: " << addr
- << ", Size: " << size << std::endl;
- bufs.buffers[index].type = static_cast<BufferTypes>(type);
- bufs.buffers[index].addr = reinterpret_cast<void *>(addr);
- bufs.buffers[index].size = size;
- index++;
- }
- bufs.numBuffers = index;
- g_variant_iter_free(iter);
-
- // TODO Invoke Core function.
- int ret = -1;
-
- GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("a(itu)"));
-
- // TODO Enable below code when we can update ret value by core function
- // if (ret == 0)
- // {
- // for (auto i = 0; i < bufs.numBuffers; ++i)
- // {
- // VERBOSE(DBus) << "out [" << index << "] Type: " << bufs.buffers[i].type
- // << ", Addr: " << bufs.buffers[i].addr << ", Size: " << bufs.buffers[i].size
- // << std::endl;
- // g_variant_builder_add(builder, "(itu)", bufs.buffers[i].type, bufs.buffers[i].addr,
- // bufs.buffers[i].size);
- // }
- // }
- npud_core_complete_buffers_create(object, invocation, g_variant_builder_end(builder), ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_buffers_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, GVariant *arg_buffers)
-{
- VERBOSE(DBus) << "on_handle_buffers_destroy with " << arg_ctx << std::endl;
- GenericBuffers bufs;
- GVariantIter *iter = NULL;
- gint32 type;
- guint64 addr;
- guint32 size;
- int index = 0;
- g_variant_get(arg_buffers, "a(itu)", &iter);
- while (iter != NULL && g_variant_iter_loop(iter, "(itu)", &type, &addr, &size))
- {
- VERBOSE(DBus) << "[" << index << "] Type: " << type << ", Addr: " << (void *)addr
- << ", Size: " << size << std::endl;
- bufs.buffers[index].type = static_cast<BufferTypes>(type);
- bufs.buffers[index].addr = reinterpret_cast<void *>(addr);
- bufs.buffers[index].size = size;
- index++;
- }
- bufs.numBuffers = index;
- g_variant_iter_free(iter);
- // TODO Invoke Core function.
- int ret = -1;
- npud_core_complete_buffers_destroy(object, invocation, ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_network_create(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, const gchar *arg_model_path)
-{
- VERBOSE(DBus) << "on_handle_network_create with " << arg_ctx << ", " << arg_model_path
- << std::endl;
- ModelID modelId = 0;
- int ret = Server::instance().core().createNetwork(arg_ctx, arg_model_path, &modelId);
- npud_core_complete_network_create(object, invocation, guint(modelId), ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_network_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_nw_handle)
-{
- VERBOSE(DBus) << "on_handle_network_destroy with " << arg_ctx << ", " << arg_nw_handle
- << std::endl;
- int ret = Server::instance().core().destroyNetwork(arg_ctx, arg_nw_handle);
- npud_core_complete_network_destroy(object, invocation, ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_request_create(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_nw_handle)
-{
- VERBOSE(DBus) << "on_handle_request_create with " << arg_ctx << ", " << arg_nw_handle
- << std::endl;
- RequestID requestID = 0;
- int ret = Server::instance().core().createRequest(arg_ctx, arg_nw_handle, &requestID);
- npud_core_complete_request_create(object, invocation, guint(requestID), ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_request_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_rq_handle)
-{
- VERBOSE(DBus) << "on_handle_request_destroy with " << arg_ctx << ", " << arg_rq_handle
- << std::endl;
- int ret = Server::instance().core().destroyRequest(arg_ctx, arg_rq_handle);
- npud_core_complete_request_destroy(object, invocation, ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_request_set_data(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_rq_handle,
- GVariant *arg_input_buffers, GVariant *arg_output_buffers)
-{
- VERBOSE(DBus) << "on_handle_request_set_data with " << arg_ctx << ", " << arg_rq_handle
- << std::endl;
- GVariantIter *iter = NULL;
- InputBuffers inBufs;
- OutputBuffers outBufs;
- gint32 type;
- guint64 addr;
- guint32 size;
- int index = 0;
-
- // inBufs
- g_variant_get(arg_input_buffers, "a(itu)", &iter);
- index = 0;
- while (iter != NULL && g_variant_iter_loop(iter, "(itu)", &type, &addr, &size))
- {
- VERBOSE(DBus) << "in [" << index << "] Type: " << type << ", Addr: " << (void *)addr
- << ", Size: " << size << std::endl;
- if (type == 0) // NPU_BUFFER_MAPPED
- {
- inBufs.buffers[index].addr = reinterpret_cast<void *>(addr);
- }
- else if (type == 1) // NPU_BUFFER_DMABUF
- {
- // TODO Support dma buffer
- VERBOSE(DBus) << "[NYI] NPU_BUFFER_DMABUF" << std::endl;
- continue;
- }
- else
- {
- VERBOSE(DBus) << "Wrong buffer type. Ignored." << std::endl;
- continue;
- }
- inBufs.buffers[index].size = size;
- inBufs.buffers[index].type = static_cast<BufferTypes>(type);
- index++;
- }
- inBufs.numBuffers = index;
- g_variant_iter_free(iter);
-
- // outBufs
- g_variant_get(arg_output_buffers, "a(itu)", &iter);
- index = 0;
- while (iter != NULL && g_variant_iter_loop(iter, "(itu)", &type, &addr, &size))
- {
- VERBOSE(DBus) << "out [" << index << "] Type: " << type << ", Addr: " << (void *)addr
- << ", Size: " << size << std::endl;
- if (type == 0) // NPU_BUFFER_MAPPED
- {
- outBufs.buffers[index].addr = reinterpret_cast<void *>(addr);
- }
- else if (type == 1) // NPU_BUFFER_DMABUF
- {
- // TODO Support dma buffer
- VERBOSE(DBus) << "[NYI] NPU_BUFFER_DMABUF" << std::endl;
- continue;
- }
- else
- {
- VERBOSE(DBus) << "Wrong buffer type. Ignored." << std::endl;
- continue;
- }
- outBufs.buffers[index].size = size;
- outBufs.buffers[index].type = static_cast<BufferTypes>(type);
- index++;
- }
- outBufs.numBuffers = index;
- g_variant_iter_free(iter);
-
- // TODO Invoke Core function.
- int ret = -1;
- npud_core_complete_request_set_data(object, invocation, ret);
- return TRUE;
-}
-
-gboolean DBus::on_handle_execute_run(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_rq_handle)
-{
- VERBOSE(DBus) << "on_handle_execute_run with " << arg_ctx << ", " << arg_rq_handle << std::endl;
- // TODO Invoke Core function.
- int ret = -1;
- npud_core_complete_execute_run(object, invocation, ret);
- return TRUE;
-}
-
-} // namespace core
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_DBUS_H__
-#define __ONE_SERVICE_NPUD_CORE_DBUS_H__
-
-#include <dbus-core.h>
-#include <gio/gio.h>
-#include <memory>
-#include <atomic>
-
-namespace npud
-{
-namespace core
-{
-
-class DBus
-{
-public:
- DBus() noexcept;
- ~DBus() noexcept;
-
- DBus(const DBus &) = delete;
- DBus &operator=(const DBus &) = delete;
-
- bool isReady() { return _isReady.load(); }
-
- static void on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data);
- static void on_name_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data);
- static void on_name_lost(GDBusConnection *conn, const gchar *name, gpointer user_data);
-
- static gboolean on_handle_device_get_available_list(NpudCore *object,
- GDBusMethodInvocation *invocation);
- static gboolean on_handle_context_create(NpudCore *object, GDBusMethodInvocation *invocation,
- gint arg_device_id, gint arg_priority);
- static gboolean on_handle_context_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx);
- static gboolean on_handle_buffers_create(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, GVariant *arg_buffers);
- static gboolean on_handle_buffers_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, GVariant *arg_buffers);
- static gboolean on_handle_network_create(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, const gchar *arg_model_path);
- static gboolean on_handle_network_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_nw_handle);
- static gboolean on_handle_request_create(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_nw_handle);
- static gboolean on_handle_request_destroy(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_rq_handle);
- static gboolean on_handle_request_set_data(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_rq_handle,
- GVariant *arg_input_buffers,
- GVariant *arg_output_buffers);
- static gboolean on_handle_execute_run(NpudCore *object, GDBusMethodInvocation *invocation,
- guint64 arg_ctx, guint arg_rq_handle);
-
-private:
- guint _gdbus_id;
- static std::atomic_bool _isReady;
-};
-
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_DBUS_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "DevManager.h"
-#include "util/Logging.h"
-
-#include <dirent.h>
-
-namespace npud
-{
-namespace core
-{
-
-DevManager::DevManager()
-{
- const auto env = util::getConfigString(util::config::DEVICE_MODULE_PATH);
- _module_dir = std::move(env);
-}
-
-void DevManager::loadModules()
-{
- VERBOSE(DevManager) << "load modules from " << _module_dir << std::endl;
-
- releaseModules();
-
- DIR *dir;
- struct dirent *entry;
-
- // NOTE
- // Return NULL(0) value when opendir or readdir error occurs.
- // NULL should be used instead of nullptr.
- dir = opendir(_module_dir.c_str());
- if (dir == NULL)
- {
- VERBOSE(DevManager) << "Fail to open module directory" << std::endl;
- return;
- }
-
- while ((entry = readdir(dir)) != NULL)
- {
- std::string modulePath(entry->d_name);
- if (modulePath.find("npud_backend") == std::string::npos)
- {
- continue;
- }
-
- DynamicLoader *loader = nullptr;
- try
- {
- loader = new DynamicLoader(modulePath.c_str());
- }
- catch (const std::exception &e)
- {
- VERBOSE(DevManager) << e.what() << std::endl;
- continue;
- }
-
- std::unique_ptr<Device> dev = std::make_unique<Device>();
- dev->modulePath = std::move(modulePath);
- dev->loader = std::unique_ptr<DynamicLoader>(loader);
-
- _dev = std::move(dev);
- break;
- }
-
- closedir(dir);
-}
-
-void DevManager::releaseModules()
-{
- if (_dev)
- {
- _dev.reset();
- }
-}
-
-std::shared_ptr<Backend> DevManager::getBackend()
-{
- if (!_dev)
- {
- throw std::runtime_error("No backend device.");
- }
- return _dev->loader->getInstance();
-}
-
-int DevManager::createContext(int deviceId, int priority, NpuContext **npuContext)
-{
- try
- {
- return getBackend()->createContext(deviceId, priority, npuContext);
- }
- catch (const std::exception &e)
- {
- VERBOSE(DevManager) << e.what() << std::endl;
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-}
-
-int DevManager::destroyContext(NpuContext *npuContext)
-{
- try
- {
- return getBackend()->destroyContext(npuContext);
- }
- catch (const std::exception &e)
- {
- VERBOSE(DevManager) << e.what() << std::endl;
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-}
-
-int DevManager::registerModel(NpuContext *npuContext, const std::string &modelPath,
- ModelID *modelId)
-{
- try
- {
- return getBackend()->registerModel(npuContext, modelPath, modelId);
- }
- catch (const std::exception &e)
- {
- VERBOSE(DevManager) << e.what() << std::endl;
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-}
-
-int DevManager::unregisterModel(NpuContext *npuContext, ModelID modelId)
-{
- try
- {
- return getBackend()->unregisterModel(npuContext, modelId);
- }
- catch (const std::exception &e)
- {
- VERBOSE(DevManager) << e.what() << std::endl;
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-}
-
-int DevManager::createRequest(NpuContext *npuContext, ModelID modelId, RequestID *requestId)
-{
- try
- {
- return getBackend()->createRequest(npuContext, modelId, requestId);
- }
- catch (const std::exception &e)
- {
- VERBOSE(DevManager) << e.what() << std::endl;
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-}
-
-int DevManager::destroyRequest(NpuContext *npuContext, RequestID requestId)
-{
- try
- {
- return getBackend()->destroyRequest(npuContext, requestId);
- }
- catch (const std::exception &e)
- {
- VERBOSE(DevManager) << e.what() << std::endl;
- return NPU_STATUS_ERROR_OPERATION_FAILED;
- }
-}
-
-} // namespace core
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_DEV_MANAGER_H__
-#define __ONE_SERVICE_NPUD_CORE_DEV_MANAGER_H__
-
-#include "DynamicLoader.h"
-
-#include <memory>
-
-namespace npud
-{
-namespace core
-{
-
-struct Device
-{
- std::string modulePath;
- std::unique_ptr<DynamicLoader> loader;
-};
-
-class DevManager
-{
-public:
- DevManager();
- ~DevManager() = default;
-
- DevManager(const DevManager &) = delete;
- DevManager &operator=(const DevManager &) = delete;
-
- void loadModules();
- void releaseModules();
- std::shared_ptr<Backend> getBackend();
-
- int createContext(int deviceId, int priority, NpuContext **npuContext);
- int destroyContext(NpuContext *npuContext);
- int registerModel(NpuContext *npuContext, const std::string &modelPath, ModelID *modelId);
- int unregisterModel(NpuContext *npuContext, ModelID modelId);
- int createRequest(NpuContext *npuContext, ModelID modelId, RequestID *requestId);
- int destroyRequest(NpuContext *npuContext, RequestID requestId);
-
-private:
- std::unique_ptr<Device> _dev;
- std::string _module_dir;
-};
-
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_DEV_MANAGER_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "DynamicLoader.h"
-
-#include "util/Logging.h"
-
-namespace npud
-{
-namespace core
-{
-
-DynamicLoader::DynamicLoader(const char *file, int flags)
- : _handle(nullptr), _filepath(file), _allocSymbol("allocate"), _deallocSymbol("deallocate")
-{
- if (!(_handle = dlopen(_filepath.c_str(), flags)))
- {
- VERBOSE(DynamicLoader) << "Fail to load " << _filepath << " module: " << dlerror() << std::endl;
- throw std::runtime_error("Fail to load " + _filepath + " module");
- }
-
- NpuAlloc alloc;
- NpuDealloc dealloc;
-
- alloc = reinterpret_cast<NpuAlloc>(dlsym(_handle, _allocSymbol.c_str()));
- dealloc = reinterpret_cast<NpuDealloc>(dlsym(_handle, _deallocSymbol.c_str()));
- if (!alloc || !dealloc)
- {
- VERBOSE(DynamicLoader) << "Fail to load " << _filepath << " symbol: " << dlerror() << std::endl;
- dlclose(_handle);
- throw std::runtime_error("Fail to load " + _filepath + " module");
- }
-
- _backend = std::shared_ptr<Backend>(alloc(), [dealloc](Backend *b) { dealloc(b); });
-}
-
-DynamicLoader::~DynamicLoader()
-{
- // NOTE
- // The _backend shared_ptr must be explicitly deleted before
- // the dynamic library handle is released.
- _backend.reset();
- dlclose(_handle);
-}
-
-std::shared_ptr<Backend> DynamicLoader::getInstance() { return _backend; }
-
-} // namespace core
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_DYNAMIC_LOADER_H__
-#define __ONE_SERVICE_NPUD_CORE_DYNAMIC_LOADER_H__
-
-#include "Backend.h"
-
-#include <dlfcn.h>
-#include <string>
-#include <memory>
-
-namespace npud
-{
-namespace core
-{
-
-using DLHandle = void *;
-
-class DynamicLoader
-{
-public:
- DynamicLoader(const char *file, int flags = RTLD_LAZY);
- ~DynamicLoader();
-
- DynamicLoader(const DynamicLoader &) = delete;
-
- std::shared_ptr<Backend> getInstance();
-
-private:
- DLHandle _handle;
- std::string _filepath;
- std::string _allocSymbol;
- std::string _deallocSymbol;
- std::shared_ptr<Backend> _backend;
-};
-
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_DYNAMIC_LOADER_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "Server.h"
-#include "util/Logging.h"
-
-#include <thread>
-
-namespace npud
-{
-namespace core
-{
-
-std::atomic_bool Server::_isRunning(false);
-
-Server::Server() noexcept
- : _mainloop(g_main_loop_new(NULL, FALSE), g_main_loop_unref), _signal(std::make_unique<Signal>()),
- _core(std::make_unique<Core>()), _dbus(std::make_unique<DBus>())
-{
-}
-
-bool Server::isServiceReady()
-{
- if (!_isRunning.load())
- {
- VERBOSE(Server) << "Server is not started." << std::endl;
- return false;
- }
-
- if (!_dbus->isReady())
- {
- VERBOSE(Server) << "DBus service is not ready." << std::endl;
- return false;
- }
-
- return true;
-}
-
-void Server::run(void)
-{
- VERBOSE(Server) << "Starting Server\n";
-
- if (_isRunning.exchange(true))
- {
- return;
- }
-
- _core->init();
-
- g_main_loop_run(_mainloop.get());
-}
-
-void Server::stop(void)
-{
- VERBOSE(Server) << "Stop Server\n";
-
- if (!_isRunning.load())
- {
- return;
- }
-
- while (!g_main_loop_is_running(_mainloop.get()))
- {
- std::this_thread::yield();
- }
-
- _core->deinit();
-
- g_main_loop_quit(_mainloop.get());
- _isRunning = false;
-}
-
-} // namespace core
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_SERVER_H__
-#define __ONE_SERVICE_NPUD_CORE_SERVER_H__
-
-#include "Signal.h"
-#include "Core.h"
-#include "DBus.h"
-
-#include <glib.h>
-#include <memory>
-#include <atomic>
-
-namespace npud
-{
-namespace core
-{
-
-class Server
-{
-public:
- Server(const Server &) = delete;
- Server &operator=(const Server &) = delete;
-
- void run(void);
- void stop(void);
-
- bool isRunning() { return _isRunning.load(); }
- bool isServiceReady();
-
- static Server &instance(void)
- {
- static Server server;
- return server;
- }
-
- const Core &core(void) { return *_core.get(); }
-
-private:
- Server() noexcept;
-
- static std::atomic_bool _isRunning;
-
- std::unique_ptr<GMainLoop, void (*)(GMainLoop *)> _mainloop;
- std::unique_ptr<Signal> _signal;
- std::unique_ptr<Core> _core;
- std::unique_ptr<DBus> _dbus;
-};
-
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_SERVER_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "Signal.h"
-#include "Server.h"
-#include "util/Logging.h"
-
-#include <csignal>
-
-namespace npud
-{
-namespace core
-{
-
-Signal::Signal(void) noexcept { init(); }
-
-void Signal::init(void)
-{
- // NOTE Types of signals
- // SIGTERM: termination request, sent to the program
- // SIGINT: external interrupt, usually initiated by the user
- // SIGILL: invalid program image, such as invalid instruction
- // SIGABRT: abnormal termination condition, as is e.g. initiated by std::abort()
- // SIGFPE: erroneous arithmetic operation such as divide by zero
- // from https://en.cppreference.com/w/cpp/utility/program/SIG_types
- std::signal(SIGTERM, handleSignal);
- std::signal(SIGINT, handleSignal);
- std::signal(SIGILL, handleSignal);
- std::signal(SIGABRT, handleSignal);
- std::signal(SIGFPE, handleSignal);
-}
-
-void Signal::handleSignal(int signum)
-{
- VERBOSE(signal) << "Signal received: " << strsignal(signum) << "(" << signum << ")\n";
- Server::instance().stop();
-}
-
-} // namespace core
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_SIGNAL_H__
-#define __ONE_SERVICE_NPUD_CORE_SIGNAL_H__
-
-namespace npud
-{
-namespace core
-{
-
-class Signal
-{
-public:
- Signal() noexcept;
-
- void init(void);
- static void handleSignal(int signum);
-};
-
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_SIGNAL_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_IR_DATATYPE_H__
-#define __ONE_SERVICE_NPUD_CORE_IR_DATATYPE_H__
-
-#include <cstdlib>
-
-namespace npud
-{
-namespace core
-{
-namespace ir
-{
-
-enum class DataType
-{
- INT8 = 0,
- UINT8,
- QUANT_UINT8_ASYMM,
- INT16,
- UINT16,
- QUANT_INT16_SYMM,
- INT32,
- UINT32,
- FLOAT32,
- INT64,
- UINT64,
- FLOAT64,
-};
-
-} // namespace ir
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_IR_DATATYPE_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_CORE_IR_LAYOUT_H__
-#define __ONE_SERVICE_NPUD_CORE_IR_LAYOUT_H__
-
-#include <functional>
-#include <stdexcept>
-#include <string>
-
-namespace npud
-{
-namespace core
-{
-namespace ir
-{
-
-enum class Layout
-{
- UNKNOWN = 0,
- NHWC,
- NCHW
-};
-
-} // namespace ir
-} // namespace core
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_CORE_IR_LAYOUT_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "Server.h"
-#include "util/Logging.h"
-
-using namespace npud;
-
-int main(int argc, const char *argv[])
-{
- auto &server = core::Server::instance();
-
- VERBOSE(main) << "Starting npud\n";
- try
- {
- server.run();
- }
- catch (const std::runtime_error &err)
- {
- std::cerr << err.what() << std::endl;
- return 1;
- }
-
- VERBOSE(main) << "Finished npud\n";
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef CONFIG
-#error Define CONFIG before including this file
-#endif
-
-// Name | Type | Default
-CONFIG(NPUD_LOG_ENABLE , bool , "0")
-CONFIG(DEVICE_MODULE_PATH , std::string , "/usr/lib/npud/devices")
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "ConfigSource.h"
-
-#include <misc/EnvConfigSource.h>
-#include <misc/GeneralConfigSource.h>
-#include <misc/IConfigSource.h>
-
-#include <algorithm>
-#include <array>
-#include <cassert>
-#include <memory>
-
-namespace npud
-{
-namespace util
-{
-
-using namespace nnfw::misc;
-
-static std::unique_ptr<IConfigSource> _source;
-
-void config_source(std::unique_ptr<IConfigSource> &&source) { _source = std::move(source); }
-
-static IConfigSource *config_source()
-{
- if (!_source)
- {
-#ifdef ENVVAR_FOR_DEFAULT_CONFIG
- // Default ConfigSource is EnvConfigSource
- _source = std::make_unique<EnvConfigSource>();
-#else
- _source = std::make_unique<GeneralConfigSource>();
-#endif // ENVVAR_FOR_DEFAULT_CONFIG
- }
- return _source.get();
-}
-
-static std::string getConfigOrDefault(const std::string &key)
-{
- static std::unordered_map<std::string, std::string> defaults;
- if (defaults.empty())
- {
-#define CONFIG(Name, Type, Default) \
- { \
- auto name = std::string{#Name}; \
- defaults.emplace(name, std::string{Default}); \
- }
-
-#include "Config.lst"
-
-#undef CONFIG
- }
-
- // Treat empty string and absence of the value to be the same
- auto ret = config_source()->get(key);
- // if not found search from defaults
- if (ret.empty())
- {
- auto itr = defaults.find(key);
- if (itr != defaults.end())
- {
- // Return the default value if exists
- ret = itr->second;
- }
- }
-
- return ret;
-}
-
-bool toBool(const std::string &val)
-{
- static const std::array<std::string, 5> false_list{"0", "OFF", "FALSE", "N", "NO"};
- auto false_found = std::find(false_list.begin(), false_list.end(), val);
- return false_found == false_list.end();
-}
-
-int toInt(const std::string &val) { return std::stoi(val); }
-
-bool getConfigBool(const std::string &key)
-{
- auto raw = getConfigOrDefault(key);
- return toBool(raw);
-}
-
-int getConfigInt(const std::string &key)
-{
- auto raw = getConfigOrDefault(key);
- return toInt(raw);
-}
-
-std::string getConfigString(const std::string &key) { return getConfigOrDefault(key); }
-
-} // namespace util
-} // namespace npud
-
-namespace npud
-{
-namespace util
-{
-namespace config
-{
-
-#define CONFIG(Name, Type, Default) const char *Name = #Name;
-
-#include "Config.lst"
-
-#undef CONFIG
-
-} // namespace config
-} // namespace util
-} // namespace npud
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_UTIL_CONFIG_SOURCE_H__
-#define __ONE_SERVICE_NPUD_UTIL_CONFIG_SOURCE_H__
-
-#include <string>
-
-namespace npud
-{
-namespace util
-{
-
-bool getConfigBool(const std::string &key);
-int getConfigInt(const std::string &key);
-std::string getConfigString(const std::string &key);
-
-} // namespace util
-} // namespace npud
-
-namespace npud
-{
-namespace util
-{
-namespace config
-{
-
-#define CONFIG(Name, Type, Default) extern const char *Name;
-
-#include "Config.lst"
-
-#undef CONFIG
-
-} // namespace config
-} // namespace util
-} // namespace npud
-
-#endif // __ONE_SERVICE_NPUD_UTIL_CONFIG_SOURCE_H__
+++ /dev/null
-/*
- * Copyright (c) 2022 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.
- */
-
-#ifndef __ONE_SERVICE_NPUD_UTIL_LOGGING_H__
-#define __ONE_SERVICE_NPUD_UTIL_LOGGING_H__
-
-#include <iostream>
-#include <cstring>
-
-#include "ConfigSource.h"
-
-namespace npud
-{
-namespace util
-{
-namespace logging
-{
-class Context
-{
-public:
- Context() noexcept : _enabled{false}
- {
- const auto env = util::getConfigBool(util::config::NPUD_LOG_ENABLE);
-
- if (env)
- {
- _enabled = true;
- }
- }
-
- static Context &get() noexcept
- {
- static Context ctx;
- return ctx;
- }
-
-public:
- bool enabled(void) const { return _enabled; }
-
-private:
- bool _enabled;
-};
-
-static Context &ctx = Context::get();
-
-inline std::string decorated_name(const char *input)
-{
- const int min_prefix = 16;
- std::string prefix(input);
- auto len_prefix = prefix.size();
- if (len_prefix > min_prefix)
- return "[" + prefix + "] ";
- std::string spaces((min_prefix - len_prefix) / 2, ' ');
- return (len_prefix % 2 ? "[ " : "[") + spaces + prefix + spaces + "] ";
-}
-} // namespace logging
-} // namespace util
-} // namespace npud
-
-#define VERBOSE(name) \
- if (::npud::util::logging::ctx.enabled()) \
- std::cout << ::npud::util::logging::decorated_name(#name)
-
-#define VERBOSE_F() \
- if (::npud::util::logging::ctx.enabled()) \
- std::cout << ::npud::util::logging::decorated_name(__func__)
-
-#define WHEN_LOG_ENABLED(METHOD) \
- if (::npud::util::logging::ctx.enabled()) \
- do \
- { \
- METHOD; \
- } while (0)
-
-#endif // __ONE_SERVICE_NPUD_UTIL_LOGGING_H__
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<busconfig>
- <policy context="default">
- <allow own="org.tizen.npud"/>
- <allow send_destination="org.tizen.npud"/>
- <allow receive_sender="org.tizen.npud"/>
- </policy>
-</busconfig>
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node name="/">
- <!-- org.tizen.npud.core:
- @short_description: Npud interface
-
- The interface used to run AI models on npu devices.
- -->
- <interface name="org.tizen.npud.core">
- <!--
- device_get_available_list:
- @error: The error status of the function.
-
- Get all available npu device lists.
- -->
- <method name="device_get_available_list">
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- context_create:
- @device_id: The device numger to use.
- @priority: The device priority.
- @ctx: The Context handle.
- @error: The error status of the function.
-
- Create context.
- -->
- <method name="context_create">
- <arg name="device_id" type="i" direction="in" />
- <arg name="priority" type="i" direction="in" />
- <arg name="ctx" type="t" direction="out" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- context_destroy:
- @ctx: The Context handle to destroy.
- @error: The error status of the function.
-
- Destroy context.
- -->
- <method name="context_destroy">
- <arg name="ctx" type="t" direction="in" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- buffers_create:
- @ctx: The Context handle.
- @buffers: The array of buffer structure. (i:type, t:address, u:size)
- @out_buffers: The array of buffer sturcture containing created buffer address.
- @error: The error status of the function.
-
- Create buffer array.
- -->
- <method name="buffers_create">
- <arg name="ctx" type="t" direction="in" />
- <arg name="buffers" type="a(itu)" direction="in" />
- <arg name="out_buffers" type="a(itu)" direction="out" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- buffers_destroy:
- @ctx: The Context handle.
- @buffers: The array of buffer structure. (i:type, t:address, u:size)
- @error: The error status of the function.
-
- Destroy buffer array.
- -->
- <method name="buffers_destroy">
- <arg name="ctx" type="t" direction="in" />
- <arg name="buffers" type="a(itu)" direction="in" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- network_create:
- @ctx: The context handle.
- @model_path: The model path to run.
- @nw_handle: The Network handle.
- @error: The error status of the function.
-
- Create network.
-
- TODO Support file descriptor input
- -->
- <method name="network_create">
- <arg name="ctx" type="t" direction="in" />
- <arg name="model_path" type="s" direction="in" />
- <arg name="nw_handle" type="u" direction="out" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- network_destroy:
- @ctx: The context handle.
- @nw_handle: The Network handle.
- @error: The error status of the function.
-
- Destroy network.
- -->
- <method name="network_destroy">
- <arg name="ctx" type="t" direction="in" />
- <arg name="nw_handle" type="u" direction="in" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- request_create:
- @ctx: The context handle.
- @nw_handle: The Network handle.
- @rq_handle: The Request handle.
- @error: The error status of the function.
-
- Create request.
- -->
- <method name="request_create">
- <arg name="ctx" type="t" direction="in" />
- <arg name="nw_handle" type="u" direction="in" />
- <arg name="rq_handle" type="u" direction="out" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- request_destroy:
- @ctx: The context handle.
- @rq_handle: The Request handle.
- @error: The error status of the function.
-
- Destroy request.
- -->
- <method name="request_destroy">
- <arg name="ctx" type="t" direction="in" />
- <arg name="rq_handle" type="u" direction="in" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- request_set_data:
- @ctx: The context handle.
- @rq_handle: The Request handle.
- @input_buffers: The input buffer datas.
- @output_buffers: The output buffer datas.
- @error: The error status of the function.
-
- Set request data.
- -->
- <method name="request_set_data">
- <arg name="ctx" type="t" direction="in" />
- <arg name="rq_handle" type="u" direction="in" />
- <arg name="input_buffers" type="a(itu)" direction="in" />
- <arg name="output_buffers" type="a(itu)" direction="in" />
- <arg name="error" type="i" direction="out" />
- </method>
- <!--
- execute_run:
- @ctx: The context handle.
- @rq_handle: The Request handle.
- @error: The error status of the function.
-
- Execute run.
- -->
- <method name="execute_run">
- <arg name="ctx" type="t" direction="in" />
- <arg name="rq_handle" type="u" direction="in" />
- <arg name="error" type="i" direction="out" />
- </method>
- </interface>
-</node>
+++ /dev/null
-if(NOT ENABLE_TEST)
- return()
-endif(NOT ENABLE_TEST)
-
-file(GLOB_RECURSE TESTS "*.cc")
-
-add_executable(npud_gtest ${TESTS})
-
-set_target_properties(npud_gtest PROPERTIES LINKER_LANGUAGE CXX)
-target_include_directories(npud_gtest PUBLIC ${NPUD_INCLUDE_DIRS})
-target_include_directories(npud_gtest PUBLIC ${GLIB2.0_INCLUDE_DIRS})
-target_link_libraries(npud_gtest PRIVATE ${GLIB2.0_LIBRARIES})
-target_link_libraries(npud_gtest PRIVATE ${LIB_PTHREAD})
-target_link_libraries(npud_gtest PRIVATE npud_core)
-target_link_libraries(npud_gtest PRIVATE gtest_main dl)
-
-install(TARGETS npud_gtest DESTINATION npud-gtest)
+++ /dev/null
-/*
- * Copyright (c) 2022 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 <core/Server.h>
-#include <gtest/gtest.h>
-#include <thread>
-#include <gio/gio.h>
-#include <dbus-core.h>
-#include <iostream>
-
-namespace
-{
-using namespace npud;
-using namespace core;
-
-//
-// DBusTest setup/teardown
-//
-class DBusTest : public ::testing::Test
-{
-protected:
- static void runTask()
- {
- auto &server = Server::instance();
- server.run();
- }
-
- void SetUp() override
- {
- std::thread child = std::thread(runTask);
- child.detach();
- auto &server = Server::instance();
- while (server.isServiceReady() != true)
- {
- }
- }
-
- void TearDown() override
- {
- auto &server = Server::instance();
- if (server.isRunning())
- {
- server.stop();
- }
- }
-
- NpudCore *getProxy()
- {
- GError *error = nullptr;
- NpudCore *proxy = nullptr;
- proxy = npud_core_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
- "org.tizen.npud", "/org/tizen/npud", NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- return proxy;
- }
-
- const std::string &getModel()
- {
- if (model.empty())
- {
- auto model_path = std::getenv("GTEST_MODEL_PATH");
- model = model_path + std::string("/mv1.q8/mv1.q8.tvn");
- }
- if (access(model.c_str(), F_OK) != 0)
- {
- model.clear();
- }
- return model;
- }
-
-private:
- std::string model;
-};
-
-//
-// DBusTest
-//
-TEST_F(DBusTest, get_proxy)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-}
-
-TEST_F(DBusTest, device_get_available_list)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- npud_core_call_device_get_available_list_sync(proxy, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-}
-
-TEST_F(DBusTest, context_create)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-}
-
-TEST_F(DBusTest, context_destroy)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-
- npud_core_call_context_destroy_sync(proxy, out_ctx, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_context_destroy_invalid_ctx)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- guint64 out_ctx = 0;
- npud_core_call_context_destroy_sync(proxy, out_ctx, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-TEST_F(DBusTest, network_create)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- const gchar *model_path = this->getModel().c_str();
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_network_create_invalid_ctx)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- guint64 out_ctx = -1;
- const gchar *model_path = this->getModel().c_str();
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_network_create_invalid_model)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- // Invalid model
- const gchar *model_path = "invalid.tvn";
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-TEST_F(DBusTest, network_destroy)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- const gchar *model_path = this->getModel().c_str();
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- npud_core_call_network_destroy_sync(proxy, out_ctx, out_nw_handle, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_network_destroy_invalid_ctx)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- const gchar *model_path = this->getModel().c_str();
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- // Invalid ctx
- out_ctx = -1;
- npud_core_call_network_destroy_sync(proxy, out_ctx, out_nw_handle, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_network_destroy_invalid_nw_handle)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- guint out_nw_handle = -1;
- npud_core_call_network_destroy_sync(proxy, out_ctx, out_nw_handle, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-TEST_F(DBusTest, request_create)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- const gchar *model_path = this->getModel().c_str();
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- guint out_rq_handle = 0;
- npud_core_call_request_create_sync(proxy, out_ctx, out_nw_handle, &out_rq_handle, &out_error,
- NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_request_create_invalid_ctx)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- const gchar *model_path = this->getModel().c_str();
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- guint out_rq_handle = 0;
- npud_core_call_request_create_sync(proxy, 0, out_nw_handle, &out_rq_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_request_create_invalid_nw)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- guint out_rq_handle = 0;
- npud_core_call_request_create_sync(proxy, out_ctx, 0, &out_rq_handle, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-TEST_F(DBusTest, request_destroy)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- const gchar *model_path = this->getModel().c_str();
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- guint out_rq_handle = 0;
- npud_core_call_request_create_sync(proxy, out_ctx, out_nw_handle, &out_rq_handle, &out_error,
- NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- npud_core_call_request_destroy_sync(proxy, out_ctx, out_rq_handle, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_request_destroy_invalid_ctx)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- const gchar *model_path = this->getModel().c_str();
- guint out_nw_handle = 0;
- npud_core_call_network_create_sync(proxy, out_ctx, model_path, &out_nw_handle, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- guint out_rq_handle = 0;
- npud_core_call_request_create_sync(proxy, out_ctx, out_nw_handle, &out_rq_handle, &out_error,
- NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- npud_core_call_request_destroy_sync(proxy, 0, out_rq_handle, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-TEST_F(DBusTest, neg_request_destroy_invalid_rq)
-{
- NpudCore *proxy = this->getProxy();
- ASSERT_NE(proxy, nullptr);
-
- GError *error = NULL;
- gint out_error = -1;
- gint arg_device_id = 0;
- gint arg_priority = 0;
- guint64 out_ctx = 0;
- npud_core_call_context_create_sync(proxy, arg_device_id, arg_priority, &out_ctx, &out_error, NULL,
- &error);
- if (error)
- {
- g_error_free(error);
- error = NULL;
- }
- ASSERT_EQ(out_error, 0);
-
- out_error = -1;
- npud_core_call_request_destroy_sync(proxy, out_ctx, 0, &out_error, NULL, &error);
- if (error)
- {
- g_error_free(error);
- }
- ASSERT_NE(out_error, 0);
-}
-
-} // unnamed namespace
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "core/Server.h"
-
-#include <gtest/gtest.h>
-#include <thread>
-
-namespace
-{
-using namespace npud;
-using namespace core;
-
-//
-// ServerTest setup/teardown
-//
-class ServerTest : public ::testing::Test
-{
-protected:
- static void runTask()
- {
- auto &server = Server::instance();
- server.run();
- }
-
- void SetUp() override
- {
- std::thread child = std::thread(runTask);
- child.detach();
- auto &server = Server::instance();
- while (server.isRunning() != true)
- {
- }
- }
-
- void TearDown() override
- {
- auto &server = Server::instance();
- if (server.isRunning())
- {
- server.stop();
- }
- }
-};
-
-//
-// ServerTest
-//
-TEST_F(ServerTest, run)
-{
- auto &server = Server::instance();
- ASSERT_EQ(server.isRunning(), true);
-}
-
-TEST_F(ServerTest, stop)
-{
- auto &server = Server::instance();
- server.stop();
- ASSERT_EQ(server.isRunning(), false);
-}
-
-} // unnamed namespace
+++ /dev/null
-/*
- * Copyright (c) 2022 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 "core/Server.h"
-#include "core/Signal.h"
-
-#include <gtest/gtest.h>
-#include <thread>
-#include <csignal>
-
-namespace
-{
-using namespace npud;
-using namespace core;
-
-//
-// SignalTest setup/teardown
-//
-class SignalTest : public ::testing::Test
-{
-protected:
- static void runTask()
- {
- auto &server = Server::instance();
- server.run();
- }
-
- void SetUp() override
- {
- std::thread child = std::thread(runTask);
- child.detach();
- auto &server = Server::instance();
- while (server.isRunning() != true)
- {
- }
- }
-
- void TearDown() override
- {
- auto &server = Server::instance();
- if (server.isRunning())
- {
- server.stop();
- }
- }
-};
-
-//
-// SignalTest
-//
-TEST_F(SignalTest, raise_SIGTERM)
-{
- auto &server = Server::instance();
- ASSERT_EQ(server.isRunning(), true);
- std::raise(SIGTERM);
- ASSERT_EQ(server.isRunning(), false);
-}
-
-TEST_F(SignalTest, raise_SIGINT)
-{
- auto &server = Server::instance();
- ASSERT_EQ(server.isRunning(), true);
- std::raise(SIGINT);
- ASSERT_EQ(server.isRunning(), false);
-}
-
-TEST_F(SignalTest, raise_SIGILL)
-{
- auto &server = Server::instance();
- ASSERT_EQ(server.isRunning(), true);
- std::raise(SIGILL);
- ASSERT_EQ(server.isRunning(), false);
-}
-
-TEST_F(SignalTest, raise_SIGABRT)
-{
- auto &server = Server::instance();
- ASSERT_EQ(server.isRunning(), true);
- std::raise(SIGABRT);
- ASSERT_EQ(server.isRunning(), false);
-}
-
-TEST_F(SignalTest, raise_SIGFPE)
-{
- auto &server = Server::instance();
- ASSERT_EQ(server.isRunning(), true);
- std::raise(SIGFPE);
- ASSERT_EQ(server.isRunning(), false);
-}
-
-} // unnamed namespace