This commit is contained in:
HailoRT-Automation
2024-09-29 11:29:10 +03:00
committed by GitHub
parent 01e4c7f5a7
commit 3d67325209
357 changed files with 7522 additions and 3723 deletions

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
find_program(CCACHE_PROGRAM ccache) find_program(CCACHE_PROGRAM ccache)
find_program(CLACHE_PROGRAM clcache) find_program(CLACHE_PROGRAM clcache)

View File

@@ -125,6 +125,8 @@ typedef enum __attribute__((packed)) {
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_CACHE_INPUT, CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_CACHE_INPUT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_CACHE_OUTPUT, CONTEXT_SWITCH_DEFS__ACTION_TYPE_ACTIVATE_CACHE_OUTPUT,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_CACHE_UPDATED, CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_CACHE_UPDATED,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_SLEEP,
CONTEXT_SWITCH_DEFS__ACTION_TYPE_HALT,
/* Must be last */ /* Must be last */
CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT
@@ -447,6 +449,10 @@ typedef struct {
uint8_t packed_vdma_channel_id; uint8_t packed_vdma_channel_id;
} CONTEXT_SWITCH_DEFS__change_boundary_input_batch_t; } CONTEXT_SWITCH_DEFS__change_boundary_input_batch_t;
typedef struct {
uint32_t sleep_time;
} CONTEXT_SWITCH_DEFS__sleep_action_data_t;
#pragma pack(pop) #pragma pack(pop)
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -1033,6 +1033,8 @@ typedef struct {
uint8_t is_action_list_end; uint8_t is_action_list_end;
uint32_t batch_counter_length; uint32_t batch_counter_length;
uint32_t batch_counter; uint32_t batch_counter;
uint32_t idle_time_length;
uint32_t idle_time;
uint32_t action_list_length; uint32_t action_list_length;
uint8_t action_list[0]; uint8_t action_list[0];
} CONTROL_PROTOCOL__download_context_action_list_response_t; } CONTROL_PROTOCOL__download_context_action_list_response_t;

View File

@@ -769,6 +769,7 @@ Updating rules:
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_EXTERNAL_ACTION_LIST_ADDRESS)\ FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_EXTERNAL_ACTION_LIST_ADDRESS)\
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_CACHE_SIZE)\ FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_CACHE_SIZE)\
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_READ_OFFSET_SIZE)\ FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_READ_OFFSET_SIZE)\
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_SLEEP_TIME)\
\ \
FIRMWARE_MODULE__X(FIRMWARE_MODULE__D2H_EVENT_MANAGER)\ FIRMWARE_MODULE__X(FIRMWARE_MODULE__D2H_EVENT_MANAGER)\
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_MESSAGE_HIGH_PRIORITY_QUEUE_CREATE_FAILED)\ FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_MESSAGE_HIGH_PRIORITY_QUEUE_CREATE_FAILED)\

2
hailort/.gitignore vendored
View File

@@ -1,3 +1,5 @@
build/ build/
build-*x86_64/
build-*aarch64/
dist/ dist/
/external/ /external/

View File

@@ -1,14 +1,12 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
option(HAILO_BUILD_PYBIND "Build Python binding" OFF)
option(HAILO_BUILD_EMULATOR "Build hailort for emulator" OFF) option(HAILO_BUILD_EMULATOR "Build hailort for emulator" OFF)
option(HAILO_BUILD_UT "Build Unit Tests" OFF) option(HAILO_BUILD_UT "Build Unit Tests" OFF)
option(HAILO_BUILD_HW_DEBUG_TOOL "Build hw debug tool" OFF) option(HAILO_INTERNAL_BUILD "Build internal hailort componments" OFF)
option(HAILO_BUILD_GSTREAMER "Compile gstreamer plugins" OFF) option(HAILO_BUILD_GSTREAMER "Compile gstreamer plugins" OFF)
option(HAILO_BUILD_EXAMPLES "Build examples" OFF) option(HAILO_BUILD_EXAMPLES "Build examples" OFF)
option(HAILO_OFFLINE_COMPILATION "Don't download external dependencies" OFF) option(HAILO_OFFLINE_COMPILATION "Don't download external dependencies" OFF)
option(HAILO_BUILD_SERVICE "Build hailort service" OFF) option(HAILO_BUILD_SERVICE "Build hailort service" OFF)
option(HAILO_BUILD_PROFILER "Build hailort profiler" ON)
option(HAILO_COMPILE_WARNING_AS_ERROR "Add compilation flag for treating compilation warnings as errors" OFF) option(HAILO_COMPILE_WARNING_AS_ERROR "Add compilation flag for treating compilation warnings as errors" OFF)
option(HAILO_SUPPORT_PACKAGING "Create HailoRT package (internal)" OFF) option(HAILO_SUPPORT_PACKAGING "Create HailoRT package (internal)" OFF)
option(HAILO_BUILD_DOC "Build doc" OFF) option(HAILO_BUILD_DOC "Build doc" OFF)
@@ -31,7 +29,7 @@ endif()
# Set firmware version # Set firmware version
add_definitions( -DFIRMWARE_VERSION_MAJOR=4 ) add_definitions( -DFIRMWARE_VERSION_MAJOR=4 )
add_definitions( -DFIRMWARE_VERSION_MINOR=18 ) add_definitions( -DFIRMWARE_VERSION_MINOR=19 )
add_definitions( -DFIRMWARE_VERSION_REVISION=0 ) add_definitions( -DFIRMWARE_VERSION_REVISION=0 )
if(HAILO_BUILD_SERVICE) if(HAILO_BUILD_SERVICE)
add_definitions( -DHAILO_SUPPORT_MULTI_PROCESS ) add_definitions( -DHAILO_SUPPORT_MULTI_PROCESS )
@@ -75,8 +73,10 @@ add_subdirectory(hrpc)
add_subdirectory(hrpc_protocol) add_subdirectory(hrpc_protocol)
add_subdirectory(libhailort) add_subdirectory(libhailort)
add_subdirectory(hailortcli) add_subdirectory(hailortcli)
if(HAILO_BUILD_HW_DEBUG_TOOL) if(HAILO_INTERNAL_BUILD)
add_subdirectory(tools/hw_debug) add_subdirectory(tools/hw_debug)
add_subdirectory(tools/pcie_tunnel)
add_subdirectory(tools/loopback_server)
endif() endif()
if(HAILO_BUILD_SERVICE) if(HAILO_BUILD_SERVICE)

View File

@@ -4,7 +4,7 @@
| Catch2 | Catch2 Authors | BSL-1.0 | 2.13.7 | Cloned entire package | https://github.com/catchorg/Catch2 | | Catch2 | Catch2 Authors | BSL-1.0 | 2.13.7 | Cloned entire package | https://github.com/catchorg/Catch2 |
| protobuf | Google Inc. | BSD | 21.12 | Cloned entire package | https://github.com/protocolbuffers/protobuf | | protobuf | Google Inc. | BSD | 21.12 | Cloned entire package | https://github.com/protocolbuffers/protobuf |
| pybind11 | Wenzel Jakob | BSD | 2.10.1 | Cloned entire package | https://github.com/pybind/pybind11 | | pybind11 | Wenzel Jakob | BSD | 2.10.1 | Cloned entire package | https://github.com/pybind/pybind11 |
| spdlog | Gabi Melman | MIT | 1.6.1 | Cloned entire package | https://github.com/gabime/spdlog | | spdlog | Gabi Melman | MIT | 1.14.1 | Cloned entire package | https://github.com/gabime/spdlog |
| folly | Facebook, Inc. and its affiliates | Apache License 2.0 | v2020.08.17.00 | Copied only the file `folly/TokenBucket.h` | https://github.com/facebook/folly | | folly | Facebook, Inc. and its affiliates | Apache License 2.0 | v2020.08.17.00 | Copied only the file `folly/TokenBucket.h` | https://github.com/facebook/folly |
| nlohmann_json_cmake_fetchcontent | ArthurSonzogni | MIT License | v3.9.1 | Cloned entire package | https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent | | nlohmann_json_cmake_fetchcontent | ArthurSonzogni | MIT License | v3.9.1 | Cloned entire package | https://github.com/ArthurSonzogni/nlohmann_json_cmake_fetchcontent |
| readerwriterqueue | Cameron Desrochers | Simplified BSD | 1.0.3 | Cloned entire package | https://github.com/cameron314/readerwriterqueue | | readerwriterqueue | Cameron Desrochers | Simplified BSD | 1.0.3 | Cloned entire package | https://github.com/cameron314/readerwriterqueue |

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
FUNCTION(disable_exceptions target) FUNCTION(disable_exceptions target)
if(WIN32) if(WIN32)

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
function(execute_process_in_clean_env) function(execute_process_in_clean_env)
cmake_parse_arguments(execute_process_in_clean_env "" "RESULT_VARIABLE" "" ${ARGN}) cmake_parse_arguments(execute_process_in_clean_env "" "RESULT_VARIABLE" "" ${ARGN})

View File

@@ -5,7 +5,7 @@ include(FetchContent)
FetchContent_Declare( FetchContent_Declare(
spdlog spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog GIT_REPOSITORY https://github.com/gabime/spdlog
GIT_TAG 22a169bc319ac06948e7ee0be6b9b0ac81386604 GIT_TAG 27cb4c76708608465c413f6d0e6b8d99a4d84302 # version 1.14.1
GIT_SHALLOW TRUE GIT_SHALLOW TRUE
SOURCE_DIR ${HAILO_EXTERNAL_DIR}/spdlog-src SOURCE_DIR ${HAILO_EXTERNAL_DIR}/spdlog-src
SUBBUILD_DIR ${HAILO_EXTERNAL_DIR}/spdlog-subbuild SUBBUILD_DIR ${HAILO_EXTERNAL_DIR}/spdlog-subbuild

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
if(WIN32) if(WIN32)
set(HAILORT_COMMON_OS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/os/windows") set(HAILORT_COMMON_OS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/os/windows")
@@ -15,12 +15,16 @@ set(SRC_FILES
${HAILORT_COMMON_OS_DIR}/socket.cpp ${HAILORT_COMMON_OS_DIR}/socket.cpp
${HAILORT_COMMON_OS_DIR}/process.cpp ${HAILORT_COMMON_OS_DIR}/process.cpp
${HAILORT_COMMON_OS_DIR}/os_utils.cpp ${HAILORT_COMMON_OS_DIR}/os_utils.cpp
${HAILORT_COMMON_OS_DIR}/file_descriptor.cpp
${HAILORT_COMMON_OS_DIR}/mmap_buffer.cpp
${HAILORT_COMMON_OS_DIR}/shared_memory_buffer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/barrier.cpp ${CMAKE_CURRENT_SOURCE_DIR}/barrier.cpp
${CMAKE_CURRENT_SOURCE_DIR}/file_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/file_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/string_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/string_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/event_internal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/event_internal.cpp
${CMAKE_CURRENT_SOURCE_DIR}/fork_support.cpp ${CMAKE_CURRENT_SOURCE_DIR}/fork_support.cpp
${CMAKE_CURRENT_SOURCE_DIR}/buffer_pool.cpp
${CMAKE_CURRENT_SOURCE_DIR}/device_measurements.cpp ${CMAKE_CURRENT_SOURCE_DIR}/device_measurements.cpp
) )
@@ -29,6 +33,8 @@ if(WIN32)
# Windows only modules: # Windows only modules:
set(SRC_FILES ${SRC_FILES} set(SRC_FILES ${SRC_FILES}
${HAILORT_COMMON_OS_DIR}/string_conversion.cpp ${HAILORT_COMMON_OS_DIR}/string_conversion.cpp
${HAILORT_COMMON_OS_DIR}/virtual_alloc_guard.cpp
${HAILORT_COMMON_OS_DIR}/named_mutex_guard.cpp
) )
elseif(UNIX) elseif(UNIX)
# Unix only modules # Unix only modules
@@ -37,4 +43,5 @@ elseif(UNIX)
) )
endif() endif()
set(HAILORT_COMMON_CPP_SOURCES ${SRC_FILES} PARENT_SCOPE) set(HAILORT_COMMON_CPP_SOURCES ${SRC_FILES} PARENT_SCOPE)

View File

@@ -0,0 +1,58 @@
/**
* Copyright (c) 2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file buffer_pool.cpp
* @brief Buffer pool implementation
**/
#include "buffer_pool.hpp"
#include "hailo/hailort.h"
namespace hailort
{
BasicBufferPool::BasicBufferPool(size_t buffer_size, std::vector<BufferPtr> &&buffers,
SpscQueue<BufferPtr> &&free_buffers_queue, size_t buffers_count) :
m_buffer_size(buffer_size),
m_buffers_count(buffers_count),
m_buffers(std::move(buffers)),
m_free_buffers_queue(std::move(free_buffers_queue))
{}
Expected<BufferPtr> BasicBufferPool::acquire_buffer()
{
TRY_WITH_ACCEPTABLE_STATUS(HAILO_SHUTDOWN_EVENT_SIGNALED, auto buffer,
m_free_buffers_queue.dequeue(DEFAULT_TRANSFER_TIMEOUT));
return buffer;
}
size_t BasicBufferPool::current_size()
{
return m_free_buffers_queue.size_approx();
}
hailo_status BasicBufferPool::return_to_pool(BufferPtr buffer)
{
CHECK(buffer->size() == m_buffer_size, HAILO_INTERNAL_FAILURE,
"Buffer size is not the same as expected for pool! ({} != {})", buffer->size(), m_buffer_size);
std::unique_lock<std::mutex> lock(m_mutex);
auto status = m_free_buffers_queue.enqueue(buffer);
CHECK_SUCCESS(status);
return HAILO_SUCCESS;
}
size_t BasicBufferPool::buffers_count()
{
return m_buffers_count;
}
size_t BasicBufferPool::buffer_size()
{
return m_buffer_size;
}
} /* namespace hailort */

View File

@@ -0,0 +1,55 @@
/**
* Copyright (c) 2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file buffer_pool.hpp
* @brief Buffer pool
**/
#ifndef _HAILO_BUFFER_POOL_HPP_
#define _HAILO_BUFFER_POOL_HPP_
#include "hailo/hailort.h"
#include "hailo/hailort_common.hpp"
#include "hailo/buffer.hpp"
#include "hailo/vdevice.hpp"
#include "hailo/dma_mapped_buffer.hpp"
#include "common/thread_safe_queue.hpp"
#include <mutex>
namespace hailort
{
// TODO: HRT-12690 - Make other buffer pools to use this as base class
class BasicBufferPool
{
public:
BasicBufferPool(size_t buffer_size, std::vector<BufferPtr> &&buffers,
SpscQueue<BufferPtr> &&m_free_buffers_queue, size_t buffers_count);
BasicBufferPool(BasicBufferPool &&) = delete;
BasicBufferPool(const BasicBufferPool &) = delete;
BasicBufferPool &operator=(BasicBufferPool &&) = delete;
BasicBufferPool &operator=(const BasicBufferPool &) = delete;
virtual ~BasicBufferPool() = default;
Expected<BufferPtr> acquire_buffer();
size_t current_size();
hailo_status return_to_pool(BufferPtr buffer);
size_t buffers_count();
size_t buffer_size();
private:
size_t m_buffer_size;
size_t m_buffers_count;
std::vector<BufferPtr> m_buffers;
SpscQueue<BufferPtr> m_free_buffers_queue;
std::mutex m_mutex;
};
using BasicBufferPoolPtr = std::shared_ptr<BasicBufferPool>;
} /* namespace hailort */
#endif /* _HAILO_BUFFER_POOL_HPP_ */

View File

@@ -20,6 +20,12 @@
#include <atomic> #include <atomic>
enum class ShouldMeasurePower {
AUTO_DETECT, // auto detect if should measure power, based on device.get_capabilities()
NO,
YES
};
class BaseMeasurement class BaseMeasurement
{ {
public: public:

View File

@@ -0,0 +1,33 @@
/**
* Copyright (c) 2020-2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file env_vars.hpp
* @brief: defines a set of environment variables used in the HailoRT
* **/
#ifndef HAILO_ENV_VARS_HPP_
#define HAILO_ENV_VARS_HPP_
namespace hailort
{
#define HAILORT_LOGGER_PATH_ENV_VAR ("HAILORT_LOGGER_PATH")
#define HAILORT_CONSOLE_LOGGER_LEVEL_ENV_VAR ("HAILORT_CONSOLE_LOGGER_LEVEL")
#define SCHEDULER_MON_ENV_VAR ("HAILO_MONITOR")
#define SCHEDULER_MON_ENV_VAR_VALUE ("1")
#define TRACE_ENV_VAR ("HAILO_TRACE")
#define TRACE_ENV_VAR_VALUE ("scheduler")
#define TRACE_ENV_VAR_TIME_IN_SECONDS_BOUNDED_DUMP ("HAILO_TRACE_TIME_IN_SECONDS_BOUNDED_DUMP")
#define TRACE_ENV_VAR_SIZE_IN_KB_BOUNDED_DUMP ("HAILO_TRACE_SIZE_IN_KB_BOUNDED_DUMP")
#define PROFILER_FILE_ENV_VAR ("HAILO_TRACE_PATH")
} /* namespace hailort */
#endif /* HAILO_ENV_VARS_HPP_ */

View File

@@ -72,7 +72,7 @@ hailo_status FileReader::read(uint8_t *buffer, size_t n)
return m_fstream->good() ? HAILO_SUCCESS : HAILO_FILE_OPERATION_FAILURE; return m_fstream->good() ? HAILO_SUCCESS : HAILO_FILE_OPERATION_FAILURE;
} }
hailo_status FileReader::read_from_offset(size_t offset, MemoryView &dst, size_t size) hailo_status FileReader::read_from_offset(uint64_t offset, MemoryView dst, size_t size)
{ {
assert(nullptr != m_fstream); assert(nullptr != m_fstream);
@@ -93,10 +93,12 @@ hailo_status FileReader::open()
{ {
if (nullptr == m_fstream) { // The first call to open creates the ifstream object if (nullptr == m_fstream) { // The first call to open creates the ifstream object
m_fstream = std::make_shared<std::ifstream>(m_file_path, std::ios::in | std::ios::binary); m_fstream = std::make_shared<std::ifstream>(m_file_path, std::ios::in | std::ios::binary);
return m_fstream->good() ? HAILO_SUCCESS : HAILO_OPEN_FILE_FAILURE; } else {
}
m_fstream->open(m_file_path, std::ios::in | std::ios::binary); m_fstream->open(m_file_path, std::ios::in | std::ios::binary);
return m_fstream->good() ? HAILO_SUCCESS : HAILO_OPEN_FILE_FAILURE; }
CHECK(m_fstream->good(), HAILO_OPEN_FILE_FAILURE, "Failed opening file, path: {}", m_file_path);
return HAILO_SUCCESS;
} }
bool FileReader::is_open() const bool FileReader::is_open() const
@@ -173,7 +175,7 @@ hailo_status BufferReader::read(uint8_t *buffer, size_t n)
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status BufferReader::read_from_offset(size_t offset, MemoryView &dst, size_t size) hailo_status BufferReader::read_from_offset(uint64_t offset, MemoryView dst, size_t size)
{ {
memcpy(dst.data(), m_memview.data() + offset, size); memcpy(dst.data(), m_memview.data() + offset, size);
return HAILO_SUCCESS; return HAILO_SUCCESS;

View File

@@ -35,7 +35,7 @@ class SeekableBytesReader
public: public:
virtual ~SeekableBytesReader() = default; virtual ~SeekableBytesReader() = default;
virtual hailo_status read(uint8_t *buffer, size_t n) = 0; virtual hailo_status read(uint8_t *buffer, size_t n) = 0;
virtual hailo_status read_from_offset(size_t offset, MemoryView &dst, size_t n) = 0; virtual hailo_status read_from_offset(uint64_t offset, MemoryView dst, size_t n) = 0;
virtual hailo_status open() = 0; virtual hailo_status open() = 0;
virtual bool is_open() const = 0; virtual bool is_open() const = 0;
virtual hailo_status seek(size_t position) = 0; virtual hailo_status seek(size_t position) = 0;
@@ -54,7 +54,7 @@ public:
FileReader(const std::string &file_path); FileReader(const std::string &file_path);
virtual hailo_status read(uint8_t *buffer, size_t n); virtual hailo_status read(uint8_t *buffer, size_t n);
virtual hailo_status read_from_offset(size_t offset, MemoryView &dst, size_t n); virtual hailo_status read_from_offset(uint64_t offset, MemoryView dst, size_t n);
virtual hailo_status open(); virtual hailo_status open();
virtual bool is_open() const; virtual bool is_open() const;
virtual hailo_status seek(size_t position); virtual hailo_status seek(size_t position);
@@ -78,7 +78,7 @@ public:
BufferReader(const MemoryView &memview); BufferReader(const MemoryView &memview);
virtual hailo_status read(uint8_t *buffer, size_t n); virtual hailo_status read(uint8_t *buffer, size_t n);
virtual hailo_status read_from_offset(size_t offset, MemoryView &dst, size_t n); virtual hailo_status read_from_offset(uint64_t offset, MemoryView dst, size_t n);
virtual hailo_status open(); virtual hailo_status open();
virtual bool is_open() const; virtual bool is_open() const;
virtual hailo_status seek(size_t position); virtual hailo_status seek(size_t position);

View File

@@ -0,0 +1,106 @@
/**
* Copyright (c) 2020-2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file internal_env_Vars.hpp
* @brief: defines a set of internal environment variables used for development
* **/
#ifndef HAILO_INTERNAL_ENV_VARS_HPP_
#define HAILO_INTERNAL_ENV_VARS_HPP_
namespace hailort
{
/* Service, hrpc-server, comunication */
/* Changes the default address for grpc communication. used for the service-over-ip feature */
#define HAILORT_SERVICE_ADDRESS_ENV_VAR ("HAILORT_SERVICE_ADDRESS")
/* Indicates to the HailoRT gRPC Service whether to use shared memory for the tesnors data.
Note: Cannot be used for service-over-ip */
#define HAILO_SERVICE_SHARED_MEMORY_ENV_VAR ("HAILO_SERVICE_SHARED_MEMORY_OFF")
#define HAILO_SERVICE_SHARED_MEMORY_OFF "1"
/* Defines a costum pcie port for raw-connection */
#define HAILO_CONNECTION_PCIE_PORT_ENV_VAR ("HAILO_CONNECTION_PCIE_PORT")
/* Forces the client to use socket-based communication on a specific address. if not set, socket communicaiton wont be used. */
#define HAILO_SOCKET_COM_ADDR_CLIENT_ENV_VAR ("HAILO_SOCKET_COM_ADDR_CLIENT")
/* Forces the hrpc-server to use socket-based communication on a specific address. if not set, socket communicaiton wont be used. */
#define HAILO_SOCKET_COM_ADDR_SERVER_ENV_VAR ("HAILO_SOCKET_COM_ADDR_SERVER")
/* HAILO_SOCKET_COM_ADDR_CLIENT_ENV_VAR and HAILO_SOCKET_COM_ADDR_SERVER_ENV_VAR can be set to either ip:port ("X.X.X.X:P"),
or to HAILO_SOCKET_COM_ADDR_UNIX_SOCKET which forces working with unix-socket*/
#define HAILO_SOCKET_COM_ADDR_UNIX_SOCKET ("localhost")
/* General */
/* Defines whether the offset of the kv cache will be updated automatically or not.
can be set to either HAILORT_AUTO_UPDATE_CACHE_OFFSET_ENV_VAR_DEFAULT or
HAILORT_AUTO_UPDATE_CACHE_OFFSET_ENV_VAR_DISABLED, or to a numeric value defining the offset update value in bytes`*/
#define HAILORT_AUTO_UPDATE_CACHE_OFFSET_ENV_VAR ("HAILORT_AUTO_UPDATE_CACHE_OFFSET")
#define HAILORT_AUTO_UPDATE_CACHE_OFFSET_ENV_VAR_DEFAULT ("default")
#define HAILORT_AUTO_UPDATE_CACHE_OFFSET_ENV_VAR_DISABLED ("disabled")
/* Used for the internal CLI mode `measure-nnc-performance` */
#define HAILO_CONFIGURE_FOR_HW_INFER_ENV_VAR ("HAILO_CONFIGURE_FOR_HW_INFER")
/* Disable context switch intermediate buffer reuse (naive plan) */
#define HAILO_FORCE_NAIVE_PER_BUFFER_TYPE_ALOCATION_ENV_VAR ("HAILO_FORCE_NAIVE_PER_BUFFER_TYPE_ALOCATION")
/* forces the minimum FD used events to be above `HIGH_FD_OFFSET`.
useful for systems with limitations on the FD count and values */
#define HAILO_USE_HIGH_FD_ENV_VAR ("HAILO_USE_HIGH_FD")
/* Force hailo15m partial cluster layout bitmap (which clusters are activated) */
#define FORCE_LAYOUT_INTERNAL_ENV_VAR ("FORCE_LAYOUT_INTERNAL")
/* Logger */
/* Forces flush of the logger to file on every trace, instead of the default (warnings and above) */
#define HAILORT_LOGGER_FLUSH_EVERY_PRINT_ENV_VAR ("HAILORT_LOGGER_FLUSH_EVERY_PRINT")
/* Force QNX Driver logs to be flushed to specific file - or if left undefined - to stderr */
#define HAILO_QNX_DRIVER_LOG_STDERR_ENV_VAR ("HAILO_QNX_DRIVER_LOG_STDERR")
/* Inference */
/* Disables the hrt-multiplexer */
#define DISABLE_MULTIPLEXER_ENV_VAR ("HAILO_DISABLE_MULTIPLEXER_INTERNAL")
/* Disable scheduler Idle optimization */
#define HAILO_DISABLE_IDLE_OPT_ENV_VAR ("HAILO_DISABLE_IDLE_OPT")
/* Model configuration */
/* If not set, hailort will try to use default desc-size, and only then fallback to larger desc-sizes */
#define HAILO_LEGACY_BOUNDARY_CHANNEL_PAGE_SIZE_ENV_VAR ("HAILO_LEGACY_BOUNDARY_CHANNEL_PAGE_SIZE")
/* If set - Action list will be sent to Firmware SRAM over DDR unrelated to the size of the action list
(Otherwise - DDR will only be used if infinite action list is needed) */
#define DDR_ACTION_LIST_ENV_VAR ("HAILO_DDR_ACTION_LIST")
#define DDR_ACTION_LIST_ENV_VAR_VALUE ("1")
/* Forces using descriptor-lists instead of CCB for config-channels on h1x devices */
#define HAILO_FORCE_CONF_CHANNEL_OVER_DESC_ENV_VAR ("HAILO_FORCE_CONF_CHANNEL_OVER_DESC")
/* Forces using descriptor-lists instead of CCB for inter-context-channels on h1x devices */
#define HAILO_FORCE_INFER_CONTEXT_CHANNEL_OVER_DESC_ENV_VAR ("HAILO_FORCE_INFER_CONTEXT_CHANNEL_OVER_DESC")
/* Forces using descriptor-lists instead of CCB for ddr-channels on h1x devices */
#define HAILO_FORCE_DDR_CHANNEL_OVER_CCB_ENV_VAR ("HAILO_FORCE_DDR_CHANNEL_OVER_CCB")
/* Sets the default power-mode of the ConfiguredNetworkGroups to `HAILO_POWER_MODE_ULTRA_PERFORMANCE` */
#define FORCE_POWER_MODE_ULTRA_PERFORMANCE_ENV_VAR ("FORCE_POWER_MODE_ULTRA_PERFORMANCE")
} /* namespace hailort */
#endif /* HAILO_INTERNAL_ENV_VARS_HPP_ */

View File

@@ -43,6 +43,8 @@ inline std::ostream& operator<<(std::ostream& os, const hailo_status& status)
return os << status_str << "(" << static_cast<int>(status) << ")"; return os << status_str << "(" << static_cast<int>(status) << ")";
} }
template <> struct fmt::formatter<hailo_status> : fmt::ostream_formatter {};
namespace hailort namespace hailort
{ {

View File

@@ -16,7 +16,7 @@
#include "hailo/expected.hpp" #include "hailo/expected.hpp"
#include "common/logger_macros.hpp" #include "common/logger_macros.hpp"
#include "common/utils.hpp" #include "common/utils.hpp"
#include "os/file_descriptor.hpp" #include "common/file_descriptor.hpp"
namespace hailort namespace hailort
{ {
@@ -85,14 +85,14 @@ public:
{ {
auto mmap = MmapBufferImpl::create_shared_memory(length); auto mmap = MmapBufferImpl::create_shared_memory(length);
CHECK_EXPECTED(mmap); CHECK_EXPECTED(mmap);
return MmapBuffer<T>(std::move(mmap.release())); return MmapBuffer<T>(mmap.release());
} }
static Expected<MmapBuffer<T>> create_file_map(size_t length, FileDescriptor &file, uintptr_t offset) static Expected<MmapBuffer<T>> create_file_map(size_t length, FileDescriptor &file, uintptr_t offset)
{ {
auto mmap = MmapBufferImpl::create_file_map(length, file, offset); auto mmap = MmapBufferImpl::create_file_map(length, file, offset);
CHECK_EXPECTED(mmap); CHECK_EXPECTED(mmap);
return MmapBuffer<T>(std::move(mmap.release())); return MmapBuffer<T>(mmap.release());
} }
#if defined(__QNX__) #if defined(__QNX__)

View File

@@ -9,7 +9,7 @@
#include "common/logger_macros.hpp" #include "common/logger_macros.hpp"
#include "os/file_descriptor.hpp" #include "common/file_descriptor.hpp"
#include <errno.h> #include <errno.h>
namespace hailort namespace hailort

View File

@@ -7,9 +7,8 @@
* @brief Wrapper around unix memory mapping (mmap) * @brief Wrapper around unix memory mapping (mmap)
**/ **/
#include "os/mmap_buffer.hpp" #include "common/mmap_buffer.hpp"
#include "vdma/driver/hailort_driver.hpp" #include "vdma/driver/hailort_driver.hpp"
#include "hailo_ioctl_common.h"
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/mman.h> #include <sys/mman.h>

View File

@@ -0,0 +1,112 @@
/**
* Copyright (c) 2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file shared_memory_buffer.cpp
* @brief Posix Shared memory implementation
**/
#include "common/shared_memory_buffer.hpp"
#include "common/utils.hpp"
#include "hailo/hailort.h"
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
namespace hailort
{
#ifndef __ANDROID__
Expected<SharedMemoryBufferPtr> SharedMemoryBuffer::create(size_t size, const std::string &shm_name)
{
auto shm_segment_fd = shm_open(shm_name.c_str(), (O_CREAT | O_RDWR), (S_IRWXU | S_IRWXG | S_IRWXO)); // mode 0777
CHECK_AS_EXPECTED((shm_segment_fd != -1), HAILO_INTERNAL_FAILURE, "Failed to create shared memory object, errno = {}", errno);
auto shm_fd = FileDescriptor(shm_segment_fd);
auto res = ftruncate(shm_fd, size);
CHECK_AS_EXPECTED(res != -1, HAILO_INTERNAL_FAILURE, "Failed to set size of shared memory object, errno = {}", errno);
TRY(auto mmapped_buffer, MmapBuffer<void>::create_file_map(size, shm_fd, 0));
auto result = make_shared_nothrow<SharedMemoryBuffer>(shm_name, std::move(shm_fd), std::move(mmapped_buffer), true);
CHECK_NOT_NULL_AS_EXPECTED(result, HAILO_OUT_OF_HOST_MEMORY);
return result;
}
Expected<SharedMemoryBufferPtr> SharedMemoryBuffer::open(size_t size, const std::string &shm_name)
{
auto shm_segment_fd = shm_open(shm_name.c_str(), O_RDWR, (S_IRWXU | S_IRWXG | S_IRWXO)); // mode 0777
CHECK_AS_EXPECTED((shm_segment_fd != -1), HAILO_INTERNAL_FAILURE, "Failed to open shared memory object, errno = {}", errno);
auto shm_fd = FileDescriptor(shm_segment_fd);
TRY(auto mmapped_buffer, MmapBuffer<void>::create_file_map(size, shm_fd, 0));
auto result = make_shared_nothrow<SharedMemoryBuffer>(shm_name, std::move(shm_fd), std::move(mmapped_buffer), false);
CHECK_NOT_NULL_AS_EXPECTED(result, HAILO_OUT_OF_HOST_MEMORY);
return result;
}
SharedMemoryBuffer::~SharedMemoryBuffer()
{
if (m_memory_owner) {
shm_unlink(m_shm_name.c_str());
}
}
size_t SharedMemoryBuffer::size() const
{
return m_shm_mmap_buffer.size();
}
void *SharedMemoryBuffer::user_address()
{
return m_shm_mmap_buffer.address();
}
std::string SharedMemoryBuffer::shm_name()
{
return m_shm_name;
}
#else
// TODO: HRT-14770 support android shared memory
Expected<SharedMemoryBufferPtr> SharedMemoryBuffer::create(size_t, const std::string &)
{
LOGGER__ERROR("SharedMemoryBuffer::create is not implemented for Android");
return make_unexpected(HAILO_NOT_IMPLEMENTED);
}
Expected<SharedMemoryBufferPtr> SharedMemoryBuffer::open(size_t, const std::string &)
{
LOGGER__ERROR("SharedMemoryBuffer::open is not implemented for Android");
return make_unexpected(HAILO_NOT_IMPLEMENTED);
}
size_t SharedMemoryBuffer::size() const
{
LOGGER__ERROR("SharedMemoryBuffer::size is not implemented for Android");
return 0;
}
void *SharedMemoryBuffer::user_address()
{
LOGGER__ERROR("SharedMemoryBuffer::user_address is not implemented for Android");
return nullptr;
}
std::string SharedMemoryBuffer::shm_name()
{
LOGGER__ERROR("SharedMemoryBuffer::shm_name is not implemented for Android");
return "";
}
#endif
} /* namespace hailort */

View File

@@ -35,13 +35,17 @@ hailo_status Socket::SocketModuleWrapper::free_module()
Expected<Socket> Socket::create(int af, int type, int protocol) Expected<Socket> Socket::create(int af, int type, int protocol)
{ {
TRY(auto module_wrapper, SocketModuleWrapper::create()); TRY(auto module_wrapper, SocketModuleWrapper::create());
auto module_wrapper_ptr = make_shared_nothrow<SocketModuleWrapper>(std::move(module_wrapper));
CHECK_NOT_NULL(module_wrapper_ptr, HAILO_OUT_OF_HOST_MEMORY);
TRY(const auto socket_fd, create_socket_fd(af, type, protocol)); TRY(const auto socket_fd, create_socket_fd(af, type, protocol));
auto obj = Socket(std::move(module_wrapper), socket_fd); auto obj = Socket(module_wrapper_ptr, socket_fd);
return obj; return obj;
} }
Socket::Socket(SocketModuleWrapper &&module_wrapper, const socket_t socket_fd) : Socket::Socket(std::shared_ptr<SocketModuleWrapper> module_wrapper, const socket_t socket_fd) :
m_module_wrapper(std::move(module_wrapper)), m_socket_fd(socket_fd) m_module_wrapper(std::move(module_wrapper)), m_socket_fd(socket_fd)
{ {
} }
@@ -107,6 +111,56 @@ hailo_status Socket::get_sock_name(sockaddr *addr, socklen_t *len)
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status Socket::listen(int backlog)
{
auto res = ::listen(m_socket_fd, backlog);
CHECK(0 == res, HAILO_ETH_FAILURE, "Failed to listen on socket. errno={}", errno);
return HAILO_SUCCESS;
}
Expected<Socket> Socket::accept()
{
auto client_socket = ::accept(m_socket_fd, nullptr, nullptr);
CHECK(client_socket != INVALID_SOCKET, make_unexpected(HAILO_ETH_FAILURE), "Failed to accept connection {}", errno);
return Socket(m_module_wrapper, client_socket);
}
hailo_status Socket::connect(const sockaddr *addr, socklen_t len)
{
int ret = ::connect(m_socket_fd, addr, len);
CHECK(0 == ret, HAILO_ETH_FAILURE, "Failed to connect to socket {}", errno);
return HAILO_SUCCESS;
}
Expected<size_t> Socket::recv(uint8_t *buffer, size_t size, int flags)
{
auto read_bytes = ::recv(m_socket_fd, buffer, size, flags);
CHECK(read_bytes >= 0, make_unexpected(HAILO_ETH_FAILURE), "Failed to read from socket {}", errno);
return Expected<size_t>(read_bytes);
}
Expected<size_t> Socket::send(const uint8_t *buffer, size_t size, int flags)
{
auto bytes_written = ::send(m_socket_fd, buffer, size, flags);
CHECK(bytes_written >= 0, make_unexpected(HAILO_ETH_FAILURE), "Failed to write to socket {}", errno);
return Expected<size_t>(bytes_written);
}
hailo_status Socket::sendall(const uint8_t *buffer, size_t size, int flags)
{
size_t offset = 0;
while (offset < size) {
const auto size_to_write = size - offset;
TRY(auto bytes_written, send(buffer + offset, size_to_write, flags));
if (bytes_written == 0) {
return HAILO_ETH_SEND_FAILURE;
}
offset += bytes_written;
}
return HAILO_SUCCESS;
}
hailo_status Socket::ntop(int af, const void *src, char *dst, socklen_t size) hailo_status Socket::ntop(int af, const void *src, char *dst, socklen_t size)
{ {
CHECK_ARG_NOT_NULL(src); CHECK_ARG_NOT_NULL(src);
@@ -205,6 +259,16 @@ hailo_status Socket::enable_broadcast()
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status Socket::allow_reuse_address()
{
int allow_reuse = 1;
auto socket_rc = setsockopt(m_socket_fd, SOL_SOCKET, SO_REUSEADDR, &allow_reuse, sizeof(allow_reuse));
CHECK(0 == socket_rc, HAILO_ETH_FAILURE, "Cannot set socket to be broadcast");
return HAILO_SUCCESS;
}
hailo_status Socket::send_to(const uint8_t *src_buffer, size_t src_buffer_size, int flags, hailo_status Socket::send_to(const uint8_t *src_buffer, size_t src_buffer_size, int flags,
const sockaddr *dest_addr, socklen_t dest_addr_size, size_t *bytes_sent) const sockaddr *dest_addr, socklen_t dest_addr_size, size_t *bytes_sent)
{ {

View File

@@ -9,8 +9,7 @@
#include "common/logger_macros.hpp" #include "common/logger_macros.hpp"
#include "os/file_descriptor.hpp" #include "common/file_descriptor.hpp"
#include "os/windows/osdep.hpp"
namespace hailort namespace hailort
{ {

View File

@@ -0,0 +1,48 @@
/**
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file mmap_buffer.cpp
* @brief Wrapper around windows memory mapping (mmap). Not implemented yet
**/
#include "common/mmap_buffer.hpp"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
namespace hailort
{
void * const MmapBufferImpl::INVALID_ADDR = NULL;
Expected<MmapBufferImpl> MmapBufferImpl::create_shared_memory(size_t)
{
LOGGER__ERROR("Creating shared memory is not implemented on windows");
return make_unexpected(HAILO_NOT_IMPLEMENTED);
}
Expected<MmapBufferImpl> MmapBufferImpl::create_file_map(size_t size, FileDescriptor &fd, uintptr_t offset)
{
DWORD offset_high = static_cast<DWORD>(offset >> 32); // High 32 bits
DWORD offset_low = static_cast<DWORD>(offset & 0xFFFFFFFF); // Low 32 bits
auto file_view_ptr = MapViewOfFile(fd, FILE_MAP_ALL_ACCESS, offset_high, offset_low, size);
CHECK_AS_EXPECTED((file_view_ptr != nullptr), HAILO_INTERNAL_FAILURE, "Failed to map view of file, error = {}", GetLastError());
return MmapBufferImpl(file_view_ptr, size);
}
hailo_status MmapBufferImpl::unmap()
{
if (m_address != nullptr) {
UnmapViewOfFile(m_address);
m_address = nullptr;
}
return HAILO_SUCCESS;
}
} /* namespace hailort */

View File

@@ -0,0 +1,45 @@
/**
* Copyright (c) 2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file named_mutex_guard.hpp
* @brief Named mutex guard implementation
**/
#include "named_mutex_guard.hpp"
#include "hailo/hailort.h"
#include "common/logger_macros.hpp"
#include "common/utils.hpp"
namespace hailort
{
Expected<std::unique_ptr<NamedMutexGuard>> NamedMutexGuard::create(const std::string &named_mutex)
{
// Create a named mutex
HANDLE mutex_handle = CreateMutex(NULL, FALSE, named_mutex.c_str());
CHECK_AS_EXPECTED(mutex_handle != NULL, HAILO_INTERNAL_FAILURE, "Failed to create named mutex, error = {}", GetLastError());
// Check if the mutex is already acquired by another instance
if (GetLastError() == ERROR_ALREADY_EXISTS) {
LOGGER__ERROR("Another instance of {} is already running", named_mutex);
CloseHandle(mutex_handle);
return make_unexpected(HAILO_INVALID_OPERATION);
}
auto guarded_named_mutex = make_unique_nothrow<NamedMutexGuard>(mutex_handle);
CHECK_NOT_NULL_AS_EXPECTED(guarded_named_mutex, HAILO_OUT_OF_HOST_MEMORY);
return guarded_named_mutex;
}
NamedMutexGuard::NamedMutexGuard(HANDLE mutex_handle) : m_mutex_handle(mutex_handle)
{}
NamedMutexGuard::~NamedMutexGuard()
{
CloseHandle(m_mutex_handle);
}
} /* namespace hailort */

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file named_mutex_guard.hpp
* @brief Named mutex guard
**/
#ifndef _HAILO_NAMED_MUTEX_GUARD_HPP_
#define _HAILO_NAMED_MUTEX_GUARD_HPP_
#include "hailo/hailort.h"
#include "hailo/expected.hpp"
#include <string>
#include <memory>
namespace hailort
{
class NamedMutexGuard
{
public:
static Expected<std::unique_ptr<NamedMutexGuard>> create(const std::string &named_mutex);
NamedMutexGuard(NamedMutexGuard &&) = delete;
NamedMutexGuard(const NamedMutexGuard &) = delete;
NamedMutexGuard &operator=(NamedMutexGuard &&) = delete;
NamedMutexGuard &operator=(const NamedMutexGuard &) = delete;
virtual ~NamedMutexGuard();
NamedMutexGuard(HANDLE mutex_handle);
private:
HANDLE m_mutex_handle;
};
} /* namespace hailort */
#endif /* _HAILO_NAMED_MUTEX_GUARD_HPP_ */

View File

@@ -0,0 +1,67 @@
/**
* Copyright (c) 2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file shared_memory_buffer.cpp
* @brief Shared memory implementaion in Windows.
* Based on Windows docs: https://learn.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory
**/
#include "common/shared_memory_buffer.hpp"
#include "common/utils.hpp"
#include "hailo/hailort.h"
#include <windows.h>
namespace hailort
{
Expected<SharedMemoryBufferPtr> SharedMemoryBuffer::create(size_t size, const std::string &shm_name)
{
HANDLE handle_map_file = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0,
static_cast<DWORD>(size), static_cast<LPCSTR>(shm_name.c_str()));
CHECK_AS_EXPECTED((handle_map_file != nullptr), HAILO_INTERNAL_FAILURE, "Failed to create shared memory object, error = {}", GetLastError());
auto shm_fd = FileDescriptor(handle_map_file);
TRY(auto mmapped_buffer, MmapBuffer<void>::create_file_map(size, shm_fd, 0));
auto result = make_shared_nothrow<SharedMemoryBuffer>(shm_name, std::move(shm_fd), std::move(mmapped_buffer), true);
CHECK_NOT_NULL_AS_EXPECTED(result, HAILO_OUT_OF_HOST_MEMORY);
return result;
}
Expected<SharedMemoryBufferPtr> SharedMemoryBuffer::open(size_t size, const std::string &shm_name)
{
HANDLE handle_map_file = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, static_cast<LPCSTR>(shm_name.c_str()));
CHECK_AS_EXPECTED((handle_map_file != nullptr), HAILO_INTERNAL_FAILURE, "Failed to open file mapping object, error = {}", GetLastError());
auto shm_fd = FileDescriptor(handle_map_file);
TRY(auto mmapped_buffer, MmapBuffer<void>::create_file_map(size, shm_fd, 0));
auto result = make_shared_nothrow<SharedMemoryBuffer>(shm_name, std::move(shm_fd), std::move(mmapped_buffer), false);
CHECK_NOT_NULL_AS_EXPECTED(result, HAILO_OUT_OF_HOST_MEMORY);
return result;
}
SharedMemoryBuffer::~SharedMemoryBuffer()
{}
size_t SharedMemoryBuffer::size() const
{
return m_shm_mmap_buffer.size();
}
void *SharedMemoryBuffer::user_address()
{
return m_shm_mmap_buffer.address();
}
std::string SharedMemoryBuffer::shm_name()
{
return m_shm_name;
}
} /* namespace hailort */

View File

@@ -41,13 +41,17 @@ hailo_status Socket::SocketModuleWrapper::free_module()
Expected<Socket> Socket::create(int af, int type, int protocol) Expected<Socket> Socket::create(int af, int type, int protocol)
{ {
TRY(auto module_wrapper, SocketModuleWrapper::create()); TRY(auto module_wrapper, SocketModuleWrapper::create());
auto module_wrapper_ptr = make_shared_nothrow<SocketModuleWrapper>(std::move(module_wrapper));
CHECK_NOT_NULL(module_wrapper_ptr, HAILO_OUT_OF_HOST_MEMORY);
TRY(const auto socket_fd, create_socket_fd(af, type, protocol)); TRY(const auto socket_fd, create_socket_fd(af, type, protocol));
auto obj = Socket(std::move(module_wrapper), socket_fd); auto obj = Socket(std::move(module_wrapper_ptr), socket_fd);
return std::move(obj); return std::move(obj);
} }
Socket::Socket(SocketModuleWrapper &&module_wrapper, const socket_t socket_fd) : Socket::Socket(std::shared_ptr<SocketModuleWrapper> module_wrapper, const socket_t socket_fd) :
m_module_wrapper(std::move(module_wrapper)), m_socket_fd(socket_fd) m_module_wrapper(std::move(module_wrapper)), m_socket_fd(socket_fd)
{ {
} }
@@ -110,6 +114,56 @@ hailo_status Socket::get_sock_name(sockaddr *addr, socklen_t *len)
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status Socket::listen(int backlog)
{
auto res = ::listen(m_socket_fd, backlog);
CHECK(0 == res, HAILO_ETH_FAILURE, "Failed to listen on socket. errno={}", errno);
return HAILO_SUCCESS;
}
Expected<Socket> Socket::accept()
{
auto client_socket = ::accept(m_socket_fd, nullptr, nullptr);
CHECK(client_socket != INVALID_SOCKET, make_unexpected(HAILO_ETH_FAILURE), "Failed to accept connection {}", errno);
return Socket(m_module_wrapper, client_socket);
}
hailo_status Socket::connect(const sockaddr *addr, socklen_t len)
{
int ret = ::connect(m_socket_fd, addr, len);
CHECK(0 == ret, HAILO_ETH_FAILURE, "Failed to connect to socket {}", errno);
return HAILO_SUCCESS;
}
Expected<size_t> Socket::recv(uint8_t *buffer, size_t size, int flags)
{
auto read_bytes = ::recv(m_socket_fd, reinterpret_cast<char*>(buffer), static_cast<int>(size), flags);
CHECK(read_bytes >= 0, make_unexpected(HAILO_ETH_FAILURE), "Failed to read from socket {}", errno);
return Expected<size_t>(read_bytes);
}
Expected<size_t> Socket::send(const uint8_t *buffer, size_t size, int flags)
{
auto bytes_written = ::send(m_socket_fd, reinterpret_cast<const char*>(buffer), static_cast<int>(size), flags);
CHECK(bytes_written >= 0, make_unexpected(HAILO_ETH_FAILURE), "Failed to write to socket {}", errno);
return Expected<size_t>(bytes_written);
}
hailo_status Socket::sendall(const uint8_t *buffer, size_t size, int flags)
{
size_t offset = 0;
while (offset < size) {
const auto size_to_write = size - offset;
TRY(auto bytes_written, send(buffer + offset, size_to_write, flags));
if (bytes_written == 0) {
return HAILO_ETH_SEND_FAILURE;
}
offset += bytes_written;
}
return HAILO_SUCCESS;
}
hailo_status Socket::ntop(int af, const void *src, char *dst, socklen_t size) hailo_status Socket::ntop(int af, const void *src, char *dst, socklen_t size)
{ {
CHECK_ARG_NOT_NULL(src); CHECK_ARG_NOT_NULL(src);
@@ -190,6 +244,17 @@ hailo_status Socket::enable_broadcast()
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status Socket::allow_reuse_address()
{
int allow_reuse = 1;
auto socket_rc = setsockopt(m_socket_fd, SOL_SOCKET, SO_REUSEADDR,
reinterpret_cast<const char*>(&allow_reuse), sizeof(allow_reuse));
CHECK(0 == socket_rc, HAILO_ETH_FAILURE, "Cannot set socket to be broadcast");
return HAILO_SUCCESS;
}
hailo_status Socket::send_to(const uint8_t *src_buffer, size_t src_buffer_size, int flags, hailo_status Socket::send_to(const uint8_t *src_buffer, size_t src_buffer_size, int flags,
const sockaddr *dest_addr, socklen_t dest_addr_size, size_t *bytes_sent) const sockaddr *dest_addr, socklen_t dest_addr_size, size_t *bytes_sent)
{ {

View File

@@ -7,7 +7,7 @@
* @brief Guard object for VirtualAlloc and VirtualFree * @brief Guard object for VirtualAlloc and VirtualFree
**/ **/
#include "os/windows/virtual_alloc_guard.hpp" #include "virtual_alloc_guard.hpp"
#include "common/logger_macros.hpp" #include "common/logger_macros.hpp"
#include "common/utils.hpp" #include "common/utils.hpp"

View File

@@ -0,0 +1,81 @@
/**
* Copyright (c) 2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file shared_memory_buffer.hpp
* @brief Shared memory buffer
**/
#ifndef _HAILO_SHARED_MEMORY_BUFFER_HPP_
#define _HAILO_SHARED_MEMORY_BUFFER_HPP_
#include "common/file_descriptor.hpp"
#include "common/mmap_buffer.hpp"
#include "hailo/hailort.h"
#include "hailo/expected.hpp"
#include "hailo/buffer.hpp"
namespace hailort
{
#define SHARED_MEMORY_NAME_SEPERATOR '_'
#define INVALID_SHARED_MEMORY_CHAR '/'
#if defined(_MSC_VER)
#define SHARED_MEMORY_NAME_PREFIX "Global\\"
#else
#define SHARED_MEMORY_NAME_PREFIX '/'
#endif
class SharedMemoryBuffer;
using SharedMemoryBufferPtr = std::shared_ptr<SharedMemoryBuffer>;
class SharedMemoryBuffer
{
public:
static Expected<SharedMemoryBufferPtr> create(size_t size, const std::string &shm_name);
static Expected<SharedMemoryBufferPtr> open(size_t size, const std::string &shm_name);
SharedMemoryBuffer(const SharedMemoryBuffer &) = delete;
SharedMemoryBuffer &operator=(SharedMemoryBuffer &&) = delete;
SharedMemoryBuffer &operator=(const SharedMemoryBuffer &) = delete;
virtual ~SharedMemoryBuffer();
SharedMemoryBuffer(const std::string &shm_name, FileDescriptor &&shm_fd, MmapBuffer<void> &&shm_mmap_buffer, bool memory_owner) :
m_shm_name(shm_name),
m_shm_fd(std::move(shm_fd)),
m_shm_mmap_buffer(std::move(shm_mmap_buffer)),
m_memory_owner(memory_owner)
{}
SharedMemoryBuffer(SharedMemoryBuffer&& other) noexcept :
m_shm_name(std::exchange(other.m_shm_name, "")),
m_shm_fd(std::move(other.m_shm_fd)),
m_shm_mmap_buffer(std::move(other.m_shm_mmap_buffer)),
m_memory_owner(std::exchange(other.m_memory_owner, false))
{}
virtual size_t size() const;
virtual void *user_address();
std::string shm_name();
static std::string get_valid_shm_name(const std::string &name)
{
std::string valid_shm_name = name;
std::replace(valid_shm_name.begin(), valid_shm_name.end(), INVALID_SHARED_MEMORY_CHAR, SHARED_MEMORY_NAME_SEPERATOR);
valid_shm_name = SHARED_MEMORY_NAME_PREFIX + valid_shm_name;
return valid_shm_name;
}
private:
std::string m_shm_name;
FileDescriptor m_shm_fd;
MmapBuffer<void> m_shm_mmap_buffer;
bool m_memory_owner;
};
} /* namespace hailort */
#endif /* _HAILO_SHARED_MEMORY_BUFFER_HPP_ */

View File

@@ -50,9 +50,18 @@ public:
hailo_status socket_bind(const sockaddr *addr, socklen_t len); hailo_status socket_bind(const sockaddr *addr, socklen_t len);
hailo_status get_sock_name(sockaddr *addr, socklen_t *len); hailo_status get_sock_name(sockaddr *addr, socklen_t *len);
hailo_status listen(int backlog);
Expected<Socket> accept();
hailo_status connect(const sockaddr *addr, socklen_t len);
Expected<size_t> recv(uint8_t *buffer, size_t size, int flags = 0);
Expected<size_t> send(const uint8_t *buffer, size_t size, int flags = 0);
hailo_status sendall(const uint8_t *buffer, size_t size, int flags = 0);
hailo_status set_recv_buffer_size_max(); hailo_status set_recv_buffer_size_max();
hailo_status set_timeout(const std::chrono::milliseconds timeout_ms, timeval_t *timeout); hailo_status set_timeout(const std::chrono::milliseconds timeout_ms, timeval_t *timeout);
hailo_status enable_broadcast(); hailo_status enable_broadcast();
hailo_status allow_reuse_address();
hailo_status abort(); hailo_status abort();
// TODO: Should these be in udp.cpp? // TODO: Should these be in udp.cpp?
@@ -96,12 +105,12 @@ private:
static hailo_status free_module(); static hailo_status free_module();
}; };
Socket(SocketModuleWrapper &&module_wrapper, const socket_t socket_fd); Socket(std::shared_ptr<SocketModuleWrapper> module_wrapper, const socket_t socket_fd);
static Expected<socket_t> create_socket_fd(int af, int type, int protocol); static Expected<socket_t> create_socket_fd(int af, int type, int protocol);
hailo_status close_socket_fd(); hailo_status close_socket_fd();
// Itialization dependency // Itialization dependency
SocketModuleWrapper m_module_wrapper; std::shared_ptr<SocketModuleWrapper> m_module_wrapper;
socket_t m_socket_fd; socket_t m_socket_fd;
}; };

View File

@@ -12,6 +12,7 @@
#include "hailo/expected.hpp" #include "hailo/expected.hpp"
#include <string> #include <string>
#include <algorithm>
namespace hailort namespace hailort
{ {
@@ -22,6 +23,14 @@ public:
static Expected<uint8_t> to_uint8(const std::string &str, int base); static Expected<uint8_t> to_uint8(const std::string &str, int base);
static Expected<uint32_t> to_uint32(const std::string &str, int base); static Expected<uint32_t> to_uint32(const std::string &str, int base);
static std::string to_lower(const std::string &str)
{
std::string lower_str = str;
std::transform(lower_str.begin(), lower_str.end(), lower_str.begin(),
[](auto ch) { return static_cast<char>(::tolower(ch)); });
return lower_str;
}
static std::string to_hex_string(const uint8_t *array, size_t size, bool uppercase, const std::string &delimiter=""); static std::string to_hex_string(const uint8_t *array, size_t size, bool uppercase, const std::string &delimiter="");
}; };

View File

@@ -0,0 +1,90 @@
/**
* Copyright (c) 2020-2024 Hailo Technologies Ltd. All rights reserved.
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
**/
/**
* @file thread_pool.hpp
* @brief Implementation of thread pool that uses async threads
**/
#ifndef _THREAD_POOL_HPP_
#define _THREAD_POOL_HPP_
#include "async_thread.hpp"
namespace hailort {
class HailoThreadPool {
public:
HailoThreadPool(size_t num_worker_threads) : m_num_threads(num_worker_threads), m_kill_threads(false) {
auto shutdown_event = Event::create_shared(Event::State::not_signalled).release();
for (size_t i = 0; i < num_worker_threads; i++) {
m_threads.emplace_back(std::make_unique<AsyncThread<hailo_status>>(
[this]() -> hailo_status {
while(true) {
std::function<hailo_status()> func;
{
std::unique_lock<std::mutex> lock(m_mutex);
m_cv.wait(lock, [this](){ return (m_kill_threads || !m_queue.empty()); });
if (m_kill_threads && m_queue.empty()) {
return HAILO_SUCCESS;
}
func = std::move(m_queue.front());
m_queue.pop();
}
hailo_status status = func();
if (HAILO_SUCCESS != status) {
LOGGER__ERROR("thread failed with status {}");
}
}
}
));
}
}
HailoThreadPool(const HailoThreadPool &) = delete;
HailoThreadPool(HailoThreadPool &&other) = delete;
HailoThreadPool& operator=(const HailoThreadPool&) = delete;
HailoThreadPool& operator=(HailoThreadPool &&) = delete;
template<class F, class... Args>
void add_job(F&& func, Args&&... args) {
auto job = std::bind(std::forward<F>(func), std::forward<Args>(args)...);
{
std::unique_lock<std::mutex> lock(m_mutex);
if (m_kill_threads) {
LOGGER__ERROR("Cannot add jobs after threadpool has been terminated");
return;
}
m_queue.emplace(job);
}
m_cv.notify_one();
}
~HailoThreadPool() {
{
std::unique_lock<std::mutex> lock(m_mutex);
m_kill_threads = true;
}
m_cv.notify_all();
for (size_t i = 0; i < m_num_threads; i++) {
AsyncThreadPtr<hailo_status> thread = std::move(m_threads[i]);
thread->get();
}
}
private:
size_t m_num_threads;
std::vector<AsyncThreadPtr<hailo_status>> m_threads;
std::queue<std::function<hailo_status()>> m_queue;
std::mutex m_mutex;
std::condition_variable m_cv;
std::atomic<bool> m_kill_threads;
};
} /* namespace hailort*/
#endif // _THREAD_POOL_HPP_

View File

@@ -26,6 +26,7 @@
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
#include <fstream> #include <fstream>
#include <algorithm>
namespace hailort namespace hailort
@@ -261,7 +262,7 @@ inline hailo_status get_status(const Expected<T> &exp)
#define _CHECK_GRPC_STATUS(status, ret_val, warning_msg) \ #define _CHECK_GRPC_STATUS(status, ret_val, warning_msg) \
do { \ do { \
if (!status.ok()) { \ if (!status.ok()) { \
LOGGER__ERROR("CHECK_GRPC_STATUS failed with error code: {}.", status.error_code()); \ LOGGER__ERROR("CHECK_GRPC_STATUS failed with error code: {}.", static_cast<int>(status.error_code())); \
LOGGER__WARNING(warning_msg); \ LOGGER__WARNING(warning_msg); \
return ret_val; \ return ret_val; \
} \ } \

View File

@@ -1,13 +1,13 @@
// SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) AND MIT // SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) AND MIT
/** /**
* Copyright (c) 2019-2022 Hailo Technologies Ltd. All rights reserved. * Copyright (c) 2019-2024 Hailo Technologies Ltd. All rights reserved.
**/ **/
#ifndef _HAILO_IOCTL_COMMON_H_ #ifndef _HAILO_IOCTL_COMMON_H_
#define _HAILO_IOCTL_COMMON_H_ #define _HAILO_IOCTL_COMMON_H_
#define HAILO_DRV_VER_MAJOR 4 #define HAILO_DRV_VER_MAJOR 4
#define HAILO_DRV_VER_MINOR 18 #define HAILO_DRV_VER_MINOR 19
#define HAILO_DRV_VER_REVISION 0 #define HAILO_DRV_VER_REVISION 0
#define _STRINGIFY_EXPANDED( x ) #x #define _STRINGIFY_EXPANDED( x ) #x
@@ -18,6 +18,7 @@
// This value is not easily changeable. // This value is not easily changeable.
// For example: the channel interrupts ioctls assume we have up to 32 channels // For example: the channel interrupts ioctls assume we have up to 32 channels
#define MAX_VDMA_CHANNELS_PER_ENGINE (32) #define MAX_VDMA_CHANNELS_PER_ENGINE (32)
#define VDMA_CHANNELS_PER_ENGINE_PER_DIRECTION (16)
#define MAX_VDMA_ENGINES (3) #define MAX_VDMA_ENGINES (3)
#define SIZE_OF_VDMA_DESCRIPTOR (16) #define SIZE_OF_VDMA_DESCRIPTOR (16)
#define VDMA_DEST_CHANNELS_START (16) #define VDMA_DEST_CHANNELS_START (16)
@@ -37,8 +38,8 @@
#define FW_ACCESS_APP_CPU_CONTROL_MASK (1 << FW_ACCESS_CONTROL_INTERRUPT_SHIFT) #define FW_ACCESS_APP_CPU_CONTROL_MASK (1 << FW_ACCESS_CONTROL_INTERRUPT_SHIFT)
#define FW_ACCESS_DRIVER_SHUTDOWN_SHIFT (2) #define FW_ACCESS_DRIVER_SHUTDOWN_SHIFT (2)
#define FW_ACCESS_DRIVER_SHUTDOWN_MASK (1 << FW_ACCESS_DRIVER_SHUTDOWN_SHIFT) #define FW_ACCESS_DRIVER_SHUTDOWN_MASK (1 << FW_ACCESS_DRIVER_SHUTDOWN_SHIFT)
#define FW_ACCESS_SOC_CONNECT_SHIFT (3) #define FW_ACCESS_SOC_CONTROL_SHIFT (3)
#define FW_ACCESS_SOC_CONNECT_MASK (1 << FW_ACCESS_SOC_CONNECT_SHIFT) #define FW_ACCESS_SOC_CONTROL_MASK (1 << FW_ACCESS_SOC_CONTROL_SHIFT)
#define INVALID_VDMA_CHANNEL (0xff) #define INVALID_VDMA_CHANNEL (0xff)
@@ -245,6 +246,12 @@ struct hailo_desc_list_release_params {
uintptr_t desc_handle; // in uintptr_t desc_handle; // in
}; };
struct hailo_write_action_list_params {
uint8_t *data; // in
size_t size; // in
uint64_t dma_address; // out
};
/* structure used in ioctl HAILO_DESC_LIST_BIND_VDMA_BUFFER */ /* structure used in ioctl HAILO_DESC_LIST_BIND_VDMA_BUFFER */
struct hailo_desc_list_program_params { struct hailo_desc_list_program_params {
size_t buffer_handle; // in size_t buffer_handle; // in
@@ -508,6 +515,7 @@ struct hailo_vdma_launch_transfer_params {
/* structure used in ioctl HAILO_SOC_CONNECT */ /* structure used in ioctl HAILO_SOC_CONNECT */
struct hailo_soc_connect_params { struct hailo_soc_connect_params {
uint16_t port_number; // in
uint8_t input_channel_index; // out uint8_t input_channel_index; // out
uint8_t output_channel_index; // out uint8_t output_channel_index; // out
uintptr_t input_desc_handle; // in uintptr_t input_desc_handle; // in
@@ -522,6 +530,7 @@ struct hailo_soc_close_params {
/* structure used in ioctl HAILO_PCI_EP_ACCEPT */ /* structure used in ioctl HAILO_PCI_EP_ACCEPT */
struct hailo_pci_ep_accept_params { struct hailo_pci_ep_accept_params {
uint16_t port_number; // in
uint8_t input_channel_index; // out uint8_t input_channel_index; // out
uint8_t output_channel_index; // out uint8_t output_channel_index; // out
uintptr_t input_desc_handle; // in uintptr_t input_desc_handle; // in
@@ -562,6 +571,7 @@ struct tCompatibleHailoIoctlData
struct hailo_soc_close_params SocCloseParams; struct hailo_soc_close_params SocCloseParams;
struct hailo_pci_ep_accept_params AcceptParams; struct hailo_pci_ep_accept_params AcceptParams;
struct hailo_pci_ep_close_params PciEpCloseParams; struct hailo_pci_ep_close_params PciEpCloseParams;
struct hailo_write_action_list_params WriteActionListParams;
} Buffer; } Buffer;
}; };
#endif // _MSC_VER #endif // _MSC_VER
@@ -632,6 +642,7 @@ enum hailo_nnc_ioctl_code {
HAILO_DISABLE_NOTIFICATION_CODE, HAILO_DISABLE_NOTIFICATION_CODE,
HAILO_READ_LOG_CODE, HAILO_READ_LOG_CODE,
HAILO_RESET_NN_CORE_CODE, HAILO_RESET_NN_CORE_CODE,
HAILO_WRITE_ACTION_LIST_CODE,
// Must be last // Must be last
HAILO_NNC_IOCTL_MAX_NR HAILO_NNC_IOCTL_MAX_NR
@@ -642,6 +653,7 @@ enum hailo_nnc_ioctl_code {
#define HAILO_DISABLE_NOTIFICATION _IO_(HAILO_NNC_IOCTL_MAGIC, HAILO_DISABLE_NOTIFICATION_CODE) #define HAILO_DISABLE_NOTIFICATION _IO_(HAILO_NNC_IOCTL_MAGIC, HAILO_DISABLE_NOTIFICATION_CODE)
#define HAILO_READ_LOG _IOWR_(HAILO_NNC_IOCTL_MAGIC, HAILO_READ_LOG_CODE, struct hailo_read_log_params) #define HAILO_READ_LOG _IOWR_(HAILO_NNC_IOCTL_MAGIC, HAILO_READ_LOG_CODE, struct hailo_read_log_params)
#define HAILO_RESET_NN_CORE _IO_(HAILO_NNC_IOCTL_MAGIC, HAILO_RESET_NN_CORE_CODE) #define HAILO_RESET_NN_CORE _IO_(HAILO_NNC_IOCTL_MAGIC, HAILO_RESET_NN_CORE_CODE)
#define HAILO_WRITE_ACTION_LIST _IOW_(HAILO_NNC_IOCTL_MAGIC, HAILO_WRITE_ACTION_LIST_CODE, struct hailo_write_action_list_params)
enum hailo_soc_ioctl_code { enum hailo_soc_ioctl_code {
HAILO_SOC_IOCTL_CONNECT_CODE, HAILO_SOC_IOCTL_CONNECT_CODE,

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/spdlog.cmake) include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/spdlog.cmake)
include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/readerwriterqueue.cmake) include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/readerwriterqueue.cmake)
@@ -10,32 +10,22 @@ set(HAILORT_SERVER_SOURCES
hailort_server.cpp hailort_server.cpp
${HRPC_CPP_SOURCES} ${HRPC_CPP_SOURCES}
${HRPC_PROTOCOL_CPP_SOURCES} ${HRPC_PROTOCOL_CPP_SOURCES}
${HAILORT_COMMON_OS_DIR}/os_utils.cpp
${HAILORT_SERVICE_DIR}/cng_buffer_pool.cpp ${HAILORT_SERVICE_DIR}/cng_buffer_pool.cpp
${HAILORT_COMMON_DIR}/common/event_internal.cpp
${HAILO_FULL_OS_DIR}/event.cpp # TODO HRT-10681: move to common ${HAILO_FULL_OS_DIR}/event.cpp # TODO HRT-10681: move to common
${DRIVER_OS_DIR}/driver_os_specific.cpp ${DRIVER_OS_DIR}/driver_os_specific.cpp
${HAILO_OS_DIR}/file_descriptor.cpp
${HAILO_OS_DIR}/mmap_buffer.cpp
${HAILORT_SRC_DIR}/vdma/pcie_session.cpp ${HAILORT_SRC_DIR}/vdma/pcie_session.cpp
${HAILORT_SRC_DIR}/vdma/memory/descriptor_list.cpp ${HAILORT_SRC_DIR}/vdma/memory/descriptor_list.cpp
${HAILORT_SRC_DIR}/vdma/memory/mapped_buffer.cpp ${HAILORT_SRC_DIR}/vdma/memory/mapped_buffer.cpp
${HAILORT_SRC_DIR}/vdma/memory/dma_able_buffer.cpp ${HAILORT_SRC_DIR}/vdma/memory/dma_able_buffer.cpp
${HAILORT_SRC_DIR}/vdma/memory/vdma_edge_layer.cpp
${HAILORT_SRC_DIR}/vdma/driver/hailort_driver.cpp ${HAILORT_SRC_DIR}/vdma/driver/hailort_driver.cpp
${HAILORT_SRC_DIR}/vdma/channel/interrupts_dispatcher.cpp ${HAILORT_SRC_DIR}/vdma/channel/interrupts_dispatcher.cpp
${HAILORT_SRC_DIR}/vdma/channel/transfer_launcher.cpp ${HAILORT_SRC_DIR}/vdma/channel/transfer_launcher.cpp
${HAILORT_SRC_DIR}/vdma/channel/boundary_channel.cpp ${HAILORT_SRC_DIR}/vdma/channel/boundary_channel.cpp
${HAILORT_SRC_DIR}/vdma/channel/channels_group.cpp ${HAILORT_SRC_DIR}/vdma/channel/channels_group.cpp
${HAILORT_SRC_DIR}/stream_common/transfer_common.cpp ${HAILORT_SRC_DIR}/vdma/channel/transfer_common.cpp
${HAILORT_COMMON_CPP_SOURCES}
) )
if(WIN32)
# hailort_driver.cpp in windows depends on string_conversion
# dma_able_buffer.cpp in windows depends on virtual_alloc_guard
set(HAILORT_SERVER_SOURCES ${HAILORT_SERVER_SOURCES}
${HAILORT_COMMON_OS_DIR}/string_conversion.cpp
${HAILO_FULL_OS_DIR}/virtual_alloc_guard.cpp)
endif()
add_executable(hailort_server ${HAILORT_SERVER_SOURCES}) add_executable(hailort_server ${HAILORT_SERVER_SOURCES})
target_include_directories(hailort_server PRIVATE target_include_directories(hailort_server PRIVATE
@@ -53,3 +43,9 @@ target_link_libraries(hailort_server PRIVATE
spdlog::spdlog spdlog::spdlog
readerwriterqueue readerwriterqueue
) )
if(WIN32)
target_link_libraries(hailort_server PRIVATE Ws2_32 Iphlpapi Shlwapi winmm.lib)
elseif(NOT CMAKE_SYSTEM_NAME STREQUAL Android)
# TODO: HRT-14770 fix android build
target_link_libraries(hailort_server PRIVATE rt)
endif()

View File

@@ -41,6 +41,16 @@ using namespace hailort;
return make_unexpected(HAILO_INTERNAL_FAILURE); \ return make_unexpected(HAILO_INTERNAL_FAILURE); \
} \ } \
} while (0) } while (0)
#define CHECK_AS_HRPC_STATUS(_cond, _status, T) \
do { \
if (!(_cond)) { \
LOGGER__ERROR("CHECK_AS_HRPC_STATUS failed, status: {}", _status); \
auto reply = T::serialize_reply(_status); \
if (reply) return reply; \
LOGGER__CRITICAL("Failed to create reply with status: {}", reply.status()); \
return make_unexpected(HAILO_INTERNAL_FAILURE); \
} \
} while (0)
#define __HAILO_CONCAT(x, y) x ## y #define __HAILO_CONCAT(x, y) x ## y
#define _HAILO_CONCAT(x, y) __HAILO_CONCAT(x, y) #define _HAILO_CONCAT(x, y) __HAILO_CONCAT(x, y)
@@ -115,7 +125,7 @@ hailo_status hrpc::HailoRTServer::cleanup_client_resources(RpcConnection client_
Expected<std::unique_ptr<hrpc::HailoRTServer>> hrpc::HailoRTServer::create_unique() Expected<std::unique_ptr<hrpc::HailoRTServer>> hrpc::HailoRTServer::create_unique()
{ {
TRY(auto connection_context, ConnectionContext::create_shared(true)); TRY(auto connection_context, ConnectionContext::create_server_shared());
auto res = make_unique_nothrow<HailoRTServer>(connection_context); auto res = make_unique_nothrow<HailoRTServer>(connection_context);
CHECK_NOT_NULL(res, HAILO_OUT_OF_HOST_MEMORY); CHECK_NOT_NULL(res, HAILO_OUT_OF_HOST_MEMORY);
return res; return res;
@@ -158,6 +168,7 @@ int main()
TRY_AS_HRPC_STATUS(auto tuple, CreateInferModelSerializer::deserialize_request(request), CreateInferModelSerializer); TRY_AS_HRPC_STATUS(auto tuple, CreateInferModelSerializer::deserialize_request(request), CreateInferModelSerializer);
auto vdevice_handle = std::get<0>(tuple); auto vdevice_handle = std::get<0>(tuple);
uint64_t hef_size = std::get<1>(tuple); uint64_t hef_size = std::get<1>(tuple);
auto name = std::get<2>(tuple);
assert(hef_size <= SIZE_MAX); assert(hef_size <= SIZE_MAX);
TRY_AS_HRPC_STATUS(auto hef_buffer, Buffer::create(static_cast<size_t>(hef_size), BufferStorageParams::create_dma()), CreateInferModelSerializer); TRY_AS_HRPC_STATUS(auto hef_buffer, Buffer::create(static_cast<size_t>(hef_size), BufferStorageParams::create_dma()), CreateInferModelSerializer);
@@ -166,8 +177,8 @@ int main()
CHECK_SUCCESS_AS_HRPC_STATUS(status, CreateInferModelSerializer); CHECK_SUCCESS_AS_HRPC_STATUS(status, CreateInferModelSerializer);
auto &vdevice_manager = ServiceResourceManager<VDevice>::get_instance(); auto &vdevice_manager = ServiceResourceManager<VDevice>::get_instance();
auto lambda = [view = MemoryView(hef_buffer)] (std::shared_ptr<VDevice> vdevice) { auto lambda = [view = MemoryView(hef_buffer), &name] (std::shared_ptr<VDevice> vdevice) {
return vdevice->create_infer_model(view); return vdevice->create_infer_model(view, name);
}; };
auto infer_model = vdevice_manager.execute<Expected<std::shared_ptr<InferModel>>>(vdevice_handle, lambda); auto infer_model = vdevice_manager.execute<Expected<std::shared_ptr<InferModel>>>(vdevice_handle, lambda);
CHECK_EXPECTED_AS_HRPC_STATUS(infer_model, CreateInferModelSerializer); CHECK_EXPECTED_AS_HRPC_STATUS(infer_model, CreateInferModelSerializer);
@@ -434,10 +445,10 @@ int main()
auto bindings_lambda = [] (std::shared_ptr<ConfiguredInferModel> configured_infer_model) { auto bindings_lambda = [] (std::shared_ptr<ConfiguredInferModel> configured_infer_model) {
return configured_infer_model->create_bindings(); return configured_infer_model->create_bindings();
}; };
TRY_AS_HRPC_STATUS(auto request_tuple, RunAsyncSerializer::deserialize_request(request), RunAsyncSerializer); TRY_AS_HRPC_STATUS(auto request_struct, RunAsyncSerializer::deserialize_request(request), RunAsyncSerializer);
auto configured_infer_model_handle = std::get<0>(request_tuple); auto configured_infer_model_handle = request_struct.configured_infer_model_handle;
auto infer_model_handle = std::get<1>(request_tuple); auto infer_model_handle = request_struct.infer_model_handle;
auto callback_id = std::get<2>(request_tuple); auto callback_id = request_struct.callback_handle;
auto bindings = cim_manager.execute<Expected<ConfiguredInferModel::Bindings>>(configured_infer_model_handle, bindings_lambda); auto bindings = cim_manager.execute<Expected<ConfiguredInferModel::Bindings>>(configured_infer_model_handle, bindings_lambda);
CHECK_EXPECTED_AS_HRPC_STATUS(bindings, RunAsyncSerializer); CHECK_EXPECTED_AS_HRPC_STATUS(bindings, RunAsyncSerializer);
@@ -452,17 +463,28 @@ int main()
std::vector<BufferPtr> inputs; // TODO: add infer vector pool std::vector<BufferPtr> inputs; // TODO: add infer vector pool
inputs.reserve(infer_model_info->inputs_names.size()); inputs.reserve(infer_model_info->inputs_names.size());
uint32_t buffer_size_index = 0;
for (const auto &input_name : infer_model_info->inputs_names) { for (const auto &input_name : infer_model_info->inputs_names) {
TRY_AS_HRPC_STATUS(auto input, bindings->input(input_name), RunAsyncSerializer); TRY_AS_HRPC_STATUS(auto input, bindings->input(input_name), RunAsyncSerializer);
TRY_AS_HRPC_STATUS(auto buffer_ptr, buffer_pool_per_cim[configured_infer_model_handle]->acquire_buffer(input_name), TRY_AS_HRPC_STATUS(auto buffer_ptr, buffer_pool_per_cim[configured_infer_model_handle]->acquire_buffer(input_name),
RunAsyncSerializer); RunAsyncSerializer);
auto status = server_context->connection().read_buffer(MemoryView(*buffer_ptr)); uint32_t read_size = 0;
while (read_size < buffer_ptr->size()) {
uint32_t current_size = request_struct.input_buffer_sizes[buffer_size_index++];
CHECK_AS_HRPC_STATUS(read_size + current_size <= buffer_ptr->size(), HAILO_INTERNAL_FAILURE,
RunAsyncSerializer);
auto status = server_context->connection().read_buffer(MemoryView(buffer_ptr->data() + read_size, current_size));
CHECK_SUCCESS_AS_HRPC_STATUS(status, RunAsyncSerializer); CHECK_SUCCESS_AS_HRPC_STATUS(status, RunAsyncSerializer);
read_size += current_size;
}
inputs.emplace_back(buffer_ptr); inputs.emplace_back(buffer_ptr);
status = input.set_buffer(MemoryView(*buffer_ptr)); auto status = input.set_buffer(MemoryView(*buffer_ptr));
CHECK_SUCCESS_AS_HRPC_STATUS(status, RunAsyncSerializer); CHECK_SUCCESS_AS_HRPC_STATUS(status, RunAsyncSerializer);
} }
@@ -488,7 +510,16 @@ int main()
return configured_infer_model->run_async(bindings, return configured_infer_model->run_async(bindings,
[callback_id, server_context, inputs, outputs, &buffer_pool_per_cim, configured_infer_model_handle, infer_model_info] [callback_id, server_context, inputs, outputs, &buffer_pool_per_cim, configured_infer_model_handle, infer_model_info]
(const AsyncInferCompletionInfo &completion_info) { (const AsyncInferCompletionInfo &completion_info) {
auto status = server_context->trigger_callback(callback_id, completion_info.status, [outputs, completion_info] (hrpc::RpcConnection connection) -> hailo_status { for (uint32_t i = 0; i < inputs.size(); i++) {
auto status = buffer_pool_per_cim[configured_infer_model_handle]->return_to_pool(infer_model_info->inputs_names[i], inputs[i]);
if (status != HAILO_SUCCESS) {
LOGGER__CRITICAL("return_to_pool failed for input {}, status = {}. Server should restart!", infer_model_info->inputs_names[i], status);
return;
}
}
auto status = server_context->trigger_callback(callback_id, completion_info.status, configured_infer_model_handle,
[outputs, completion_info] (hrpc::RpcConnection connection) -> hailo_status {
if (HAILO_SUCCESS == completion_info.status) { if (HAILO_SUCCESS == completion_info.status) {
for (auto output : outputs) { for (auto output : outputs) {
auto status = connection.write_buffer(MemoryView(*output)); auto status = connection.write_buffer(MemoryView(*output));
@@ -503,13 +534,6 @@ int main()
LOGGER__CRITICAL("Error {} returned from connection.write(). Server Should restart!", status); LOGGER__CRITICAL("Error {} returned from connection.write(). Server Should restart!", status);
} }
for (uint32_t i = 0; i < inputs.size(); i++) {
status = buffer_pool_per_cim[configured_infer_model_handle]->return_to_pool(infer_model_info->inputs_names[i], inputs[i]);
if (status != HAILO_SUCCESS) {
LOGGER__CRITICAL("return_to_pool failed for input {}, status = {}. Server should restart!", infer_model_info->inputs_names[i], status);
return;
}
}
for (uint32_t i = 0; i < outputs.size(); i++) { for (uint32_t i = 0; i < outputs.size(); i++) {
status = buffer_pool_per_cim[configured_infer_model_handle]->return_to_pool(infer_model_info->outputs_names[i], outputs[i]); status = buffer_pool_per_cim[configured_infer_model_handle]->return_to_pool(infer_model_info->outputs_names[i], outputs[i]);
if (status != HAILO_SUCCESS) { if (status != HAILO_SUCCESS) {
@@ -527,6 +551,52 @@ int main()
TRY_AS_HRPC_STATUS(auto reply, RunAsyncSerializer::serialize_reply(HAILO_SUCCESS), RunAsyncSerializer); TRY_AS_HRPC_STATUS(auto reply, RunAsyncSerializer::serialize_reply(HAILO_SUCCESS), RunAsyncSerializer);
return reply; return reply;
}); });
dispatcher.register_action(HailoRpcActionID::DEVICE__CREATE,
[] (const MemoryView &request, hrpc::ServerContextPtr /*server_context*/) -> Expected<Buffer> {
auto status = CreateDeviceSerializer::deserialize_request(request);
CHECK_SUCCESS_AS_HRPC_STATUS(status, CreateDeviceSerializer);
TRY_AS_HRPC_STATUS(auto device, Device::create(), CreateDeviceSerializer);
auto &manager = ServiceResourceManager<Device>::get_instance();
auto id = manager.register_resource(SINGLE_CLIENT_PID, std::move(device));
auto reply = CreateDeviceSerializer::serialize_reply(HAILO_SUCCESS, id);
return reply;
});
dispatcher.register_action(HailoRpcActionID::DEVICE__DESTROY,
[] (const MemoryView &request, hrpc::ServerContextPtr /*server_context*/) -> Expected<Buffer> {
auto &manager = ServiceResourceManager<Device>::get_instance();
TRY_AS_HRPC_STATUS(auto device_handle, DestroyDeviceSerializer::deserialize_request(request), DestroyDeviceSerializer);
(void)manager.release_resource(device_handle, SINGLE_CLIENT_PID);
TRY_AS_HRPC_STATUS(auto reply, DestroyDeviceSerializer::serialize_reply(HAILO_SUCCESS), DestroyDeviceSerializer);
return reply;
});
dispatcher.register_action(HailoRpcActionID::DEVICE__IDENTIFY,
[] (const MemoryView &request, hrpc::ServerContextPtr /*server_context*/) -> Expected<Buffer> {
TRY_AS_HRPC_STATUS(auto device_handle, IdentifyDeviceSerializer::deserialize_request(request), IdentifyDeviceSerializer);
auto &manager = ServiceResourceManager<Device>::get_instance();
auto device_lambda = [] (std::shared_ptr<Device> device) {
return device->identify();
};
TRY_AS_HRPC_STATUS(auto identity,
manager.execute<Expected<hailo_device_identity_t>>(device_handle, device_lambda), IdentifyDeviceSerializer);
TRY_AS_HRPC_STATUS(auto reply, IdentifyDeviceSerializer::serialize_reply(HAILO_SUCCESS, identity), IdentifyDeviceSerializer);
return reply;
});
dispatcher.register_action(HailoRpcActionID::DEVICE__EXTENDED_INFO,
[] (const MemoryView &request, hrpc::ServerContextPtr /*server_context*/) -> Expected<Buffer> {
TRY_AS_HRPC_STATUS(auto device_handle, ExtendedDeviceInfoSerializer::deserialize_request(request), ExtendedDeviceInfoSerializer);
auto &manager = ServiceResourceManager<Device>::get_instance();
auto device_lambda = [] (std::shared_ptr<Device> device) {
return device->get_extended_device_information();
};
TRY_AS_HRPC_STATUS(auto extended_info,
manager.execute<Expected<hailo_extended_device_information_t>>(device_handle, device_lambda), ExtendedDeviceInfoSerializer);
TRY_AS_HRPC_STATUS(auto reply, ExtendedDeviceInfoSerializer::serialize_reply(HAILO_SUCCESS, extended_info), ExtendedDeviceInfoSerializer);
return reply;
});
server->set_dispatcher(dispatcher); server->set_dispatcher(dispatcher);
auto status = server->serve(); auto status = server->serve();

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/spdlog.cmake) include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/spdlog.cmake)
@@ -30,6 +30,8 @@ target_link_libraries(hailort_service
if(WIN32) if(WIN32)
# Needed in order to compile eth utils (we compile here ${HAILORT_COMMON_CPP_SOURCES}, consider removing) # Needed in order to compile eth utils (we compile here ${HAILORT_COMMON_CPP_SOURCES}, consider removing)
target_link_libraries(hailort_service Iphlpapi Shlwapi Kernel32 Advapi32) target_link_libraries(hailort_service Iphlpapi Shlwapi Kernel32 Advapi32)
elseif(NOT CMAKE_SYSTEM_NAME STREQUAL Android)
target_link_libraries(hailort_service rt)
endif() endif()
target_include_directories(hailort_service target_include_directories(hailort_service

View File

@@ -14,9 +14,8 @@
namespace hailort namespace hailort
{ {
Expected<BasicBufferPoolPtr> ServiceNetworkGroupBufferPool::create_stream_buffer_pool(size_t buffer_size,
Expected<std::shared_ptr<ServiceStreamBufferPool>> ServiceStreamBufferPool::create(uint32_t vdevice_handle, size_t buffer_count, hailo_dma_buffer_direction_t direction, EventPtr shutdown_event)
size_t buffer_size, size_t buffer_count, hailo_dma_buffer_direction_t direction, EventPtr shutdown_event)
{ {
auto map_buffer_lambda = [direction](std::shared_ptr<VDevice> vdevice, BufferPtr buffer) { auto map_buffer_lambda = [direction](std::shared_ptr<VDevice> vdevice, BufferPtr buffer) {
return DmaMappedBuffer::create(*vdevice, buffer->data(), buffer->size(), direction); return DmaMappedBuffer::create(*vdevice, buffer->data(), buffer->size(), direction);
@@ -26,59 +25,28 @@ Expected<std::shared_ptr<ServiceStreamBufferPool>> ServiceStreamBufferPool::crea
TRY(auto free_buffers_queue, TRY(auto free_buffers_queue,
SpscQueue<BufferPtr>::create(buffer_count, shutdown_event, DEFAULT_TRANSFER_TIMEOUT)); SpscQueue<BufferPtr>::create(buffer_count, shutdown_event, DEFAULT_TRANSFER_TIMEOUT));
std::vector<AllocatedMappedBuffer> buffers; std::vector<BufferPtr> buffers;
buffers.reserve(buffer_count); buffers.reserve(buffer_count);
for (size_t i = 0; i < buffer_count; i++) { for (size_t i = 0; i < buffer_count; i++) {
TRY(auto buffer, Buffer::create_shared(buffer_size, BufferStorageParams::create_dma())); TRY(auto buffer, Buffer::create_shared(buffer_size, BufferStorageParams::create_dma()));
TRY(auto mapped_buffer, TRY(auto mapped_buffer,
vdevice_manager.execute<Expected<DmaMappedBuffer>>(vdevice_handle, map_buffer_lambda, buffer)); vdevice_manager.execute<Expected<DmaMappedBuffer>>(m_vdevice_handle, map_buffer_lambda, buffer));
auto status = free_buffers_queue.enqueue(buffer); auto status = free_buffers_queue.enqueue(buffer);
CHECK_SUCCESS(status); CHECK_SUCCESS(status);
buffers.emplace_back(AllocatedMappedBuffer{ buffer, std::move(mapped_buffer)}); buffers.emplace_back(buffer);
m_mapped_buffers.emplace_back(DmaMappedBuffer(std::move(mapped_buffer)));
} }
auto buffer_pool_ptr = make_shared_nothrow<ServiceStreamBufferPool>(buffer_size, std::move(buffers), auto buffer_pool_ptr = make_shared_nothrow<BasicBufferPool>(buffer_size, std::move(buffers),
std::move(free_buffers_queue), buffer_count); std::move(free_buffers_queue), buffer_count);
CHECK_NOT_NULL_AS_EXPECTED(buffer_pool_ptr, HAILO_OUT_OF_HOST_MEMORY); CHECK_NOT_NULL_AS_EXPECTED(buffer_pool_ptr, HAILO_OUT_OF_HOST_MEMORY);
return buffer_pool_ptr; return buffer_pool_ptr;
} }
ServiceStreamBufferPool::ServiceStreamBufferPool(size_t buffer_size, std::vector<AllocatedMappedBuffer> &&buffers,
SpscQueue<BufferPtr> &&free_buffers_queue, size_t buffers_count) :
m_buffer_size(buffer_size),
m_buffers_count(buffers_count),
m_buffers(std::move(buffers)),
m_free_buffers_queue(std::move(free_buffers_queue))
{}
Expected<BufferPtr> ServiceStreamBufferPool::acquire_buffer()
{
TRY_WITH_ACCEPTABLE_STATUS(HAILO_SHUTDOWN_EVENT_SIGNALED, auto buffer,
m_free_buffers_queue.dequeue(DEFAULT_TRANSFER_TIMEOUT));
return buffer;
}
hailo_status ServiceStreamBufferPool::return_to_pool(BufferPtr buffer)
{
CHECK(buffer->size() == m_buffer_size, HAILO_INTERNAL_FAILURE,
"Buffer size is not the same as expected for pool! ({} != {})", buffer->size(), m_buffer_size);
std::unique_lock<std::mutex> lock(m_mutex);
auto status = m_free_buffers_queue.enqueue(buffer);
CHECK_SUCCESS(status);
return HAILO_SUCCESS;
}
size_t ServiceStreamBufferPool::buffers_count()
{
return m_buffers_count;
}
Expected<std::shared_ptr<ServiceNetworkGroupBufferPool>> ServiceNetworkGroupBufferPool::create(uint32_t vdevice_handle) Expected<std::shared_ptr<ServiceNetworkGroupBufferPool>> ServiceNetworkGroupBufferPool::create(uint32_t vdevice_handle)
{ {
TRY(auto shutdown_event, Event::create_shared(Event::State::not_signalled)); TRY(auto shutdown_event, Event::create_shared(Event::State::not_signalled));
@@ -90,14 +58,13 @@ Expected<std::shared_ptr<ServiceNetworkGroupBufferPool>> ServiceNetworkGroupBuff
} }
ServiceNetworkGroupBufferPool::ServiceNetworkGroupBufferPool(EventPtr shutdown_event, uint32_t vdevice_handle) : ServiceNetworkGroupBufferPool::ServiceNetworkGroupBufferPool(EventPtr shutdown_event, uint32_t vdevice_handle) :
m_stream_name_to_buffer_pool(), m_shutdown_event(shutdown_event), m_vdevice_handle(vdevice_handle) m_stream_name_to_buffer_pool(), m_mapped_buffers(), m_shutdown_event(shutdown_event), m_vdevice_handle(vdevice_handle), m_is_shutdown(false)
{} {}
hailo_status ServiceNetworkGroupBufferPool::allocate_pool(const std::string &name, hailo_status ServiceNetworkGroupBufferPool::allocate_pool(const std::string &name,
hailo_dma_buffer_direction_t direction, size_t frame_size, size_t pool_size) hailo_dma_buffer_direction_t direction, size_t frame_size, size_t pool_size)
{ {
TRY(auto buffer_pool, ServiceStreamBufferPool::create(m_vdevice_handle, frame_size, TRY(auto buffer_pool, create_stream_buffer_pool(frame_size, pool_size, direction, m_shutdown_event));
pool_size, direction, m_shutdown_event));
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
m_stream_name_to_buffer_pool[name] = buffer_pool; m_stream_name_to_buffer_pool[name] = buffer_pool;
@@ -111,9 +78,9 @@ hailo_status ServiceNetworkGroupBufferPool::reallocate_pool(const std::string &n
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
auto pool_size = m_stream_name_to_buffer_pool[name]->buffers_count(); auto pool_size = m_stream_name_to_buffer_pool[name]->buffers_count();
m_stream_name_to_buffer_pool[name].reset(); m_stream_name_to_buffer_pool[name].reset();
m_mapped_buffers.clear();
TRY(auto buffer_pool, ServiceStreamBufferPool::create(m_vdevice_handle, frame_size, TRY(auto buffer_pool, create_stream_buffer_pool(frame_size, pool_size, direction, m_shutdown_event));
pool_size, direction, m_shutdown_event));
m_stream_name_to_buffer_pool[name] = buffer_pool; m_stream_name_to_buffer_pool[name] = buffer_pool;
return HAILO_SUCCESS; return HAILO_SUCCESS;
@@ -125,8 +92,15 @@ Expected<BufferPtr> ServiceNetworkGroupBufferPool::acquire_buffer(const std::str
"acquire_buffer() for stream {} failed, stream name does not exist in buffer pool", stream_name); "acquire_buffer() for stream {} failed, stream name does not exist in buffer pool", stream_name);
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
TRY(auto buffer, m_stream_name_to_buffer_pool.at(stream_name)->acquire_buffer()); auto pool = m_stream_name_to_buffer_pool.at(stream_name);
m_cv.wait(lock, [this, pool] () {
return (pool->current_size() > 0) || m_is_shutdown;
});
if (m_is_shutdown) {
return make_unexpected(HAILO_SHUTDOWN_EVENT_SIGNALED);
}
TRY(auto buffer, pool->acquire_buffer());
return buffer; return buffer;
} }
@@ -135,15 +109,23 @@ hailo_status ServiceNetworkGroupBufferPool::return_to_pool(const std::string &st
CHECK(contains(m_stream_name_to_buffer_pool, stream_name), HAILO_INTERNAL_FAILURE, CHECK(contains(m_stream_name_to_buffer_pool, stream_name), HAILO_INTERNAL_FAILURE,
"acquire_buffer() for stream {} failed, stream name does not exist in buffer pool", stream_name); "acquire_buffer() for stream {} failed, stream name does not exist in buffer pool", stream_name);
{
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
auto status = m_stream_name_to_buffer_pool.at(stream_name)->return_to_pool(buffer); auto status = m_stream_name_to_buffer_pool.at(stream_name)->return_to_pool(buffer);
CHECK_SUCCESS(status); CHECK_SUCCESS(status);
}
m_cv.notify_all();
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status ServiceNetworkGroupBufferPool::shutdown() hailo_status ServiceNetworkGroupBufferPool::shutdown()
{ {
{
std::unique_lock<std::mutex> lock(m_mutex);
m_is_shutdown = true;
}
m_cv.notify_all();
return m_shutdown_event->signal(); return m_shutdown_event->signal();
} }

View File

@@ -15,40 +15,12 @@
#include "hailo/buffer.hpp" #include "hailo/buffer.hpp"
#include "hailo/vdevice.hpp" #include "hailo/vdevice.hpp"
#include "hailo/dma_mapped_buffer.hpp" #include "hailo/dma_mapped_buffer.hpp"
#include "utils/thread_safe_queue.hpp" #include "common/thread_safe_queue.hpp"
#include "common/buffer_pool.hpp"
namespace hailort namespace hailort
{ {
class ServiceStreamBufferPool
{
public:
static Expected<std::shared_ptr<ServiceStreamBufferPool>> create(uint32_t vdevice_handle, size_t buffer_size,
size_t buffer_count, hailo_dma_buffer_direction_t direction, EventPtr shutdown_event);
struct AllocatedMappedBuffer {
BufferPtr buffer;
DmaMappedBuffer mapped_buffer;
};
ServiceStreamBufferPool(size_t buffer_size, std::vector<AllocatedMappedBuffer> &&buffers,
SpscQueue<BufferPtr> &&m_free_buffers_queue, size_t buffers_count);
virtual ~ServiceStreamBufferPool() = default;
Expected<BufferPtr> acquire_buffer();
hailo_status return_to_pool(BufferPtr buffer);
size_t buffers_count();
private:
size_t m_buffer_size;
size_t m_buffers_count;
std::vector<AllocatedMappedBuffer> m_buffers;
SpscQueue<BufferPtr> m_free_buffers_queue;
std::mutex m_mutex;
};
using BufferPoolPtr = std::shared_ptr<ServiceStreamBufferPool>;
using stream_name_t = std::string; using stream_name_t = std::string;
// This object holds a buffer pool for each stream of the network group. // This object holds a buffer pool for each stream of the network group.
@@ -77,10 +49,17 @@ public:
hailo_status shutdown(); hailo_status shutdown();
private: private:
std::unordered_map<stream_name_t, BufferPoolPtr> m_stream_name_to_buffer_pool; Expected<BasicBufferPoolPtr> create_stream_buffer_pool(size_t buffer_size,
size_t buffer_count, hailo_dma_buffer_direction_t direction, EventPtr shutdown_event);
std::unordered_map<stream_name_t, BasicBufferPoolPtr> m_stream_name_to_buffer_pool;
// This is in order to keep the DmaMappedBuffer buffers alive while using the buffers pool.
std::vector<DmaMappedBuffer> m_mapped_buffers;
EventPtr m_shutdown_event; EventPtr m_shutdown_event;
uint32_t m_vdevice_handle; uint32_t m_vdevice_handle;
std::mutex m_mutex; std::mutex m_mutex;
std::condition_variable m_cv;
bool m_is_shutdown;
}; };
} /* namespace hailort */ } /* namespace hailort */

View File

@@ -94,6 +94,53 @@ void HailoRtRpcService::abort_vstreams_by_pids(std::set<uint32_t> &pids)
} }
} }
hailo_status HailoRtRpcService::shutdown_configured_network_group(uint32_t vdevice_handle)
{
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
return cng->shutdown();
};
auto &cng_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
auto status = cng_manager.execute(vdevice_handle, lambda);
CHECK_SUCCESS(status);
return HAILO_SUCCESS;
}
void HailoRtRpcService::shutdown_configured_network_groups_by_pids(std::set<uint32_t> &pids)
{
auto cng_handles = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance().resources_handles_by_pids(pids);
for (auto &handle : cng_handles) {
auto status = shutdown_configured_network_group(handle);
if (status != HAILO_SUCCESS) {
LOGGER__ERROR("Failed to shutdown configured network group queue with handle={}, status={}", handle, status);
}
}
}
void HailoRtRpcService::shutdown_buffer_pool_by_pids(std::set<uint32_t> &pids)
{
auto buffer_pools_handles = ServiceResourceManager<ServiceNetworkGroupBufferPool>::get_instance().resources_handles_by_pids(pids);
for (auto &handle : buffer_pools_handles) {
auto status = shutdown_cng_buffer_pool(handle);
if (status != HAILO_SUCCESS) {
LOGGER__ERROR("Failed to shutdown cng buffer pool with handle={}, status={}", handle, status);
}
}
}
void HailoRtRpcService::shutdown_vdevice_cb_queue_by_pids(std::set<uint32_t> &pids)
{
auto vdevice_cb_queue_handles = ServiceResourceManager<VDeviceCallbacksQueue>::get_instance().resources_handles_by_pids(pids);
for (auto &handle : vdevice_cb_queue_handles) {
auto status = shutdown_vdevice_cb_queue(handle);
if (status != HAILO_SUCCESS) {
LOGGER__ERROR("Failed to shutdown vdevice callbacks queue with handle={}, status={}", handle, status);
}
}
}
void HailoRtRpcService::remove_disconnected_clients() void HailoRtRpcService::remove_disconnected_clients()
{ {
std::this_thread::sleep_for(hailort::HAILO_KEEPALIVE_INTERVAL / 2); std::this_thread::sleep_for(hailort::HAILO_KEEPALIVE_INTERVAL / 2);
@@ -113,10 +160,17 @@ void HailoRtRpcService::remove_disconnected_clients()
// blocking operation (which will be finished with timeout). // blocking operation (which will be finished with timeout).
// To release the vstream the ServiceResourceManager is waiting for the resource_mutex which is also locked in execute. // To release the vstream the ServiceResourceManager is waiting for the resource_mutex which is also locked in execute.
abort_vstreams_by_pids(pids_to_remove); abort_vstreams_by_pids(pids_to_remove);
// It is important to shutdown the cb Queue before the NG shutdown, as ongoing callbacks might continue to try to enqueue
shutdown_vdevice_cb_queue_by_pids(pids_to_remove);
shutdown_configured_network_groups_by_pids(pids_to_remove);
shutdown_buffer_pool_by_pids(pids_to_remove);
for (auto &client_pid : pids_to_remove) { for (auto &client_pid : pids_to_remove) {
ServiceResourceManager<OutputVStream>::get_instance().release_by_pid(client_pid); ServiceResourceManager<OutputVStream>::get_instance().release_by_pid(client_pid);
ServiceResourceManager<InputVStream>::get_instance().release_by_pid(client_pid); ServiceResourceManager<InputVStream>::get_instance().release_by_pid(client_pid);
ServiceResourceManager<ConfiguredNetworkGroup>::get_instance().release_by_pid(client_pid); ServiceResourceManager<ConfiguredNetworkGroup>::get_instance().release_by_pid(client_pid);
ServiceResourceManager<VDeviceCallbacksQueue>::get_instance().release_by_pid(client_pid);
ServiceResourceManager<ServiceNetworkGroupBufferPool>::get_instance().release_by_pid(client_pid);
ServiceResourceManager<VDevice>::get_instance().release_by_pid(client_pid); ServiceResourceManager<VDevice>::get_instance().release_by_pid(client_pid);
LOGGER__INFO("Client disconnected, pid: {}", client_pid); LOGGER__INFO("Client disconnected, pid: {}", client_pid);
@@ -126,7 +180,6 @@ void HailoRtRpcService::remove_disconnected_clients()
} }
} }
void HailoRtRpcService::keep_alive() void HailoRtRpcService::keep_alive()
{ {
while (true) { while (true) {
@@ -191,12 +244,17 @@ grpc::Status HailoRtRpcService::VDevice_create(grpc::ServerContext *, const VDev
update_client_id_timestamp(request->pid()); update_client_id_timestamp(request->pid());
std::unique_lock<std::mutex> lock(m_vdevice_mutex); std::unique_lock<std::mutex> lock(m_vdevice_mutex);
auto &vdevice_manager = ServiceResourceManager<VDevice>::get_instance(); auto &vdevice_manager = ServiceResourceManager<VDevice>::get_instance();
auto &cb_queue_manager = ServiceResourceManager<VDeviceCallbacksQueue>::get_instance();
auto vdevice_handle = vdevice_manager.register_resource(request->pid(), std::move(vdevice.release())); auto vdevice_handle = vdevice_manager.register_resource(request->pid(), std::move(vdevice.release()));
auto cb_queue = VDeviceCallbacksQueue::create(MAX_QUEUE_SIZE); auto cb_queue = VDeviceCallbacksQueue::create(MAX_QUEUE_SIZE);
if (HAILO_SUCCESS != cb_queue.status()) {
// cb_queue_handle and vdevice_handle indexes must be the same
cb_queue_manager.advance_current_handle_index();
}
CHECK_EXPECTED_AS_RPC_STATUS(cb_queue, reply); CHECK_EXPECTED_AS_RPC_STATUS(cb_queue, reply);
auto &cb_queue_manager = ServiceResourceManager<VDeviceCallbacksQueue>::get_instance();
auto cb_queue_handle = cb_queue_manager.register_resource(request->pid(), std::move(cb_queue.release())); auto cb_queue_handle = cb_queue_manager.register_resource(request->pid(), std::move(cb_queue.release()));
if (cb_queue_handle != vdevice_handle) { if (cb_queue_handle != vdevice_handle) {
LOGGER__ERROR("cb_queue_handle = {} must be equal to vdevice_handle ={}", cb_queue_handle, vdevice_handle); LOGGER__ERROR("cb_queue_handle = {} must be equal to vdevice_handle ={}", cb_queue_handle, vdevice_handle);
@@ -209,17 +267,26 @@ grpc::Status HailoRtRpcService::VDevice_create(grpc::ServerContext *, const VDev
return grpc::Status::OK; return grpc::Status::OK;
} }
grpc::Status HailoRtRpcService::VDevice_release(grpc::ServerContext*, const Release_Request *request, hailo_status HailoRtRpcService::shutdown_vdevice_cb_queue(uint32_t vdevice_handle)
Release_Reply *reply)
{ {
auto lambda = [](std::shared_ptr<VDeviceCallbacksQueue> cb_queue) { auto lambda = [](std::shared_ptr<VDeviceCallbacksQueue> cb_queue) {
return cb_queue->shutdown(); return cb_queue->shutdown();
}; };
auto &cb_queue_manager = ServiceResourceManager<VDeviceCallbacksQueue>::get_instance(); auto &cb_queue_manager = ServiceResourceManager<VDeviceCallbacksQueue>::get_instance();
auto status = cb_queue_manager.execute(request->vdevice_identifier().vdevice_handle(), lambda); auto status = cb_queue_manager.execute(vdevice_handle, lambda);
CHECK_SUCCESS(status);
return HAILO_SUCCESS;
}
grpc::Status HailoRtRpcService::VDevice_release(grpc::ServerContext*, const Release_Request *request,
Release_Reply *reply)
{
auto status = shutdown_vdevice_cb_queue(request->vdevice_identifier().vdevice_handle());
CHECK_SUCCESS_AS_RPC_STATUS(status, reply); CHECK_SUCCESS_AS_RPC_STATUS(status, reply);
auto &cb_queue_manager = ServiceResourceManager<VDeviceCallbacksQueue>::get_instance();
cb_queue_manager.release_resource(request->vdevice_identifier().vdevice_handle(), request->pid()); cb_queue_manager.release_resource(request->vdevice_identifier().vdevice_handle(), request->pid());
auto &manager = ServiceResourceManager<VDevice>::get_instance(); auto &manager = ServiceResourceManager<VDevice>::get_instance();
@@ -307,9 +374,16 @@ grpc::Status HailoRtRpcService::VDevice_configure(grpc::ServerContext*, const VD
hailo_status HailoRtRpcService::create_buffer_pools_for_ng(uint32_t vdevice_handle, uint32_t ng_handle, uint32_t request_pid, hailo_status HailoRtRpcService::create_buffer_pools_for_ng(uint32_t vdevice_handle, uint32_t ng_handle, uint32_t request_pid,
bool allocate_for_raw_streams) bool allocate_for_raw_streams)
{ {
TRY(auto cng_buffer_pool, ServiceNetworkGroupBufferPool::create(vdevice_handle));
auto &cng_buffer_pool_manager = ServiceResourceManager<ServiceNetworkGroupBufferPool>::get_instance(); auto &cng_buffer_pool_manager = ServiceResourceManager<ServiceNetworkGroupBufferPool>::get_instance();
auto cng_buffer_pool_exp = ServiceNetworkGroupBufferPool::create(vdevice_handle);
if (HAILO_SUCCESS != cng_buffer_pool_exp.status()) {
// cng_buffer_pool_handle and network_group_handle indexes must be the same
cng_buffer_pool_manager.advance_current_handle_index();
return cng_buffer_pool_exp.status();
}
auto cng_buffer_pool = cng_buffer_pool_exp.release();
auto cng_buffer_pool_handle = cng_buffer_pool_manager.register_resource(request_pid, cng_buffer_pool); auto cng_buffer_pool_handle = cng_buffer_pool_manager.register_resource(request_pid, cng_buffer_pool);
CHECK(cng_buffer_pool_handle == ng_handle, HAILO_INTERNAL_FAILURE, CHECK(cng_buffer_pool_handle == ng_handle, HAILO_INTERNAL_FAILURE,
"cng_buffer_pool_handle = {} must be equal to network_group_handle ={}", cng_buffer_pool_handle, ng_handle); "cng_buffer_pool_handle = {} must be equal to network_group_handle ={}", cng_buffer_pool_handle, ng_handle);
@@ -431,16 +505,44 @@ ProtoCallbackIdentifier serialize_callback_identifier(uint32_t vdevice_handle, u
return cb_identifier; return cb_identifier;
} }
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_release(grpc::ServerContext*, const Release_Request *request, ProtoCallbackIdentifier serialize_callback_identifier_shm(uint32_t vdevice_handle, uint32_t ng_handle, callback_type_t cb_type,
Release_Reply *reply) const std::string &stream_name, uint32_t cb_idx, hailo_status status, const ProtoShmBufferIdentifier &shm_buffer_identifier)
{
ProtoCallbackIdentifier cb_identifier;
cb_identifier.set_vdevice_handle(vdevice_handle);
cb_identifier.set_network_group_handle(ng_handle);
cb_identifier.set_cb_type(cb_type);
cb_identifier.set_stream_name(stream_name);
cb_identifier.set_cb_idx(cb_idx);
cb_identifier.set_status(status);
auto proto_shm_identifier = cb_identifier.mutable_shared_memory_identifier();
proto_shm_identifier->set_name(shm_buffer_identifier.name());
proto_shm_identifier->set_size(shm_buffer_identifier.size());
return cb_identifier;
}
hailo_status HailoRtRpcService::shutdown_cng_buffer_pool(uint32_t network_group_handle)
{ {
auto buffer_shutdown_lambda = [](std::shared_ptr<ServiceNetworkGroupBufferPool> cng_buffer_pool) { auto buffer_shutdown_lambda = [](std::shared_ptr<ServiceNetworkGroupBufferPool> cng_buffer_pool) {
return cng_buffer_pool->shutdown(); return cng_buffer_pool->shutdown();
}; };
auto &buffer_pool_manager = ServiceResourceManager<ServiceNetworkGroupBufferPool>::get_instance(); auto &buffer_pool_manager = ServiceResourceManager<ServiceNetworkGroupBufferPool>::get_instance();
auto status = buffer_pool_manager.execute(request->network_group_identifier().network_group_handle(), buffer_shutdown_lambda); auto status = buffer_pool_manager.execute(network_group_handle, buffer_shutdown_lambda);
CHECK_SUCCESS(status);
return HAILO_SUCCESS;
}
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_release(grpc::ServerContext*, const Release_Request *request,
Release_Reply *reply)
{
auto status = shutdown_cng_buffer_pool(request->network_group_identifier().network_group_handle());
CHECK_SUCCESS_AS_RPC_STATUS(status, reply); CHECK_SUCCESS_AS_RPC_STATUS(status, reply);
auto &buffer_pool_manager = ServiceResourceManager<ServiceNetworkGroupBufferPool>::get_instance();
buffer_pool_manager.release_resource(request->network_group_identifier().network_group_handle(), request->pid()); buffer_pool_manager.release_resource(request->network_group_identifier().network_group_handle(), request->pid());
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance(); auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
@@ -456,6 +558,11 @@ hailo_status HailoRtRpcService::add_input_named_buffer(const ProtoTransferReques
// Prepare input buffer // Prepare input buffer
BufferPtr buffer; BufferPtr buffer;
MemoryView mem_view; MemoryView mem_view;
if (proto_stream_transfer_request.has_shared_memory_identifier()) {
TRY(buffer, Buffer::create_shared(proto_stream_transfer_request.shared_memory_identifier().size(),
BufferStorageParams::open_shared_memory(proto_stream_transfer_request.shared_memory_identifier().name())));
mem_view = MemoryView(*buffer);
} else {
auto *data = reinterpret_cast<const uint8_t*>(proto_stream_transfer_request.data().c_str()); auto *data = reinterpret_cast<const uint8_t*>(proto_stream_transfer_request.data().c_str());
if (reinterpret_cast<size_t>(data) % HailoRTCommon::HW_DATA_ALIGNMENT == 0) { if (reinterpret_cast<size_t>(data) % HailoRTCommon::HW_DATA_ALIGNMENT == 0) {
// Input buffers is aligned to 8 // Input buffers is aligned to 8
@@ -466,10 +573,15 @@ hailo_status HailoRtRpcService::add_input_named_buffer(const ProtoTransferReques
BufferStorageParams::create_dma())); BufferStorageParams::create_dma()));
mem_view = MemoryView(*buffer); mem_view = MemoryView(*buffer);
} }
}
// Preparing callback // Preparing callback
auto &stream_name = proto_stream_transfer_request.stream_name(); auto &stream_name = proto_stream_transfer_request.stream_name();
CHECK(stream_name != INVALID_STREAM_NAME, HAILO_INTERNAL_FAILURE, "Got invalid stream name");
auto cb_idx = proto_stream_transfer_request.cb_idx(); auto cb_idx = proto_stream_transfer_request.cb_idx();
CHECK(cb_idx != INVALID_CB_INDEX, HAILO_INTERNAL_FAILURE, "Got invalid callback index");
std::function<void(hailo_status)> transfer_done = [this, vdevice_handle, ng_handle, cb_idx, stream_name, buffer, infer_async_request] std::function<void(hailo_status)> transfer_done = [this, vdevice_handle, ng_handle, cb_idx, stream_name, buffer, infer_async_request]
(hailo_status status) (hailo_status status)
{ {
@@ -493,18 +605,38 @@ hailo_status HailoRtRpcService::add_input_named_buffer(const ProtoTransferReques
hailo_status HailoRtRpcService::add_output_named_buffer(const ProtoTransferRequest &proto_stream_transfer_request, uint32_t vdevice_handle, hailo_status HailoRtRpcService::add_output_named_buffer(const ProtoTransferRequest &proto_stream_transfer_request, uint32_t vdevice_handle,
uint32_t ng_handle, NamedBuffersCallbacks &named_buffers_callbacks) uint32_t ng_handle, NamedBuffersCallbacks &named_buffers_callbacks)
{ {
// Prepare output buffer
auto &stream_name = proto_stream_transfer_request.stream_name(); auto &stream_name = proto_stream_transfer_request.stream_name();
TRY(auto buffer, acquire_buffer_from_cng_pool(ng_handle, stream_name)); CHECK(stream_name != INVALID_STREAM_NAME, HAILO_INTERNAL_FAILURE, "Got invalid stream name");
// Prepare output buffer
BufferPtr buffer;
bool is_shared_mem = proto_stream_transfer_request.has_shared_memory_identifier();
auto shm_identifier = proto_stream_transfer_request.shared_memory_identifier();
if (is_shared_mem) {
TRY(buffer, Buffer::create_shared(shm_identifier.size(),
BufferStorageParams::open_shared_memory(shm_identifier.name())));
} else {
TRY(buffer, acquire_buffer_from_cng_pool(ng_handle, stream_name));
}
// Prepare callback // Prepare callback
auto cb_idx = proto_stream_transfer_request.cb_idx(); auto cb_idx = proto_stream_transfer_request.cb_idx();
std::function<void(hailo_status)> transfer_done = [this, vdevice_handle, ng_handle, cb_idx, stream_name, buffer] CHECK(cb_idx != INVALID_CB_INDEX, HAILO_INTERNAL_FAILURE, "Got invalid callback index");
std::function<void(hailo_status)> transfer_done = [this, vdevice_handle, ng_handle, cb_idx, stream_name, buffer,
is_shared_mem, shm_identifier]
(hailo_status status) (hailo_status status)
{ {
auto cb_identifier = serialize_callback_identifier(vdevice_handle, ng_handle, CALLBACK_TYPE_TRANSFER, ProtoCallbackIdentifier cb_identifier;
if (is_shared_mem) {
cb_identifier = serialize_callback_identifier_shm(vdevice_handle, ng_handle, CALLBACK_TYPE_TRANSFER,
stream_name, cb_idx, status, shm_identifier);
} else {
cb_identifier = serialize_callback_identifier(vdevice_handle, ng_handle, CALLBACK_TYPE_TRANSFER,
stream_name, cb_idx, status, buffer); stream_name, cb_idx, status, buffer);
return_buffer_to_cng_pool(ng_handle, stream_name, buffer); return_buffer_to_cng_pool(ng_handle, stream_name, buffer);
}
enqueue_cb_identifier(vdevice_handle, std::move(cb_identifier)); enqueue_cb_identifier(vdevice_handle, std::move(cb_identifier));
}; };
@@ -542,6 +674,9 @@ void HailoRtRpcService::enqueue_cb_identifier(uint32_t vdevice_handle, ProtoCall
auto &cb_queue_manager = ServiceResourceManager<VDeviceCallbacksQueue>::get_instance(); auto &cb_queue_manager = ServiceResourceManager<VDeviceCallbacksQueue>::get_instance();
auto status = cb_queue_manager.execute(vdevice_handle, lambda, std::move(cb_identifier)); auto status = cb_queue_manager.execute(vdevice_handle, lambda, std::move(cb_identifier));
if (HAILO_SHUTDOWN_EVENT_SIGNALED != status) {
LOGGER__TRACE("Failed to enqueue callback to VDeviceCallbacksQueue '{}' because it is shutdown", vdevice_handle);
}
if (status != HAILO_SUCCESS) { if (status != HAILO_SUCCESS) {
LOGGER__ERROR("Failed to enqueue callback to VDeviceCallbacksQueue with status={}", status); LOGGER__ERROR("Failed to enqueue callback to VDeviceCallbacksQueue with status={}", status);
} }
@@ -1323,6 +1458,7 @@ grpc::Status HailoRtRpcService::InputVStreams_create(grpc::ServerContext *, cons
auto &vstreams_manager = ServiceResourceManager<InputVStream>::get_instance(); auto &vstreams_manager = ServiceResourceManager<InputVStream>::get_instance();
for (size_t i = 0; i < vstreams.size(); i++) { for (size_t i = 0; i < vstreams.size(); i++) {
reply->add_names(vstreams[i].name());
auto handle = vstreams_manager.register_resource(client_pid, make_shared_nothrow<InputVStream>(std::move(vstreams[i]))); auto handle = vstreams_manager.register_resource(client_pid, make_shared_nothrow<InputVStream>(std::move(vstreams[i])));
reply->add_handles(handle); reply->add_handles(handle);
} }
@@ -1388,7 +1524,7 @@ grpc::Status HailoRtRpcService::OutputVStreams_create(grpc::ServerContext *, con
vstreams[i].get_frame_size(), output_params.at(vstreams[i].name()).queue_size); vstreams[i].get_frame_size(), output_params.at(vstreams[i].name()).queue_size);
}; };
CHECK_SUCCESS_AS_RPC_STATUS(cng_buffer_pool_manager.execute(network_group_handle, allocate_lambda), reply); CHECK_SUCCESS_AS_RPC_STATUS(cng_buffer_pool_manager.execute(network_group_handle, allocate_lambda), reply);
reply->add_names(vstreams[i].name());
auto handle = vstream_manager.register_resource(client_pid, make_shared_nothrow<OutputVStream>(std::move(vstreams[i]))); auto handle = vstream_manager.register_resource(client_pid, make_shared_nothrow<OutputVStream>(std::move(vstreams[i])));
reply->add_handles(handle); reply->add_handles(handle);
} }

View File

@@ -227,6 +227,7 @@ private:
hailo_status abort_input_vstream(uint32_t handle); hailo_status abort_input_vstream(uint32_t handle);
hailo_status abort_output_vstream(uint32_t handle); hailo_status abort_output_vstream(uint32_t handle);
void abort_vstreams_by_pids(std::set<uint32_t> &pids); void abort_vstreams_by_pids(std::set<uint32_t> &pids);
void release_configured_network_groups_by_pid(uint32_t client_pid);
void remove_disconnected_clients(); void remove_disconnected_clients();
void update_client_id_timestamp(uint32_t pid); void update_client_id_timestamp(uint32_t pid);
Expected<size_t> get_min_buffer_pool_size(uint32_t ng_handle); Expected<size_t> get_min_buffer_pool_size(uint32_t ng_handle);
@@ -247,6 +248,12 @@ private:
Expected<BufferPtr> acquire_buffer_from_cng_pool(uint32_t ng_handle, const std::string &output_name); Expected<BufferPtr> acquire_buffer_from_cng_pool(uint32_t ng_handle, const std::string &output_name);
Expected<size_t> output_vstream_frame_size(uint32_t vstream_handle); Expected<size_t> output_vstream_frame_size(uint32_t vstream_handle);
hailo_status update_buffer_size_in_pool(uint32_t vstream_handle, uint32_t network_group_handle); hailo_status update_buffer_size_in_pool(uint32_t vstream_handle, uint32_t network_group_handle);
void shutdown_configured_network_groups_by_pids(std::set<uint32_t> &pids);
void shutdown_buffer_pool_by_pids(std::set<uint32_t> &pids);
void shutdown_vdevice_cb_queue_by_pids(std::set<uint32_t> &pids);
hailo_status shutdown_cng_buffer_pool(uint32_t network_group_handle);
hailo_status shutdown_vdevice_cb_queue(uint32_t vdevice_handle);
hailo_status shutdown_configured_network_group(uint32_t vdevice_handle);
std::mutex m_keep_alive_mutex; std::mutex m_keep_alive_mutex;
std::map<uint32_t, std::chrono::time_point<std::chrono::high_resolution_clock>> m_clients_pids; std::map<uint32_t, std::chrono::time_point<std::chrono::high_resolution_clock>> m_clients_pids;

View File

@@ -8,5 +8,8 @@
[Service] [Service]
HAILORT_LOGGER_PATH="/var/log/hailo" HAILORT_LOGGER_PATH="/var/log/hailo"
HAILORT_LOGGER_FLUSH_EVERY_PRINT=0
HAILO_MONITOR=0 HAILO_MONITOR=0
HAILO_TRACE=0
HAILO_TRACE_TIME_IN_SECONDS_BOUNDED_DUMP=0
HAILO_TRACE_SIZE_IN_KB_BOUNDED_DUMP=0
HAILO_TRACE_PATH=""

View File

@@ -83,6 +83,13 @@ public:
return index; return index;
} }
// For cases where other resources are already registered and we want to align the indexes
void advance_current_handle_index()
{
std::unique_lock<std::mutex> lock(m_mutex);
m_current_handle_index++;
}
Expected<uint32_t> dup_handle(uint32_t handle, uint32_t pid) Expected<uint32_t> dup_handle(uint32_t handle, uint32_t pid)
{ {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);

View File

@@ -30,28 +30,30 @@
#include <syslog.h> #include <syslog.h>
#include <sys/stat.h> #include <sys/stat.h>
void RunService() { using namespace hailort;
const std::string server_address = hailort::HAILORT_SERVICE_ADDRESS;
hailort::HailoRtRpcService service;
void RunService()
{
const std::string server_address = HAILORT_SERVICE_ADDRESS;
HailoRtRpcService service;
grpc::ServerBuilder builder; grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.SetMaxReceiveMessageSize(-1); builder.SetMaxReceiveMessageSize(-1);
builder.RegisterService(&service); builder.RegisterService(&service);
std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
chmod(hailort::HAILO_DEFAULT_SERVICE_ADDR.c_str(), S_IROTH | S_IWOTH | S_IRUSR | S_IWUSR); chmod(HAILO_DEFAULT_SERVICE_ADDR.c_str(), S_IROTH | S_IWOTH | S_IRUSR | S_IWUSR);
server->Wait(); server->Wait();
} }
void write_pid_to_lock_file() void write_pid_to_lock_file()
{ {
auto status = hailort::Filesystem::create_directory(HAILO_DAEMON_PID_DIR); auto status = Filesystem::create_directory(HAILO_DAEMON_PID_DIR);
if (status != HAILO_SUCCESS) { if (status != HAILO_SUCCESS) {
HAILORT_OS_LOG_ERROR("Cannot create directory at path, status={}", status); HAILORT_OS_LOG_ERROR("Cannot create directory at path, status={}", status);
return; return;
} }
auto locked_file = hailort::LockedFile::create(HAILO_DAEMON_PID_FILE, "wx"); auto locked_file = LockedFile::create(HAILO_DAEMON_PID_FILE, "wx");
if (HAILO_SUCCESS != locked_file.status()) { if (HAILO_SUCCESS != locked_file.status()) {
HAILORT_OS_LOG_ERROR("Failed to lock pid file for hailort service, status={}", locked_file.status()); HAILORT_OS_LOG_ERROR("Failed to lock pid file for hailort service, status={}", locked_file.status());
return; return;

View File

@@ -17,7 +17,7 @@
#include "hailo/hailort.h" #include "hailo/hailort.h"
#include "hailo/network_group.hpp" #include "hailo/network_group.hpp"
#include "hailo/hailort_common.hpp" #include "hailo/hailort_common.hpp"
#include "utils/thread_safe_queue.hpp" #include "common/thread_safe_queue.hpp"
namespace hailort namespace hailort
{ {
@@ -27,6 +27,11 @@ namespace hailort
class VDeviceCallbacksQueue final class VDeviceCallbacksQueue final
{ {
public: public:
~VDeviceCallbacksQueue()
{
shutdown();
};
static Expected<std::unique_ptr<VDeviceCallbacksQueue>> create(uint32_t max_queue_size) static Expected<std::unique_ptr<VDeviceCallbacksQueue>> create(uint32_t max_queue_size)
{ {
TRY(auto shutdown_event, Event::create_shared(Event::State::not_signalled)); TRY(auto shutdown_event, Event::create_shared(Event::State::not_signalled));
@@ -48,6 +53,9 @@ public:
{ {
std::unique_lock<std::mutex> lock(m_mutex); std::unique_lock<std::mutex> lock(m_mutex);
auto status = m_callbacks_ids_queue.enqueue(std::move(callback_id)); auto status = m_callbacks_ids_queue.enqueue(std::move(callback_id));
if (HAILO_SHUTDOWN_EVENT_SIGNALED == status) {
return status;
}
CHECK_SUCCESS(status); CHECK_SUCCESS(status);
return HAILO_SUCCESS; return HAILO_SUCCESS;

View File

@@ -29,12 +29,15 @@
#include "hailort_rpc_service.hpp" #include "hailort_rpc_service.hpp"
#include "rpc/rpc_definitions.hpp" #include "rpc/rpc_definitions.hpp"
#include "common/os_utils.hpp" #include "common/os_utils.hpp"
#include "common/os/windows/named_mutex_guard.hpp"
#include <winsvc.h> #include <winsvc.h>
#include <windows.h> #include <windows.h>
#include <tchar.h> #include <tchar.h>
#include <strsafe.h> #include <strsafe.h>
using namespace hailort;
#define SERVICE_NAME ("hailort_service") #define SERVICE_NAME ("hailort_service")
static const DWORD HRT_SERVICE_INIT_WAIT_TIME_MS(3000); static const DWORD HRT_SERVICE_INIT_WAIT_TIME_MS(3000);
static const DWORD HRT_SERVICE_ZERO_WAIT_TIME_MS(0); static const DWORD HRT_SERVICE_ZERO_WAIT_TIME_MS(0);
@@ -46,9 +49,16 @@ std::unique_ptr<grpc::Server> g_hailort_rpc_server = nullptr;
void RunService() void RunService()
{ {
const std::string server_address = hailort::HAILORT_SERVICE_ADDRESS; // Create a named mutex
hailort::HailoRtRpcService service; auto service_named_mutex = NamedMutexGuard::create(HAILORT_SERVICE_NAMED_MUTEX);
if (HAILO_SUCCESS != service_named_mutex.status()) {
LOGGER__ERROR("Failed to create service named mutex with status={}. Please check if another instance is already running.",
service_named_mutex.status());
return;
}
const std::string server_address = HAILORT_SERVICE_ADDRESS;
HailoRtRpcService service;
grpc::ServerBuilder builder; grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.SetMaxReceiveMessageSize(-1); builder.SetMaxReceiveMessageSize(-1);

View File

@@ -8,3 +8,8 @@
reg ADD HKLM\SYSTEM\CurrentControlSet\Services\hailort_service /f /v Environment /t REG_MULTI_SZ /d ^ reg ADD HKLM\SYSTEM\CurrentControlSet\Services\hailort_service /f /v Environment /t REG_MULTI_SZ /d ^
HAILORT_LOGGER_PATH="%PROGRAMDATA%\HailoRT_Service\logs"\0^ HAILORT_LOGGER_PATH="%PROGRAMDATA%\HailoRT_Service\logs"\0^
HAILO_TRACE=0\0^
HAILO_TRACE_TIME_IN_SECONDS_BOUNDED_DUMP=0\0^
HAILO_TRACE_SIZE_IN_KB_BOUNDED_DUMP=0\0^
HAILO_TRACE_PATH=""\0
@REM TODO: HRT-7304 - Add `HAILO_MONITOR`

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
include(GNUInstallDirs) include(GNUInstallDirs)
include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/cli11.cmake) include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/cli11.cmake)
@@ -65,7 +65,11 @@ add_executable(hailortcli
target_compile_options(hailortcli PRIVATE ${HAILORT_COMPILE_OPTIONS}) target_compile_options(hailortcli PRIVATE ${HAILORT_COMPILE_OPTIONS})
set_property(TARGET hailortcli PROPERTY CXX_STANDARD 14) set_property(TARGET hailortcli PROPERTY CXX_STANDARD 14)
set_property(TARGET hailortcli PROPERTY INSTALL_RPATH "$ORIGIN" "../lib/") # Link with a relative libhailort
# Link with a relative libhailort
set_property(TARGET hailortcli PROPERTY INSTALL_RPATH "$ORIGIN")
set_property(TARGET hailortcli APPEND PROPERTY INSTALL_RPATH "\$ORIGIN/../lib/")
target_link_libraries(hailortcli target_link_libraries(hailortcli
libhailort libhailort
CLI11::CLI11 CLI11::CLI11
@@ -82,7 +86,10 @@ if(WIN32)
elseif(CMAKE_SYSTEM_NAME STREQUAL QNX) elseif(CMAKE_SYSTEM_NAME STREQUAL QNX)
include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/pevents.cmake) include(${HAILO_EXTERNALS_CMAKE_SCRIPTS}/pevents.cmake)
target_link_libraries(hailortcli pevents) target_link_libraries(hailortcli pevents)
elseif(NOT CMAKE_SYSTEM_NAME STREQUAL Android)
target_link_libraries(hailortcli rt)
endif() endif()
target_include_directories(hailortcli target_include_directories(hailortcli
PRIVATE PRIVATE
${CMAKE_CURRENT_BINARY_DIR} # CMAKE_CURRENT_BINARY_DIR is necessary for config_definitions_header ${CMAKE_CURRENT_BINARY_DIR} # CMAKE_CURRENT_BINARY_DIR is necessary for config_definitions_header

View File

@@ -8,6 +8,7 @@
**/ **/
#include "benchmark_command.hpp" #include "benchmark_command.hpp"
#include "CLI/App.hpp"
#include "hailortcli.hpp" #include "hailortcli.hpp"
#include "infer_stats_printer.hpp" #include "infer_stats_printer.hpp"
@@ -30,8 +31,8 @@ BenchmarkCommand::BenchmarkCommand(CLI::App &parent_app) :
m_app->add_option("-t, --time-to-run", m_params.time_to_run, "Measurement time in seconds per hw_only/streaming/latency measurement mode") m_app->add_option("-t, --time-to-run", m_params.time_to_run, "Measurement time in seconds per hw_only/streaming/latency measurement mode")
->check(CLI::PositiveNumber) ->check(CLI::PositiveNumber)
->default_val(15); ->default_val(15);
m_app->add_option("--no-power", m_not_measure_power, "Skip power measurement, even if the platform supports it. The default value is False") auto no_power_opt = m_app->add_option("--no-power", m_not_measure_power, "Skip power measurement, even if the platform supports it. The default value is False");
->default_val("false"); hailo_deprecate_options(m_app, { std::make_shared<OptionDeprecation>(no_power_opt) }, false);
m_app->add_option("--batch-size", m_params.batch_size, "Inference batch size (default is 1)") m_app->add_option("--batch-size", m_params.batch_size, "Inference batch size (default is 1)")
->default_val(1); ->default_val(1);
m_app->add_option("--power-mode", m_params.power_mode, m_app->add_option("--power-mode", m_params.power_mode,
@@ -64,15 +65,15 @@ hailo_status BenchmarkCommand::execute()
{ {
std::cout << "Starting Measurements..." << std::endl; std::cout << "Starting Measurements..." << std::endl;
std::cout << "Measuring FPS in hw_only mode" << std::endl; std::cout << "Measuring FPS in HW-only mode" << std::endl;
TRY(auto hw_only_mode_info, hw_only_mode(), "hw_only measuring failed"); TRY(auto hw_only_mode_info, hw_only_mode(), "Measuring FPS in HW-only mode failed");
std::cout << "Measuring FPS " << (!m_not_measure_power ? "and Power " : "") << "in streaming mode" << std::endl; std::cout << "Measuring FPS (and Power on supported platforms) in streaming mode" << std::endl;
TRY(auto streaming_mode_info, fps_streaming_mode(), "FPS in streaming mode failed"); TRY(auto streaming_mode_info, fps_streaming_mode(), "Measuring FPS (and Power on supported platforms) in streaming mode failed");
// TODO - HRT-6931 - measure latency only in the case of single device. // TODO - HRT-6931 - measure latency only in the case of single device.
std::cout << "Measuring HW Latency" << std::endl; std::cout << "Measuring HW Latency" << std::endl;
TRY(auto latency_info, latency(), "Latency measuring failed"); TRY(auto latency_info, latency(), "Measuring Latency failed");
assert(hw_only_mode_info.network_group_results().size() == streaming_mode_info.network_group_results().size()); assert(hw_only_mode_info.network_group_results().size() == streaming_mode_info.network_group_results().size());
assert(latency_info.network_group_results().size() == streaming_mode_info.network_group_results().size()); assert(latency_info.network_group_results().size() == streaming_mode_info.network_group_results().size());
@@ -101,7 +102,7 @@ hailo_status BenchmarkCommand::execute()
std::cout << " (overall) = " << InferStatsPrinter::latency_result_to_ms(overall_latency.value()) << " ms" << std::endl; std::cout << " (overall) = " << InferStatsPrinter::latency_result_to_ms(overall_latency.value()) << " ms" << std::endl;
} }
} }
if (!m_not_measure_power) { if (streaming_mode_info.power_measurements_are_valid) {
for (const auto &pair : streaming_mode_info.m_power_measurements) { for (const auto &pair : streaming_mode_info.m_power_measurements) {
std::cout << "Device " << pair.first << ":" << std::endl; std::cout << "Device " << pair.first << ":" << std::endl;
const auto &data = pair.second->data(); const auto &data = pair.second->data();
@@ -123,7 +124,7 @@ hailo_status BenchmarkCommand::execute()
Expected<InferResult> BenchmarkCommand::hw_only_mode() Expected<InferResult> BenchmarkCommand::hw_only_mode()
{ {
m_params.transform.transform = (m_params.inputs_name_and_file_path.size() > 0); m_params.transform.transform = (m_params.inputs_name_and_file_path.size() > 0);
m_params.power_measurement.measure_power = false; m_params.power_measurement.measure_power = ShouldMeasurePower::NO;
m_params.measure_latency = false; m_params.measure_latency = false;
m_params.mode = InferMode::HW_ONLY; m_params.mode = InferMode::HW_ONLY;
return run_command_hef(m_params); return run_command_hef(m_params);
@@ -131,7 +132,7 @@ Expected<InferResult> BenchmarkCommand::hw_only_mode()
Expected<InferResult> BenchmarkCommand::fps_streaming_mode() Expected<InferResult> BenchmarkCommand::fps_streaming_mode()
{ {
m_params.power_measurement.measure_power = !m_not_measure_power; m_params.power_measurement.measure_power = ShouldMeasurePower::AUTO_DETECT;
m_params.mode = InferMode::STREAMING; m_params.mode = InferMode::STREAMING;
m_params.measure_latency = false; m_params.measure_latency = false;
m_params.transform.transform = true; m_params.transform.transform = true;
@@ -141,7 +142,7 @@ Expected<InferResult> BenchmarkCommand::fps_streaming_mode()
Expected<InferResult> BenchmarkCommand::latency() Expected<InferResult> BenchmarkCommand::latency()
{ {
m_params.power_measurement.measure_power = false; m_params.power_measurement.measure_power = ShouldMeasurePower::NO;
m_params.measure_latency = true; m_params.measure_latency = true;
m_params.mode = InferMode::STREAMING; m_params.mode = InferMode::STREAMING;
m_params.transform.transform = true; m_params.transform.transform = true;

View File

@@ -15,9 +15,6 @@
BoardConfigCommand::BoardConfigCommand(CLI::App &parent_app) : BoardConfigCommand::BoardConfigCommand(CLI::App &parent_app) :
ContainerCommand(parent_app.add_subcommand("board-config", "Board configuration tool")) ContainerCommand(parent_app.add_subcommand("board-config", "Board configuration tool"))
{ {
// This will make the board-config command to be hidden in the --help print in the command line.
m_app->group("");
add_subcommand<BoardConfigReadSubcommand>(); add_subcommand<BoardConfigReadSubcommand>();
add_subcommand<BoardConfigWriteSubcommand>(); add_subcommand<BoardConfigWriteSubcommand>();
} }

View File

@@ -44,11 +44,11 @@ public:
protected: protected:
template<typename CommandType> template<typename CommandType>
CommandType &add_subcommand(bool hidden = false) CommandType &add_subcommand(OptionVisibility visibility = OptionVisibility::VISIBLE)
{ {
// Unnamed "option groups" hide subcommands/options from the help message // Unnamed "option groups" hide subcommands/options from the help message
// (see https://github.com/CLIUtils/CLI11/blob/main/README.md) // (see https://github.com/CLIUtils/CLI11/blob/main/README.md)
auto *parent = hidden ? m_app->add_option_group("") : m_app; auto *parent = (visibility == OptionVisibility::HIDDEN) ? m_app->add_option_group("") : m_app;
auto command = std::make_shared<CommandType>(*parent); auto command = std::make_shared<CommandType>(*parent);
m_subcommands.push_back(command); m_subcommands.push_back(command);
return *command; return *command;

View File

@@ -362,6 +362,14 @@ Expected<ordered_json> DownloadActionListCommand::parse_action_data(uint32_t bas
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__resume_vdma_channel_action_data_t *>(action); data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__resume_vdma_channel_action_data_t *>(action);
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__resume_vdma_channel_action_data_t); action_length_local = sizeof(CONTEXT_SWITCH_DEFS__resume_vdma_channel_action_data_t);
break; break;
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_SLEEP:
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__sleep_action_data_t *>(action);
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__sleep_action_data_t);
break;
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_HALT:
data_json = json({});
action_length_local = 0;
break;
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT: case CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT:
// Fallthrough // Fallthrough
// Handling CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT is needed because we compile this file with -Wswitch-enum // Handling CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT is needed because we compile this file with -Wswitch-enum
@@ -413,9 +421,10 @@ Expected<ordered_json> DownloadActionListCommand::parse_context(Device &device,
uint8_t converted_context_type = static_cast<uint8_t>(context_type); uint8_t converted_context_type = static_cast<uint8_t>(context_type);
uint32_t action_list_base_address = 0; uint32_t action_list_base_address = 0;
uint32_t batch_counter = 0; uint32_t batch_counter = 0;
uint32_t idle_time = 0;
TRY(auto action_list, device.download_context_action_list(network_group_id, converted_context_type, context_index, TRY(auto action_list, device.download_context_action_list(network_group_id, converted_context_type, context_index,
&action_list_base_address, &batch_counter)); &action_list_base_address, &batch_counter, &idle_time));
// Needs to fit in 2 bytes due to firmware limitation of action list size // Needs to fit in 2 bytes due to firmware limitation of action list size
CHECK_AS_EXPECTED(IS_FIT_IN_UINT16(action_list.size()), HAILO_INTERNAL_FAILURE, CHECK_AS_EXPECTED(IS_FIT_IN_UINT16(action_list.size()), HAILO_INTERNAL_FAILURE,
"Action list size is expected to fit in 2B. actual size is {}", action_list.size()); "Action list size is expected to fit in 2B. actual size is {}", action_list.size());
@@ -424,6 +433,7 @@ Expected<ordered_json> DownloadActionListCommand::parse_context(Device &device,
{"action_list_base_address", action_list_base_address}, {"action_list_base_address", action_list_base_address},
{"action_list_size", action_list.size() }, {"action_list_size", action_list.size() },
{"batch_counter", batch_counter}, {"batch_counter", batch_counter},
{"idle_time", idle_time},
{"context_name", context_name}, {"context_name", context_name},
}; };

View File

@@ -25,6 +25,7 @@ using ordered_json = nlohmann::ordered_json;
class DownloadActionListCommand : public DeviceCommand class DownloadActionListCommand : public DeviceCommand
{ {
public: public:
using DeviceCommand::execute;
explicit DownloadActionListCommand(CLI::App &parent_app); explicit DownloadActionListCommand(CLI::App &parent_app);
// To be used from external commands // To be used from external commands
static hailo_status execute(Device &device, const std::string &output_file_path, static hailo_status execute(Device &device, const std::string &output_file_path,
@@ -115,6 +116,8 @@ static std::pair<CONTEXT_SWITCH_DEFS__ACTION_TYPE_t, std::string> mapping[] = {
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_CHANGE_BOUNDARY_INPUT_BATCH, "change boundary input batch"}, {CONTEXT_SWITCH_DEFS__ACTION_TYPE_CHANGE_BOUNDARY_INPUT_BATCH, "change boundary input batch"},
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_PAUSE_VDMA_CHANNEL, "pause vdma channel"}, {CONTEXT_SWITCH_DEFS__ACTION_TYPE_PAUSE_VDMA_CHANNEL, "pause vdma channel"},
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_RESUME_VDMA_CHANNEL, "resume vdma channel"}, {CONTEXT_SWITCH_DEFS__ACTION_TYPE_RESUME_VDMA_CHANNEL, "resume vdma channel"},
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_SLEEP, "sleep"},
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_HALT, "halt"},
}; };
static_assert(ARRAY_ENTRIES(mapping) == CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT, static_assert(ARRAY_ENTRIES(mapping) == CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT,
"Missing a mapping from a CONTEXT_SWITCH_DEFS__ACTION_TYPE_t to it's string value"); "Missing a mapping from a CONTEXT_SWITCH_DEFS__ACTION_TYPE_t to it's string value");
@@ -130,6 +133,7 @@ NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__module_config_done_inter
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t, config_stream_index, ccw_bursts); NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t, config_stream_index, ccw_bursts);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__enable_nms_action_t, nms_unit_index, network_index, number_of_classes, burst_size); NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__enable_nms_action_t, nms_unit_index, network_index, number_of_classes, burst_size);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__write_data_by_type_action_t, address, data_type, data, shift, mask, network_index); NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__write_data_by_type_action_t, address, data_type, data, shift, mask, network_index);
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__sleep_action_data_t, sleep_time);
// Non-default implementations // Non-default implementations
void to_json(json &j, const CONTEXT_SWITCH_DEFS__deactivate_vdma_channel_action_data_t &data); void to_json(json &j, const CONTEXT_SWITCH_DEFS__deactivate_vdma_channel_action_data_t &data);

View File

@@ -226,11 +226,31 @@ hailo_status FwControlTestMemoriesCommand::execute_on_device(Device &device)
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
FwControlDebugHaltContinueCommand::FwControlDebugHaltContinueCommand(CLI::App &parent_app) :
DeviceCommand(parent_app.add_subcommand("continue", "Continue breakpoint action"))
{}
hailo_status FwControlDebugHaltContinueCommand::execute_on_device(Device &device)
{
auto status = device.continue_context_switch_breakpoint(0);
CHECK_SUCCESS(status, "Failed to excute debug operation");
std::cout << "Control Operation Debug Continue completed successfully" << std::endl;
return HAILO_SUCCESS;
}
FwControlDebugCommand::FwControlDebugCommand(CLI::App &parent_app) :
ContainerCommand(parent_app.add_subcommand("debug", "Access to usefull debug operations"))
{
add_subcommand<FwControlDebugHaltContinueCommand>();
}
FwControlCommand::FwControlCommand(CLI::App &parent_app) : FwControlCommand::FwControlCommand(CLI::App &parent_app) :
ContainerCommand(parent_app.add_subcommand("fw-control", "Useful firmware control operations")) ContainerCommand(parent_app.add_subcommand("fw-control", "Useful firmware control operations"))
{ {
add_subcommand<FwControlIdentifyCommand>(); add_subcommand<FwControlIdentifyCommand>();
add_subcommand<FwControlResetCommand>(); add_subcommand<FwControlResetCommand>(OptionVisibility::HIDDEN);
add_subcommand<FwControlTestMemoriesCommand>(); add_subcommand<FwControlTestMemoriesCommand>(OptionVisibility::HIDDEN);
add_subcommand<DownloadActionListCommand>(); add_subcommand<DownloadActionListCommand>(OptionVisibility::HIDDEN);
add_subcommand<FwControlDebugCommand>(OptionVisibility::HIDDEN);
} }

View File

@@ -44,6 +44,19 @@ protected:
virtual hailo_status execute_on_device(Device &device) override; virtual hailo_status execute_on_device(Device &device) override;
}; };
class FwControlDebugHaltContinueCommand : public DeviceCommand {
public:
explicit FwControlDebugHaltContinueCommand(CLI::App &parent_app);
protected:
virtual hailo_status execute_on_device(Device &device) override;
};
class FwControlDebugCommand : public ContainerCommand {
public:
explicit FwControlDebugCommand(CLI::App &parent_app);
};
class FwControlCommand : public ContainerCommand { class FwControlCommand : public ContainerCommand {
public: public:
explicit FwControlCommand(CLI::App &parent_app); explicit FwControlCommand(CLI::App &parent_app);

View File

@@ -190,7 +190,7 @@ public:
add_subcommand<BenchmarkCommand>(); add_subcommand<BenchmarkCommand>();
add_subcommand<PowerMeasurementSubcommand>(); add_subcommand<PowerMeasurementSubcommand>();
add_subcommand<SensorConfigCommand>(); add_subcommand<SensorConfigCommand>();
add_subcommand<BoardConfigCommand>(); add_subcommand<BoardConfigCommand>(OptionVisibility::HIDDEN);
add_subcommand<FwConfigCommand>(); add_subcommand<FwConfigCommand>();
add_subcommand<FwLoggerCommand>(); add_subcommand<FwLoggerCommand>();
add_subcommand<FwUpdateCommand>(); add_subcommand<FwUpdateCommand>();
@@ -198,7 +198,7 @@ public:
add_subcommand<MonCommand>(); add_subcommand<MonCommand>();
#if defined(__GNUC__) #if defined(__GNUC__)
add_subcommand<UdpRateLimiterCommand>(); add_subcommand<UdpRateLimiterCommand>();
add_subcommand<HwInferEstimatorCommand>(); add_subcommand<HwInferEstimatorCommand>(OptionVisibility::HIDDEN);
#endif #endif
add_subcommand<ParseHefCommand>(); add_subcommand<ParseHefCommand>();
add_subcommand<FwControlCommand>(); add_subcommand<FwControlCommand>();

View File

@@ -342,6 +342,7 @@ public:
std::map<std::string, std::shared_ptr<LongPowerMeasurement>> m_power_measurements; std::map<std::string, std::shared_ptr<LongPowerMeasurement>> m_power_measurements;
std::map<std::string, std::shared_ptr<LongPowerMeasurement>> m_current_measurements; std::map<std::string, std::shared_ptr<LongPowerMeasurement>> m_current_measurements;
std::map<std::string, std::shared_ptr<AccumulatorResults>> m_temp_measurements; std::map<std::string, std::shared_ptr<AccumulatorResults>> m_temp_measurements;
bool power_measurements_are_valid = false;
private: private:
std::vector<NetworkGroupInferResult> m_network_group_results; std::vector<NetworkGroupInferResult> m_network_group_results;

View File

@@ -16,6 +16,8 @@
#include "hailo/vstream.hpp" #include "hailo/vstream.hpp"
#include "hailo/vdevice.hpp" #include "hailo/vdevice.hpp"
#include "common/internal_env_vars.hpp"
#include <iostream> #include <iostream>
#define BYTES_TO_KILOBYTES (1024) #define BYTES_TO_KILOBYTES (1024)
@@ -25,9 +27,6 @@ HwInferEstimatorCommand::HwInferEstimatorCommand(CLI::App &parent_app) :
"measure nerual network performance for given network using only the HW components without host SW")), "measure nerual network performance for given network using only the HW components without host SW")),
m_params({}) m_params({})
{ {
// This will make the command to be hidden in the --help print in the command line.
m_app->group("");
add_vdevice_options(m_app, m_params.vdevice_params); add_vdevice_options(m_app, m_params.vdevice_params);
m_app->add_option("hef", m_params.hef_path, "Path of the HEF to load") m_app->add_option("hef", m_params.hef_path, "Path of the HEF to load")
->check(CLI::ExistingFile) ->check(CLI::ExistingFile)
@@ -81,10 +80,10 @@ hailo_status HwInferEstimatorCommand::execute()
TRY(auto configure_params, get_configure_params(m_params, hef, interface)); TRY(auto configure_params, get_configure_params(m_params, hef, interface));
/* Use Env var to configure all desc list with max depth */ /* Use Env var to configure all desc list with max depth */
setenv("HAILO_CONFIGURE_FOR_HW_INFER","Y",1); setenv(HAILO_CONFIGURE_FOR_HW_INFER_ENV_VAR,"Y",1);
TRY(auto network_group_list, TRY(auto network_group_list,
device->configure(hef, configure_params), "Failed configure device from hef"); device->configure(hef, configure_params), "Failed configure device from hef");
unsetenv("HAILO_CONFIGURE_FOR_HW_INFER"); unsetenv(HAILO_CONFIGURE_FOR_HW_INFER_ENV_VAR);
CHECK(1 == network_group_list.size(), HAILO_INVALID_OPERATION, CHECK(1 == network_group_list.size(), HAILO_INVALID_OPERATION,
"HW Inference is not supported on HEFs with multiple network groups"); "HW Inference is not supported on HEFs with multiple network groups");

View File

@@ -10,6 +10,7 @@
#include "hailo/hailort.h" #include "hailo/hailort.h"
#include "common/filesystem.hpp" #include "common/filesystem.hpp"
#include "common/env_vars.hpp"
#include "mon_command.hpp" #include "mon_command.hpp"
#include "common.hpp" #include "common.hpp"

View File

@@ -138,8 +138,19 @@ Expected<std::string> NetworkRunner::get_network_group_name(const NetworkParams
Expected<std::shared_ptr<FullAsyncNetworkRunner>> FullAsyncNetworkRunner::create_shared(VDevice &vdevice, Expected<std::shared_ptr<FullAsyncNetworkRunner>> FullAsyncNetworkRunner::create_shared(VDevice &vdevice,
NetworkParams params) NetworkParams params)
{ {
TRY(auto infer_model_ptr, vdevice.create_infer_model(params.hef_path)); std::string net_group_name = params.net_group_name;
TRY(auto net_group_name, get_network_group_name(params, infer_model_ptr->hef())); if (net_group_name.empty()) {
TRY(auto hef, Hef::create(params.hef_path));
TRY(net_group_name, get_network_group_name(params, hef));
}
TRY(auto infer_model_ptr, vdevice.create_infer_model(params.hef_path, net_group_name));
/* Validate params */
for (const auto &vstream_params : params.vstream_params) {
CHECK_AS_EXPECTED((contains(infer_model_ptr->get_input_names(), vstream_params.name)) ||
(contains(infer_model_ptr->get_output_names(), vstream_params.name)),
HAILO_INVALID_ARGUMENT, "The model doesnt have an edge with the given name '{}'", vstream_params.name);
}
/* Configure Params */ /* Configure Params */
infer_model_ptr->set_batch_size(params.batch_size); infer_model_ptr->set_batch_size(params.batch_size);
@@ -263,6 +274,14 @@ Expected<std::shared_ptr<NetworkRunner>> NetworkRunner::create_shared(VDevice &v
auto output_streams = cfgr_net_group->get_output_streams(); auto output_streams = cfgr_net_group->get_output_streams();
CHECK_AS_EXPECTED(output_streams.size() > 0, HAILO_INTERNAL_FAILURE); CHECK_AS_EXPECTED(output_streams.size() > 0, HAILO_INTERNAL_FAILURE);
/* Validate params */
for (const auto &stream_param : final_net_params.stream_params) {
CHECK_AS_EXPECTED(
(std::any_of(input_streams.begin(), input_streams.end(), [name = stream_param.name] (const auto &stream) { return name == stream.get().name(); })) ||
(std::any_of(output_streams.begin(), output_streams.end(), [name = stream_param.name] (const auto &stream) { return name == stream.get().name(); })),
HAILO_INVALID_ARGUMENT, "The model doesnt have an edge with the given name '{}'", stream_param.name);
}
auto net_runner = make_shared_nothrow<RawNetworkRunner>(final_net_params, net_group_name, vdevice, auto net_runner = make_shared_nothrow<RawNetworkRunner>(final_net_params, net_group_name, vdevice,
std::move(input_streams), std::move(output_streams), cfgr_net_group); std::move(input_streams), std::move(output_streams), cfgr_net_group);
CHECK_NOT_NULL_AS_EXPECTED(net_runner, HAILO_OUT_OF_HOST_MEMORY); CHECK_NOT_NULL_AS_EXPECTED(net_runner, HAILO_OUT_OF_HOST_MEMORY);
@@ -370,13 +389,20 @@ double NetworkRunner::get_last_measured_fps()
Expected<std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>> NetworkRunner::create_vstreams( Expected<std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>> NetworkRunner::create_vstreams(
ConfiguredNetworkGroup &net_group, const std::map<std::string, hailo_vstream_params_t> &params) ConfiguredNetworkGroup &net_group, const std::map<std::string, hailo_vstream_params_t> &params)
{//TODO: support network name {//TODO: support network name
size_t match_count = 0;
/* Validate params */
TRY(auto input_vstreams_info, net_group.get_input_vstream_infos());
TRY(auto output_vstreams_info, net_group.get_output_vstream_infos());
for (const auto &pair : params) {
CHECK_AS_EXPECTED(
(std::any_of(input_vstreams_info.begin(), input_vstreams_info.end(), [name = pair.first] (const auto &info) { return name == std::string(info.name); })) ||
(std::any_of(output_vstreams_info.begin(), output_vstreams_info.end(), [name = pair.first] (const auto &info) { return name == std::string(info.name); })),
HAILO_INVALID_ARGUMENT, "The model doesnt have an edge with the given name '{}'", pair.first);
}
std::map<std::string, hailo_vstream_params_t> input_vstreams_params; std::map<std::string, hailo_vstream_params_t> input_vstreams_params;
TRY(auto input_vstreams_info, net_group.get_input_vstream_infos());
for (auto &input_vstream_info : input_vstreams_info) { for (auto &input_vstream_info : input_vstreams_info) {
if (params.end() != params.find(input_vstream_info.name)) { if (params.end() != params.find(input_vstream_info.name)) {
match_count++;
input_vstreams_params.emplace(input_vstream_info.name, params.at(input_vstream_info.name)); input_vstreams_params.emplace(input_vstream_info.name, params.at(input_vstream_info.name));
} else { } else {
input_vstreams_params.emplace(input_vstream_info.name, HailoRTDefaults::get_vstreams_params()); input_vstreams_params.emplace(input_vstream_info.name, HailoRTDefaults::get_vstreams_params());
@@ -384,18 +410,14 @@ Expected<std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>> Netwo
} }
std::map<std::string, hailo_vstream_params_t> output_vstreams_params; std::map<std::string, hailo_vstream_params_t> output_vstreams_params;
TRY(auto output_vstreams_info, net_group.get_output_vstream_infos());
for (auto &output_vstream_info : output_vstreams_info) { for (auto &output_vstream_info : output_vstreams_info) {
if (params.end() != params.find(output_vstream_info.name)) { if (params.end() != params.find(output_vstream_info.name)) {
match_count++;
output_vstreams_params.emplace(output_vstream_info.name, params.at(output_vstream_info.name)); output_vstreams_params.emplace(output_vstream_info.name, params.at(output_vstream_info.name));
} else { } else {
output_vstreams_params.emplace(output_vstream_info.name, HailoRTDefaults::get_vstreams_params()); output_vstreams_params.emplace(output_vstream_info.name, HailoRTDefaults::get_vstreams_params());
} }
} }
CHECK(match_count == params.size(), make_unexpected(HAILO_INVALID_ARGUMENT), "One of the params has an invalid vStream name");
TRY(auto input_vstreams, VStreamsBuilder::create_input_vstreams(net_group, input_vstreams_params)); TRY(auto input_vstreams, VStreamsBuilder::create_input_vstreams(net_group, input_vstreams_params));
TRY(auto output_vstreams, VStreamsBuilder::create_output_vstreams(net_group, output_vstreams_params)); TRY(auto output_vstreams, VStreamsBuilder::create_output_vstreams(net_group, output_vstreams_params));

View File

@@ -739,18 +739,15 @@ Expected<std::vector<std::shared_ptr<NetworkRunner>>> Run2::init_and_run_net_run
if (get_measure_power() || get_measure_current() || get_measure_temp()) { if (get_measure_power() || get_measure_current() || get_measure_temp()) {
TRY(auto physical_devices, vdevice->get_physical_devices()); TRY(auto physical_devices, vdevice->get_physical_devices());
for (auto &device : physical_devices) { for (auto &device : physical_devices) {
TRY(const auto identity, device.get().identify()); TRY(auto caps, device.get().get_capabilities(), "Failed getting device capabilities");
CHECK_AS_EXPECTED(HailoRTCommon::is_power_measurement_supported(identity.device_architecture) || !(get_measure_power()),
HAILO_INVALID_OPERATION, "HW arch {} does not support power measurement. Disable the power-measure option", CHECK_AS_EXPECTED((caps.power_measurements || (get_measure_power())),
HailoRTCommon::get_device_arch_str(identity.device_architecture)); HAILO_INVALID_OPERATION, "Power measurement not supported. Disable the power-measure option");
CHECK_AS_EXPECTED(HailoRTCommon::is_current_measurement_supported(identity.device_architecture) || !(get_measure_current()), CHECK_AS_EXPECTED((caps.current_measurements || !(get_measure_current())),
HAILO_INVALID_OPERATION, "HW arch {} does not support current measurement. Disable the current-measure option", HAILO_INVALID_OPERATION, "Current measurement not supported. Disable the current-measure option");
HailoRTCommon::get_device_arch_str(identity.device_architecture)); CHECK_AS_EXPECTED((caps.temperature_measurements || !(get_measure_temp())),
CHECK_AS_EXPECTED(HailoRTCommon::is_temp_measurement_supported(identity.device_architecture) || !(get_measure_temp()), HAILO_INVALID_OPERATION, "Temperature measurement not supported. Disable the temp-measure option");
HAILO_INVALID_OPERATION, "HW arch {} does not support temperature measurement. Disable the temp-measure option",
HailoRTCommon::get_device_arch_str(identity.device_architecture));
TRY(auto measurement_live_track, MeasurementLiveTrack::create_shared(device.get(), TRY(auto measurement_live_track, MeasurementLiveTrack::create_shared(device.get(),
get_measure_power(), get_measure_current(), get_measure_temp())); get_measure_power(), get_measure_current(), get_measure_temp()));

View File

@@ -90,5 +90,4 @@ private:
NetworkParams m_params; NetworkParams m_params;
}; };
#endif /* _HAILO_HAILORTCLI_RUN2_RUN2_COMMAND_HPP_ */ #endif /* _HAILO_HAILORTCLI_RUN2_RUN2_COMMAND_HPP_ */

View File

@@ -107,7 +107,7 @@ static void add_run_command_params(CLI::App *run_subcommand, inference_runner_pa
// TODO: init values in RunCommand ctor // TODO: init values in RunCommand ctor
params.measure_latency = false; params.measure_latency = false;
params.measure_overall_latency = false; params.measure_overall_latency = false;
params.power_measurement.measure_power = false; params.power_measurement.measure_power = ShouldMeasurePower::NO;
params.power_measurement.measure_current = false; params.power_measurement.measure_current = false;
params.show_progress = true; params.show_progress = true;
params.time_to_run = 0; params.time_to_run = 0;
@@ -167,8 +167,8 @@ static void add_run_command_params(CLI::App *run_subcommand, inference_runner_pa
run_subcommand->add_option("--dot", params.dot_output, run_subcommand->add_option("--dot", params.dot_output,
"If set print the pipeline graph as a .dot file at the specified path") "If set print the pipeline graph as a .dot file at the specified path")
->check(FileSuffixValidator(DOT_SUFFIX)); ->check(FileSuffixValidator(DOT_SUFFIX));
CLI::Option *measure_power_opt = run_subcommand->add_flag("--measure-power", auto measure_power_cb = [&params] (bool measure_power) { params.power_measurement.measure_power = measure_power ? ShouldMeasurePower::YES : ShouldMeasurePower::NO; };
params.power_measurement.measure_power, "Measure power consumption"); CLI::Option *measure_power_opt = run_subcommand->add_flag( "--measure-power", measure_power_cb, "Measure power consumption");
CLI::Option *measure_current_opt = run_subcommand->add_flag("--measure-current", CLI::Option *measure_current_opt = run_subcommand->add_flag("--measure-current",
params.power_measurement.measure_current, "Measure current")->excludes(measure_power_opt); params.power_measurement.measure_current, "Measure current")->excludes(measure_power_opt);
measure_power_opt->excludes(measure_current_opt); measure_power_opt->excludes(measure_current_opt);
@@ -271,7 +271,7 @@ static void add_run_command_params(CLI::App *run_subcommand, inference_runner_pa
"--batch-size should be a divisor of --frames-count if provided"); "--batch-size should be a divisor of --frames-count if provided");
// TODO HRT-5363 support multiple devices // TODO HRT-5363 support multiple devices
PARSE_CHECK((params.vdevice_params.device_count == 1) || params.csv_output.empty() || PARSE_CHECK((params.vdevice_params.device_count == 1) || params.csv_output.empty() ||
!(params.power_measurement.measure_power || params.power_measurement.measure_current || params.measure_temp), !((ShouldMeasurePower::YES == params.power_measurement.measure_power) || params.power_measurement.measure_current || params.measure_temp),
"Writing measurements in csv format is not supported for multiple devices"); "Writing measurements in csv format is not supported for multiple devices");
if ((0 == params.time_to_run) && (0 == params.frames_count)) { if ((0 == params.time_to_run) && (0 == params.frames_count)) {
@@ -1036,10 +1036,12 @@ Expected<InferResult> activate_and_run_single_device(
CHECK_AS_EXPECTED(1 == network_groups.size(), HAILO_INVALID_OPERATION, "Inference is not supported on HEFs with multiple network groups"); CHECK_AS_EXPECTED(1 == network_groups.size(), HAILO_INVALID_OPERATION, "Inference is not supported on HEFs with multiple network groups");
TRY(auto activated_net_group, network_groups[0]->activate(), "Failed activate network_group"); TRY(auto activated_net_group, network_groups[0]->activate(), "Failed activate network_group");
TRY(auto input_dataset, create_dataset(network_groups, params)); TRY(auto input_dataset, create_dataset(network_groups, params));
TRY(auto caps, device.get_capabilities());
hailo_power_measurement_types_t measurement_type = HAILO_POWER_MEASUREMENT_TYPES__MAX_ENUM; hailo_power_measurement_types_t measurement_type = HAILO_POWER_MEASUREMENT_TYPES__MAX_ENUM;
bool should_measure_power = false; bool should_measure_power = false;
if (params.power_measurement.measure_power) { if ((ShouldMeasurePower::YES == params.power_measurement.measure_power) ||
((ShouldMeasurePower::AUTO_DETECT == params.power_measurement.measure_power) && caps.power_measurements)) {
measurement_type = HAILO_POWER_MEASUREMENT_TYPES__POWER; measurement_type = HAILO_POWER_MEASUREMENT_TYPES__POWER;
should_measure_power = true; should_measure_power = true;
} else if (params.power_measurement.measure_current) { } else if (params.power_measurement.measure_current) {
@@ -1079,6 +1081,7 @@ Expected<InferResult> activate_and_run_single_device(
status = inference_result.set_power_measurement(device.get_dev_id(), std::move(long_power_measurement_ptr)); status = inference_result.set_power_measurement(device.get_dev_id(), std::move(long_power_measurement_ptr));
CHECK_SUCCESS_AS_EXPECTED(status); CHECK_SUCCESS_AS_EXPECTED(status);
} }
inference_result.power_measurements_are_valid = true;
} }
if (should_measure_temp) { if (should_measure_temp) {
@@ -1157,10 +1160,20 @@ Expected<InferResult> activate_and_run_vdevice(
} }
TRY(const auto input_dataset, create_dataset(network_groups, params), "Failed creating input dataset"); TRY(const auto input_dataset, create_dataset(network_groups, params), "Failed creating input dataset");
// we currently support all devices or none for power measurements
auto all_phy_devices_support_power_measurements = true;
for (const auto &device : physical_devices) {
TRY(const auto caps, device.get().get_capabilities(), "Failed getting device capabilities");
if (!caps.power_measurements) {
all_phy_devices_support_power_measurements = false;
break;
}
}
hailo_power_measurement_types_t measurement_type = HAILO_POWER_MEASUREMENT_TYPES__MAX_ENUM; hailo_power_measurement_types_t measurement_type = HAILO_POWER_MEASUREMENT_TYPES__MAX_ENUM;
bool should_measure_power = false; bool should_measure_power = false;
if (params.power_measurement.measure_power) { if ((ShouldMeasurePower::YES == params.power_measurement.measure_power) ||
((ShouldMeasurePower::AUTO_DETECT == params.power_measurement.measure_power) && all_phy_devices_support_power_measurements)) {
measurement_type = HAILO_POWER_MEASUREMENT_TYPES__POWER; measurement_type = HAILO_POWER_MEASUREMENT_TYPES__POWER;
should_measure_power = true; should_measure_power = true;
} else if (params.power_measurement.measure_current) { } else if (params.power_measurement.measure_current) {
@@ -1215,6 +1228,7 @@ Expected<InferResult> activate_and_run_vdevice(
} }
} }
CHECK_SUCCESS_AS_EXPECTED(status); CHECK_SUCCESS_AS_EXPECTED(status);
inference_result.power_measurements_are_valid = true;
} }
if (params.measure_temp) { if (params.measure_temp) {
@@ -1261,23 +1275,18 @@ Expected<InferResult> run_command_hef_vdevice(const inference_runner_params &par
} }
TRY(const auto interface, vdevice->get_default_streams_interface(), "Failed to get default streams interface"); TRY(const auto interface, vdevice->get_default_streams_interface(), "Failed to get default streams interface");
TRY(auto configure_params, get_configure_params(params, hef, interface)); TRY(auto configure_params, get_configure_params(params, hef, interface), "Failed getting configure params");
TRY(auto network_group_list, vdevice->configure(hef, configure_params), "Failed configure vdevice from hef"); TRY(auto network_group_list, vdevice->configure(hef, configure_params), "Failed configure vdevice from hef");
for (auto &device : physical_devices) { for (auto &device : physical_devices) {
TRY(const auto identity, device.get().identify()); TRY(auto caps, device.get().get_capabilities(), "Failed getting device capabilities");
CHECK_AS_EXPECTED((HailoRTCommon::is_power_measurement_supported(identity.device_architecture) ||
!(params.power_measurement.measure_power)), HAILO_INVALID_OPERATION, CHECK_AS_EXPECTED((caps.power_measurements || (params.power_measurement.measure_power != ShouldMeasurePower::YES)),
"HW arch {} does not support power measurement. Disable the power-measure option", HAILO_INVALID_OPERATION, "Power measurement not supported. Disable the power-measure option");
HailoRTCommon::get_device_arch_str(identity.device_architecture)); CHECK_AS_EXPECTED((caps.current_measurements || !(params.power_measurement.measure_current)),
CHECK_AS_EXPECTED((HailoRTCommon::is_current_measurement_supported(identity.device_architecture) || HAILO_INVALID_OPERATION, "Current measurement not supported. Disable the current-measure option");
!(params.power_measurement.measure_current)), HAILO_INVALID_OPERATION, CHECK_AS_EXPECTED((caps.temperature_measurements || !(params.measure_temp)),
"HW arch {} does not support current measurement. Disable the current-measure option", HAILO_INVALID_OPERATION, "Temperature measurement not supported. Disable the temp-measure option");
HailoRTCommon::get_device_arch_str(identity.device_architecture));
CHECK_AS_EXPECTED((HailoRTCommon::is_temp_measurement_supported(identity.device_architecture) ||
!(params.measure_temp)), HAILO_INVALID_OPERATION,
"HW arch {} does not support temperature measurement. Disable the temp-measure option",
HailoRTCommon::get_device_arch_str(identity.device_architecture));
if (use_batch_to_measure_opt(params)) { if (use_batch_to_measure_opt(params)) {
status = DownloadActionListCommand::set_batch_to_measure(device.get(), params.runtime_data.batch_to_measure); status = DownloadActionListCommand::set_batch_to_measure(device.get(), params.runtime_data.batch_to_measure);

View File

@@ -30,7 +30,7 @@ struct transformation_params {
}; };
struct measure_power_params { struct measure_power_params {
bool measure_power; ShouldMeasurePower measure_power;
bool measure_current; bool measure_current;
uint32_t sampling_period; uint32_t sampling_period;
uint32_t averaging_factor; uint32_t averaging_factor;

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
set(HRPC_IMPL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/os") set(HRPC_IMPL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/os")
if(WIN32) if(WIN32)

View File

@@ -42,7 +42,7 @@ hailo_status ResultEvent::wait(std::chrono::milliseconds timeout)
Client::~Client() Client::~Client()
{ {
is_running = false; m_is_running = false;
(void)m_connection.close(); (void)m_connection.close();
if (m_thread.joinable()) { if (m_thread.joinable()) {
m_thread.join(); m_thread.join();
@@ -51,7 +51,7 @@ Client::~Client()
hailo_status Client::connect() hailo_status Client::connect()
{ {
TRY(m_conn_context, ConnectionContext::create_shared(false)); TRY(m_conn_context, ConnectionContext::create_client_shared(m_device_id));
TRY(auto conn, RawConnection::create_shared(m_conn_context)); TRY(auto conn, RawConnection::create_shared(m_conn_context));
auto status = conn->connect(); auto status = conn->connect();
CHECK_SUCCESS(status); CHECK_SUCCESS(status);
@@ -68,7 +68,7 @@ hailo_status Client::connect()
hailo_status Client::message_loop() hailo_status Client::message_loop()
{ {
while (is_running) { while (m_is_running) {
rpc_message_header_t header; rpc_message_header_t header;
TRY_WITH_ACCEPTABLE_STATUS(HAILO_COMMUNICATION_CLOSED, auto message, m_connection.read_message(header)); TRY_WITH_ACCEPTABLE_STATUS(HAILO_COMMUNICATION_CLOSED, auto message, m_connection.read_message(header));
@@ -80,9 +80,16 @@ hailo_status Client::message_loop()
continue; continue;
} }
std::unique_lock<std::mutex> lock(m_message_mutex); std::shared_ptr<ResultEvent> event = nullptr;
auto event = m_events[header.message_id]; {
lock.unlock(); std::unique_lock<std::mutex> lock(m_events_mutex);
m_events_cv.wait(lock, [this, &header] () {
return contains(m_events, header.message_id);
});
event = m_events[header.message_id];
m_events.erase(header.message_id);
}
auto status = event->signal(std::move(message)); auto status = event->signal(std::move(message));
CHECK_SUCCESS(status); CHECK_SUCCESS(status);
} }
@@ -93,8 +100,9 @@ hailo_status Client::message_loop()
Expected<Buffer> Client::execute_request(HailoRpcActionID action_id, const MemoryView &request, Expected<Buffer> Client::execute_request(HailoRpcActionID action_id, const MemoryView &request,
std::function<hailo_status(RpcConnection)> write_buffers_callback) std::function<hailo_status(RpcConnection)> write_buffers_callback)
{ {
std::unique_lock<std::mutex> lock(m_message_mutex);
rpc_message_header_t header; rpc_message_header_t header;
{
std::unique_lock<std::mutex> lock(m_write_mutex);
header.size = static_cast<uint32_t>(request.size()); header.size = static_cast<uint32_t>(request.size());
header.message_id = m_messages_sent++; header.message_id = m_messages_sent++;
header.action_id = static_cast<uint32_t>(action_id); header.action_id = static_cast<uint32_t>(action_id);
@@ -105,15 +113,19 @@ Expected<Buffer> Client::execute_request(HailoRpcActionID action_id, const Memor
status = write_buffers_callback(m_connection); status = write_buffers_callback(m_connection);
CHECK_SUCCESS_AS_EXPECTED(status); CHECK_SUCCESS_AS_EXPECTED(status);
} }
}
TRY(auto event, ResultEvent::create_shared()); std::shared_ptr<ResultEvent> event = nullptr;
{
std::unique_lock<std::mutex> events_lock(m_events_mutex);
TRY(event, ResultEvent::create_shared());
m_events[header.message_id] = event; m_events[header.message_id] = event;
}
m_events_cv.notify_all();
lock.unlock(); auto status = event->wait(REQUEST_TIMEOUT);
status = event->wait(REQUEST_TIMEOUT);
CHECK_SUCCESS_AS_EXPECTED(status); CHECK_SUCCESS_AS_EXPECTED(status);
m_events.erase(header.message_id);
return event->release(); return event->release();
} }

View File

@@ -42,7 +42,7 @@ private:
class Client class Client
{ {
public: public:
Client() = default; Client(const std::string &device_id) : m_device_id(device_id), m_is_running(true) {}
~Client(); ~Client();
hailo_status connect(); hailo_status connect();
@@ -53,14 +53,17 @@ public:
protected: protected:
hailo_status message_loop(); hailo_status message_loop();
bool is_running = true; std::string m_device_id;
bool m_is_running;
std::shared_ptr<ConnectionContext> m_conn_context; std::shared_ptr<ConnectionContext> m_conn_context;
RpcConnection m_connection; RpcConnection m_connection;
std::thread m_thread; std::thread m_thread;
std::unordered_map<uint32_t, std::shared_ptr<ResultEvent>> m_events; std::unordered_map<uint32_t, std::shared_ptr<ResultEvent>> m_events;
std::unordered_map<HailoRpcActionID, std::function<hailo_status(const MemoryView&, RpcConnection)>> m_custom_callbacks; std::unordered_map<HailoRpcActionID, std::function<hailo_status(const MemoryView&, RpcConnection)>> m_custom_callbacks;
uint32_t m_messages_sent = 0; uint32_t m_messages_sent = 0;
std::mutex m_message_mutex; std::mutex m_write_mutex;
std::condition_variable m_events_cv;
std::mutex m_events_mutex;
}; };
} // namespace hrpc } // namespace hrpc

View File

@@ -10,44 +10,59 @@
#include "hrpc/os/pcie/raw_connection_internal.hpp" #include "hrpc/os/pcie/raw_connection_internal.hpp"
#include "common/logger_macros.hpp" #include "common/logger_macros.hpp"
#include "common/utils.hpp" #include "common/utils.hpp"
#include "common/internal_env_vars.hpp"
#include "hailo/hailort.h" #include "hailo/hailort.h"
#include "vdma/driver/hailort_driver.hpp" #include "vdma/driver/hailort_driver.hpp"
// TODO: Remove this after we can choose ports in the driver // TODO: Remove this after we can choose ports in the driver
#define PCIE_PORT (1213355091) #define DEFAULT_PCIE_PORT (12133)
uint16_t get_pcie_port()
{
auto port_str = get_env_variable(HAILO_CONNECTION_PCIE_PORT_ENV_VAR);
if (port_str) {
return static_cast<uint16_t>(std::stoi(port_str.value()));
}
return DEFAULT_PCIE_PORT;
}
using namespace hrpc; using namespace hrpc;
Expected<std::shared_ptr<ConnectionContext>> PcieConnectionContext::create_shared(bool is_accepting) Expected<std::shared_ptr<ConnectionContext>> PcieConnectionContext::create_client_shared(const std::string &device_id)
{ {
const auto max_size = PcieSession::max_transfer_size(); const auto max_size = PcieSession::max_transfer_size();
TRY(auto write_buffer, Buffer::create(static_cast<size_t>(max_size), BufferStorageParams::create_dma())); TRY(auto write_buffer, Buffer::create(static_cast<size_t>(max_size), BufferStorageParams::create_dma()));
TRY(auto read_buffer, Buffer::create(static_cast<size_t>(max_size), BufferStorageParams::create_dma())); TRY(auto read_buffer, Buffer::create(static_cast<size_t>(max_size), BufferStorageParams::create_dma()));
std::shared_ptr<PcieConnectionContext> ptr = nullptr; if (device_id.size() > 0) {
if (is_accepting) { TRY(auto driver, HailoRTDriver::create_pcie(device_id));
// Server side auto ptr = make_shared_nothrow<PcieConnectionContext>(std::move(driver), false,
TRY(auto driver, HailoRTDriver::create_pcie_ep());
ptr = make_shared_nothrow<PcieConnectionContext>(std::move(driver), is_accepting,
std::move(write_buffer), std::move(read_buffer)); std::move(write_buffer), std::move(read_buffer));
CHECK_NOT_NULL(ptr, HAILO_OUT_OF_HOST_MEMORY); CHECK_NOT_NULL(ptr, HAILO_OUT_OF_HOST_MEMORY);
return std::dynamic_pointer_cast<ConnectionContext>(ptr); return std::dynamic_pointer_cast<ConnectionContext>(ptr);
} else { }
// Client side
TRY(auto device_infos, HailoRTDriver::scan_devices()); TRY(auto device_infos, HailoRTDriver::scan_devices(HailoRTDriver::AcceleratorType::SOC_ACCELERATOR));
CHECK(device_infos.size() > 0, HAILO_NOT_FOUND, "No devices found"); CHECK(device_infos.size() > 0, HAILO_NOT_FOUND, "No devices found");
for (auto &device_info : device_infos) {
if (HailoRTDriver::AcceleratorType::SOC_ACCELERATOR == device_info.accelerator_type) { TRY(auto driver, HailoRTDriver::create(device_infos[0].device_id, device_infos[0].dev_path));
TRY(auto driver, HailoRTDriver::create(device_info.device_id, device_info.dev_path)); auto ptr = make_shared_nothrow<PcieConnectionContext>(std::move(driver), false,
ptr = make_shared_nothrow<PcieConnectionContext>(std::move(driver), is_accepting,
std::move(write_buffer), std::move(read_buffer)); std::move(write_buffer), std::move(read_buffer));
CHECK_NOT_NULL(ptr, HAILO_OUT_OF_HOST_MEMORY); CHECK_NOT_NULL(ptr, HAILO_OUT_OF_HOST_MEMORY);
return std::dynamic_pointer_cast<ConnectionContext>(ptr); return std::dynamic_pointer_cast<ConnectionContext>(ptr);
} }
}
} Expected<std::shared_ptr<ConnectionContext>> PcieConnectionContext::create_server_shared()
LOGGER__ERROR("No suitable device found"); {
return make_unexpected(HAILO_NOT_FOUND); const auto max_size = PcieSession::max_transfer_size();
TRY(auto write_buffer, Buffer::create(static_cast<size_t>(max_size), BufferStorageParams::create_dma()));
TRY(auto read_buffer, Buffer::create(static_cast<size_t>(max_size), BufferStorageParams::create_dma()));
TRY(auto driver, HailoRTDriver::create_pcie_ep());
auto ptr = make_shared_nothrow<PcieConnectionContext>(std::move(driver), true,
std::move(write_buffer), std::move(read_buffer));
CHECK_NOT_NULL(ptr, HAILO_OUT_OF_HOST_MEMORY);
return std::dynamic_pointer_cast<ConnectionContext>(ptr);
} }
hailo_status PcieConnectionContext::wait_for_available_connection() hailo_status PcieConnectionContext::wait_for_available_connection()
@@ -86,7 +101,7 @@ Expected<std::shared_ptr<RawConnection>> PcieRawConnection::accept()
auto new_conn = make_shared_nothrow<PcieRawConnection>(m_context); auto new_conn = make_shared_nothrow<PcieRawConnection>(m_context);
CHECK_NOT_NULL_AS_EXPECTED(new_conn, HAILO_OUT_OF_HOST_MEMORY); CHECK_NOT_NULL_AS_EXPECTED(new_conn, HAILO_OUT_OF_HOST_MEMORY);
TRY(auto session, PcieSession::accept(m_context->driver(), PCIE_PORT)); TRY(auto session, PcieSession::accept(m_context->driver(), get_pcie_port()));
status = new_conn->set_session(std::move(session)); status = new_conn->set_session(std::move(session));
CHECK_SUCCESS(status); CHECK_SUCCESS(status);
@@ -103,14 +118,14 @@ hailo_status PcieRawConnection::set_session(PcieSession &&session)
hailo_status PcieRawConnection::connect() hailo_status PcieRawConnection::connect()
{ {
TRY(auto session, PcieSession::connect(m_context->driver(), PCIE_PORT)); TRY(auto session, PcieSession::connect(m_context->driver(), get_pcie_port()));
auto status = set_session(std::move(session)); auto status = set_session(std::move(session));
CHECK_SUCCESS(status); CHECK_SUCCESS(status);
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status PcieRawConnection::write(const uint8_t *buffer, size_t size) hailo_status PcieRawConnection::write(const uint8_t *buffer, size_t size, std::chrono::milliseconds timeout)
{ {
if (0 == size) { if (0 == size) {
return HAILO_SUCCESS; return HAILO_SUCCESS;
@@ -126,7 +141,7 @@ hailo_status PcieRawConnection::write(const uint8_t *buffer, size_t size)
auto size_left = size - bytes_written; auto size_left = size - bytes_written;
if (is_aligned) { if (is_aligned) {
amount_to_write = std::min(static_cast<size_t>(size_left), static_cast<size_t>(max_size)); amount_to_write = std::min(static_cast<size_t>(size_left), static_cast<size_t>(max_size));
auto status = m_session->write(buffer + bytes_written, amount_to_write, m_timeout); auto status = m_session->write(buffer + bytes_written, amount_to_write, timeout);
if (HAILO_STREAM_ABORT == status) { if (HAILO_STREAM_ABORT == status) {
return HAILO_COMMUNICATION_CLOSED; return HAILO_COMMUNICATION_CLOSED;
} }
@@ -134,7 +149,7 @@ hailo_status PcieRawConnection::write(const uint8_t *buffer, size_t size)
} else { } else {
amount_to_write = std::min(static_cast<size_t>(size_left), m_context->write_buffer().size()); amount_to_write = std::min(static_cast<size_t>(size_left), m_context->write_buffer().size());
memcpy(m_context->write_buffer().data(), buffer + bytes_written, amount_to_write); memcpy(m_context->write_buffer().data(), buffer + bytes_written, amount_to_write);
auto status = m_session->write(m_context->write_buffer().data(), amount_to_write, m_timeout); auto status = m_session->write(m_context->write_buffer().data(), amount_to_write, timeout);
if (HAILO_STREAM_ABORT == status) { if (HAILO_STREAM_ABORT == status) {
return HAILO_COMMUNICATION_CLOSED; return HAILO_COMMUNICATION_CLOSED;
} }
@@ -147,7 +162,7 @@ hailo_status PcieRawConnection::write(const uint8_t *buffer, size_t size)
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status PcieRawConnection::read(uint8_t *buffer, size_t size) hailo_status PcieRawConnection::read(uint8_t *buffer, size_t size, std::chrono::milliseconds timeout)
{ {
if (0 == size) { if (0 == size) {
return HAILO_SUCCESS; return HAILO_SUCCESS;
@@ -163,14 +178,14 @@ hailo_status PcieRawConnection::read(uint8_t *buffer, size_t size)
auto size_left = size - bytes_read; auto size_left = size - bytes_read;
if (is_aligned) { if (is_aligned) {
amount_to_read = std::min(static_cast<size_t>(size_left), static_cast<size_t>(max_size)); amount_to_read = std::min(static_cast<size_t>(size_left), static_cast<size_t>(max_size));
auto status = m_session->read(buffer + bytes_read, amount_to_read, m_timeout); auto status = m_session->read(buffer + bytes_read, amount_to_read, timeout);
if (HAILO_STREAM_ABORT == status) { if (HAILO_STREAM_ABORT == status) {
return HAILO_COMMUNICATION_CLOSED; return HAILO_COMMUNICATION_CLOSED;
} }
CHECK_SUCCESS(status); CHECK_SUCCESS(status);
} else { } else {
amount_to_read = std::min(static_cast<size_t>(size_left), m_context->read_buffer().size()); amount_to_read = std::min(static_cast<size_t>(size_left), m_context->read_buffer().size());
auto status = m_session->read(m_context->read_buffer().data(), amount_to_read, m_timeout); auto status = m_session->read(m_context->read_buffer().data(), amount_to_read, timeout);
if (HAILO_STREAM_ABORT == status) { if (HAILO_STREAM_ABORT == status) {
return HAILO_COMMUNICATION_CLOSED; return HAILO_COMMUNICATION_CLOSED;
} }

View File

@@ -25,7 +25,8 @@ namespace hrpc
class PcieConnectionContext : public ConnectionContext class PcieConnectionContext : public ConnectionContext
{ {
public: public:
static Expected<std::shared_ptr<ConnectionContext>> create_shared(bool is_accepting); static Expected<std::shared_ptr<ConnectionContext>> create_client_shared(const std::string &device_id);
static Expected<std::shared_ptr<ConnectionContext>> create_server_shared();
PcieConnectionContext(std::shared_ptr<HailoRTDriver> &&driver, bool is_accepting, PcieConnectionContext(std::shared_ptr<HailoRTDriver> &&driver, bool is_accepting,
Buffer &&write_buffer, Buffer &&read_buffer) Buffer &&write_buffer, Buffer &&read_buffer)
@@ -61,8 +62,10 @@ public:
virtual Expected<std::shared_ptr<RawConnection>> accept() override; virtual Expected<std::shared_ptr<RawConnection>> accept() override;
virtual hailo_status connect() override; virtual hailo_status connect() override;
virtual hailo_status write(const uint8_t *buffer, size_t size) override; virtual hailo_status write(const uint8_t *buffer, size_t size,
virtual hailo_status read(uint8_t *buffer, size_t size) override; std::chrono::milliseconds timeout = DEFAULT_WRITE_TIMEOUT) override;
virtual hailo_status read(uint8_t *buffer, size_t size,
std::chrono::milliseconds timeout = DEFAULT_READ_TIMEOUT) override;
virtual hailo_status close() override; virtual hailo_status close() override;
explicit PcieRawConnection(std::shared_ptr<PcieConnectionContext> context) : m_context(context) {} explicit PcieRawConnection(std::shared_ptr<PcieConnectionContext> context) : m_context(context) {}

View File

@@ -13,9 +13,11 @@
#include <sys/un.h> #include <sys/un.h>
#include <string> #include <string>
#include <unistd.h> #include <unistd.h>
#include <common/logger_macros.hpp>
#include <common/utils.hpp> #include "common/logger_macros.hpp"
#include <hailo/hailort.h> #include "common/utils.hpp"
#include "common/internal_env_vars.hpp"
#include "hailo/hailort.h"
using namespace hrpc; using namespace hrpc;
@@ -27,10 +29,8 @@ Expected<std::shared_ptr<ConnectionContext>> OsConnectionContext::create_shared(
return std::dynamic_pointer_cast<ConnectionContext>(ptr); return std::dynamic_pointer_cast<ConnectionContext>(ptr);
} }
Expected<std::shared_ptr<RawConnection>> OsRawConnection::create_shared(std::shared_ptr<OsConnectionContext> context) Expected<std::shared_ptr<OsRawConnection>> OsRawConnection::create_localhost_server(std::shared_ptr<OsConnectionContext> context)
{ {
std::shared_ptr<RawConnection> ptr;
if (context->is_accepting()) {
int fd = ::socket(AF_UNIX, SOCK_STREAM, 0); int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
CHECK_AS_EXPECTED(fd >= 0, HAILO_OPEN_FILE_FAILURE, "Socket creation error, errno = {}", errno); CHECK_AS_EXPECTED(fd >= 0, HAILO_OPEN_FILE_FAILURE, "Socket creation error, errno = {}", errno);
@@ -47,18 +47,105 @@ Expected<std::shared_ptr<RawConnection>> OsRawConnection::create_shared(std::sha
result = ::listen(fd, 5); result = ::listen(fd, 5);
CHECK_AS_EXPECTED(result >= 0, HAILO_FILE_OPERATION_FAILURE, "Listen error, errno = {}", errno); CHECK_AS_EXPECTED(result >= 0, HAILO_FILE_OPERATION_FAILURE, "Listen error, errno = {}", errno);
ptr = make_shared_nothrow<OsRawConnection>(fd, context); auto ptr = make_shared_nothrow<OsRawConnection>(fd, context);
} else { CHECK_NOT_NULL_AS_EXPECTED(ptr, HAILO_OUT_OF_HOST_MEMORY);
return ptr;
int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
CHECK_AS_EXPECTED(fd >= 0, HAILO_OPEN_FILE_FAILURE, "Socket creation error, errno = {}", errno);
ptr = make_shared_nothrow<OsRawConnection>(fd, context);
} }
Expected<std::shared_ptr<OsRawConnection>> OsRawConnection::create_localhost_client(std::shared_ptr<OsConnectionContext> context)
{
int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
CHECK_AS_EXPECTED(fd >= 0, HAILO_OPEN_FILE_FAILURE, "Socket creation error, errno = {}", errno);
auto ptr = make_shared_nothrow<OsRawConnection>(fd, context);
CHECK_NOT_NULL_AS_EXPECTED(ptr, HAILO_OUT_OF_HOST_MEMORY); CHECK_NOT_NULL_AS_EXPECTED(ptr, HAILO_OUT_OF_HOST_MEMORY);
return ptr; return ptr;
} }
Expected<std::shared_ptr<OsRawConnection>> OsRawConnection::create_by_addr_server(std::shared_ptr<OsConnectionContext> context,
const std::string &ip, uint16_t port)
{
int fd = ::socket(AF_INET, SOCK_STREAM, 0);
CHECK_AS_EXPECTED(fd >= 0, HAILO_OPEN_FILE_FAILURE, "Socket creation error, errno = {}", errno);
sockaddr_in server_addr = {};
socklen_t addr_len = sizeof(server_addr);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
auto inet_rc = inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr);
CHECK_AS_EXPECTED(1 == inet_rc, HAILO_ETH_FAILURE,
"Failed to run 'inet_pton', errno = {}. make sure 'HAILO_SOCKET_COM_ADDR_SERVER' is set correctly (ip:port)", errno);
int result = ::bind(fd, (struct sockaddr*)&server_addr, addr_len);
CHECK_AS_EXPECTED(result >= 0, HAILO_FILE_OPERATION_FAILURE, "Bind error, errno = {}", errno);
result = ::listen(fd, 5);
CHECK_AS_EXPECTED(result >= 0, HAILO_FILE_OPERATION_FAILURE, "Listen error, errno = {}", errno);
auto res = make_shared_nothrow<OsRawConnection>(fd, context);
CHECK_NOT_NULL_AS_EXPECTED(res, HAILO_OUT_OF_HOST_MEMORY);
return res;
}
Expected<std::shared_ptr<OsRawConnection>> OsRawConnection::create_by_addr_client(std::shared_ptr<OsConnectionContext> context,
const std::string &ip, uint16_t port)
{
int fd = ::socket(AF_INET, SOCK_STREAM, 0);
CHECK_AS_EXPECTED(fd >= 0, HAILO_OPEN_FILE_FAILURE, "Socket creation error, errno = {}", errno);
sockaddr_in server_addr = {};
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
auto inet_rc = inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr);
CHECK_AS_EXPECTED(1 == inet_rc, HAILO_ETH_FAILURE,
"Failed to run 'inet_pton', errno = {}. make sure 'HAILO_SOCKET_COM_ADDR_CLIENT' is set correctly (ip:port)", errno);
auto res = make_shared_nothrow<OsRawConnection>(fd, context);
CHECK_NOT_NULL_AS_EXPECTED(res, HAILO_OUT_OF_HOST_MEMORY);
return res;
}
Expected<std::pair<std::string, uint16_t>> OsRawConnection::parse_ip_port(const std::string &ip_port)
{
std::istringstream ss(ip_port);
std::string ip;
uint16_t port;
if (std::getline(ss, ip, ':') && (ss >> port)) {
return std::make_pair(ip, port);
}
CHECK_AS_EXPECTED(false, HAILO_INVALID_ARGUMENT ,"Failed to parse ip and port. Format should be as follows: 'X.X.X.X:PP' (e.g. 127.0.0.1:2000)");
}
Expected<std::shared_ptr<RawConnection>> OsRawConnection::create_shared(std::shared_ptr<OsConnectionContext> context)
{
std::shared_ptr<RawConnection> ptr;
if (context->is_accepting()) {
auto force_socket_com_value = get_env_variable(HAILO_SOCKET_COM_ADDR_SERVER_ENV_VAR);
CHECK_EXPECTED(force_socket_com_value); // We know its set, otherwise we'll be working with PCIeRawCon
if (HAILO_SOCKET_COM_ADDR_UNIX_SOCKET == force_socket_com_value.value()) {
TRY(ptr, create_localhost_server(context));
} else {
TRY(auto ip_port_pair, parse_ip_port(force_socket_com_value.value()));
TRY(ptr, create_by_addr_server(context, std::get<0>(ip_port_pair), std::get<1>(ip_port_pair)));
}
} else {
auto force_socket_com_value = get_env_variable(HAILO_SOCKET_COM_ADDR_CLIENT_ENV_VAR);
CHECK_EXPECTED(force_socket_com_value); // We know its set, otherwise we'll be working with PCIeRawCon
if (HAILO_SOCKET_COM_ADDR_UNIX_SOCKET == force_socket_com_value.value()) {
TRY(ptr, create_localhost_client(context));
} else {
TRY(auto ip_port_pair, parse_ip_port(force_socket_com_value.value()));
TRY(ptr, create_by_addr_client(context, std::get<0>(ip_port_pair), std::get<1>(ip_port_pair)));
}
}
return ptr;
}
Expected<std::shared_ptr<RawConnection>> OsRawConnection::accept() Expected<std::shared_ptr<RawConnection>> OsRawConnection::accept()
{ {
int fd = ::accept(m_fd, nullptr, nullptr); int fd = ::accept(m_fd, nullptr, nullptr);
@@ -70,7 +157,7 @@ Expected<std::shared_ptr<RawConnection>> OsRawConnection::accept()
return ptr; return ptr;
} }
hailo_status OsRawConnection::connect() hailo_status OsRawConnection::connect_localhost()
{ {
struct sockaddr_un server_addr; struct sockaddr_un server_addr;
std::string addr = "/tmp/unix_socket"; std::string addr = "/tmp/unix_socket";
@@ -85,7 +172,48 @@ hailo_status OsRawConnection::connect()
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status OsRawConnection::write(const uint8_t *buffer, size_t size) hailo_status OsRawConnection::connect_by_addr(const std::string &ip, uint16_t port)
{
sockaddr_in server_addr = {};
socklen_t addr_len = sizeof(server_addr);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
auto inet_rc = inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr);
CHECK(1 == inet_rc, HAILO_ETH_FAILURE,
"Failed to run 'inet_pton', errno = {}. make sure 'HAILO_SOCKET_COM_ADDR_XX' is set correctly (ip:port)", errno);
auto result = ::connect(m_fd, (struct sockaddr*)&server_addr, addr_len);
CHECK(result >= 0, HAILO_FILE_OPERATION_FAILURE, "Connect error, errno = {}. "
"make sure 'HAILO_SOCKET_COM_ADDR_XX' is set correctly (ip:port)", errno);
return HAILO_SUCCESS;
}
hailo_status OsRawConnection::connect()
{
if (m_context->is_accepting()) {
auto force_socket_com_value = get_env_variable(HAILO_SOCKET_COM_ADDR_SERVER_ENV_VAR);
CHECK_EXPECTED(force_socket_com_value); // We know its set, otherwise we'll be working with PCIeRawCon
if (HAILO_SOCKET_COM_ADDR_UNIX_SOCKET == force_socket_com_value.value()) {
return connect_localhost();
} else {
TRY(auto ip_port_pair, parse_ip_port(force_socket_com_value.value()));
return connect_by_addr(std::get<0>(ip_port_pair), std::get<1>(ip_port_pair));
}
} else {
auto force_socket_com_value = get_env_variable(HAILO_SOCKET_COM_ADDR_CLIENT_ENV_VAR);
CHECK_EXPECTED(force_socket_com_value); // We know its set, otherwise we'll be working with PCIeRawCon
if (HAILO_SOCKET_COM_ADDR_UNIX_SOCKET == force_socket_com_value.value()) {
return connect_localhost();
} else {
TRY(auto ip_port_pair, parse_ip_port(force_socket_com_value.value()));
return connect_by_addr(std::get<0>(ip_port_pair), std::get<1>(ip_port_pair));
}
}
}
hailo_status OsRawConnection::write(const uint8_t *buffer, size_t size, std::chrono::milliseconds /*timeout*/)
{ {
size_t bytes_written = 0; size_t bytes_written = 0;
while (bytes_written < size) { while (bytes_written < size) {
@@ -96,7 +224,7 @@ hailo_status OsRawConnection::write(const uint8_t *buffer, size_t size)
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status OsRawConnection::read(uint8_t *buffer, size_t size) hailo_status OsRawConnection::read(uint8_t *buffer, size_t size, std::chrono::milliseconds /*timeout*/)
{ {
size_t bytes_read = 0; size_t bytes_read = 0;
while (bytes_read < size) { while (bytes_read < size) {

View File

@@ -39,12 +39,26 @@ public:
virtual Expected<std::shared_ptr<RawConnection>> accept() override; virtual Expected<std::shared_ptr<RawConnection>> accept() override;
virtual hailo_status connect() override; virtual hailo_status connect() override;
virtual hailo_status write(const uint8_t *buffer, size_t size) override; virtual hailo_status write(const uint8_t *buffer, size_t size,
virtual hailo_status read(uint8_t *buffer, size_t size) override; std::chrono::milliseconds timeout = DEFAULT_WRITE_TIMEOUT) override;
virtual hailo_status read(uint8_t *buffer, size_t size,
std::chrono::milliseconds timeout = DEFAULT_READ_TIMEOUT) override;
virtual hailo_status close() override; virtual hailo_status close() override;
OsRawConnection(int fd, std::shared_ptr<OsConnectionContext> context) : m_fd(fd), m_context(context) {} OsRawConnection(int fd, std::shared_ptr<OsConnectionContext> context) : m_fd(fd), m_context(context) {}
private: private:
static Expected<std::shared_ptr<OsRawConnection>> create_by_addr_server(std::shared_ptr<OsConnectionContext> context,
const std::string &ip, uint16_t port);
static Expected<std::shared_ptr<OsRawConnection>> create_by_addr_client(std::shared_ptr<OsConnectionContext> context,
const std::string &ip, uint16_t port);
static Expected<std::shared_ptr<OsRawConnection>> create_localhost_server(std::shared_ptr<OsConnectionContext> context);
static Expected<std::shared_ptr<OsRawConnection>> create_localhost_client(std::shared_ptr<OsConnectionContext> context);
hailo_status connect_by_addr(const std::string &ip, uint16_t port);
hailo_status connect_localhost();
static Expected<std::pair<std::string, uint16_t>> parse_ip_port(const std::string &ip_port);
int m_fd; int m_fd;
std::shared_ptr<OsConnectionContext> m_context; std::shared_ptr<OsConnectionContext> m_context;
}; };

View File

@@ -37,17 +37,19 @@ hailo_status OsRawConnection::connect()
return HAILO_NOT_IMPLEMENTED; return HAILO_NOT_IMPLEMENTED;
} }
hailo_status OsRawConnection::write(const uint8_t *buffer, size_t size) hailo_status OsRawConnection::write(const uint8_t *buffer, size_t size, std::chrono::milliseconds timeout)
{ {
(void)buffer; (void)buffer;
(void)size; (void)size;
(void)timeout;
return HAILO_NOT_IMPLEMENTED; return HAILO_NOT_IMPLEMENTED;
} }
hailo_status OsRawConnection::read(uint8_t *buffer, size_t size) hailo_status OsRawConnection::read(uint8_t *buffer, size_t size, std::chrono::milliseconds timeout)
{ {
(void)buffer; (void)buffer;
(void)size; (void)size;
(void)timeout;
return HAILO_NOT_IMPLEMENTED; return HAILO_NOT_IMPLEMENTED;
} }

View File

@@ -36,8 +36,10 @@ public:
virtual Expected<std::shared_ptr<RawConnection>> accept() override; virtual Expected<std::shared_ptr<RawConnection>> accept() override;
virtual hailo_status connect() override; virtual hailo_status connect() override;
virtual hailo_status write(const uint8_t *buffer, size_t size) override; virtual hailo_status write(const uint8_t *buffer, size_t size,
virtual hailo_status read(uint8_t *buffer, size_t size) override; std::chrono::milliseconds timeout = DEFAULT_WRITE_TIMEOUT) override;
virtual hailo_status read(uint8_t *buffer, size_t size,
std::chrono::milliseconds timeout = DEFAULT_READ_TIMEOUT) override;
virtual hailo_status close() override; virtual hailo_status close() override;
explicit OsRawConnection(std::shared_ptr<OsConnectionContext> /*context*/) {} explicit OsRawConnection(std::shared_ptr<OsConnectionContext> /*context*/) {}

View File

@@ -10,6 +10,7 @@
#include "hailo/vdevice.hpp" #include "hailo/vdevice.hpp"
#include "hrpc/raw_connection.hpp" #include "hrpc/raw_connection.hpp"
#include "hrpc/os/pcie/raw_connection_internal.hpp" #include "hrpc/os/pcie/raw_connection_internal.hpp"
#include "common/internal_env_vars.hpp"
#ifdef _WIN32 #ifdef _WIN32
#include "hrpc/os/windows/raw_connection_internal.hpp" #include "hrpc/os/windows/raw_connection_internal.hpp"
@@ -17,21 +18,31 @@
#include "hrpc/os/posix/raw_connection_internal.hpp" #include "hrpc/os/posix/raw_connection_internal.hpp"
#endif #endif
#define HAILO_FORCE_SOCKET_COM_ENV_VAR "HAILO_FORCE_SOCKET_COM"
using namespace hrpc; using namespace hrpc;
Expected<std::shared_ptr<ConnectionContext>> ConnectionContext::create_shared(bool is_accepting) Expected<std::shared_ptr<ConnectionContext>> ConnectionContext::create_client_shared(const std::string &device_id)
{ {
// The env var HAILO_FORCE_HRPC_CLIENT_ENV_VAR is supported for debug purposes auto should_force_socket_com = get_env_variable(HAILO_SOCKET_COM_ADDR_CLIENT_ENV_VAR);
char *socket_com = std::getenv(HAILO_FORCE_SOCKET_COM_ENV_VAR); // TODO: Remove duplication
auto force_socket_com = (nullptr != socket_com) && ("1" == std::string(socket_com));
if (force_socket_com || VDevice::force_hrpc_client()) {// If forcing hrpc service, its because we work without EP driver -> use sockets // If forcing hrpc service, its because we work without EP driver -> use sockets
return OsConnectionContext::create_shared(is_accepting); if (should_force_socket_com.has_value() || VDevice::should_force_hrpc_client()) {
return OsConnectionContext::create_shared(false);
} else { } else {
return PcieConnectionContext::create_shared(is_accepting); return PcieConnectionContext::create_client_shared(device_id);
}
}
Expected<std::shared_ptr<ConnectionContext>> ConnectionContext::create_server_shared()
{
auto should_force_socket_com = get_env_variable(HAILO_SOCKET_COM_ADDR_SERVER_ENV_VAR);
// If forcing hrpc service, its because we work without EP driver -> use sockets
if (should_force_socket_com.has_value() || VDevice::should_force_hrpc_client()) {
return OsConnectionContext::create_shared(true);
} else {
return PcieConnectionContext::create_server_shared();
} }
} }

View File

@@ -15,6 +15,9 @@
#include <memory> #include <memory>
#define DEFAULT_WRITE_TIMEOUT (std::chrono::milliseconds(10000))
#define DEFAULT_READ_TIMEOUT (std::chrono::milliseconds(HAILO_INFINITE))
using namespace hailort; using namespace hailort;
namespace hrpc namespace hrpc
@@ -23,7 +26,8 @@ namespace hrpc
class ConnectionContext class ConnectionContext
{ {
public: public:
static Expected<std::shared_ptr<ConnectionContext>> create_shared(bool is_accepting); static Expected<std::shared_ptr<ConnectionContext>> create_client_shared(const std::string &device_id = "");
static Expected<std::shared_ptr<ConnectionContext>> create_server_shared();
bool is_accepting() const { return m_is_accepting; } bool is_accepting() const { return m_is_accepting; }
@@ -45,12 +49,11 @@ public:
virtual Expected<std::shared_ptr<RawConnection>> accept() = 0; virtual Expected<std::shared_ptr<RawConnection>> accept() = 0;
virtual hailo_status connect() = 0; virtual hailo_status connect() = 0;
virtual hailo_status write(const uint8_t *buffer, size_t size) = 0; virtual hailo_status write(const uint8_t *buffer, size_t size,
virtual hailo_status read(uint8_t *buffer, size_t size) = 0; std::chrono::milliseconds timeout = DEFAULT_WRITE_TIMEOUT) = 0;
virtual hailo_status read(uint8_t *buffer, size_t size,
std::chrono::milliseconds timeout = DEFAULT_READ_TIMEOUT) = 0;
virtual hailo_status close() = 0; virtual hailo_status close() = 0;
protected:
std::chrono::milliseconds m_timeout = std::chrono::milliseconds(HAILO_INFINITE);
}; };
} // namespace hrpc } // namespace hrpc

View File

@@ -15,9 +15,10 @@ namespace hrpc
ServerContext::ServerContext(Server &server, RpcConnection connection) : ServerContext::ServerContext(Server &server, RpcConnection connection) :
m_server(server), m_connection(connection) {} m_server(server), m_connection(connection) {}
hailo_status ServerContext::trigger_callback(uint32_t callback_id, hailo_status callback_status, std::function<hailo_status(RpcConnection)> write_buffers_callback) hailo_status ServerContext::trigger_callback(uint32_t callback_id, hailo_status callback_status,
rpc_object_handle_t callback_owner_handle, std::function<hailo_status(RpcConnection)> write_buffers_callback)
{ {
return m_server.trigger_callback(callback_id, m_connection, callback_status, write_buffers_callback); return m_server.trigger_callback(callback_id, callback_status, callback_owner_handle, m_connection, write_buffers_callback);
} }
RpcConnection &ServerContext::connection() RpcConnection &ServerContext::connection()
@@ -36,14 +37,15 @@ Expected<Buffer> Dispatcher::call_action(HailoRpcActionID action_id, const Memor
if (m_actions.find(action_id) != m_actions.end()) { if (m_actions.find(action_id) != m_actions.end()) {
return m_actions[action_id](request, server_context); return m_actions[action_id](request, server_context);
} }
LOGGER__ERROR("Failed to find RPC action {}", action_id); LOGGER__ERROR("Failed to find RPC action {}", static_cast<int>(action_id));
return make_unexpected(HAILO_RPC_FAILED); return make_unexpected(HAILO_RPC_FAILED);
} }
hailo_status Server::serve() hailo_status Server::serve()
{ {
TRY(auto server_connection, RawConnection::create_shared(m_connection_context));
while (true) { while (true) {
TRY(auto client_connection, create_client_connection()); TRY(auto client_connection, create_client_connection(server_connection));
auto th = std::thread([this, client_connection]() { serve_client(client_connection); }); auto th = std::thread([this, client_connection]() { serve_client(client_connection); });
th.detach(); th.detach();
} }
@@ -55,11 +57,9 @@ void Server::set_dispatcher(Dispatcher dispatcher)
m_dispatcher = dispatcher; m_dispatcher = dispatcher;
} }
Expected<RpcConnection> Server::create_client_connection() Expected<RpcConnection> Server::create_client_connection(std::shared_ptr<hrpc::RawConnection> server_connection)
{ {
TRY(auto server_connection, RawConnection::create_shared(m_connection_context));
TRY(auto conn, server_connection->accept()); TRY(auto conn, server_connection->accept());
return RpcConnection(conn); return RpcConnection(conn);
} }
@@ -95,10 +95,11 @@ hailo_status Server::serve_client(RpcConnection client_connection)
return HAILO_SUCCESS; return HAILO_SUCCESS;
} }
hailo_status Server::trigger_callback(uint32_t callback_id, RpcConnection connection, hailo_status callback_status, hailo_status Server::trigger_callback(uint32_t callback_id, hailo_status callback_status, rpc_object_handle_t callback_owner_handle,
std::function<hailo_status(RpcConnection)> write_buffers_callback) RpcConnection connection, std::function<hailo_status(RpcConnection)> write_buffers_callback)
{ {
TRY(auto reply, CallbackCalledSerializer::serialize_reply(callback_status, callback_id)); // TODO: callback handling should be outside of HRPC (HRT-14638)
TRY(auto reply, CallbackCalledSerializer::serialize_reply(callback_status, callback_id, callback_owner_handle));
std::unique_lock<std::mutex> lock(m_write_mutex); std::unique_lock<std::mutex> lock(m_write_mutex);
rpc_message_header_t header; rpc_message_header_t header;

View File

@@ -27,7 +27,7 @@ class ServerContext
public: public:
ServerContext(Server &server, RpcConnection connection); ServerContext(Server &server, RpcConnection connection);
hailo_status trigger_callback(uint32_t callback_id, hailo_status callback_status, hailo_status trigger_callback(uint32_t callback_id, hailo_status callback_status,
std::function<hailo_status(RpcConnection)> write_buffers_callback = nullptr); rpc_object_handle_t callback_owner_handle, std::function<hailo_status(RpcConnection)> write_buffers_callback = nullptr);
RpcConnection &connection(); RpcConnection &connection();
private: private:
@@ -63,10 +63,10 @@ public:
protected: protected:
std::shared_ptr<ConnectionContext> m_connection_context; std::shared_ptr<ConnectionContext> m_connection_context;
private: private:
Expected<RpcConnection> create_client_connection(); Expected<RpcConnection> create_client_connection(std::shared_ptr<hrpc::RawConnection> server_connection);
hailo_status serve_client(RpcConnection client_connection); hailo_status serve_client(RpcConnection client_connection);
hailo_status trigger_callback(uint32_t callback_id, RpcConnection connection, hailo_status callback_status, hailo_status trigger_callback(uint32_t callback_id, hailo_status callback_status, rpc_object_handle_t callback_owner_handle,
std::function<hailo_status(RpcConnection)> write_buffers_callback = nullptr); RpcConnection connection, std::function<hailo_status(RpcConnection)> write_buffers_callback = nullptr);
virtual hailo_status cleanup_client_resources(RpcConnection client_connection) = 0; virtual hailo_status cleanup_client_resources(RpcConnection client_connection) = 0;
Dispatcher m_dispatcher; Dispatcher m_dispatcher;

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
protobuf_generate_cpp(PROTO_RPC_SRC PROTO_RPC_HEADER rpc.proto) protobuf_generate_cpp(PROTO_RPC_SRC PROTO_RPC_HEADER rpc.proto)
get_filename_component(PROTO_HEADER_DIRECTORY ${PROTO_RPC_HEADER} DIRECTORY) get_filename_component(PROTO_HEADER_DIRECTORY ${PROTO_RPC_HEADER} DIRECTORY)

View File

@@ -20,6 +20,11 @@ message RpcRequest {
ConfiguredInferModel_Deactivate_Request deactivate_request = 12; ConfiguredInferModel_Deactivate_Request deactivate_request = 12;
ConfiguredInferModel_Shutdown_Request shutdown_request = 13; ConfiguredInferModel_Shutdown_Request shutdown_request = 13;
ConfiguredInferModel_AsyncInfer_Request async_infer_request = 14; ConfiguredInferModel_AsyncInfer_Request async_infer_request = 14;
Device_Create_Request create_device_request = 15;
Device_Destroy_Request destroy_device_request = 16;
Device_Identify_Request identify_device_request = 17;
Device_ExtendedInfo_Request extended_device_info_request = 18;
} }
} }
@@ -42,7 +47,13 @@ message RpcReply {
ConfiguredInferModel_Shutdown_Reply shutdown_reply = 13; ConfiguredInferModel_Shutdown_Reply shutdown_reply = 13;
ConfiguredInferModel_AsyncInfer_Reply async_infer_reply = 14; ConfiguredInferModel_AsyncInfer_Reply async_infer_reply = 14;
CallbackCalled_Reply callback_called_reply = 15; Device_Create_Reply create_device_reply = 15;
Device_Destroy_Reply destroy_device_reply = 16;
Device_Identify_Reply identify_device_reply = 17;
Device_ExtendedInfo_Reply extended_device_info_reply = 18;
// Here comes replies that have no matching requests
CallbackCalled_Reply callback_called_reply = 19;
} }
} }
@@ -79,6 +90,7 @@ message VDevice_Destroy_Reply {
message VDevice_CreateInferModel_Request { message VDevice_CreateInferModel_Request {
HailoObjectHandle vdevice_handle = 1; HailoObjectHandle vdevice_handle = 1;
uint64 hef_size = 2; uint64 hef_size = 2;
string name = 3;
// Protocol note: After this message, server expects to get HEF data (buffer of size 'hef_size') // Protocol note: After this message, server expects to get HEF data (buffer of size 'hef_size')
} }
@@ -193,6 +205,7 @@ message ConfiguredInferModel_AsyncInfer_Request {
HailoObjectHandle configured_infer_model_handle = 1; HailoObjectHandle configured_infer_model_handle = 1;
HailoObjectHandle infer_model_handle = 2; HailoObjectHandle infer_model_handle = 2;
HailoCallbackHandle callback_handle = 3; HailoCallbackHandle callback_handle = 3;
repeated uint32 input_buffer_sizes = 4;
// Protocol note: After this messgae, server expects to get the input buffers, one after the other, in order // Protocol note: After this messgae, server expects to get the input buffers, one after the other, in order
} }
@@ -203,5 +216,92 @@ message ConfiguredInferModel_AsyncInfer_Reply {
message CallbackCalled_Reply { message CallbackCalled_Reply {
uint32 status = 1; uint32 status = 1;
HailoCallbackHandle callback_handle = 2; HailoCallbackHandle callback_handle = 2;
HailoObjectHandle configured_infer_model_handle = 3;
// Protocol note: After this messgae, and only if status is HAILO_SUCCESS, server expects to get the output buffers, one after the other, in order // Protocol note: After this messgae, and only if status is HAILO_SUCCESS, server expects to get the output buffers, one after the other, in order
} }
message Device_Create_Request {
}
message Device_Create_Reply {
uint32 status = 1;
HailoObjectHandle device_handle = 2;
}
message Device_Destroy_Request {
HailoObjectHandle device_handle = 1;
}
message Device_Destroy_Reply {
uint32 status = 1;
}
message Device_Identify_Request {
HailoObjectHandle device_handle = 1;
}
// Added "_value" to the names so that the symbols will not clash with the macros defined in <sys/types.h>
message FirmwareVersionProto {
uint32 major_value = 1;
uint32 minor_value = 2;
uint32 revision_value = 3;
}
enum DeviceArchitectureProto {
HAILO8_A0 = 0;
HAILO8 = 1;
HAILO8L = 2;
HAILO15H = 3;
PLUTO = 4;
HAILO15M = 5;
HAILO10H = 6;
}
message DeviceIdentityProto {
uint32 protocol_version = 1;
FirmwareVersionProto fw_version = 2;
uint32 logger_version = 3;
string board_name = 4;
bool is_release = 5;
bool extended_context_switch_buffer = 6;
DeviceArchitectureProto device_architecture = 7;
repeated uint32 serial_number = 8;
repeated uint32 part_number = 9;
string product_name = 10;
}
message Device_Identify_Reply {
uint32 status = 1;
DeviceIdentityProto identity = 2;
}
message Device_ExtendedInfo_Request {
HailoObjectHandle device_handle = 1;
}
message DeviceSupportedFeaturesProto {
bool ethernet = 1;
bool mipi = 2;
bool pcie = 3;
bool current_monitoring = 4;
bool mdio = 5;
}
enum DeviceBootSourceProto {
BOOT_SOURCE_INVALID = 0;
BOOT_SOURCE_PCIE = 1;
BOOT_SOURCE_FLASH = 2;
BOOT_SOURCE_MAX = 3;
}
message Device_ExtendedInfo_Reply {
uint32 status = 1;
uint32 neural_network_core_clock_rate = 2;
DeviceSupportedFeaturesProto supported_features = 3;
DeviceBootSourceProto boot_source = 4;
repeated uint32 soc_id = 5;
uint32 lcs = 6;
repeated uint32 eth_mac_address = 7;
repeated uint32 unit_level_tracking_id = 8;
repeated uint32 soc_pm_values = 9;
}

View File

@@ -40,7 +40,7 @@ Expected<Buffer> CreateVDeviceSerializer::serialize_request(const hailo_vdevice_
proto_params->set_scheduling_algorithm(params.scheduling_algorithm); proto_params->set_scheduling_algorithm(params.scheduling_algorithm);
proto_params->set_group_id(params.group_id == nullptr ? "" : std::string(params.group_id)); proto_params->set_group_id(params.group_id == nullptr ? "" : std::string(params.group_id));
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
@@ -101,7 +101,7 @@ Expected<Buffer> DestroyVDeviceSerializer::serialize_request(rpc_object_handle_t
auto proto_vdevice_handle= request.mutable_vdevice_handle(); auto proto_vdevice_handle= request.mutable_vdevice_handle();
proto_vdevice_handle->set_id(vdevice_handle); proto_vdevice_handle->set_id(vdevice_handle);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'DestroyVDevice'"); HAILO_RPC_FAILED, "Failed to serialize 'DestroyVDevice'");
@@ -142,16 +142,17 @@ hailo_status DestroyVDeviceSerializer::deserialize_reply(const MemoryView &seria
return static_cast<hailo_status>(reply.status()); return static_cast<hailo_status>(reply.status());
} }
Expected<Buffer> CreateInferModelSerializer::serialize_request(rpc_object_handle_t vdevice_handle, uint64_t hef_size) Expected<Buffer> CreateInferModelSerializer::serialize_request(rpc_object_handle_t vdevice_handle, uint64_t hef_size,
const std::string &name)
{ {
VDevice_CreateInferModel_Request request; VDevice_CreateInferModel_Request request;
auto proto_vdevice_handle = request.mutable_vdevice_handle(); auto proto_vdevice_handle = request.mutable_vdevice_handle();
proto_vdevice_handle->set_id(vdevice_handle); proto_vdevice_handle->set_id(vdevice_handle);
request.set_hef_size(hef_size); request.set_hef_size(hef_size);
request.set_name(name);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'CreateVInferModel'"); HAILO_RPC_FAILED, "Failed to serialize 'CreateVInferModel'");
@@ -159,14 +160,14 @@ Expected<Buffer> CreateInferModelSerializer::serialize_request(rpc_object_handle
return serialized_request; return serialized_request;
} }
Expected<std::tuple<rpc_object_handle_t, uint64_t>> CreateInferModelSerializer::deserialize_request(const MemoryView &serialized_request) Expected<std::tuple<rpc_object_handle_t, uint64_t, std::string>> CreateInferModelSerializer::deserialize_request(const MemoryView &serialized_request)
{ {
VDevice_CreateInferModel_Request request; VDevice_CreateInferModel_Request request;
CHECK_AS_EXPECTED(request.ParseFromArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.ParseFromArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'CreateVInferModel'"); HAILO_RPC_FAILED, "Failed to de-serialize 'CreateVInferModel'");
return std::make_tuple(request.vdevice_handle().id(), request.hef_size()); return std::make_tuple(request.vdevice_handle().id(), request.hef_size(), request.name());
} }
Expected<Buffer> CreateInferModelSerializer::serialize_reply(hailo_status status, rpc_object_handle_t infer_model_handle) Expected<Buffer> CreateInferModelSerializer::serialize_reply(hailo_status status, rpc_object_handle_t infer_model_handle)
@@ -202,7 +203,7 @@ Expected<Buffer> DestroyInferModelSerializer::serialize_request(rpc_object_handl
auto proto_infer_model_handle = request.mutable_infer_model_handle(); auto proto_infer_model_handle = request.mutable_infer_model_handle();
proto_infer_model_handle->set_id(infer_model_handle); proto_infer_model_handle->set_id(infer_model_handle);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'DestroyInferModel'"); HAILO_RPC_FAILED, "Failed to serialize 'DestroyInferModel'");
@@ -279,7 +280,7 @@ Expected<Buffer> CreateConfiguredInferModelSerializer::serialize_request(rpc_cre
request.set_power_mode(static_cast<uint32_t>(params.power_mode)); request.set_power_mode(static_cast<uint32_t>(params.power_mode));
request.set_latency_flag(static_cast<uint32_t>(params.latency_flag)); request.set_latency_flag(static_cast<uint32_t>(params.latency_flag));
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'CreateConfiguredInferModel'"); HAILO_RPC_FAILED, "Failed to serialize 'CreateConfiguredInferModel'");
@@ -363,7 +364,7 @@ Expected<Buffer> DestroyConfiguredInferModelSerializer::serialize_request(rpc_ob
auto proto_infer_model_handle = request.mutable_configured_infer_model_handle(); auto proto_infer_model_handle = request.mutable_configured_infer_model_handle();
proto_infer_model_handle->set_id(configured_infer_model_handle); proto_infer_model_handle->set_id(configured_infer_model_handle);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'DestroyConfiguredInferModel'"); HAILO_RPC_FAILED, "Failed to serialize 'DestroyConfiguredInferModel'");
@@ -413,7 +414,7 @@ Expected<Buffer> SetSchedulerTimeoutSerializer::serialize_request(rpc_object_han
proto_configured_infer_model_handle->set_id(configured_infer_model_handle); proto_configured_infer_model_handle->set_id(configured_infer_model_handle);
request.set_timeout(static_cast<uint32_t>(timeout.count())); request.set_timeout(static_cast<uint32_t>(timeout.count()));
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'SetSchedulerTimeout'"); HAILO_RPC_FAILED, "Failed to serialize 'SetSchedulerTimeout'");
@@ -463,7 +464,7 @@ Expected<Buffer> SetSchedulerThresholdSerializer::serialize_request(rpc_object_h
proto_configured_infer_model_handle->set_id(configured_infer_model_handle); proto_configured_infer_model_handle->set_id(configured_infer_model_handle);
request.set_threshold(threshold); request.set_threshold(threshold);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'SetSchedulerThreshold'"); HAILO_RPC_FAILED, "Failed to serialize 'SetSchedulerThreshold'");
@@ -513,7 +514,7 @@ Expected<Buffer> SetSchedulerPrioritySerializer::serialize_request(rpc_object_ha
proto_configured_infer_model_handle->set_id(configured_infer_model_handle); proto_configured_infer_model_handle->set_id(configured_infer_model_handle);
request.set_priority(priority); request.set_priority(priority);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'SetSchedulerPriority'"); HAILO_RPC_FAILED, "Failed to serialize 'SetSchedulerPriority'");
@@ -562,7 +563,7 @@ Expected<Buffer> GetHwLatencyMeasurementSerializer::serialize_request(rpc_object
auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle(); auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle();
proto_configured_infer_model_handle->set_id(configured_infer_model_handle); proto_configured_infer_model_handle->set_id(configured_infer_model_handle);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'GetHwLatencyMeasurement'"); HAILO_RPC_FAILED, "Failed to serialize 'GetHwLatencyMeasurement'");
@@ -611,7 +612,7 @@ Expected<Buffer> ActivateSerializer::serialize_request(rpc_object_handle_t confi
auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle(); auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle();
proto_configured_infer_model_handle->set_id(configured_infer_model_handle); proto_configured_infer_model_handle->set_id(configured_infer_model_handle);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'Activate'"); HAILO_RPC_FAILED, "Failed to serialize 'Activate'");
@@ -659,7 +660,7 @@ Expected<Buffer> DeactivateSerializer::serialize_request(rpc_object_handle_t con
auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle(); auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle();
proto_configured_infer_model_handle->set_id(configured_infer_model_handle); proto_configured_infer_model_handle->set_id(configured_infer_model_handle);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'Deactivate'"); HAILO_RPC_FAILED, "Failed to serialize 'Deactivate'");
@@ -707,7 +708,7 @@ Expected<Buffer> ShutdownSerializer::serialize_request(rpc_object_handle_t confi
auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle(); auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle();
proto_configured_infer_model_handle->set_id(configured_infer_model_handle); proto_configured_infer_model_handle->set_id(configured_infer_model_handle);
// TODO (HRT-13983) - check if we can use GetCachedSize // TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'Shutdown'"); HAILO_RPC_FAILED, "Failed to serialize 'Shutdown'");
@@ -748,21 +749,22 @@ hailo_status ShutdownSerializer::deserialize_reply(const MemoryView &serialized_
return static_cast<hailo_status>(reply.status()); return static_cast<hailo_status>(reply.status());
} }
Expected<Buffer> RunAsyncSerializer::serialize_request(rpc_object_handle_t configured_infer_model_handle, rpc_object_handle_t infer_model_handle, Expected<Buffer> RunAsyncSerializer::serialize_request(const RunAsyncSerializer::Request &request_struct)
rpc_object_handle_t callback_handle)
{ {
ConfiguredInferModel_AsyncInfer_Request request; ConfiguredInferModel_AsyncInfer_Request request;
auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle(); auto proto_configured_infer_model_handle = request.mutable_configured_infer_model_handle();
proto_configured_infer_model_handle->set_id(configured_infer_model_handle); proto_configured_infer_model_handle->set_id(request_struct.configured_infer_model_handle);
auto proto_infer_model_handle = request.mutable_infer_model_handle(); auto proto_infer_model_handle = request.mutable_infer_model_handle();
proto_infer_model_handle->set_id(infer_model_handle); proto_infer_model_handle->set_id(request_struct.infer_model_handle);
auto proto_cb_handle = request.mutable_callback_handle(); auto proto_cb_handle = request.mutable_callback_handle();
proto_cb_handle->set_id(callback_handle); proto_cb_handle->set_id(request_struct.callback_handle);
// TODO (HRT-13983) - check if we can use GetCachedSize *request.mutable_input_buffer_sizes() = {request_struct.input_buffer_sizes.begin(), request_struct.input_buffer_sizes.end()};
// TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'RunAsync'"); HAILO_RPC_FAILED, "Failed to serialize 'RunAsync'");
@@ -770,7 +772,7 @@ Expected<Buffer> RunAsyncSerializer::serialize_request(rpc_object_handle_t confi
return serialized_request; return serialized_request;
} }
Expected<std::tuple<rpc_object_handle_t, rpc_object_handle_t, rpc_object_handle_t>> RunAsyncSerializer::deserialize_request( Expected<RunAsyncSerializer::Request> RunAsyncSerializer::deserialize_request(
const MemoryView &serialized_request) const MemoryView &serialized_request)
{ {
ConfiguredInferModel_AsyncInfer_Request request; ConfiguredInferModel_AsyncInfer_Request request;
@@ -778,8 +780,14 @@ Expected<std::tuple<rpc_object_handle_t, rpc_object_handle_t, rpc_object_handle_
CHECK_AS_EXPECTED(request.ParseFromArray(serialized_request.data(), static_cast<int>(serialized_request.size())), CHECK_AS_EXPECTED(request.ParseFromArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'RunAsync'"); HAILO_RPC_FAILED, "Failed to de-serialize 'RunAsync'");
return std::make_tuple(request.configured_infer_model_handle().id(), request.infer_model_handle().id(), std::vector<uint32_t> input_buffer_sizes(request.input_buffer_sizes().begin(), request.input_buffer_sizes().end());
request.callback_handle().id());
RunAsyncSerializer::Request request_struct;
request_struct.configured_infer_model_handle = request.configured_infer_model_handle().id();
request_struct.infer_model_handle = request.infer_model_handle().id();
request_struct.callback_handle = request.callback_handle().id();
request_struct.input_buffer_sizes = input_buffer_sizes;
return request_struct;
} }
Expected<Buffer> RunAsyncSerializer::serialize_reply(hailo_status status) Expected<Buffer> RunAsyncSerializer::serialize_reply(hailo_status status)
@@ -805,7 +813,8 @@ hailo_status RunAsyncSerializer::deserialize_reply(const MemoryView &serialized_
return static_cast<hailo_status>(reply.status()); return static_cast<hailo_status>(reply.status());
} }
Expected<Buffer> CallbackCalledSerializer::serialize_reply(hailo_status status, rpc_object_handle_t callback_handle) Expected<Buffer> CallbackCalledSerializer::serialize_reply(hailo_status status, rpc_object_handle_t callback_handle,
rpc_object_handle_t configured_infer_model_handle)
{ {
CallbackCalled_Reply reply; CallbackCalled_Reply reply;
@@ -813,6 +822,9 @@ Expected<Buffer> CallbackCalledSerializer::serialize_reply(hailo_status status,
auto proto_callback_handle = reply.mutable_callback_handle(); auto proto_callback_handle = reply.mutable_callback_handle();
proto_callback_handle->set_id(callback_handle); proto_callback_handle->set_id(callback_handle);
auto proto_cim_handle = reply.mutable_configured_infer_model_handle();
proto_cim_handle->set_id(configured_infer_model_handle);
TRY(auto serialized_reply, Buffer::create(reply.ByteSizeLong(), BufferStorageParams::create_dma())); TRY(auto serialized_reply, Buffer::create(reply.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(reply.SerializeToArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())), CHECK_AS_EXPECTED(reply.SerializeToArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
@@ -821,14 +833,319 @@ Expected<Buffer> CallbackCalledSerializer::serialize_reply(hailo_status status,
return serialized_reply; return serialized_reply;
} }
Expected<std::tuple<hailo_status, rpc_object_handle_t>> CallbackCalledSerializer::deserialize_reply(const MemoryView &serialized_reply) Expected<std::tuple<hailo_status, rpc_object_handle_t, rpc_object_handle_t>>
CallbackCalledSerializer::deserialize_reply(const MemoryView &serialized_reply)
{ {
CallbackCalled_Reply reply; CallbackCalled_Reply reply;
CHECK_AS_EXPECTED(reply.ParseFromArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())), CHECK_AS_EXPECTED(reply.ParseFromArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'CallbackCalled'"); HAILO_RPC_FAILED, "Failed to de-serialize 'CallbackCalled'");
return std::make_tuple(static_cast<hailo_status>(reply.status()), reply.callback_handle().id()); return std::make_tuple(static_cast<hailo_status>(reply.status()), reply.callback_handle().id(),
reply.configured_infer_model_handle().id());
}
Expected<Buffer> CreateDeviceSerializer::serialize_request()
{
Device_Create_Request request;
// TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'CreateDevice'");
return serialized_request;
}
hailo_status CreateDeviceSerializer::deserialize_request(const MemoryView &serialized_request)
{
Device_Create_Request request;
CHECK_AS_EXPECTED(request.ParseFromArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'CreateDevice'");
return HAILO_SUCCESS;
}
Expected<Buffer> CreateDeviceSerializer::serialize_reply(hailo_status status, rpc_object_handle_t device_handle)
{
Device_Create_Reply reply;
reply.set_status(status);
auto proto_device_handle = reply.mutable_device_handle();
proto_device_handle->set_id(device_handle);
TRY(auto serialized_reply, Buffer::create(reply.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(reply.SerializeToArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to serialize 'CreateDevice'");
return serialized_reply;
}
Expected<std::tuple<hailo_status, rpc_object_handle_t>> CreateDeviceSerializer::deserialize_reply(const MemoryView &serialized_reply)
{
Device_Create_Reply reply;
CHECK_AS_EXPECTED(reply.ParseFromArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'CreateDevice'");
return std::make_tuple(static_cast<hailo_status>(reply.status()), reply.device_handle().id());
}
Expected<Buffer> DestroyDeviceSerializer::serialize_request(rpc_object_handle_t device_handle)
{
Device_Destroy_Request request;
auto proto_device_handle= request.mutable_device_handle();
proto_device_handle->set_id(device_handle);
// TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'DestroyDevice'");
return serialized_request;
}
Expected<rpc_object_handle_t> DestroyDeviceSerializer::deserialize_request(const MemoryView &serialized_request)
{
Device_Destroy_Request request;
CHECK_AS_EXPECTED(request.ParseFromArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'DestroyDevice'");
return request.device_handle().id();
}
Expected<Buffer> DestroyDeviceSerializer::serialize_reply(hailo_status status)
{
Device_Destroy_Reply reply;
reply.set_status(status);
TRY(auto serialized_reply, Buffer::create(reply.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(reply.SerializeToArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to serialize 'DestroyDevice'");
return serialized_reply;
}
hailo_status DestroyDeviceSerializer::deserialize_reply(const MemoryView &serialized_reply)
{
Device_Destroy_Reply reply;
CHECK_AS_EXPECTED(reply.ParseFromArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'DestroyDevice'");
return static_cast<hailo_status>(reply.status());
}
Expected<Buffer> IdentifyDeviceSerializer::serialize_request(rpc_object_handle_t device_handle)
{
Device_Identify_Request request;
auto proto_device_handle = request.mutable_device_handle();
proto_device_handle->set_id(device_handle);
// TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'IdentifyDevice'");
return serialized_request;
}
Expected<rpc_object_handle_t> IdentifyDeviceSerializer::deserialize_request(const MemoryView &serialized_request)
{
Device_Identify_Request request;
CHECK_AS_EXPECTED(request.ParseFromArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'IdentifyDevice'");
return request.device_handle().id();
}
Expected<Buffer> IdentifyDeviceSerializer::serialize_reply(hailo_status status, const hailo_device_identity_t &identity)
{
Device_Identify_Reply reply;
reply.set_status(status);
auto proto_identity = reply.mutable_identity();
proto_identity->set_protocol_version(identity.protocol_version);
proto_identity->set_logger_version(identity.logger_version);
proto_identity->set_board_name(identity.board_name);
proto_identity->set_is_release(identity.is_release);
proto_identity->set_extended_context_switch_buffer(identity.extended_context_switch_buffer);
proto_identity->set_device_architecture(static_cast<DeviceArchitectureProto>(identity.device_architecture));
auto mut_serial_number = proto_identity->mutable_serial_number();
for (uint8_t i = 0; i < identity.serial_number_length; i++) {
mut_serial_number->Add(identity.serial_number[i]);
}
auto mut_part_number = proto_identity->mutable_part_number();
for (uint8_t i = 0; i < identity.part_number_length; i++) {
mut_part_number->Add(identity.part_number[i]);
}
proto_identity->set_product_name(identity.product_name);
auto fw_version = proto_identity->mutable_fw_version();
fw_version->set_major_value(identity.fw_version.major);
fw_version->set_minor_value(identity.fw_version.minor);
fw_version->set_revision_value(identity.fw_version.revision);
TRY(auto serialized_reply, Buffer::create(reply.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(reply.SerializeToArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to serialize 'IdentifyDevice'");
return serialized_reply;
}
Expected<std::tuple<hailo_status, hailo_device_identity_t>> IdentifyDeviceSerializer::deserialize_reply(const MemoryView &serialized_reply)
{
Device_Identify_Reply reply;
CHECK_AS_EXPECTED(reply.ParseFromArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'IdentifyDevice'");
hailo_device_identity_t identity = {};
identity.protocol_version = reply.identity().protocol_version();
identity.logger_version = reply.identity().logger_version();
identity.is_release = reply.identity().is_release();
identity.extended_context_switch_buffer = reply.identity().extended_context_switch_buffer();
identity.device_architecture = static_cast<hailo_device_architecture_t>(reply.identity().device_architecture());
std::memcpy(identity.board_name, reply.identity().board_name().c_str(), reply.identity().board_name().size());
identity.board_name_length = static_cast<uint8_t>(reply.identity().board_name().size());
std::transform(reply.identity().serial_number().begin(), reply.identity().serial_number().end(), identity.serial_number, [](uint32_t val) {
return static_cast<uint8_t>(val);
});
identity.part_number_length = static_cast<uint8_t>(reply.identity().part_number().size());
std::transform(reply.identity().part_number().begin(), reply.identity().part_number().end(), identity.part_number, [](uint32_t val) {
return static_cast<uint8_t>(val);
});
identity.part_number_length = static_cast<uint8_t>(reply.identity().serial_number().size());
std::memcpy(identity.product_name, reply.identity().product_name().c_str(), reply.identity().product_name().size());
identity.product_name_length = static_cast<uint8_t>(reply.identity().product_name().size());
identity.fw_version.major = reply.identity().fw_version().major_value();
identity.fw_version.minor = reply.identity().fw_version().minor_value();
identity.fw_version.revision = reply.identity().fw_version().revision_value();
return std::make_tuple(static_cast<hailo_status>(reply.status()), identity);
}
Expected<Buffer> ExtendedDeviceInfoSerializer::serialize_request(rpc_object_handle_t device_handle)
{
Device_ExtendedInfo_Request request;
auto proto_device_handle = request.mutable_device_handle();
proto_device_handle->set_id(device_handle);
// TODO (HRT-14732) - check if we can use GetCachedSize
TRY(auto serialized_request, Buffer::create(request.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(request.SerializeToArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to serialize 'ExtendedDeviceInfo'");
return serialized_request;
}
Expected<rpc_object_handle_t> ExtendedDeviceInfoSerializer::deserialize_request(const MemoryView &serialized_request)
{
Device_ExtendedInfo_Request request;
CHECK_AS_EXPECTED(request.ParseFromArray(serialized_request.data(), static_cast<int>(serialized_request.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'ExtendedDeviceInfo'");
return request.device_handle().id();
}
Expected<Buffer> ExtendedDeviceInfoSerializer::serialize_reply(hailo_status status, const hailo_extended_device_information_t &extended_info)
{
Device_ExtendedInfo_Reply reply;
reply.set_status(status);
reply.set_neural_network_core_clock_rate(extended_info.neural_network_core_clock_rate);
auto supported_features = reply.mutable_supported_features();
supported_features->set_ethernet(extended_info.supported_features.ethernet);
supported_features->set_mipi(extended_info.supported_features.mipi);
supported_features->set_pcie(extended_info.supported_features.pcie);
supported_features->set_current_monitoring(extended_info.supported_features.current_monitoring);
supported_features->set_mdio(extended_info.supported_features.mdio);
reply.set_boot_source(static_cast<DeviceBootSourceProto>(extended_info.boot_source));
auto soc_id = reply.mutable_soc_id();
for (auto i = 0; i < HAILO_SOC_ID_LENGTH; i++) {
soc_id->Add(extended_info.soc_id[i]);
}
reply.set_lcs(extended_info.lcs);
auto eth_mac_address = reply.mutable_eth_mac_address();
for (auto i = 0; i < HAILO_ETH_MAC_LENGTH; i++) {
eth_mac_address->Add(extended_info.eth_mac_address[i]);
}
auto unit_level_tracking_id = reply.mutable_unit_level_tracking_id();
for (auto i = 0; i < HAILO_UNIT_LEVEL_TRACKING_BYTES_LENGTH; i++) {
unit_level_tracking_id->Add(extended_info.unit_level_tracking_id[i]);
}
auto soc_pm_values = reply.mutable_soc_pm_values();
for (auto i = 0; i < HAILO_SOC_PM_VALUES_BYTES_LENGTH; i++) {
soc_pm_values->Add(extended_info.soc_pm_values[i]);
}
TRY(auto serialized_reply, Buffer::create(reply.ByteSizeLong(), BufferStorageParams::create_dma()));
CHECK_AS_EXPECTED(reply.SerializeToArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to serialize 'ExtendedDeviceInfo'");
return serialized_reply;
}
Expected<std::tuple<hailo_status, hailo_extended_device_information_t>> ExtendedDeviceInfoSerializer::deserialize_reply(const MemoryView &serialized_reply)
{
Device_ExtendedInfo_Reply reply;
CHECK_AS_EXPECTED(reply.ParseFromArray(serialized_reply.data(), static_cast<int>(serialized_reply.size())),
HAILO_RPC_FAILED, "Failed to de-serialize 'ExtendedDeviceInfo'");
hailo_extended_device_information_t extended_info = {};
extended_info.neural_network_core_clock_rate = reply.neural_network_core_clock_rate();
extended_info.supported_features.ethernet = reply.supported_features().ethernet();
extended_info.supported_features.mipi = reply.supported_features().mipi();
extended_info.supported_features.pcie = reply.supported_features().pcie();
extended_info.supported_features.current_monitoring = reply.supported_features().current_monitoring();
extended_info.supported_features.mdio = reply.supported_features().mdio();
extended_info.boot_source = static_cast<hailo_device_boot_source_t>(reply.boot_source());
std::transform(reply.soc_id().begin(), reply.soc_id().end(), extended_info.soc_id, [](uint32_t val) {
return static_cast<uint8_t>(val);
});
extended_info.lcs = static_cast<uint8_t>(reply.lcs());
// Ensure that the sizes of the input and output arrays match before transformation
assert(reply.eth_mac_address().size() == HAILO_ETH_MAC_LENGTH);
std::transform(reply.eth_mac_address().begin(), reply.eth_mac_address().begin() + HAILO_ETH_MAC_LENGTH,
extended_info.eth_mac_address, [](uint32_t val) { return static_cast<uint8_t>(val); });
assert(reply.unit_level_tracking_id().size() == HAILO_UNIT_LEVEL_TRACKING_BYTES_LENGTH);
std::transform(reply.unit_level_tracking_id().begin(), reply.unit_level_tracking_id().begin() + HAILO_UNIT_LEVEL_TRACKING_BYTES_LENGTH,
extended_info.unit_level_tracking_id, [](uint32_t val) { return static_cast<uint8_t>(val); });
assert(reply.soc_pm_values().size() == HAILO_SOC_PM_VALUES_BYTES_LENGTH);
std::transform(reply.soc_pm_values().begin(), reply.soc_pm_values().begin() + HAILO_SOC_PM_VALUES_BYTES_LENGTH,
extended_info.soc_pm_values, [](uint32_t val) { return static_cast<uint8_t>(val); });
return std::make_tuple(static_cast<hailo_status>(reply.status()), extended_info);
} }
} /* namespace hailort */ } /* namespace hailort */

View File

@@ -16,6 +16,7 @@
#include <chrono> #include <chrono>
#include <unordered_map> #include <unordered_map>
#include <vector>
namespace hailort namespace hailort
{ {
@@ -41,6 +42,11 @@ enum class HailoRpcActionID {
CONFIGURED_INFER_MODEL__SHUTDOWN, CONFIGURED_INFER_MODEL__SHUTDOWN,
CONFIGURED_INFER_MODEL__RUN_ASYNC, CONFIGURED_INFER_MODEL__RUN_ASYNC,
DEVICE__CREATE,
DEVICE__DESTROY,
DEVICE__IDENTIFY,
DEVICE__EXTENDED_INFO,
CALLBACK_CALLED, CALLBACK_CALLED,
MAX_VALUE, MAX_VALUE,
@@ -97,8 +103,8 @@ class CreateInferModelSerializer
public: public:
CreateInferModelSerializer() = delete; CreateInferModelSerializer() = delete;
static Expected<Buffer> serialize_request(rpc_object_handle_t vdevice_handle, uint64_t hef_size); static Expected<Buffer> serialize_request(rpc_object_handle_t vdevice_handle, uint64_t hef_size, const std::string &name);
static Expected<std::tuple<rpc_object_handle_t, uint64_t>> deserialize_request(const MemoryView &serialized_request); static Expected<std::tuple<rpc_object_handle_t, uint64_t, std::string>> deserialize_request(const MemoryView &serialized_request);
static Expected<Buffer> serialize_reply(hailo_status status, rpc_object_handle_t infer_model_handle = INVALID_HANDLE_ID); static Expected<Buffer> serialize_reply(hailo_status status, rpc_object_handle_t infer_model_handle = INVALID_HANDLE_ID);
static Expected<std::tuple<hailo_status, rpc_object_handle_t>> deserialize_reply(const MemoryView &serialized_reply); static Expected<std::tuple<hailo_status, rpc_object_handle_t>> deserialize_reply(const MemoryView &serialized_reply);
@@ -230,9 +236,16 @@ class RunAsyncSerializer
public: public:
RunAsyncSerializer() = delete; RunAsyncSerializer() = delete;
static Expected<Buffer> serialize_request(rpc_object_handle_t configured_infer_model_handle, rpc_object_handle_t infer_model_handle, struct Request
rpc_object_handle_t callback_handle); {
static Expected<std::tuple<rpc_object_handle_t, rpc_object_handle_t, rpc_object_handle_t>> deserialize_request(const MemoryView &serialized_request); rpc_object_handle_t configured_infer_model_handle;
rpc_object_handle_t infer_model_handle;
rpc_object_handle_t callback_handle;
std::vector<uint32_t> input_buffer_sizes;
};
static Expected<Buffer> serialize_request(const Request &request_struct);
static Expected<Request> deserialize_request(const MemoryView &serialized_request);
static Expected<Buffer> serialize_reply(hailo_status status); static Expected<Buffer> serialize_reply(hailo_status status);
static hailo_status deserialize_reply(const MemoryView &serialized_reply); static hailo_status deserialize_reply(const MemoryView &serialized_reply);
@@ -243,10 +256,59 @@ class CallbackCalledSerializer
public: public:
CallbackCalledSerializer() = delete; CallbackCalledSerializer() = delete;
static Expected<Buffer> serialize_reply(hailo_status status, rpc_object_handle_t callback_handle = INVALID_HANDLE_ID); static Expected<Buffer> serialize_reply(hailo_status status, rpc_object_handle_t callback_handle = INVALID_HANDLE_ID,
rpc_object_handle_t configured_infer_model_handle = INVALID_HANDLE_ID);
static Expected<std::tuple<hailo_status, rpc_object_handle_t, rpc_object_handle_t>> deserialize_reply(const MemoryView &serialized_reply);
};
class CreateDeviceSerializer
{
public:
CreateDeviceSerializer() = delete;
static Expected<Buffer> serialize_request();
static hailo_status deserialize_request(const MemoryView &serialized_request);
static Expected<Buffer> serialize_reply(hailo_status status, rpc_object_handle_t device_handle = INVALID_HANDLE_ID);
static Expected<std::tuple<hailo_status, rpc_object_handle_t>> deserialize_reply(const MemoryView &serialized_reply); static Expected<std::tuple<hailo_status, rpc_object_handle_t>> deserialize_reply(const MemoryView &serialized_reply);
}; };
class DestroyDeviceSerializer
{
public:
DestroyDeviceSerializer() = delete;
static Expected<Buffer> serialize_request(rpc_object_handle_t device_handle);
static Expected<rpc_object_handle_t> deserialize_request(const MemoryView &serialized_request);
static Expected<Buffer> serialize_reply(hailo_status status);
static hailo_status deserialize_reply(const MemoryView &serialized_reply);
};
class IdentifyDeviceSerializer
{
public:
IdentifyDeviceSerializer() = delete;
static Expected<Buffer> serialize_request(rpc_object_handle_t device_handle);
static Expected<rpc_object_handle_t> deserialize_request(const MemoryView &serialized_request);
static Expected<Buffer> serialize_reply(hailo_status status, const hailo_device_identity_t &identity = {});
static Expected<std::tuple<hailo_status, hailo_device_identity_t>> deserialize_reply(const MemoryView &serialized_reply);
};
class ExtendedDeviceInfoSerializer
{
public:
ExtendedDeviceInfoSerializer() = delete;
static Expected<Buffer> serialize_request(rpc_object_handle_t device_handle);
static Expected<rpc_object_handle_t> deserialize_request(const MemoryView &serialized_request);
static Expected<Buffer> serialize_reply(hailo_status status, const hailo_extended_device_information_t &extended_info = {});
static Expected<std::tuple<hailo_status, hailo_extended_device_information_t>> deserialize_reply(const MemoryView &serialized_reply);
};
} /* namespace hailort */ } /* namespace hailort */

View File

@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
# set(CMAKE_C_CLANG_TIDY "clang-tidy;-checks=*") # set(CMAKE_C_CLANG_TIDY "clang-tidy;-checks=*")
set(HAILORT_MAJOR_VERSION 4) set(HAILORT_MAJOR_VERSION 4)
set(HAILORT_MINOR_VERSION 18) set(HAILORT_MINOR_VERSION 19)
set(HAILORT_REVISION_VERSION 0) set(HAILORT_REVISION_VERSION 0)
# Add the cmake folder so the modules there are found # Add the cmake folder so the modules there are found
@@ -27,10 +27,6 @@ target_include_directories(hef_proto
$<BUILD_INTERFACE: ${Protobuf_INCLUDE_DIRS}> $<BUILD_INTERFACE: ${Protobuf_INCLUDE_DIRS}>
) )
if(HAILO_BUILD_PROFILER)
add_definitions( -DHAILO_ENABLE_PROFILER_BUILD )
endif()
protobuf_generate_cpp(PROTO_SCHEDULER_MON_SRC PROTO_SCHEDULER_MON_HEADR scheduler_mon.proto) protobuf_generate_cpp(PROTO_SCHEDULER_MON_SRC PROTO_SCHEDULER_MON_HEADR scheduler_mon.proto)
add_library(scheduler_mon_proto ${PROTO_SCHEDULER_MON_SRC} ${PROTO_SCHEDULER_MON_HEADR}) add_library(scheduler_mon_proto ${PROTO_SCHEDULER_MON_SRC} ${PROTO_SCHEDULER_MON_HEADR})
target_link_libraries(scheduler_mon_proto libprotobuf-lite) target_link_libraries(scheduler_mon_proto libprotobuf-lite)

View File

@@ -1,9 +1,12 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
if(HAILO_BUILD_PYBIND)
add_subdirectory(python)
endif()
# QNX currently doesnt support GStreamer # QNX currently doesnt support GStreamer
if(HAILO_BUILD_GSTREAMER AND CMAKE_HOST_UNIX AND NOT CMAKE_SYSTEM_NAME STREQUAL QNX) if(HAILO_BUILD_GSTREAMER AND NOT CMAKE_SYSTEM_NAME STREQUAL QNX)
add_subdirectory(gstreamer) add_subdirectory(gstreamer)
endif() endif()
option(HAILO_BUILD_PYHAILORT_INTERNAL OFF)
option(HAILO_BUILD_RAW_CONNECTION OFF)
if(HAILO_BUILD_RAW_CONNECTION OR HAILO_BUILD_PYHAILORT_INTERNAL)
add_subdirectory(python/src/internal/)
endif()

View File

@@ -1,34 +1,24 @@
cmake_minimum_required(VERSION 3.0.0) cmake_minimum_required(VERSION 3.5.0)
project(gsthailo) project(gsthailo)
include(GNUInstallDirs) include(GNUInstallDirs)
if(NOT CMAKE_HOST_UNIX) find_package(HailoRT 4.19.0 EXACT REQUIRED)
message(FATAL_ERROR "Only unix hosts are supported, stopping build")
endif()
find_package(HailoRT 4.18.0 EXACT REQUIRED)
# GST_PLUGIN_DEFINE needs PACKAGE to be defined # GST_PLUGIN_DEFINE needs PACKAGE to be defined
set(GST_HAILO_PACKAGE_NAME "hailo") set(GST_HAILO_PACKAGE_NAME "hailo")
set(GST_HAILO_VERSION "1.0") set(GST_HAILO_VERSION "1.0")
find_package(PkgConfig REQUIRED) include(find_libs_for_gstreamer.cmake)
pkg_search_module(GLIB REQUIRED glib-2.0)
pkg_search_module(GSTREAMER REQUIRED gstreamer-1.0)
pkg_search_module(GSTREAMER_BASE REQUIRED gstreamer-base-1.0)
pkg_search_module(GSTREAMER_VIDEO REQUIRED gstreamer-video-1.0)
pkg_search_module(GSTREAMER_PLUGINS_BASE REQUIRED gstreamer-plugins-base-1.0)
add_library(gsthailo SHARED set(GSTHAILO_SOURCES
gst-hailo/gsthailoplugin.cpp gst-hailo/gsthailoplugin.cpp
gst-hailo/sync_gsthailonet.cpp gst-hailo/sync_gsthailonet.cpp
gst-hailo/sync_gst_hailosend.cpp gst-hailo/sync_gst_hailosend.cpp
gst-hailo/sync_gst_hailorecv.cpp gst-hailo/sync_gst_hailorecv.cpp
gst-hailo/gsthailonet.cpp gst-hailo/gsthailonet.cpp
gst-hailo/gsthailo_allocator.cpp gst-hailo/gsthailo_allocator.cpp
gst-hailo/gsthailo_dmabuf_allocator.cpp
gst-hailo/gsthailodevicestats.cpp gst-hailo/gsthailodevicestats.cpp
gst-hailo/common.cpp gst-hailo/common.cpp
gst-hailo/network_group_handle.cpp gst-hailo/network_group_handle.cpp
@@ -36,8 +26,18 @@ add_library(gsthailo SHARED
gst-hailo/metadata/tensor_meta.cpp gst-hailo/metadata/tensor_meta.cpp
gst-hailo/hailo_events/hailo_events.cpp) gst-hailo/hailo_events/hailo_events.cpp)
# dmabuf is supported only on linux
if (UNIX)
list(APPEND GSTHAILO_SOURCES gst-hailo/gsthailo_dmabuf_allocator.cpp gst-hailo/os/linux/dma_buf_allocator_wrapper.cpp)
elseif (MSVC)
list(APPEND GSTHAILO_SOURCES gst-hailo/os/windows/dma_buf_allocator_wrapper.cpp)
endif ()
add_library(gsthailo SHARED ${GSTHAILO_SOURCES})
set_property(TARGET gsthailo PROPERTY CXX_STANDARD 14) set_property(TARGET gsthailo PROPERTY CXX_STANDARD 14)
# TODO HRT-14797: After creating a directory containing all the relevant Hailo GST files (tensor_meta.hpp and hailo_gst.h) - update the PUBLIC_HEADER to be that dir
set_target_properties(gsthailo PROPERTIES set_target_properties(gsthailo PROPERTIES
PUBLIC_HEADER "gst-hailo/metadata/tensor_meta.hpp" PUBLIC_HEADER "gst-hailo/metadata/tensor_meta.hpp"
CXX_STANDARD 14 CXX_STANDARD 14
@@ -48,17 +48,54 @@ set_target_properties(gsthailo PROPERTIES
# VISIBILITY_INLINES_HIDDEN YES # VISIBILITY_INLINES_HIDDEN YES
) )
target_compile_options(gsthailo PRIVATE if (UNIX)
-Werror -Wall -Wextra -Wconversion set(HAILORT_COMPILE_OPTIONS
${HAILORT_COMPILE_OPTIONS}
-DVERSION="${GST_HAILO_VERSION}" -DVERSION="${GST_HAILO_VERSION}"
-DPACKAGE="${GST_HAILO_PACKAGE_NAME}") -DPACKAGE="${GST_HAILO_PACKAGE_NAME}"
)
elseif (WIN32)
set(HAILORT_COMPILE_OPTIONS
${HAILORT_COMPILE_OPTIONS}
/DWIN32_LEAN_AND_MEAN
/DNOMINMAX # NOMINMAX is required in order to play nice with std::min/std::max (otherwise Windows.h defines it's own)
/D_HAILO_EXPORTING
/wd4201 # Anonymous union/struct
/wd4251 # C++ ABI with STL
-DVERSION="${GST_HAILO_VERSION}"
-DPACKAGE="${GST_HAILO_PACKAGE_NAME}"
)
else()
message(FATAL_ERROR "Unexpeced host, stopping build")
endif()
target_include_directories(gsthailo PRIVATE ${GSTREAMER_VIDEO_INCLUDE_DIRS}) target_compile_options(gsthailo PRIVATE ${HAILORT_COMPILE_OPTIONS})
if (UNIX)
target_include_directories(gsthailo PRIVATE ${GSTREAMER_VIDEO_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/gst-hailo ${CMAKE_CURRENT_SOURCE_DIR}/gst-hailo/os/linux)
target_link_libraries(gsthailo HailoRT::libhailort ${GSTREAMER_VIDEO_LDFLAGS} -lgstallocators-1.0) target_link_libraries(gsthailo HailoRT::libhailort ${GSTREAMER_VIDEO_LDFLAGS} -lgstallocators-1.0)
else()
target_include_directories(gsthailo PRIVATE ${GSTREAMER_INCLUDE_DIRS} ${GSTREAMER_VIDEO_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS} ${GLIBCONFIG_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/gst-hailo ${CMAKE_CURRENT_SOURCE_DIR}/gst-hailo/os/windows)
target_link_libraries(gsthailo HailoRT::libhailort ${GSTREAMER_LIBRARIES} ${GSTREAMER_BASE_LIBRARIES} ${GSTREAMER_VIDEO_LIBRARIES} ${GLIB_LIBRARIES} ${GOBJECT_LIBRARIES} -lgstallocators-1.0)
endif()
if (UNIX)
set(GSTREAMER_LIB_DEST "${CMAKE_INSTALL_LIBDIR}/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/gstreamer-1.0/")
set(PUBLIC_HEADER_DEST "${CMAKE_INSTALL_INCLUDEDIR}/gstreamer-1.0/gst/hailo/")
elseif (MSVC)
if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x64")
set(GSTREAMER_DEST "C:\\gstreamer\\1.0\\msvc_x86_64")
else()
message(FATAL_ERROR "HailoRT GStreamer elements installation is not supported on this architecture.")
endif()
set(GSTREAMER_LIB_DEST "${GSTREAMER_DEST}\\lib\\gstreamer-1.0")
set(PUBLIC_HEADER_DEST "${CMAKE_INSTALL_INCLUDEDIR}\\gstreamer-1.0\\gst\\hailo")
endif()
# Install command using the set variables
install(TARGETS gsthailo install(TARGETS gsthailo
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION "${GSTREAMER_LIB_DEST}"
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION "${GSTREAMER_LIB_DEST}"
# TODO: get gstreamer-1.0 in an automate way ARCHIVE DESTINATION "${GSTREAMER_LIB_DEST}"
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/gstreamer-1.0/gst/hailo/" PUBLIC_HEADER DESTINATION "${PUBLIC_HEADER_DEST}"
CONFIGURATIONS Release) CONFIGURATIONS Release)

View File

@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.0.0)
if (UNIX)
include(find_libs_for_gstreamer_linux.cmake)
elseif (MSVC)
include(find_libs_for_gstreamer_windows.cmake)
else()
message(FATAL_ERROR "HailoRT GStreamer elements compilation is supported only on UNIX or MSVC.")
endif()

View File

@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.0.0)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0)
pkg_search_module(GSTREAMER REQUIRED gstreamer-1.0)
pkg_search_module(GSTREAMER_BASE REQUIRED gstreamer-base-1.0)
pkg_search_module(GSTREAMER_VIDEO REQUIRED gstreamer-video-1.0)
pkg_search_module(GSTREAMER_PLUGINS_BASE REQUIRED gstreamer-plugins-base-1.0)

View File

@@ -0,0 +1,87 @@
cmake_minimum_required(VERSION 3.0.0)
# CMake variable GSTREAMER_ROOT_DIR defines the location of the gstreamer files.
# It's default value is C:/gstreamer/1.0/msvc_x86_64.
if (NOT GSTREAMER_ROOT_DIR)
message("Gstreamer Windows compilation - GSTREAMER_ROOT_DIR is not set. default value is C:/gstreamer/1.0/msvc_x86_64")
set(GSTREAMER_ROOT_DIR "C:/gstreamer/1.0/msvc_x86_64")
endif()
set(GLIB_ROOT_DIR ${GSTREAMER_ROOT_DIR})
# Find the GStreamer library and include directories
find_path(GSTREAMER_INCLUDE_DIRS
NAMES gst/gst.h
PATHS ${GSTREAMER_ROOT_DIR}/include/gstreamer-1.0
REQUIRED
)
find_library(GSTREAMER_LIBRARIES
NAMES gstreamer-1.0
PATHS ${GSTREAMER_ROOT_DIR}/lib
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GStreamer DEFAULT_MSG
GSTREAMER_LIBRARIES GSTREAMER_INCLUDE_DIRS
REQUIRED
)
# Find the GStreamer base library and include directories
find_path(GSTREAMER_BASE_INCLUDE_DIRS
NAMES gst/base/base.h
PATHS ${GSTREAMER_ROOT_DIR}/include/gstreamer-1.0
)
find_library(GSTREAMER_BASE_LIBRARIES
NAMES gstbase-1.0
PATHS ${GSTREAMER_ROOT_DIR}/lib
)
find_package_handle_standard_args(GStreamerPluginsBase DEFAULT_MSG
GSTREAMER_BASE_LIBRARIES GSTREAMER_BASE_INCLUDE_DIRS
)
# Find the GStreamer video library and include directories
find_path(GSTREAMER_VIDEO_INCLUDE_DIRS
NAMES gst/video/video.h
PATHS ${GSTREAMER_ROOT_DIR}/include/gstreamer-1.0
)
find_library(GSTREAMER_VIDEO_LIBRARIES
NAMES gstvideo-1.0
PATHS ${GSTREAMER_ROOT_DIR}/lib
)
find_package_handle_standard_args(GStreamerVideo DEFAULT_MSG
GSTREAMER_VIDEO_LIBRARIES GSTREAMER_VIDEO_INCLUDE_DIRS
)
# Find the GLib library and include directories
find_path(GLIB_INCLUDE_DIRS
NAMES glib.h
PATHS ${GLIB_ROOT_DIR}/include/glib-2.0
${GLIB_ROOT_DIR}/lib/glib-2.0/include
REQUIRED
)
find_library(GLIB_LIBRARIES
NAMES glib-2.0
PATHS ${GLIB_ROOT_DIR}/lib
)
find_library(GOBJECT_LIBRARIES
NAMES gobject-2.0
PATHS ${GLIB_ROOT_DIR}/lib
)
# Add the directory containing glibconfig.h to the include directories
find_path(GLIBCONFIG_INCLUDE_DIR
NAMES glibconfig.h
PATHS ${GLIB_ROOT_DIR}/lib/glib-2.0/include
REQUIRED
)
find_package_handle_standard_args(GLib DEFAULT_MSG
GLIB_LIBRARIES GLIB_INCLUDE_DIRS GLIBCONFIG_INCLUDE_DIR
REQUIRED
)

View File

@@ -23,20 +23,22 @@
#include "hailo/device.hpp" #include "hailo/device.hpp"
#include "hailo/network_group.hpp" #include "hailo/network_group.hpp"
#include "hailo/vstream.hpp" #include "hailo/vstream.hpp"
#include "hailo_gst.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#include <gst/gst.h>
#pragma GCC diagnostic pop
#include <vector> #include <vector>
using namespace hailort; using namespace hailort;
#define ERROR(msg, ...) g_print("HailoNet Error: " msg, ##__VA_ARGS__) #define GST_HAILO_USE_DMA_BUFFER_ENV_VAR "GST_HAILO_USE_DMA_BUFFER"
#define HAILONET_ERROR(msg, ...) g_print("HailoNet Error: " msg, ##__VA_ARGS__)
#define PLUGIN_AUTHOR "Hailo Technologies Ltd. (\"Hailo\")" #define PLUGIN_AUTHOR "Hailo Technologies Ltd. (\"Hailo\")"
#ifdef _MSC_VER
#define MAX_STRING_SIZE (MAX_PATH)
#else
#define MAX_STRING_SIZE (PATH_MAX) #define MAX_STRING_SIZE (PATH_MAX)
#endif
#define MAX_QUEUED_BUFFERS_IN_INPUT (16) #define MAX_QUEUED_BUFFERS_IN_INPUT (16)
#define MAX_QUEUED_BUFFERS_IN_OUTPUT (16) #define MAX_QUEUED_BUFFERS_IN_OUTPUT (16)
@@ -115,6 +117,9 @@ using namespace hailort;
#define CHECK_NOT_NULL(arg, status) _CHECK(nullptr != (arg), status, "CHECK_NOT_NULL for %s failed", #arg) #define CHECK_NOT_NULL(arg, status) _CHECK(nullptr != (arg), status, "CHECK_NOT_NULL for %s failed", #arg)
#define CHECK_NOT_NULL_AS_EXPECTED(arg, status) \
_CHECK(nullptr != (arg), make_unexpected(status), "CHECK_NOT_NULL_AS_EXPECTED for %s failed", #arg)
#define _CHECK_SUCCESS(status, ...) \ #define _CHECK_SUCCESS(status, ...) \
do { \ do { \
const auto &__check_success_status = (status); \ const auto &__check_success_status = (status); \
@@ -269,9 +274,6 @@ private:
bool m_was_changed; bool m_was_changed;
}; };
template<>
HailoElemProperty<gchar*>::~HailoElemProperty();
#define GST_TYPE_SCHEDULING_ALGORITHM (gst_scheduling_algorithm_get_type ()) #define GST_TYPE_SCHEDULING_ALGORITHM (gst_scheduling_algorithm_get_type ())
GType gst_scheduling_algorithm_get_type (void); GType gst_scheduling_algorithm_get_type (void);

View File

@@ -27,33 +27,47 @@ static GstMemory *gst_hailo_allocator_alloc(GstAllocator* allocator, gsize size,
GstHailoAllocator *hailo_allocator = GST_HAILO_ALLOCATOR(allocator); GstHailoAllocator *hailo_allocator = GST_HAILO_ALLOCATOR(allocator);
auto buffer = Buffer::create(size, BufferStorageParams::create_dma()); auto buffer = Buffer::create(size, BufferStorageParams::create_dma());
if (!buffer) { if (!buffer) {
ERROR("Creating buffer for allocator has failed, status = %d\n", buffer.status()); HAILONET_ERROR("Creating buffer for allocator has failed, status = %d\n", buffer.status());
return nullptr; return nullptr;
} }
GstMemory *memory = gst_memory_new_wrapped(static_cast<GstMemoryFlags>(0), buffer->data(), GstMemory *memory = gst_memory_new_wrapped(static_cast<GstMemoryFlags>(0), buffer->data(),
buffer->size(), 0, buffer->size(), nullptr, nullptr); buffer->size(), 0, buffer->size(), nullptr, nullptr);
if (nullptr == memory) { if (nullptr == memory) {
ERROR("Creating new GstMemory for allocator has failed!\n"); HAILONET_ERROR("Creating new GstMemory for allocator has failed!\n");
return nullptr; return nullptr;
} }
hailo_allocator->buffers[memory] = std::move(buffer.release()); assert(nullptr != hailo_allocator->buffers);
(*hailo_allocator->buffers)[memory] = std::move(buffer.release());
return memory; return memory;
} }
static void gst_hailo_allocator_free(GstAllocator* allocator, GstMemory *mem) { static void gst_hailo_allocator_free(GstAllocator* allocator, GstMemory *mem) {
GstHailoAllocator *hailo_allocator = GST_HAILO_ALLOCATOR(allocator); GstHailoAllocator *hailo_allocator = GST_HAILO_ALLOCATOR(allocator);
hailo_allocator->buffers.erase(mem); hailo_allocator->buffers->erase(mem);
}
static void gst_hailo_allocator_dispose(GObject *object) {
GstHailoAllocator *allocator = GST_HAILO_ALLOCATOR(object);
if (allocator->buffers != nullptr) {
delete allocator->buffers;
allocator->buffers = nullptr;
}
G_OBJECT_CLASS(gst_hailo_allocator_parent_class)->dispose(object);
} }
static void gst_hailo_allocator_class_init(GstHailoAllocatorClass* klass) { static void gst_hailo_allocator_class_init(GstHailoAllocatorClass* klass) {
GstAllocatorClass* allocator_class = GST_ALLOCATOR_CLASS(klass); GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->dispose = gst_hailo_allocator_dispose;
GstAllocatorClass* allocator_class = GST_ALLOCATOR_CLASS(klass);
allocator_class->alloc = gst_hailo_allocator_alloc; allocator_class->alloc = gst_hailo_allocator_alloc;
allocator_class->free = gst_hailo_allocator_free; allocator_class->free = gst_hailo_allocator_free;
} }
static void gst_hailo_allocator_init(GstHailoAllocator* allocator) { static void gst_hailo_allocator_init(GstHailoAllocator* allocator) {
allocator->buffers = std::unordered_map<GstMemory*, Buffer>(); allocator->buffers = new std::unordered_map<GstMemory*, Buffer>();
} }

View File

@@ -35,7 +35,7 @@ G_BEGIN_DECLS
struct GstHailoAllocator struct GstHailoAllocator
{ {
GstAllocator parent; GstAllocator parent;
std::unordered_map<GstMemory*, Buffer> buffers; std::unordered_map<GstMemory*, Buffer> *buffers;
}; };
struct GstHailoAllocatorClass struct GstHailoAllocatorClass

View File

@@ -39,7 +39,7 @@ static GstMemory *gst_hailo_dmabuf_allocator_alloc(GstAllocator* allocator, gsiz
if (!GstHailoDmaHeapControl::dma_heap_fd_open) { if (!GstHailoDmaHeapControl::dma_heap_fd_open) {
GstHailoDmaHeapControl::dma_heap_fd = open(DEVPATH, O_RDWR | O_CLOEXEC); GstHailoDmaHeapControl::dma_heap_fd = open(DEVPATH, O_RDWR | O_CLOEXEC);
if (GstHailoDmaHeapControl::dma_heap_fd < 0) { if (GstHailoDmaHeapControl::dma_heap_fd < 0) {
ERROR("open fd failed!\n"); HAILONET_ERROR("open fd failed!\n");
return nullptr; return nullptr;
} }
GstHailoDmaHeapControl::dma_heap_fd_open = true; GstHailoDmaHeapControl::dma_heap_fd_open = true;
@@ -55,37 +55,52 @@ static GstMemory *gst_hailo_dmabuf_allocator_alloc(GstAllocator* allocator, gsiz
int ret = ioctl(GstHailoDmaHeapControl::dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &heap_data); int ret = ioctl(GstHailoDmaHeapControl::dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &heap_data);
if (ret < 0) { if (ret < 0) {
ERROR("ioctl DMA_HEAP_IOCTL_ALLOC failed! ret = %d\n", ret); HAILONET_ERROR("ioctl DMA_HEAP_IOCTL_ALLOC failed! ret = %d\n", ret);
return nullptr; return nullptr;
} }
if (GST_IS_DMABUF_ALLOCATOR(hailo_allocator) == false) { if (GST_IS_DMABUF_ALLOCATOR(hailo_allocator) == false) {
ERROR("hailo_allocator is not dmabuf!\n"); HAILONET_ERROR("hailo_allocator is not dmabuf!\n");
return nullptr; return nullptr;
} }
GstMemory *memory = gst_dmabuf_allocator_alloc(allocator, heap_data.fd, size); GstMemory *memory = gst_dmabuf_allocator_alloc(allocator, heap_data.fd, size);
if (nullptr == memory) { if (nullptr == memory) {
ERROR("Creating new GstMemory for allocator has failed!\n"); HAILONET_ERROR("Creating new GstMemory for allocator has failed!\n");
return nullptr; return nullptr;
} }
hailo_allocator->dma_buffers[memory] = heap_data; assert(nullptr != hailo_allocator->dma_buffers);
(*hailo_allocator->dma_buffers)[memory] = heap_data;
return memory; return memory;
} }
static void gst_hailo_dmabuf_allocator_free(GstAllocator* allocator, GstMemory *mem) { static void gst_hailo_dmabuf_allocator_free(GstAllocator* allocator, GstMemory *mem) {
GstHailoDmabufAllocator *hailo_allocator = GST_HAILO_DMABUF_ALLOCATOR(allocator); GstHailoDmabufAllocator *hailo_allocator = GST_HAILO_DMABUF_ALLOCATOR(allocator);
close(hailo_allocator->dma_buffers[mem].fd); assert(nullptr != hailo_allocator->dma_buffers);
hailo_allocator->dma_buffers.erase(mem); close((*hailo_allocator->dma_buffers)[mem].fd);
hailo_allocator->dma_buffers->erase(mem);
} }
static void gst_hailo_dmabuf_allocator_dispose(GObject *object) {
GstHailoDmabufAllocator *allocator = GST_HAILO_DMABUF_ALLOCATOR(object);
if (nullptr != allocator->dma_buffers) {
delete allocator->dma_buffers;
allocator->dma_buffers = nullptr;
}
G_OBJECT_CLASS(gst_hailo_dmabuf_allocator_parent_class)->dispose(object);
}
static void gst_hailo_dmabuf_allocator_class_init(GstHailoDmabufAllocatorClass* klass) { static void gst_hailo_dmabuf_allocator_class_init(GstHailoDmabufAllocatorClass* klass) {
GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
gobject_class->dispose = gst_hailo_dmabuf_allocator_dispose;
GstAllocatorClass* allocator_class = GST_ALLOCATOR_CLASS(klass); GstAllocatorClass* allocator_class = GST_ALLOCATOR_CLASS(klass);
allocator_class->alloc = gst_hailo_dmabuf_allocator_alloc; allocator_class->alloc = gst_hailo_dmabuf_allocator_alloc;
allocator_class->free = gst_hailo_dmabuf_allocator_free; allocator_class->free = gst_hailo_dmabuf_allocator_free;
} }
static void gst_hailo_dmabuf_allocator_init(GstHailoDmabufAllocator* allocator) { static void gst_hailo_dmabuf_allocator_init(GstHailoDmabufAllocator* allocator) {
allocator->dma_buffers = std::unordered_map<GstMemory*, dma_heap_allocation_data>(); allocator->dma_buffers = new std::unordered_map<GstMemory*, dma_heap_allocation_data>();
} }

View File

@@ -35,8 +35,6 @@ G_BEGIN_DECLS
#define GST_IS_HAILO_DMABUF_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_HAILO_DMABUF_ALLOCATOR)) #define GST_IS_HAILO_DMABUF_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_HAILO_DMABUF_ALLOCATOR))
#define GST_IS_HAILO_DMABUF_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_HAILO_DMABUF_ALLOCATOR)) #define GST_IS_HAILO_DMABUF_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_HAILO_DMABUF_ALLOCATOR))
#define GST_HAILO_USE_DMA_BUFFER_ENV_VAR "GST_HAILO_USE_DMA_BUFFER"
class GstHailoDmaHeapControl { class GstHailoDmaHeapControl {
public: public:
static bool dma_heap_fd_open; static bool dma_heap_fd_open;
@@ -46,7 +44,7 @@ public:
struct GstHailoDmabufAllocator struct GstHailoDmabufAllocator
{ {
GstDmaBufAllocator parent; GstDmaBufAllocator parent;
std::unordered_map<GstMemory*, dma_heap_allocation_data> dma_buffers; std::unordered_map<GstMemory*, dma_heap_allocation_data> *dma_buffers;
}; };
struct GstHailoDmabufAllocatorClass struct GstHailoDmabufAllocatorClass

View File

@@ -219,8 +219,8 @@ void HailoDeviceStatsImpl::join_thread()
hailo_status HailoDeviceStatsImpl::run_measure_loop() hailo_status HailoDeviceStatsImpl::run_measure_loop()
{ {
// Checking temperature sensor before starting thread // Checking temperature sensor before starting thread
auto temp_info = m_device->get_chip_temperature(); auto initial_temp_info = m_device->get_chip_temperature();
GST_CHECK_EXPECTED_AS_STATUS(temp_info, m_element, RESOURCE, "Getting chip temperature failed, status = %d", temp_info.status()); GST_CHECK_EXPECTED_AS_STATUS(initial_temp_info, m_element, RESOURCE, "Getting chip temperature failed, status = %d", initial_temp_info.status());
hailo_status status = m_device->stop_power_measurement(); hailo_status status = m_device->stop_power_measurement();
GST_CHECK_SUCCESS(status, m_element, RESOURCE, "Stopping power measurement failed, status = %d", status); GST_CHECK_SUCCESS(status, m_element, RESOURCE, "Stopping power measurement failed, status = %d", status);

Some files were not shown because too many files have changed in this diff Show More