committed by
GitHub
parent
d61a3bc83f
commit
5c346eddad
@@ -1,19 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
option(HAILO_BUILD_PYBIND "Build Python binding" OFF)
|
||||
option(HAILO_BUILD_PYHAILORT_VENV "Build pyhailort in venv. Only used if HAILO_BUILD_PYBIND is on" ON)
|
||||
option(HAILO_BUILD_EMULATOR "Build hailort for emulator" OFF)
|
||||
option(HAILO_BUILD_UT "Build Unit Tests" OFF)
|
||||
option(HAILO_BUILD_GSTREAMER "Compile gstreamer plugins" OFF)
|
||||
option(HAILO_BUILD_EXAMPLES "Build examples" OFF)
|
||||
option(HAILO_OFFLINE_COMPILATION "Don't download external dependencies" OFF)
|
||||
option(HAILO_MICROPROFILE "Microprofile code" OFF)
|
||||
option(HAILO_BUILD_SERVICE "Build hailort service" OFF)
|
||||
|
||||
if(WIN32 AND ${HAILO_BUILD_SERVICE})
|
||||
message(FATAL_ERROR "HailoRT service is not supported on Windows")
|
||||
endif()
|
||||
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
@@ -67,14 +53,6 @@ else()
|
||||
message(FATAL_ERROR "Unexpeced host, stopping build")
|
||||
endif()
|
||||
|
||||
enable_testing()
|
||||
|
||||
# Flag for emulator (FPGA/Veloce)
|
||||
if(HAILO_BUILD_EMULATOR)
|
||||
message(WARNING "HailoRT is building with Emulator flag on")
|
||||
set(HAILORT_COMPILE_OPTIONS ${HAILORT_COMPILE_OPTIONS} -DHAILO_EMULATOR)
|
||||
endif()
|
||||
|
||||
# Enable output of compile commands during generation
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
|
||||
@@ -23,12 +23,20 @@ HailoRT supports Linux and Windows, and can be compiled from sources to be integ
|
||||
|
||||
See [**hailo.ai developer zone documentation**](https://hailo.ai/developer-zone/documentation/hailort/latest/) (registration is required for full documentation access).
|
||||
|
||||
For compilation instructions, see [**Compiling HailoRT from Sources**](https://hailo.ai/developer-zone/documentation/hailort/latest/?sp_referrer=install/install.html#compiling-from-sources).
|
||||
|
||||
For HailoRT API examples - see [**HailoRT examples**](https://github.com/hailo-ai/hailort/tree/master/hailort/libhailort/examples).
|
||||
|
||||
## Changelog
|
||||
|
||||
See [**hailo.ai developer zone - HailoRT changelog**](https://hailo.ai/developer-zone/documentation/hailort/latest/?sp_referrer=changelog/changelog.html) (registration required).
|
||||
|
||||
## Licenses
|
||||
|
||||
HailoRT uses 2 licenses:
|
||||
- libhailort, pyhailort & hailortcli - distributed under the [**MIT license**](https://opensource.org/licenses/MIT)
|
||||
- hailonet (GStreamer plugin) - distributed under the [**LGPL 2.1 license**](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt)
|
||||
|
||||
## Contact
|
||||
|
||||
Contact information and support is available at [**hailo.ai**](https://hailo.ai/contact-us/).
|
||||
|
||||
@@ -96,16 +96,25 @@ typedef enum __attribute__((packed)) {
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_DEACTIVATE_CFG_CHANNEL,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_REPEATED_ACTION,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_DMA_IDLE_ACTION,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_NMS_IDLE,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_NMS,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_FETCH_CCW_BURSTS,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_VALIDATE_VDMA_CHANNEL,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_BURST_CREDITS_TASK_START,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_DDR_BUFFERING_RESET,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_OPEN_BOUNDARY_INPUT_CHANNEL,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_OPEN_BOUNDARY_OUTPUT_CHANNEL,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_ENABLE_NMS,
|
||||
|
||||
/* Must be last */
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT
|
||||
} CONTEXT_SWITCH_DEFS__ACTION_TYPE_t;
|
||||
|
||||
typedef enum {
|
||||
CONTEXT_SWITCH_DEFS__EDGE_LAYER_DIRECTION_UNINITIALIZED = 0,
|
||||
CONTEXT_SWITCH_DEFS__EDGE_LAYER_DIRECTION_HOST_TO_DEVICE,
|
||||
CONTEXT_SWITCH_DEFS__EDGE_LAYER_DIRECTION_DEVICE_TO_HOST,
|
||||
} CONTEXT_SWITCH_DEFS__EDGE_LAYER_DIRECTION_t;
|
||||
|
||||
typedef struct {
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_t action_type;
|
||||
uint32_t time_stamp;
|
||||
@@ -164,9 +173,20 @@ typedef struct {
|
||||
uint8_t config_stream_index;
|
||||
} CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t initial_l3_cut;
|
||||
uint16_t initial_l3_offset;
|
||||
uint32_t active_apu;
|
||||
uint32_t active_ia;
|
||||
uint64_t active_sc;
|
||||
uint64_t active_l2;
|
||||
uint64_t l2_offset_0;
|
||||
uint64_t l2_offset_1;
|
||||
} CONTEXT_SWITCH_DEFS__sequencer_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t cluster_index;
|
||||
CONTORL_PROTOCOL__sequencer_config_t sequencer_config;
|
||||
CONTEXT_SWITCH_DEFS__sequencer_config_t sequencer_config;
|
||||
} CONTEXT_SWITCH_DEFS__trigger_sequencer_action_data_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -198,17 +218,22 @@ typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t edge_layer_direction;
|
||||
bool is_inter_context;
|
||||
bool is_single_context_network_group;
|
||||
uint8_t host_buffer_type; // CONTROL_PROTOCOL__HOST_BUFFER_TYPE_t
|
||||
uint32_t initial_credit_size;
|
||||
} CONTEXT_SWITCH_DEFS__validate_vdma_channel_action_data_t;
|
||||
|
||||
typedef enum {
|
||||
CONTEXT_SWITCH_DEFS__CREDIT_TYPE_UNINITIALIZED = 0,
|
||||
CONTEXT_SWITCH_DEFS__CREDIT_IN_BYTES,
|
||||
CONTEXT_SWITCH_DEFS__CREDIT_IN_DESCRIPTORS,
|
||||
} CONTEXT_SWITCH_DEFS__CREDIT_TYPE_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
uint8_t network_index;
|
||||
uint32_t frame_periph_size;
|
||||
uint8_t credit_type;
|
||||
uint8_t credit_type; // CONTEXT_SWITCH_DEFS__CREDIT_TYPE_t
|
||||
uint16_t periph_bytes_per_buffer;
|
||||
uint8_t host_buffer_type; // CONTROL_PROTOCOL__HOST_BUFFER_TYPE_t, relevant only for descriptors credit.
|
||||
} CONTEXT_SWITCH_DEFS__fetch_data_action_data_t;
|
||||
@@ -247,7 +272,7 @@ typedef struct {
|
||||
uint8_t pred_cluster_ob_interface;
|
||||
uint8_t succ_prepost_ob_index;
|
||||
uint8_t succ_prepost_ob_interface;
|
||||
} CONTEXT_SWITCH_DEFS__wait_nms_idle_data_t;
|
||||
} CONTEXT_SWITCH_DEFS__wait_nms_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
@@ -259,10 +284,6 @@ typedef struct {
|
||||
uint8_t module_index;
|
||||
} CONTEXT_SWITCH_DEFS__module_config_done_interrupt_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t application_index;
|
||||
} CONTEXT_SWITCH_DEFS__application_change_interrupt_data_t;
|
||||
|
||||
/* edge layers structs */
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
@@ -270,7 +291,6 @@ typedef struct {
|
||||
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
uint32_t initial_credit_size;
|
||||
bool is_single_context_app;
|
||||
} CONTEXT_SWITCH_DEFS__activate_boundary_input_data_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -314,14 +334,15 @@ typedef struct {
|
||||
uint32_t buffered_rows_count;
|
||||
} CONTEXT_SWITCH_DEFS__activate_ddr_buffer_output_data_t;
|
||||
|
||||
typedef union {
|
||||
CONTEXT_SWITCH_DEFS__activate_boundary_input_data_t activate_boundary_input_data;
|
||||
CONTEXT_SWITCH_DEFS__activate_inter_context_input_data_t activate_inter_context_input_data;
|
||||
CONTEXT_SWITCH_DEFS__activate_ddr_buffer_input_data_t activate_ddr_buffer_input_data;
|
||||
CONTEXT_SWITCH_DEFS__activate_boundary_output_data_t activate_boundary_output_data;
|
||||
CONTEXT_SWITCH_DEFS__activate_inter_context_output_data_t activate_inter_context_output_data;
|
||||
CONTEXT_SWITCH_DEFS__activate_ddr_buffer_output_data_t activate_ddr_buffer_output_data;
|
||||
} CONTEXT_SWITCH_COMMON__activate_edge_layer_action_t;
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
} CONTEXT_SWITCH_DEFS__open_boundary_input_channel_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
} CONTEXT_SWITCH_DEFS__open_boundary_output_channel_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
@@ -334,6 +355,11 @@ typedef struct {
|
||||
uint8_t config_stream_index;
|
||||
} CONTEXT_SWITCH_DEFS__deactivate_cfg_channel_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t nms_unit_index;
|
||||
uint8_t network_index;
|
||||
} CONTEXT_SWITCH_DEFS__enable_nms_action_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -38,7 +38,6 @@ extern "C" {
|
||||
#define CONTROL_PROTOCOL__MAX_CONTEXT_SWITCH_APPLICATIONS (32)
|
||||
#define CONTROL_PROTOCOL__MAX_NUMBER_OF_CLUSTERS (8)
|
||||
#define CONTROL_PROTOCOL__MAX_CONTROL_LENGTH (1500)
|
||||
#define CONTROL_PROTOCOL__MAX_TOTAL_CONTEXTS (128)
|
||||
#define CONTROL_PROTOCOL__SOC_ID_LENGTH (32)
|
||||
#define CONTROL_PROTOCOL__MAX_CFG_CHANNELS (4)
|
||||
#define CONTROL_PROTOCOL__MAX_NETWORKS_PER_NETWORK_GROUP (8)
|
||||
@@ -67,13 +66,6 @@ extern "C" {
|
||||
*/
|
||||
#define CONTROL_PROTOCOL__IGNORE_DYNAMIC_BATCH_SIZE (0)
|
||||
|
||||
#define CONTROL_PROTOCOL__TRIGGER_SUB_INDEX_SHIFT (0)
|
||||
#define CONTROL_PROTOCOL__TRIGGER_SUB_INDEX_BIT_MASK (0x000000FF)
|
||||
#define CONTROL_PROTOCOL__TRIGGER_INDEX_SHIFT (16)
|
||||
#define CONTROL_PROTOCOL__TRIGGER_INDEX_BIT_MASK (0x00FF0000)
|
||||
#define CONTROL_PROTOCOL__TRIGGER_TYPE_SHIFT (28)
|
||||
#define CONTROL_PROTOCOL__TRIGGER_TYPE_BIT_MASK (0xF0000000)
|
||||
|
||||
// Tightly coupled with BOARD_CONFIG_supported_features_t struct
|
||||
#define CONTROL_PROTOCOL__SUPPORTED_FEATURES_ETHERNET_BIT_OFFSET (0)
|
||||
#define CONTROL_PROTOCOL__SUPPORTED_FEATURES_MIPI_BIT_OFFSET (1)
|
||||
@@ -86,19 +78,6 @@ extern "C" {
|
||||
/* Value to represent an operation should be performed on all streams. */
|
||||
#define CONTROL_PROTOCOL__ALL_DATAFLOW_MANAGERS (0xFF)
|
||||
|
||||
#define CONTROL_PROTOCOL__WRITE_TRIGGER_SUB_INDEX(val)\
|
||||
(((uint32_t)val) << CONTROL_PROTOCOL__TRIGGER_SUB_INDEX_SHIFT)
|
||||
#define CONTROL_PROTOCOL__READ_TRIGGER_SUB_INDEX(val)\
|
||||
(((uint32_t)(val) & CONTROL_PROTOCOL__TRIGGER_SUB_INDEX_BIT_MASK) >> (CONTROL_PROTOCOL__TRIGGER_SUB_INDEX_SHIFT))
|
||||
#define CONTROL_PROTOCOL__WRITE_TRIGGER_INDEX(val)\
|
||||
(((uint32_t)val) << CONTROL_PROTOCOL__TRIGGER_INDEX_SHIFT)
|
||||
#define CONTROL_PROTOCOL__READ_TRIGGER_INDEX(val)\
|
||||
(((uint32_t)(val) & CONTROL_PROTOCOL__TRIGGER_INDEX_BIT_MASK) >> (CONTROL_PROTOCOL__TRIGGER_INDEX_SHIFT))
|
||||
#define CONTROL_PROTOCOL__WRITE_TRIGGER_TYPE(val)\
|
||||
(((uint32_t)val) << CONTROL_PROTOCOL__TRIGGER_TYPE_SHIFT)
|
||||
#define CONTROL_PROTOCOL__READ_TRIGGER_TYPE(val)\
|
||||
(((uint32_t)(val) & CONTROL_PROTOCOL__TRIGGER_TYPE_BIT_MASK) >> (CONTROL_PROTOCOL__TRIGGER_TYPE_SHIFT))
|
||||
|
||||
|
||||
#define CONTROL_PROTOCOL__OPCODES_VARIABLES \
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_IDENTIFY, true, CPU_ID_APP_CPU)\
|
||||
@@ -133,7 +112,7 @@ extern "C" {
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_SENSOR_LOAD_AND_START, false, CPU_ID_APP_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_SENSOR_RESET, false, CPU_ID_APP_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_SENSOR_GET_SECTIONS_INFO, false, CPU_ID_APP_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_CONTEXT_SWITCH_SET_MAIN_HEADER, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_CONTEXT_SWITCH_SET_NETWORK_GROUP_HEADER, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_CONTEXT_SWITCH_SET_CONTEXT_INFO, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_IDLE_TIME_SET_MEASUREMENT, false, CPU_ID_APP_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_IDLE_TIME_GET_MEASUREMENT, false, CPU_ID_APP_CPU)\
|
||||
@@ -173,6 +152,8 @@ extern "C" {
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_CORE_WD_ENABLE, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_CORE_WD_CONFIG, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_CONTEXT_SWITCH_CLEAR_CONFIGURED_APPS, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_GET_HW_CONSTS, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_SET_SLEEP_STATE, false, CPU_ID_APP_CPU)\
|
||||
|
||||
typedef enum {
|
||||
#define CONTROL_PROTOCOL__OPCODE_X(name, is_critical, cpu_id) name,
|
||||
@@ -432,6 +413,11 @@ typedef struct {
|
||||
bool should_activate;
|
||||
} CONTROL_PROTOCOL__set_overcurrent_state_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t sleep_state_length;
|
||||
uint8_t sleep_state; /* of type CONTROL_PROTOCOL__sleep_state_t */
|
||||
} CONTROL_PROTOCOL__set_sleep_state_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t is_required_length;
|
||||
bool is_required;
|
||||
@@ -446,6 +432,7 @@ typedef struct {
|
||||
uint16_t core_bytes_per_buffer;
|
||||
uint16_t core_buffers_per_frame;
|
||||
uint16_t periph_bytes_per_buffer;
|
||||
uint16_t periph_buffers_per_frame;
|
||||
uint16_t feature_padding_payload;
|
||||
uint16_t buffer_padding_payload;
|
||||
uint16_t buffer_padding;
|
||||
@@ -868,10 +855,6 @@ typedef struct {
|
||||
uint32_t inbound_to_outbound_latency_nsec;
|
||||
} CONTROL_PROTOCOL__latency_read_response_t;
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_VER_V1_0_0 = 0x010000,
|
||||
} CONTROL_PROTOCOL__CONTEXT_SWITCH_VERSION_t;
|
||||
|
||||
typedef struct {
|
||||
bool is_abbale_supported;
|
||||
} CONTROL_PROTOCOL__VALIDATION_FEATURE_LIST_t;
|
||||
@@ -882,8 +865,6 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8_t dynamic_contexts_count;
|
||||
uint32_t host_boundary_channels_bitmap[CONTROL_PROTOCOL__MAX_VDMA_ENGINES_COUNT];
|
||||
uint8_t power_mode; // CONTROL_PROTOCOL__power_mode_t
|
||||
CONTROL_PROTOCOL__INFER_FEATURE_LIST_t infer_features;
|
||||
CONTROL_PROTOCOL__VALIDATION_FEATURE_LIST_t validation_features;
|
||||
uint8_t networks_count;
|
||||
@@ -891,13 +872,9 @@ typedef struct {
|
||||
} CONTROL_PROTOCOL__application_header_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t context_switch_version_length;
|
||||
uint32_t context_switch_version;
|
||||
uint32_t application_count_length;
|
||||
uint8_t application_count;
|
||||
uint32_t application_header_length;
|
||||
CONTROL_PROTOCOL__application_header_t application_header[CONTROL_PROTOCOL__MAX_CONTEXT_SWITCH_APPLICATIONS];
|
||||
} CONTROL_PROTOCOL__context_switch_set_main_header_request_t;
|
||||
CONTROL_PROTOCOL__application_header_t application_header;
|
||||
} CONTROL_PROTOCOL__context_switch_set_network_group_header_request_t;
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__WATCHDOG_MODE_HW_SW = 0,
|
||||
@@ -908,7 +885,6 @@ typedef enum {
|
||||
} CONTROL_PROTOCOL__WATCHDOG_MODE_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_VERSION_t context_switch_version;
|
||||
uint8_t application_count;
|
||||
CONTROL_PROTOCOL__application_header_t application_header[CONTROL_PROTOCOL__MAX_CONTEXT_SWITCH_APPLICATIONS];
|
||||
} CONTROL_PROTOCOL__context_switch_main_header_t;
|
||||
@@ -943,107 +919,11 @@ typedef struct {
|
||||
CONTROL_PROTOCOL__temperature_info_t info;
|
||||
} CONTROL_PROTOCOL__get_chip_temperature_response_t;
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_NONE = 0,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_LCU,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_INPUT_STREAM,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_OUTPUT_STREAM,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_NMS_IDLE,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_DMA_IDLE,
|
||||
|
||||
/* must be last*/
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_COUNT,
|
||||
} CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_t;
|
||||
|
||||
typedef enum {
|
||||
/* this enum starts from 128 for each debug while reading memory buffer */
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_START_INDEX = 128,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_READ_VDMA = CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_START_INDEX,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_TRIGGER_SEQUENCER,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_WAIT_FOR_SEQUENCER_DONE,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_TRIGGER_NEW_DATA_FROM_DATA_INPUT,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ENABLE_LCU_NON_DEFAULT,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_DISABLE_LCU,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_WAIT_FOR_MODULE_CONFIG_DONE,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ADD_DDR_PAIR_INFO,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ADD_DDR_BUFFERING_START,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ENABLE_LCU_DEFAULT,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ADD_REPEATED,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_FETCH_CCW_BURSTS,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_BURST_CREDITS_TASK_START,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_EDGE_LAYER_ACTIVATION_ACTIONS_POSITION,
|
||||
|
||||
/* must be last*/
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_COUNT,
|
||||
} CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_TYPE_t;
|
||||
|
||||
typedef uint8_t CONTROL_PROTOCOL__TRIGGER_TYPE_t;
|
||||
|
||||
typedef struct {
|
||||
/* Empty struct - place holder */
|
||||
uint8_t reserved;
|
||||
} CONTROL_PROTOCOL__TRIGGER_NONE_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t cluster_index;
|
||||
uint8_t lcu_index;
|
||||
} CONTROL_PROTOCOL__TRIGGER_LCU_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t stream_index;
|
||||
} CONTROL_PROTOCOL__TRIGGER_INPUT_STREAM_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t stream_index;
|
||||
} CONTROL_PROTOCOL__TRIGGER_OUTPUT_STREAM_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t aggregator_index;
|
||||
uint8_t pred_cluster_ob_index;
|
||||
uint8_t pred_cluster_ob_cluster_index;
|
||||
uint8_t pred_cluster_ob_interface;
|
||||
uint8_t succ_prepost_ob_index;
|
||||
uint8_t succ_prepost_ob_interface;
|
||||
} CONTROL_PROTOCOL__TRIGGER_NMS_IDLE_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t stream_index;
|
||||
} CONTROL_PROTOCOL__TRIGGER_DMA_IDLE_t;
|
||||
|
||||
typedef union {
|
||||
CONTROL_PROTOCOL__TRIGGER_NONE_t none_trigger;
|
||||
CONTROL_PROTOCOL__TRIGGER_LCU_t lcu_trigger;
|
||||
CONTROL_PROTOCOL__TRIGGER_INPUT_STREAM_t input_stream_trigger;
|
||||
CONTROL_PROTOCOL__TRIGGER_OUTPUT_STREAM_t output_stream_trigger;
|
||||
CONTROL_PROTOCOL__TRIGGER_NMS_IDLE_t nms_idle_trigger;
|
||||
CONTROL_PROTOCOL__TRIGGER_DMA_IDLE_t dma_idle_trigger;
|
||||
} CONTROL_PROTOCOL__trigger_parameters_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__TRIGGER_TYPE_t type;
|
||||
CONTROL_PROTOCOL__trigger_parameters_t params;
|
||||
} CONTROL_PROTOCOL__TRIGGER_t;
|
||||
|
||||
typedef uint8_t CONTROL_PROTOCOL__shmifo_to_pcie_channel_mapping_t;
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__EDGE_CONNECTION_TYPE_NETWORK_BOUNDARY_INPUT,
|
||||
CONTROL_PROTOCOL__EDGE_CONNECTION_TYPE_NETWORK_BOUNDARY_OUTPUT,
|
||||
CONTROL_PROTOCOL__EDGE_CONNECTION_TYPE_INTERMEDIATE_BUFFER_INPUT,
|
||||
CONTROL_PROTOCOL__EDGE_CONNECTION_TYPE_INTERMEDIATE_BUFFER_OUTPUT,
|
||||
CONTROL_PROTOCOL__EDGE_CONNECTION_TYPE_DDR_BUFFER_INPUT,
|
||||
CONTROL_PROTOCOL__EDGE_CONNECTION_TYPE_DDR_BUFFER_OUTPUT,
|
||||
|
||||
/* must be last */
|
||||
CONTROL_PROTOCOL__EDGE_CONNECTION_TYPE_COUNT
|
||||
} CONTROL_PROTOCOL__EDGE_CONNECTION_TYPE_t;
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__HOST_BUFFER_TYPE_EXTERNAL_DESC = 0,
|
||||
CONTROL_PROTOCOL__HOST_BUFFER_TYPE_CCB,
|
||||
|
||||
// The buffer uses external descriptors that is host managed - the firmware don't need to config this buffer
|
||||
CONTROL_PROTOCOL__HOST_BUFFER_TYPE_HOST_MANAGED_EXTERNAL_DESC,
|
||||
CONTROL_PROTOCOL__HOST_BUFFER_TYPE_HOST_MANAGED_EXTERNAL_DESC, /* DEPRECATED */
|
||||
|
||||
/* must be last */
|
||||
CONTROL_PROTOCOL__HOST_BUFFER_TYPE_COUNT
|
||||
@@ -1057,74 +937,6 @@ typedef struct {
|
||||
uint32_t bytes_in_pattern;
|
||||
} CONTROL_PROTOCOL__host_buffer_info_t;
|
||||
|
||||
/* TODO: merge CONTROL_PROTOCOL__edge_layer_common_info_t into the header (HRT-7113) */
|
||||
typedef struct {
|
||||
uint8_t communication_type;
|
||||
uint8_t edge_connection_type;
|
||||
} CONTROL_PROTOCOL__edge_layer_header_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t engine_index;
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t stream_index;
|
||||
uint8_t network_index;
|
||||
CONTROL_PROTOCOL__nn_stream_config_t nn_stream_config;
|
||||
} CONTROL_PROTOCOL__edge_layer_common_info_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
} CONTROL_PROTOCOL__network_boundary_output_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
} CONTROL_PROTOCOL__inter_context_output_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
uint32_t buffered_rows_count;
|
||||
} CONTROL_PROTOCOL__ddr_buffer_output_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
} CONTROL_PROTOCOL__eth_network_boundary_output_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
uint32_t initial_credit_size;
|
||||
} CONTROL_PROTOCOL__network_boundary_input_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
uint32_t initial_credit_size;
|
||||
} CONTROL_PROTOCOL__inter_context_input_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
uint32_t initial_credit_size;
|
||||
uint8_t connected_d2h_engine_index;
|
||||
uint8_t connected_d2h_channel_index;
|
||||
} CONTROL_PROTOCOL__ddr_buffer_input_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
} CONTROL_PROTOCOL__eth_network_boundary_input_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t should_use_stream_remap;
|
||||
} CONTROL_PROTOCOL__stream_remap_data_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__host_buffer_info_t config_buffer_info;
|
||||
uint8_t engine_index;
|
||||
uint8_t vdma_channel_index;
|
||||
} CONTROL_PROTOCOL__config_channel_info_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// TODO: warning C4200
|
||||
@@ -1136,16 +948,10 @@ typedef struct {
|
||||
uint8_t is_first_control_per_context;
|
||||
uint32_t is_last_control_per_context_length;
|
||||
uint8_t is_last_control_per_context;
|
||||
uint32_t cfg_channels_count_length;
|
||||
uint8_t cfg_channels_count;
|
||||
uint32_t config_channel_infos_length;
|
||||
CONTROL_PROTOCOL__config_channel_info_t config_channel_infos[CONTROL_PROTOCOL__MAX_CFG_CHANNELS];
|
||||
uint32_t context_stream_remap_data_length;
|
||||
CONTROL_PROTOCOL__stream_remap_data_t context_stream_remap_data;
|
||||
uint32_t number_of_edge_layers_length;
|
||||
uint8_t number_of_edge_layers;
|
||||
uint32_t number_of_trigger_groups_length;
|
||||
uint8_t number_of_trigger_groups;
|
||||
uint32_t context_type_length;
|
||||
uint8_t context_type; // CONTROL_PROTOCOL__context_switch_context_type_t
|
||||
uint32_t actions_count_length;
|
||||
uint32_t actions_count;
|
||||
uint32_t context_network_data_length;
|
||||
uint8_t context_network_data[0];
|
||||
} CONTROL_PROTOCOL__context_switch_set_context_info_request_t;
|
||||
@@ -1153,169 +959,12 @@ typedef struct {
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
typedef uint8_t CONTROL_PROTOCOL__ACTION_TYPE_t;
|
||||
|
||||
/* Each CONTROL_PROTOCOL__*_ACTION_t must start with a CONTROL_PROTOCOL__ACTION_HEADER_t */
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_TYPE_t action_type;
|
||||
uint8_t action_type; // CONTEXT_SWITCH_DEFS__ACTION_TYPE_t
|
||||
bool is_repeated;
|
||||
} CONTROL_PROTOCOL__ACTION_HEADER_t;
|
||||
|
||||
/**
|
||||
* Repeated actions are sent in the following manner via the control protocol:
|
||||
* 1) CONTROL_PROTOCOL__REPEATED_ACTION_t with:
|
||||
* a) 'action_type' = CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ADD_REPEATED
|
||||
* b) 'is_repeated' = false
|
||||
* 2) 'count' sub-actions whose type matches the 'sub_action_type' defined by (1).
|
||||
* The sub-actions will be consecutive, and will all be marked as 'is_repeated' = true in thier headers.
|
||||
* The sub-actions may be in different slices, if there is a 'CONTROL_PROTOCOL__CONTEXT_SWITCH_TRIGGER_TYPE_NONE' between them.
|
||||
*
|
||||
* E.g. - 3 repeated 'CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ENABLE_LCU_DEFAULT's:
|
||||
* |--------------------------------------------------------------------------------------------------|
|
||||
* | time | data |
|
||||
* |--------------------------------------------------------------------------------------------------|
|
||||
* | ... | |
|
||||
* | | | CONTROL_PROTOCOL__REPEATED_ACTION_t { |
|
||||
* | | | .header = { CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ADD_REPEATED, false}; |
|
||||
* | | | .sub_action_type = CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ENABLE_LCU_DEFAULT; |
|
||||
* | | | .num_actions = 3; |
|
||||
* | | | } |
|
||||
* | | | CONTROL_PROTOCOL__ENABLE_LCU_DEFAULT_ACTION_t { |
|
||||
* | | | .header = { CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ENABLE_LCU_DEFAULT, true }; |
|
||||
* | | | .cluster_index = <some_cluster_index>; |
|
||||
* | | | .lcu_index = <some_lcu_index>; |
|
||||
* | | | .network_index = <some_network_index>; |
|
||||
* | | | } |
|
||||
* | | | CONTROL_PROTOCOL__ENABLE_LCU_DEFAULT_ACTION_t { |
|
||||
* | | | .header = { CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ENABLE_LCU_DEFAULT, true }; |
|
||||
* | | | .cluster_index = <some_cluster_index>; |
|
||||
* | | | .lcu_index = <some_lcu_index>; |
|
||||
* | | | .network_index = <some_network_index>; |
|
||||
* | | | } |
|
||||
* | | | CONTROL_PROTOCOL__ENABLE_LCU_DEFAULT_ACTION_t { |
|
||||
* | | | .header = { CONTROL_PROTOCOL__CONTEXT_SWITCH_ACTION_ENABLE_LCU_DEFAULT, true }; |
|
||||
* | | | .cluster_index = <some_cluster_index>; |
|
||||
* | | | .lcu_index = <some_lcu_index>; |
|
||||
* | | | .network_index = <some_network_index>; |
|
||||
* | V | } |
|
||||
* | ... | (Next action control) |
|
||||
* |--------------------------------------------------------------------------------------------------|
|
||||
* See also: "CONTEXT_SWITCH_DEFS__repeated_action_header_t" in "context_switch_defs.h"
|
||||
*/
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
CONTROL_PROTOCOL__ACTION_TYPE_t sub_action_type;
|
||||
uint8_t num_actions;
|
||||
} CONTROL_PROTOCOL__REPEATED_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint16_t descriptors_count;
|
||||
uint8_t config_stream_index;
|
||||
} CONTROL_PROTOCOL__READ_VDMA_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint16_t ccw_bursts;
|
||||
uint8_t config_stream_index;
|
||||
} CONTROL_PROTOCOL__FETCH_CCW_BURSTS_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t initial_l3_cut;
|
||||
uint16_t initial_l3_offset;
|
||||
uint32_t active_apu;
|
||||
uint32_t active_ia;
|
||||
uint64_t active_sc;
|
||||
uint64_t active_l2;
|
||||
uint64_t l2_offset_0;
|
||||
uint64_t l2_offset_1;
|
||||
} CONTORL_PROTOCOL__sequencer_config_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint8_t cluster_index;
|
||||
CONTORL_PROTOCOL__sequencer_config_t sequencer_config;
|
||||
} CONTROL_PROTOCOL__TRIGGER_SEQUENCER_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint8_t sequencer_index;
|
||||
} CONTROL_PROTOCOL__WAIT_FOR_SEQUENCER_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint8_t stream_index;
|
||||
} CONTROL_PROTOCOL__FETCH_NEW_DATA_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint8_t cluster_index;
|
||||
uint8_t lcu_index;
|
||||
uint16_t kernel_done_address;
|
||||
uint32_t kernel_done_count;
|
||||
uint8_t network_index;
|
||||
} CONTROL_PROTOCOL__ENABLE_LCU_NON_DEAFULT_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint8_t cluster_index;
|
||||
uint8_t lcu_index;
|
||||
uint8_t network_index;
|
||||
} CONTROL_PROTOCOL__ENABLE_LCU_DEFAULT_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint8_t cluster_index;
|
||||
uint8_t lcu_index;
|
||||
} CONTROL_PROTOCOL__DISABLE_LCU_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint8_t module_index;
|
||||
} CONTORL_PROTOCOL__WAIT_FOR_MODULE_CONFIG_DONE_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint8_t h2d_engine_index;
|
||||
uint8_t h2d_vdma_channel_index;
|
||||
uint8_t d2h_engine_index;
|
||||
uint8_t d2h_vdma_channel_index;
|
||||
uint32_t descriptors_per_frame;
|
||||
uint16_t programmed_descriptors_count;
|
||||
} CONTROL_PROTOCOL__ADD_DDR_PAIR_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
} CONTROL_PROTOCOL__ADD_DDR_BUFFERING_START_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
} CONTROL_PROTOCOL__BURST_CREDITS_TASK_START_ACTION_T;
|
||||
|
||||
typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
} CONTROL_PROTOCOL__EDGE_LAYER_ACTIVATION_ACTIONS_POSITION_MARKER_T;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__TRIGGER_t trigger;
|
||||
uint16_t triggers_action_count;
|
||||
} CONTROL_PROTOCOL__trigger_group_t;
|
||||
|
||||
typedef CONTROL_PROTOCOL__read_memory_request_t CONTROL_PROTOCOL__read_user_config_request_t;
|
||||
typedef CONTROL_PROTOCOL__read_memory_response_t CONTROL_PROTOCOL__read_user_config_response_t;
|
||||
typedef CONTROL_PROTOCOL__write_memory_request_t CONTROL_PROTOCOL__write_user_config_request_t;
|
||||
@@ -1331,6 +980,10 @@ typedef struct {
|
||||
} CONTROL_PROTOCOL__idle_time_get_measurement_response_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t network_group_id_length;
|
||||
uint32_t network_group_id;
|
||||
uint32_t context_type_length;
|
||||
uint8_t context_type; // CONTROL_PROTOCOL__context_switch_context_type_t
|
||||
uint32_t context_index_length;
|
||||
uint8_t context_index;
|
||||
uint32_t action_list_offset_length;
|
||||
@@ -1579,7 +1232,15 @@ typedef enum {
|
||||
CONTROL_PROTOCOL__TOP_MEM_BLOCK_SUB_SERVER6_26,
|
||||
CONTROL_PROTOCOL__TOP_MEM_BLOCK_SUB_SERVER7_27,
|
||||
CONTROL_PROTOCOL__TOP_NUM_MEM_BLOCKS
|
||||
} CONTROL_PROTOCOL__biTOP_st_top_mem_block_t;
|
||||
} CONTROL_PROTOCOL__bist_top_mem_block_t;
|
||||
|
||||
/* Must be identical to hailo_sleep_state_t, tightly coupled */
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL_SLEEP_STATE_SLEEPING = 0,
|
||||
CONTROL_PROTOCOL_SLEEP_STATE_AWAKE = 1,
|
||||
/* must be last */
|
||||
CONTROL_PROTOCOL_SLEEP_STATE_COUNT
|
||||
} CONTROL_PROTOCOL__sleep_state_t;
|
||||
|
||||
/*only allowing bist on the following memories*/
|
||||
#define CONTROL_PROTOCOL__BIST_TOP_WHITELIST ((1 << CONTROL_PROTOCOL__TOP_MEM_BLOCK_L4_0_2) | \
|
||||
@@ -1603,6 +1264,21 @@ typedef struct {
|
||||
uint32_t cluster_bypass_bitmap_1;
|
||||
} CONTROL_PROTOCOL__run_bist_test_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t fifo_word_granularity_bytes;
|
||||
uint16_t max_periph_buffers_per_frame;
|
||||
uint16_t max_periph_bytes_per_buffer;
|
||||
uint16_t max_acceptable_bytes_per_buffer;
|
||||
uint32_t outbound_data_stream_size;
|
||||
uint8_t should_optimize_credits;
|
||||
uint32_t default_initial_credit_size;
|
||||
} CONTROL_PROTOCOL__hw_consts_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t hw_consts_length;
|
||||
CONTROL_PROTOCOL__hw_consts_t hw_consts;
|
||||
} CONTROL_PROTOCOL__get_hw_consts_response_t;
|
||||
|
||||
typedef union {
|
||||
CONTROL_PROTOCOL_identify_response_t identity_response;
|
||||
CONTROL_PROTOCOL__core_identify_response_t core_identity_response;
|
||||
@@ -1628,6 +1304,8 @@ typedef union {
|
||||
CONTROL_PROTOCOL__get_health_information_response_t get_health_information_response;
|
||||
CONTROL_PROTOCOL__get_throttling_state_response_t get_throttling_state_response;
|
||||
CONTROL_PROTOCOL__get_overcurrent_state_response_t get_overcurrent_state_response;
|
||||
CONTROL_PROTOCOL__get_hw_consts_response_t get_hw_consts_response;
|
||||
|
||||
// Note: This array is larger than any legal request:
|
||||
// * Functions in this module won't write more than CONTROL_PROTOCOL__MAX_CONTROL_LENGTH bytes
|
||||
// when recieving a pointer to CONTROL_PROTOCOL__request_parameters_t.
|
||||
@@ -1660,7 +1338,7 @@ typedef union {
|
||||
CONTROL_PROTOCOL__sensor_reset_request_t sensor_reset_request;
|
||||
CONTROL_PROTOCOL__sensor_get_config_request_t sensor_get_config_request;
|
||||
CONTROL_PROTOCOL__sensor_set_generic_i2c_slave_request_t sensor_set_generic_i2c_slave_request;
|
||||
CONTROL_PROTOCOL__context_switch_set_main_header_request_t context_switch_set_main_header_request;
|
||||
CONTROL_PROTOCOL__context_switch_set_network_group_header_request_t context_switch_set_network_group_header_request;
|
||||
CONTROL_PROTOCOL__context_switch_set_context_info_request_t context_switch_set_context_info_request;
|
||||
CONTROL_PROTOCOL__idle_time_set_measurement_request_t idle_time_set_measurement_request;
|
||||
CONTROL_PROTOCOL__download_context_action_list_request_t download_context_action_list_request;
|
||||
@@ -1685,6 +1363,7 @@ typedef union {
|
||||
CONTROL_PROTOCOL__set_throttling_state_request_t set_throttling_state_request;
|
||||
CONTROL_PROTOCOL__sensor_set_i2c_bus_index_t sensor_set_i2c_bus_index;
|
||||
CONTROL_PROTOCOL__set_overcurrent_state_request_t set_overcurrent_state_request;
|
||||
CONTROL_PROTOCOL__set_sleep_state_request_t set_sleep_state_request;
|
||||
// Note: This array is larger than any legal request:
|
||||
// * Functions in this module won't write more than CONTROL_PROTOCOL__MAX_CONTROL_LENGTH bytes
|
||||
// when recieving a pointer to CONTROL_PROTOCOL__request_parameters_t.
|
||||
@@ -1721,28 +1400,40 @@ typedef struct {
|
||||
#define CONTROL_PROTOCOL__CONTEXT_NETWORK_DATA_SINGLE_CONTROL_MAX_SIZE \
|
||||
(CONTROL_PROTOCOL__MAX_REQUEST_PARAMETERS_LENGTH - sizeof(CONTROL_PROTOCOL__context_switch_set_context_info_request_t))
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_PRELIMINARY,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_DYNAMIC,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_BATCH_SWITCHING,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_ACTIVATION,
|
||||
|
||||
/* must be last*/
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_COUNT,
|
||||
} CONTROL_PROTOCOL__context_switch_context_type_t;
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_INDEX_ACTIVATION_CONTEXT = 0,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_INDEX_BATCH_SWITCHING_CONTEXT,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_INDEX_PRELIMINARY_CONTEXT,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_NUMBER_OF_NON_DYNAMIC_CONTEXTS,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_INDEX_FIRST_DYNAMIC_CONTEXT = CONTROL_PROTOCOL__CONTEXT_SWITCH_NUMBER_OF_NON_DYNAMIC_CONTEXTS,
|
||||
|
||||
/* must be last*/
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_INDEX_COUNT,
|
||||
} CONTROL_PROTOCOL__context_switch_context_index_t;
|
||||
|
||||
#define CONTROL_PROTOCOL__MAX_CONTEXTS_PER_NETWORK_GROUP (64)
|
||||
|
||||
typedef struct {
|
||||
bool is_first_control_per_context;
|
||||
bool is_last_control_per_context;
|
||||
uint8_t cfg_channels_count;
|
||||
CONTROL_PROTOCOL__config_channel_info_t config_channel_infos[CONTROL_PROTOCOL__MAX_CFG_CHANNELS];
|
||||
CONTROL_PROTOCOL__stream_remap_data_t context_stream_remap_data;
|
||||
uint8_t number_of_edge_layers;
|
||||
uint8_t number_of_trigger_groups;
|
||||
uint8_t context_type; // CONTROL_PROTOCOL__context_switch_context_type_t
|
||||
uint32_t actions_count;
|
||||
uint32_t context_network_data_length;
|
||||
uint8_t context_network_data[CONTROL_PROTOCOL__CONTEXT_NETWORK_DATA_SINGLE_CONTROL_MAX_SIZE];
|
||||
} CONTROL_PROTOCOL__context_switch_context_info_single_control_t;
|
||||
|
||||
/* Context switch user structs */
|
||||
|
||||
#define CONTROL_PROTOCOL__CONTEXT_NETWORK_DATA_MAX_SIZE (8 * 1024)
|
||||
|
||||
typedef struct {
|
||||
uint8_t interrupt_type;
|
||||
uint8_t interrupt_index;
|
||||
uint8_t interrupt_sub_index;
|
||||
} CONTROL_PROTOCOL__dataflow_interrupt_t;
|
||||
/* End of context switch structs */
|
||||
CASSERT(sizeof(CONTROL_PROTOCOL__context_switch_context_index_t)<=UINT8_MAX, control_protocol_h);
|
||||
CASSERT(sizeof(CONTROL_PROTOCOL__context_switch_context_type_t)<=UINT8_MAX, control_protocol_h);
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__MESSAGE_TYPE__REQUEST = 0,
|
||||
@@ -1769,7 +1460,6 @@ typedef enum {
|
||||
CONTROL_PROTOCOL__RESET_TYPE__COUNT
|
||||
} CONTROL_PROTOCOL__reset_type_t;
|
||||
|
||||
|
||||
typedef union {
|
||||
/* Needed in order to parse unknown header */
|
||||
CONTROL_PROTOCOL__common_header_t common;
|
||||
|
||||
@@ -29,7 +29,7 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
D2H_EVENT_COMMUNICATION_TYPE_UDP = 0,
|
||||
D2H_EVENT_COMMUNICATION_TYPE_PCIE,
|
||||
D2H_EVENT_COMMUNICATION_TYPE_VDMA,
|
||||
D2H_EVENT_COMMUNICATION_TYPE__COUNT
|
||||
} D2H_EVENT_COMMUNICATION_TYPE_t;
|
||||
|
||||
@@ -72,7 +72,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t connection_status;
|
||||
uint32_t connection_type;
|
||||
uint32_t pcie_is_active;
|
||||
uint32_t vdma_is_active;
|
||||
uint32_t host_port;
|
||||
uint32_t host_ip_addr;
|
||||
} D2H_EVENT_host_info_event_message_t;
|
||||
@@ -156,7 +156,16 @@ typedef struct {
|
||||
D2H_EVENT__message_parameters_t message_parameters;
|
||||
} D2H_EVENT_MESSAGE_t;
|
||||
|
||||
#define PCIE_D2H_EVENT_MAX_SIZE (0x370)
|
||||
#define D2H_EVENT_BUFFER_NOT_IN_USE (0)
|
||||
#define D2H_EVENT_BUFFER_IN_USE (1)
|
||||
#define D2H_EVENT_MAX_SIZE (0x370)
|
||||
|
||||
typedef struct {
|
||||
uint16_t is_buffer_in_use;
|
||||
uint16_t buffer_len;
|
||||
uint8_t buffer[D2H_EVENT_MAX_SIZE];
|
||||
} D2H_event_buffer_t;
|
||||
|
||||
/**********************************************************************
|
||||
* Public Functions
|
||||
**********************************************************************/
|
||||
|
||||
@@ -22,26 +22,28 @@ extern "C" {
|
||||
#define REVISION_NUMBER_SHIFT (0)
|
||||
#define REVISION_APP_CORE_FLAG_BIT_SHIFT (27)
|
||||
#define REVISION_RESERVED_0_FLAG_BIT_SHIFT (28)
|
||||
#define REVISION_RESERVED_1_FLAG_BIT_SHIFT (29)
|
||||
#define REVISION_EXTENDED_CONTEXT_SWITCH_BUFFER_FLAG_BIT_SHIFT (29)
|
||||
#define REVISION_DEV_FLAG_BIT_SHIFT (30)
|
||||
#define REVISION_SECOND_STAGE_FLAG_BIT_SHIFT (31)
|
||||
|
||||
#define REVISION_NUMBER_WIDTH (27U)
|
||||
#define REVISION_APP_CORE_FLAG_BIT_WIDTH (1U)
|
||||
#define REVISION_RESERVED_0_FLAG_BIT_WIDTH (1U)
|
||||
#define REVISION_RESERVED_1_FLAG_BIT_WIDTH (1U)
|
||||
#define REVISION_EXTENDED_CONTEXT_SWITCH_BUFFER_FLAG_BIT_WIDTH (1U)
|
||||
#define REVISION_DEV_FLAG_BIT_WIDTH (1U)
|
||||
#define REVISION_SECOND_STAGE_FLAG_BIT_WIDTH (1U)
|
||||
|
||||
#define REVISION_NUMBER_MASK (GET_MASK(REVISION_NUMBER_WIDTH, REVISION_NUMBER_SHIFT))
|
||||
#define REVISION_APP_CORE_FLAG_BIT_MASK (GET_MASK(REVISION_APP_CORE_FLAG_BIT_WIDTH, REVISION_APP_CORE_FLAG_BIT_SHIFT))
|
||||
#define REVISION_RESERVED_0_FLAG_BIT_MASK (GET_MASK(REVISION_RESERVED_0_FLAG_BIT_WIDTH, REVISION_RESERVED_0_FLAG_BIT_SHIFT))
|
||||
#define REVISION_RESERVED_1_FLAG_BIT_MASK (GET_MASK(REVISION_RESERVED_1_FLAG_BIT_WIDTH, REVISION_RESERVED_1_FLAG_BIT_SHIFT))
|
||||
#define REVISION_EXTENDED_CONTEXT_SWITCH_BUFFER_FLAG_BIT_MASK (GET_MASK(REVISION_EXTENDED_CONTEXT_SWITCH_BUFFER_FLAG_BIT_WIDTH, REVISION_EXTENDED_CONTEXT_SWITCH_BUFFER_FLAG_BIT_SHIFT))
|
||||
#define REVISION_DEV_FLAG_BIT_MASK (GET_MASK(REVISION_DEV_FLAG_BIT_WIDTH, REVISION_DEV_FLAG_BIT_SHIFT))
|
||||
#define REVISION_SECOND_STAGE_FLAG_BIT_MASK (GET_MASK(REVISION_SECOND_STAGE_FLAG_BIT_WIDTH, REVISION_SECOND_STAGE_FLAG_BIT_SHIFT))
|
||||
|
||||
#define GET_REVISION_NUMBER_VALUE(binary_revision) (REVISION_NUMBER_MASK & binary_revision)
|
||||
#define IS_REVISION_DEV(binary_revision) (REVISION_DEV_FLAG_BIT_MASK == (REVISION_DEV_FLAG_BIT_MASK & binary_revision))
|
||||
#define IS_REVISION_EXTENDED_CONTEXT_SWITCH_BUFFER(binary_revision) (REVISION_EXTENDED_CONTEXT_SWITCH_BUFFER_FLAG_BIT_MASK == \
|
||||
(REVISION_EXTENDED_CONTEXT_SWITCH_BUFFER_FLAG_BIT_MASK & binary_revision))
|
||||
#define DEV_STRING_NOTE(__is_release) ((__is_release)? "" : " (dev)")
|
||||
|
||||
/**
|
||||
|
||||
@@ -307,7 +307,7 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONTEXT_SWITCH_APP_HEADER_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONTEXT_SWITCH_CLUSTER_END_GARANTEE_TRIGGER_LENGTH)/* DEPRECATED */\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONTEXT_SWITCH_NUMBER_OF_EDGE_LAYERS_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONTEXT_SWITCH_NUMBER_OF_TRIGGER_GROUPS_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONTEXT_SWITCH_NUMBER_OF_ACTION_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONTEXT_SWITCH_TRIGGER_GROUPS_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_CONTEXT_SWITCH_CONTEXT_NETWORK_DATA_LENGTH_HIGHER_THEN_MAX_CONTROL_SIZE)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_IDLE_TIME_MEASUREMENT_ALREADY_SET)\
|
||||
@@ -404,6 +404,11 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_INFER_FEATURES_LENGTH) /* DEPRECATED */\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONFIG_CHANNEL_INFOS)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_IS_BATCH_SIZE_FLOW_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONTEXT_SWITCH_CONTEXT_TYPE_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CONTEXT_SWITCH_CONTEXT_NETWORK_GROUP_ID_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_SET_SLEEP_STATE_FAILED)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_SLEEP_STATE_SIZE)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_SLEEP_STATE)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__POWER_MEASUREMENT)\
|
||||
FIRMWARE_STATUS__X(HAILO_POWER_MEASUREMENT_STATUS_POWER_INIT_ERROR)\
|
||||
@@ -650,7 +655,7 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_ADD_ACTION_FUNCTION_REACHED_FORBIDDEN_MEMORY_SPACE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_ADD_CONTEXT_INFO_FUNCTION_REACHED_FORBIDDEN_MEMORY_SPACE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_PARSING_ERROR_WHILE_READING_TRIGGER_GROUPS)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_TRIGGER_GROUP_POINTER_REACHED_FORBIDDEN_MEMORY_SPACE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_POINTER_REACHED_FORBIDDEN_MEMORY_SPACE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_DOWNLOAD_ACTION_LIST_INVALID_CONTEXT_INDEX)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_RECEIVED_INVALID_APPLICATION_COUNT)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_RECEIVED_INVALID_TOTAL_CONTEXTS_COUNT)\
|
||||
@@ -732,10 +737,6 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_WAIT_FOR_PREDICATE_INTERRUPTED_BY_RESET_REQUEST)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_WAIT_FOR_DMA_IDLE_INTERRUPTED_BY_RESET_REQUEST)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_ACTION_NOT_SUPPORTED)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_AGGREGATOR_INDEX)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_OUTPUT_BUFFER_INDEX)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_OUTPUT_BUFFER_CLUSTER_INDEX)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_OUTPUT_BUFFER_INTERFACE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_ACTION_IS_NOT_SUPPORTED)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_CFG_CHANNELS_COUNT)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_HOST_BUFFER_TYPE)\
|
||||
@@ -745,6 +746,11 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_ADD_ACTION_TO_BATCH_SWITCH_BUFFER_REACHED_FORBIDDEN_MEMORY_SPACE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_TASK_STATUS_WAIT_FOR_INTERRUPT_INTERRUPTED_BY_BATCH_CHANGE_REQUEST)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_CANT_CLEAR_CONFIGURED_APPS_WHILE_ACTIVATED)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_CONTEXT_TYPE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_UNEXPECTED_CONTEXT_ORDER)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_DYNAMIC_CONTEXT_COUNT)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_CONTEXT_INDEX_OUT_OF_RANGE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_TOTAL_PROVIDED_EDGE_LAYERS_LARGER_THEN_EXPECTED)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__D2H_EVENT_MANAGER)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_MESSAGE_HIGH_PRIORITY_QUEUE_CREATE_FAILED)\
|
||||
@@ -753,11 +759,12 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_INVALID_MESSAGE_QUEUE_HANDLE)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_SENDING_MESSAGE_FAIL)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_SEND_EVENT_OVER_UDP_FAIL)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_SEND_EVENT_OVER_PCIE_FAIL)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_SEND_EVENT_OVER_VDMA_FAIL)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_INVALID_COMMUNICATION_TYPE)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_PCIE_NOT_ACTIVE)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_VDMA_COMMUNICATION_NOT_ACTIVE)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_INVALID_PRIORITY_QUEUE_HANDLE)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_INIT_UDP_FAIL)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_INVALID_PARAMETERS)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__WD)\
|
||||
FIRMWARE_STATUS__X(WD_STATUS_INVALID_PARAMETERS)\
|
||||
@@ -997,6 +1004,8 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(VDMA_SERVICE_STATUS_TOO_LARGE_BYTES_IN_PATTERN)\
|
||||
FIRMWARE_STATUS__X(VDMA_SERVICE_STATUS_INVALID_ENGINE_INDEX)\
|
||||
FIRMWARE_STATUS__X(VDMA_SERVICE_STATUS_INVALID_CONSTANTS)\
|
||||
FIRMWARE_STATUS__X(VDMA_SERVICE_STATUS_INVALID_CHANNEL_INDEX)\
|
||||
FIRMWARE_STATUS__X(VDMA_SERVICE_STATUS_INVALID_EDGE_LAYER_DIRECTION)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__MEMORY_LOGGER)\
|
||||
FIRMWARE_STATUS__X(MEMORY_LOGGER_STATUS_DEBUG_INSUFFICIENT_MEMORY)\
|
||||
@@ -1049,6 +1058,30 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(BURST_CREDITS_TASK_STATUS_INFER_REACHED_TIMEOUT)\
|
||||
FIRMWARE_STATUS__X(BURST_CREDITS_TASK_STATUS_TASK_DEACTIVATED)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__TASK_SYNC_EVENTS)\
|
||||
FIRMWARE_STATUS__X(TASK_SYNC_EVENTS_STATUS_START_TASK_WHILE_IT_IS_RUNNING)\
|
||||
FIRMWARE_STATUS__X(TASK_SYNC_EVENTS_STATUS_START_TASK_WHILE_TASK_NOT_DONE)\
|
||||
FIRMWARE_STATUS__X(TASK_SYNC_EVENTS_STATUS_FAILED_TO_RESET_STATE_MACHINE)\
|
||||
FIRMWARE_STATUS__X(TASK_SYNC_EVENTS_STATUS_DONE_TASK_WHILE_IT_IS_NOT_RUNNING)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__NMS_MANAGER)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_INVALID_ARGUMENT)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_WAIT_FOR_INTERRUPT_INTERRUPTED_BY_RESET_REQUEST)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_INVALID_AGGREGATOR_INDEX)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_INVALID_OUTPUT_BUFFER_INDEX)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_INVALID_OUTPUT_BUFFER_CLUSTER_INDEX)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_INVALID_OUTPUT_BUFFER_INTERFACE)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_NOT_SUPPORTED_OPERATION)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_INVALID_NETWORK_INDEX)\
|
||||
FIRMWARE_STATUS__X(NMS_MANAGER_STATUS_INVALID_NMS_UNIT_INDEX)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__CLUSTER_MANAGER)\
|
||||
FIRMWARE_STATUS__X(CLUSTER_MANAGER_STATUS_INVALID_CLUSTER_INDEX)\
|
||||
FIRMWARE_STATUS__X(CLUSTER_MANAGER_STATUS_INVALID_INITIAL_L3_CUT)\
|
||||
FIRMWARE_STATUS__X(CLUSTER_MANAGER_STATUS_INVALID_INITIAL_L3_OFFSET)\
|
||||
FIRMWARE_STATUS__X(CLUSTER_MANAGER_STATUS_INVALID_LCU_INDEX)\
|
||||
FIRMWARE_STATUS__X(CLUSTER_MANAGER_STATUS_INVALID_KERNEL_DONE_ADDRESS)\
|
||||
FIRMWARE_STATUS__X(CLUSTER_MANAGER_STATUS_RECEIVED_UNEXPECTED_INTERRUPT)\
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -66,7 +66,8 @@ typedef enum {
|
||||
SOC__NN_CLOCK_250MHz = 250 * 1000 * 1000,
|
||||
SOC__NN_CLOCK_225MHz = 225 * 1000 * 1000,
|
||||
SOC__NN_CLOCK_200MHz = 200 * 1000 * 1000,
|
||||
SOC__NN_CLOCK_100MHz = 100 * 1000 * 1000
|
||||
SOC__NN_CLOCK_100MHz = 100 * 1000 * 1000,
|
||||
SOC__NN_CLOCK_25MHz = 25 * 1000 * 1000
|
||||
} SOC__NN_CLOCK_HZ_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -79,7 +80,8 @@ typedef enum {
|
||||
SOC__CPU_CLOCK_125MHz = SOC__NN_CLOCK_250MHz >> 1,
|
||||
SOC__CPU_CLOCK_112MHz = SOC__NN_CLOCK_225MHz >> 1,
|
||||
SOC__CPU_CLOCK_100MHz = SOC__NN_CLOCK_200MHz >> 1,
|
||||
SOC__CPU_CLOCK_50MHz = SOC__NN_CLOCK_100MHz >> 1
|
||||
SOC__CPU_CLOCK_50MHz = SOC__NN_CLOCK_100MHz >> 1,
|
||||
SOC__CPU_CLOCK_12MHz = SOC__NN_CLOCK_25MHz >> 1
|
||||
} SOC__CPU_CLOCK_HZ_t;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -1,32 +1,35 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
option(HAILO_BUILD_PYBIND "Build Python binding" OFF)
|
||||
option(HAILO_BUILD_EMULATOR "Build hailort for emulator" OFF)
|
||||
option(HAILO_BUILD_UT "Build Unit Tests" OFF)
|
||||
option(HAILO_BUILD_HW_DEBUG_TOOL "Build hw debug tool" OFF)
|
||||
option(HAILO_BUILD_GSTREAMER "Compile gstreamer plugins" OFF)
|
||||
option(HAILO_BUILD_EXAMPLES "Build examples" OFF)
|
||||
option(HAILO_OFFLINE_COMPILATION "Don't download external dependencies" OFF)
|
||||
option(HAILO_BUILD_SERVICE "Build hailort service" OFF)
|
||||
option(HAILO_BUILD_PROFILER "Build hailort profiler" ON)
|
||||
|
||||
if(WIN32 AND ${HAILO_BUILD_SERVICE})
|
||||
message(FATAL_ERROR "HailoRT service is not supported on Windows")
|
||||
endif()
|
||||
|
||||
# Flag for emulator (FPGA/Veloce)
|
||||
if(HAILO_BUILD_EMULATOR)
|
||||
message(WARNING "HailoRT is building with Emulator flag on")
|
||||
set(HAILORT_COMPILE_OPTIONS ${HAILORT_COMPILE_OPTIONS} -DHAILO_EMULATOR)
|
||||
endif()
|
||||
|
||||
# Set firmware version
|
||||
add_definitions( -DFIRMWARE_VERSION_MAJOR=4 )
|
||||
add_definitions( -DFIRMWARE_VERSION_MINOR=10 )
|
||||
add_definitions( -DFIRMWARE_VERSION_MINOR=12 )
|
||||
add_definitions( -DFIRMWARE_VERSION_REVISION=0 )
|
||||
if(HAILO_BUILD_SERVICE)
|
||||
add_definitions( -DHAILO_SUPPORT_MULTI_PROCESS )
|
||||
endif()
|
||||
|
||||
message(STATUS "Building pre_build")
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/execute_cmake.cmake)
|
||||
set(HAILO_EXTERNAL_DIR ${CMAKE_CURRENT_LIST_DIR}/external)
|
||||
set(HAILO_PRE_BUILD_BUILD_TOOLS ${CMAKE_CURRENT_LIST_DIR}/pre_build/build/tools)
|
||||
|
||||
set(PRE_BUILD_BUILD_TYPE "Release")
|
||||
execute_cmake(
|
||||
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/pre_build
|
||||
BUILD_DIR ${CMAKE_CURRENT_LIST_DIR}/pre_build/build
|
||||
CONFIGURE_ARGS
|
||||
-DCMAKE_BUILD_TYPE=${PRE_BUILD_BUILD_TYPE}
|
||||
-DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_LIST_DIR}/pre_build/install
|
||||
-DHAILO_EXTERNAL_DIR=${HAILO_EXTERNAL_DIR}
|
||||
-DHAILO_OFFLINE_COMPILATION=${HAILO_OFFLINE_COMPILATION}
|
||||
-DHAILO_BUILD_SERVICE=${HAILO_BUILD_SERVICE}
|
||||
BUILD_ARGS
|
||||
--config ${PRE_BUILD_BUILD_TYPE} --target install ${CMAKE_EXTRA_BUILD_ARGS}
|
||||
PARALLEL_BUILD
|
||||
)
|
||||
# The logic of prepare_externals is executed in a sperate module so that it can be run externally (via cmake -P prepare_externals.cmake)
|
||||
include(prepare_externals.cmake)
|
||||
|
||||
# BENCHMARK_ENABLE_TESTING can be used by other 3rd party projects, therefore we define it
|
||||
# before adding projects
|
||||
@@ -83,7 +86,7 @@ if(HAILO_BUILD_PYBIND)
|
||||
if(NOT PYTHON_EXECUTABLE AND PYBIND11_PYTHON_VERSION)
|
||||
# PYBIND11_PYTHON_VERSION is prioritized (not virtual environment) if PYTHON_EXECUTABLE is not set.
|
||||
# See https://pybind11.readthedocs.io/en/stable/changelog.html#v2-6-0-oct-21-2020
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.22.0")
|
||||
find_package(PythonInterp ${PYBIND11_PYTHON_VERSION} REQUIRED)
|
||||
set(PYTHON_EXECUTABLE ${Python_EXECUTABLE})
|
||||
else()
|
||||
@@ -116,32 +119,12 @@ if(HAILO_BUILD_SERVICE)
|
||||
add_subdirectory(rpc)
|
||||
endif()
|
||||
|
||||
# microprofile
|
||||
if(HAILO_MICROPROFILE)
|
||||
add_library(microprofile STATIC EXCLUDE_FROM_ALL external/microprofile/microprofile.cpp)
|
||||
set_target_properties(microprofile PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_STANDARD_REQUIRED YES
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
target_compile_definitions(microprofile
|
||||
PRIVATE
|
||||
-DMICROPROFILE_WEBSERVER=1
|
||||
-DMICROPROFILE_GPU_TIMERS=0
|
||||
-DMICROPROFILE_NAME_MAX_LEN=256
|
||||
PUBLIC
|
||||
-DMICROPROFILE_ENABLED=1
|
||||
)
|
||||
target_include_directories(microprofile PUBLIC external/microprofile)
|
||||
else()
|
||||
add_library(microprofile INTERFACE)
|
||||
target_compile_definitions(microprofile INTERFACE -DMICROPROFILE_ENABLED=0)
|
||||
target_include_directories(microprofile INTERFACE external/microprofile)
|
||||
endif()
|
||||
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(libhailort)
|
||||
add_subdirectory(hailortcli)
|
||||
if(HAILO_BUILD_HW_DEBUG_TOOL)
|
||||
add_subdirectory(tools/hw_debug)
|
||||
endif()
|
||||
|
||||
if(HAILO_BUILD_SERVICE)
|
||||
add_subdirectory(hailort_service)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
| CLI11 | University of Cincinnati | 3-Clause BSD | 2.2.0 | Fork | https://github.com/hailo-ai/CLI11 |
|
||||
| Catch2 | Catch2 Authors | BSL-1.0 | 2.13.7 | Cloned entire package | https://github.com/catchorg/Catch2 |
|
||||
| protobuf | Google Inc. | BSD | 3.19.4 | Cloned entire package | https://github.com/protocolbuffers/protobuf |
|
||||
| pybind11 | Wenzel Jakob | BSD | 2.6.2 | 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 |
|
||||
| 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 |
|
||||
@@ -12,5 +12,4 @@
|
||||
| benchmark | Google Inc. | Apache License 2.0 | 1.6.0 | Cloned entire package | https://github.com/google/benchmark.git |
|
||||
| md5 | Alexander Peslyak | cut-down BSD | - | Copied code from website | http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 |
|
||||
| pevents | Mahmoud Al-Qudsi | MIT License | master | Cloned entire package | https://github.com/neosmart/pevents.git |
|
||||
| microprofile | Jonas Meyer | Unlicense License | 3.1 | Cloned entire package | https://github.com/jonasmr/microprofile |
|
||||
| grpc | Google Inc. | Apache License 2.0 | 1.46.0 | Cloned entire package | https://github.com/grpc/grpc |
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
**/
|
||||
/**
|
||||
* @file circular_buffer.hpp
|
||||
* @brief
|
||||
* @brief Manages a Single-Producer Single-Consumer queue. The size of the queue must be a power of 2.
|
||||
* This file exports both low level C struct, and a C++ wrapper.
|
||||
*
|
||||
**/
|
||||
|
||||
@@ -77,7 +78,7 @@ public:
|
||||
|
||||
void push_back(const T& element)
|
||||
{
|
||||
// assert(CB_AVAIL(m_circ, CB_HEAD(m_circ), CB_TAIL(m_circ)));
|
||||
assert(CB_AVAIL(m_circ, CB_HEAD(m_circ), CB_TAIL(m_circ)));
|
||||
m_array[CB_HEAD(m_circ)] = element;
|
||||
CB_ENQUEUE(m_circ, 1);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
@@ -34,11 +35,35 @@ public:
|
||||
static Expected<time_t> get_file_modified_time(const std::string &file_path);
|
||||
static Expected<bool> is_directory(const std::string &path);
|
||||
static hailo_status create_directory(const std::string &dir_path);
|
||||
static Expected<std::string> get_current_dir();
|
||||
static std::string get_home_directory();
|
||||
static bool is_path_accesible(const std::string &path);
|
||||
static bool does_file_exists(const std::string &path);
|
||||
static bool has_suffix(const std::string &file_name, const std::string &suffix)
|
||||
{
|
||||
return (file_name.size() >= suffix.size()) && equal(suffix.rbegin(), suffix.rend(), file_name.rbegin());
|
||||
}
|
||||
|
||||
static std::string remove_suffix(const std::string &file_name, const std::string &suffix)
|
||||
{
|
||||
if (!has_suffix(file_name, suffix)) {
|
||||
return file_name;
|
||||
}
|
||||
|
||||
return file_name.substr(0, file_name.length() - suffix.length());
|
||||
}
|
||||
|
||||
// Emultes https://docs.python.org/3/library/os.path.html#os.path.basename
|
||||
static std::string basename(const std::string &file_name)
|
||||
{
|
||||
const auto last_separator_index = file_name.find_last_of(SEPARATOR);
|
||||
if (std::string::npos == last_separator_index) {
|
||||
// No separator found => the file_name is a "basename"
|
||||
return file_name;
|
||||
}
|
||||
return file_name.substr(last_separator_index + 1);
|
||||
}
|
||||
|
||||
private:
|
||||
// OS-specific filesystem directory separator char (i.e. backslash on Windows or forward slash on UNIX)
|
||||
static const char *SEPARATOR;
|
||||
@@ -117,6 +142,11 @@ public:
|
||||
static Expected<LockedFile> create(const std::string &file_path, const std::string &mode);
|
||||
~LockedFile();
|
||||
|
||||
LockedFile(const LockedFile &other) = delete;
|
||||
LockedFile &operator=(const LockedFile &other) = delete;
|
||||
LockedFile &operator=(LockedFile &&other) = delete;
|
||||
LockedFile(LockedFile &&other);
|
||||
|
||||
int get_fd() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -29,12 +29,12 @@ public:
|
||||
using duration = std::chrono::nanoseconds;
|
||||
using TimestampsArray = CircularArray<duration>;
|
||||
|
||||
explicit LatencyMeter(const std::set<uint32_t> &output_channels, size_t timestamps_list_length) :
|
||||
explicit LatencyMeter(const std::set<std::string> &output_names, size_t timestamps_list_length) :
|
||||
m_start_timestamps(timestamps_list_length),
|
||||
m_latency_count(0),
|
||||
m_latency_sum(0)
|
||||
{
|
||||
for (uint32_t ch : output_channels) {
|
||||
for (auto &ch : output_names) {
|
||||
m_end_timestamps_per_channel.emplace(ch, TimestampsArray(timestamps_list_length));
|
||||
}
|
||||
}
|
||||
@@ -54,12 +54,12 @@ public:
|
||||
* after this function is called on all channels.
|
||||
* @note Assumes that only one thread per channel is calling this function.
|
||||
*/
|
||||
void add_end_sample(uint32_t channel_index, duration timestamp)
|
||||
void add_end_sample(const std::string &stream_name, duration timestamp)
|
||||
{
|
||||
// Safe to access from several threads (when each pass different channel) because the map cannot
|
||||
// be changed in runtime.
|
||||
assert(m_end_timestamps_per_channel.find(channel_index) != m_end_timestamps_per_channel.end());
|
||||
m_end_timestamps_per_channel.at(channel_index).push_back(timestamp);
|
||||
assert(m_end_timestamps_per_channel.find(stream_name) != m_end_timestamps_per_channel.end());
|
||||
m_end_timestamps_per_channel.at(stream_name).push_back(timestamp);
|
||||
update_latency();
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ private:
|
||||
std::mutex m_lock;
|
||||
|
||||
TimestampsArray m_start_timestamps;
|
||||
std::unordered_map<uint32_t, TimestampsArray> m_end_timestamps_per_channel;
|
||||
std::unordered_map<std::string, TimestampsArray> m_end_timestamps_per_channel;
|
||||
|
||||
size_t m_latency_count;
|
||||
duration m_latency_sum;
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
#include "common/logger_macros.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <pwd.h>
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
@@ -145,7 +147,12 @@ static_assert(false, "Unsupported Platform!");
|
||||
Expected<bool> Filesystem::is_directory(const std::string &path)
|
||||
{
|
||||
struct stat path_stat{};
|
||||
CHECK(0 == stat(path.c_str(), &path_stat), make_unexpected(HAILO_FILE_OPERATION_FAILURE),
|
||||
auto ret_Val = stat(path.c_str(), &path_stat);
|
||||
if (ret_Val != 0 && (errno == ENOENT)) {
|
||||
// Directory path does not exist
|
||||
return false;
|
||||
}
|
||||
CHECK(0 == ret_Val, make_unexpected(HAILO_FILE_OPERATION_FAILURE),
|
||||
"stat() on path \"{}\" failed. errno {}", path.c_str(), errno);
|
||||
|
||||
return S_ISDIR(path_stat.st_mode);
|
||||
@@ -158,6 +165,54 @@ hailo_status Filesystem::create_directory(const std::string &dir_path)
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
Expected<std::string> Filesystem::get_current_dir()
|
||||
{
|
||||
char cwd[PATH_MAX];
|
||||
auto ret_val = getcwd(cwd, sizeof(cwd));
|
||||
CHECK_AS_EXPECTED(nullptr != ret_val, HAILO_FILE_OPERATION_FAILURE, "Failed to get current directory path with errno {}", errno);
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
std::string Filesystem::get_home_directory()
|
||||
{
|
||||
const char *homedir = getenv("HOME");
|
||||
if (NULL == homedir) {
|
||||
homedir = getpwuid(getuid())->pw_dir;
|
||||
}
|
||||
|
||||
#ifdef __QNX__
|
||||
const std::string root_dir = "/";
|
||||
std::string homedir_str = std::string(homedir);
|
||||
if (homedir_str == root_dir) {
|
||||
return homedir_str + "home";
|
||||
}
|
||||
#endif
|
||||
|
||||
return homedir;
|
||||
}
|
||||
|
||||
bool Filesystem::is_path_accesible(const std::string &path)
|
||||
{
|
||||
auto ret = access(path.c_str(), W_OK);
|
||||
if (ret == 0) {
|
||||
return true;
|
||||
}
|
||||
else if (EACCES == errno) {
|
||||
return false;
|
||||
} else {
|
||||
std::cerr << "Failed checking path " << path << " access permissions, errno = " << errno << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Filesystem::does_file_exists(const std::string &path)
|
||||
{
|
||||
// From https://stackoverflow.com/a/12774387
|
||||
struct stat buffer;
|
||||
return (0 == stat(path.c_str(), &buffer));
|
||||
}
|
||||
|
||||
Expected<TempFile> TempFile::create(const std::string &file_name, const std::string &file_directory)
|
||||
{
|
||||
if (!file_directory.empty()) {
|
||||
@@ -211,12 +266,18 @@ LockedFile::LockedFile(FILE *fp, int fd) : m_fp(fp), m_fd(fd)
|
||||
|
||||
LockedFile::~LockedFile()
|
||||
{
|
||||
if (-1 == flock(m_fd, LOCK_UN)) {
|
||||
LOGGER__ERROR("Failed to unlock file with errno {}", errno);
|
||||
if (m_fp != nullptr) {
|
||||
// The lock is released when all descriptors are closed.
|
||||
// Since we use LOCK_EX, this is the only fd open and the lock will be release after d'tor.
|
||||
fclose(m_fp);
|
||||
}
|
||||
}
|
||||
|
||||
LockedFile::LockedFile(LockedFile &&other) :
|
||||
m_fp(std::exchange(other.m_fp, nullptr)),
|
||||
m_fd(other.m_fd)
|
||||
{}
|
||||
|
||||
int LockedFile::get_fd() const
|
||||
{
|
||||
return m_fd;
|
||||
|
||||
@@ -230,7 +230,7 @@ hailo_status Socket::send_to(const uint8_t *src_buffer, size_t src_buffer_size,
|
||||
} else if (EPIPE == errno) {
|
||||
// When socket is aborted from another thread sendto will return errno EPIPE
|
||||
LOGGER__INFO("Udp send aborted!");
|
||||
return HAILO_STREAM_INTERNAL_ABORT;
|
||||
return HAILO_STREAM_ABORTED_BY_USER;
|
||||
} else {
|
||||
LOGGER__ERROR("Udp failed to send data, errno:{}.", errno);
|
||||
return HAILO_ETH_SEND_FAILURE;
|
||||
@@ -272,7 +272,7 @@ hailo_status Socket::recv_from(uint8_t *dest_buffer, size_t dest_buffer_size, in
|
||||
}
|
||||
else if ((0 == number_of_received_bytes) && (0 != dest_buffer_size)) {
|
||||
LOGGER__INFO("Udp socket was aborted");
|
||||
return HAILO_STREAM_INTERNAL_ABORT;
|
||||
return HAILO_STREAM_ABORTED_BY_USER;
|
||||
}
|
||||
|
||||
if (result_src_addr_size > src_addr_size) {
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include "common/logger_macros.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <io.h>
|
||||
#include <AclAPI.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
namespace hailort
|
||||
@@ -145,4 +148,93 @@ Expected<bool> Filesystem::is_directory(const std::string &path)
|
||||
return PathIsDirectoryA(path.c_str());
|
||||
}
|
||||
|
||||
Expected<std::string> Filesystem::get_current_dir()
|
||||
{
|
||||
char cwd[MAX_PATH];
|
||||
auto ret_val = GetCurrentDirectoryA(MAX_PATH, cwd);
|
||||
CHECK_AS_EXPECTED(0 != ret_val, HAILO_FILE_OPERATION_FAILURE, "Failed to get current directory path with error: {}", WSAGetLastError());
|
||||
|
||||
return std::string(cwd);
|
||||
}
|
||||
|
||||
hailo_status Filesystem::create_directory(const std::string &dir_path)
|
||||
{
|
||||
auto ret_val = CreateDirectory(dir_path.c_str(), nullptr);
|
||||
CHECK((0 != ret_val) || (GetLastError() == ERROR_ALREADY_EXISTS), HAILO_FILE_OPERATION_FAILURE, "Failed to create directory {}", dir_path);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
bool Filesystem::is_path_accesible(const std::string &path)
|
||||
{
|
||||
// The code is based on examples from: https://cpp.hotexamples.com/examples/-/-/AccessCheck/cpp-accesscheck-function-examples.html
|
||||
bool return_val = false;
|
||||
SECURITY_INFORMATION security_Info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION;
|
||||
PSECURITY_DESCRIPTOR security_desc = NULL;
|
||||
DWORD access_mask = GENERIC_WRITE;
|
||||
GENERIC_MAPPING mapping = {0xFFFFFFFF};
|
||||
mapping.GenericRead = FILE_GENERIC_READ;
|
||||
mapping.GenericWrite = FILE_GENERIC_WRITE;
|
||||
mapping.GenericExecute = FILE_GENERIC_EXECUTE;
|
||||
mapping.GenericAll = FILE_ALL_ACCESS;
|
||||
HANDLE h_token = NULL;
|
||||
HANDLE h_impersonated_token = NULL;
|
||||
PRIVILEGE_SET privilege_set = {0};
|
||||
DWORD privilege_set_size = sizeof(privilege_set);
|
||||
DWORD granted_access = 0;
|
||||
BOOL access_status = FALSE;
|
||||
|
||||
// Retrieves a copy of the security descriptor for the path
|
||||
DWORD result = GetNamedSecurityInfo(path.c_str(), SE_FILE_OBJECT, security_Info, NULL, NULL, NULL, NULL, &security_desc);
|
||||
if (result != ERROR_SUCCESS) {
|
||||
std::cerr << "Failed to get security information for path " << path << " with error = " << result << std::endl;
|
||||
return_val = false;
|
||||
goto l_exit;
|
||||
}
|
||||
|
||||
MapGenericMask(&access_mask, &mapping);
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &h_token) == 0) {
|
||||
return_val = false;
|
||||
std::cerr << "OpenProcessToken() Failed. Cannot check path " << path << " access permissions, last_error = " << GetLastError() << std::endl;
|
||||
goto l_release_security_desc;
|
||||
}
|
||||
|
||||
// Getting a handle to an impersonation token. It will represent the client that is attempting to gain access.
|
||||
if (DuplicateToken(h_token, SecurityImpersonation, &h_impersonated_token) == 0) {
|
||||
std::cerr << "DuplicateToken() Failed. Cannot check path " << path << " access permissions, last_error = " << GetLastError() << std::endl;
|
||||
return_val = false;
|
||||
goto l_close_token;
|
||||
}
|
||||
|
||||
if (AccessCheck(security_desc, h_impersonated_token, access_mask, &mapping, &privilege_set, &privilege_set_size, &granted_access, &access_status) == 0) {
|
||||
std::cerr << "AccessCheck Failed. Cannot check path " << path << " access permissions, last_error = " << GetLastError() << std::endl;
|
||||
return_val = false;
|
||||
goto l_close_impersonated_token;
|
||||
}
|
||||
|
||||
return_val = (access_status == TRUE);
|
||||
|
||||
l_close_impersonated_token:
|
||||
if (NULL != h_impersonated_token) {
|
||||
(void)CloseHandle(h_impersonated_token);
|
||||
}
|
||||
|
||||
l_close_token:
|
||||
if (NULL != h_token) {
|
||||
(void)CloseHandle(h_token);
|
||||
}
|
||||
|
||||
l_release_security_desc:
|
||||
if (NULL != security_desc) {
|
||||
(void)LocalFree(security_desc);
|
||||
}
|
||||
l_exit:
|
||||
return return_val;
|
||||
}
|
||||
|
||||
bool Filesystem::does_file_exists(const std::string &path)
|
||||
{
|
||||
// From https://stackoverflow.com/a/2112304
|
||||
return ((GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES) && (GetLastError() == ERROR_FILE_NOT_FOUND));
|
||||
}
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace hailort
|
||||
#define IS_FIT_IN_UINT8(number) ((std::numeric_limits<uint8_t>::max() >= ((int32_t)(number))) && (std::numeric_limits<uint8_t>::min() <= ((int32_t)(number))))
|
||||
#define IS_FIT_IN_UINT16(number) ((std::numeric_limits<uint16_t>::max() >= ((int32_t)(number))) && (std::numeric_limits<uint16_t>::min() <= ((int32_t)(number))))
|
||||
|
||||
#define IS_FIT_IN_UINT16(number) ((std::numeric_limits<uint16_t>::max() >= ((int32_t)(number))) && (std::numeric_limits<uint16_t>::min() <= ((int32_t)(number))))
|
||||
|
||||
|
||||
template <typename T>
|
||||
static inline bool contains(const std::vector<T> &container, const T &value)
|
||||
@@ -53,24 +51,6 @@ static inline bool contains(const std::set<T> &container, T value)
|
||||
return (container.find(value) != container.end());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class unlock_guard {
|
||||
public:
|
||||
unlock_guard(T &lock) : m_lock(lock) {
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
~unlock_guard() {
|
||||
m_lock.lock();
|
||||
}
|
||||
|
||||
unlock_guard(const unlock_guard&) = delete;
|
||||
unlock_guard& operator=(const unlock_guard&) = delete;
|
||||
|
||||
private:
|
||||
T &m_lock;
|
||||
};
|
||||
|
||||
// From https://stackoverflow.com/questions/57092289/do-stdmake-shared-and-stdmake-unique-have-a-nothrow-version
|
||||
template <class T, class... Args>
|
||||
static inline std::unique_ptr<T> make_unique_nothrow(Args&&... args)
|
||||
@@ -250,16 +230,18 @@ _ISEMPTY( \
|
||||
} while(0)
|
||||
#define CHECK_AS_RPC_STATUS(cond, reply, ret_val, ...) _CHECK_AS_RPC_STATUS((cond), (reply), (ret_val), ISEMPTY(__VA_ARGS__), "" __VA_ARGS__)
|
||||
|
||||
#define _CHECK_GRPC_STATUS(status, ret_val) \
|
||||
#define _CHECK_GRPC_STATUS(status, ret_val, warning_msg) \
|
||||
do { \
|
||||
if (!status.ok()) { \
|
||||
LOGGER__ERROR("CHECK_GRPC_STATUS failed with error massage: {}.", status.error_message()); \
|
||||
LOGGER__WARNING(warning_msg); \
|
||||
return ret_val; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define CHECK_GRPC_STATUS(status) _CHECK_GRPC_STATUS(status, HAILO_RPC_FAILED)
|
||||
#define CHECK_GRPC_STATUS_AS_EXPECTED(status) _CHECK_GRPC_STATUS(status, make_unexpected(HAILO_RPC_FAILED))
|
||||
#define SERVICE_WARNING_MSG ("Make sure HailoRT service is enabled and active!")
|
||||
#define CHECK_GRPC_STATUS(status) _CHECK_GRPC_STATUS(status, HAILO_RPC_FAILED, SERVICE_WARNING_MSG)
|
||||
#define CHECK_GRPC_STATUS_AS_EXPECTED(status) _CHECK_GRPC_STATUS(status, make_unexpected(HAILO_RPC_FAILED), SERVICE_WARNING_MSG)
|
||||
#endif
|
||||
|
||||
#define _CHECK_EXPECTED(obj, is_default, fmt, ...) \
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#ifndef _HAILO_IOCTL_COMMON_H_
|
||||
#define _HAILO_IOCTL_COMMON_H_
|
||||
|
||||
|
||||
#define DESCRIPTORS_IN_BUFFER(buffer_size, desc_page_size) (((buffer_size) + (desc_page_size) - 1) / (desc_page_size))
|
||||
|
||||
// This value is not easily changeable.
|
||||
// For example: the channel interrupts ioctls assume we have up to 32 channels
|
||||
#define MAX_VDMA_CHANNELS_PER_ENGINE (32)
|
||||
@@ -84,6 +87,11 @@ struct hailo_channel_interrupt_timestamp {
|
||||
uint16_t desc_num_processed;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint16_t is_buffer_in_use;
|
||||
uint16_t buffer_len;
|
||||
} hailo_d2h_buffer_details_t;
|
||||
|
||||
// This struct is the same as `enum dma_data_direction` (defined in linux/dma-direction)
|
||||
enum hailo_dma_data_direction {
|
||||
HAILO_DMA_BIDIRECTIONAL = 0,
|
||||
@@ -145,6 +153,7 @@ struct hailo_desc_list_bind_vdma_buffer_params {
|
||||
uintptr_t desc_handle; // in
|
||||
uint16_t desc_page_size; // in
|
||||
uint8_t channel_index; // in
|
||||
size_t offset; // in
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_ENABLE */
|
||||
@@ -152,9 +161,6 @@ struct hailo_vdma_channel_enable_params {
|
||||
uint8_t engine_index; // in
|
||||
uint8_t channel_index; // in
|
||||
enum hailo_dma_data_direction direction; // in
|
||||
// If desc_list_handle is set to valid handle (different than INVALID_DRIVER_HANDLE_VALUE),
|
||||
// the driver will start the channel with the given descriptors list.
|
||||
uintptr_t desc_list_handle; // in
|
||||
bool enable_timestamps_measure; // in
|
||||
uint64_t channel_handle; // out
|
||||
};
|
||||
@@ -221,9 +227,9 @@ struct hailo_fw_control {
|
||||
enum hailo_cpu_id cpu_id;
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_BAR_TRANSFER */
|
||||
/* structure used in ioctl HAILO_MEMORY_TRANSFER */
|
||||
// Max bar transfer size gotten from ATR0_TABLE_SIZE
|
||||
#define MAX_BAR_TRANSFER_LENGTH (4096)
|
||||
#define MAX_MEMORY_TRANSFER_LENGTH (4096)
|
||||
|
||||
enum hailo_transfer_direction {
|
||||
TRANSFER_READ = 0,
|
||||
@@ -233,12 +239,34 @@ enum hailo_transfer_direction {
|
||||
TRANSFER_MAX_ENUM = INT_MAX,
|
||||
};
|
||||
|
||||
struct hailo_bar_transfer_params {
|
||||
enum hailo_transfer_memory_type {
|
||||
HAILO_TRANSFER_DEVICE_DIRECT_MEMORY,
|
||||
|
||||
// vDMA memories
|
||||
HAILO_TRANSFER_MEMORY_VDMA0 = 0x100,
|
||||
HAILO_TRANSFER_MEMORY_VDMA1,
|
||||
HAILO_TRANSFER_MEMORY_VDMA2,
|
||||
|
||||
// PCIe driver memories
|
||||
HAILO_TRANSFER_MEMORY_PCIE_BAR0 = 0x200,
|
||||
HAILO_TRANSFER_MEMORY_PCIE_BAR2 = 0x202,
|
||||
HAILO_TRANSFER_MEMORY_PCIE_BAR4 = 0x204,
|
||||
|
||||
// DRAM DMA driver memories
|
||||
HAILO_TRANSFER_MEMORY_DMA_ENGINE0 = 0x300,
|
||||
HAILO_TRANSFER_MEMORY_DMA_ENGINE1,
|
||||
HAILO_TRANSFER_MEMORY_DMA_ENGINE2,
|
||||
|
||||
/** Max enum value to maintain ABI Integrity */
|
||||
HAILO_TRANSFER_MEMORY_MAX_ENUM = INT_MAX,
|
||||
};
|
||||
|
||||
struct hailo_memory_transfer_params {
|
||||
enum hailo_transfer_direction transfer_direction; // in
|
||||
uint32_t bar_index; // in
|
||||
off_t offset; // in
|
||||
enum hailo_transfer_memory_type memory_type; // in
|
||||
uint64_t address; // in
|
||||
size_t count; // in
|
||||
uint8_t buffer[MAX_BAR_TRANSFER_LENGTH]; // in/out
|
||||
uint8_t buffer[MAX_MEMORY_TRANSFER_LENGTH]; // in/out
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_READ_REGISTER */
|
||||
@@ -286,10 +314,12 @@ struct hailo_d2h_notification {
|
||||
};
|
||||
|
||||
enum hailo_board_type {
|
||||
HAILO8 = 0,
|
||||
HAILO_MERCURY,
|
||||
HAILO_BOARD_COUNT,
|
||||
HAILO_INVALID_BOARD = 0xFFFFFFFF,
|
||||
HAILO_BOARD_TYPE_HAILO8 = 0,
|
||||
HAILO_BOARD_TYPE_MERCURY,
|
||||
HAILO_BOARD_TYPE_COUNT,
|
||||
|
||||
/** Max enum value to maintain ABI Integrity */
|
||||
HAILO_BOARD_TYPE_MAX_ENUM = INT_MAX
|
||||
};
|
||||
|
||||
enum hailo_dma_type {
|
||||
@@ -306,6 +336,7 @@ struct hailo_device_properties {
|
||||
enum hailo_allocation_mode allocation_mode;
|
||||
enum hailo_dma_type dma_type;
|
||||
size_t dma_engines_count;
|
||||
bool is_fw_loaded;
|
||||
#ifdef __QNX__
|
||||
pid_t resource_manager_pid;
|
||||
#endif // __QNX__
|
||||
@@ -345,7 +376,7 @@ struct hailo_allocate_continuous_buffer_params {
|
||||
#pragma pack(pop)
|
||||
|
||||
enum hailo_general_ioctl_code {
|
||||
HAILO_BAR_TRANSFER_CODE,
|
||||
HAILO_MEMORY_TRANSFER_CODE,
|
||||
HAILO_FW_CONTROL_CODE,
|
||||
HAILO_READ_NOTIFICATION_CODE,
|
||||
HAILO_DISABLE_NOTIFICATION_CODE,
|
||||
@@ -358,7 +389,7 @@ enum hailo_general_ioctl_code {
|
||||
HAILO_GENERAL_IOCTL_MAX_NR,
|
||||
};
|
||||
|
||||
#define HAILO_BAR_TRANSFER _IOWR_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_BAR_TRANSFER_CODE, struct hailo_bar_transfer_params)
|
||||
#define HAILO_MEMORY_TRANSFER _IOWR_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_MEMORY_TRANSFER_CODE, struct hailo_memory_transfer_params)
|
||||
#define HAILO_FW_CONTROL _IOWR_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_FW_CONTROL_CODE, struct hailo_fw_control)
|
||||
#define HAILO_READ_NOTIFICATION _IOW_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_READ_NOTIFICATION_CODE, struct hailo_d2h_notification)
|
||||
#define HAILO_DISABLE_NOTIFICATION _IO_(HAILO_GENERAL_IOCTL_MAGIC, HAILO_DISABLE_NOTIFICATION_CODE)
|
||||
@@ -393,7 +424,7 @@ enum hailo_vdma_ioctl_code {
|
||||
|
||||
#define HAILO_VDMA_CHANNEL_ENABLE _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_ENABLE_CODE, struct hailo_vdma_channel_enable_params)
|
||||
#define HAILO_VDMA_CHANNEL_DISABLE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_DISABLE_CODE, struct hailo_vdma_channel_disable_params)
|
||||
#define HAILO_VDMA_CHANNEL_WAIT_INT _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_WAIT_INT_CODE, struct hailo_vdma_channel_wait_params)
|
||||
#define HAILO_VDMA_CHANNEL_WAIT_INT _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_WAIT_INT_CODE, struct hailo_vdma_channel_wait_params)
|
||||
#define HAILO_VDMA_CHANNEL_ABORT _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_ABORT_CODE, struct hailo_vdma_channel_abort_params)
|
||||
#define HAILO_VDMA_CHANNEL_CLEAR_ABORT _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_CLEAR_ABORT_CODE, struct hailo_vdma_channel_clear_abort_params)
|
||||
#define HAILO_VDMA_CHANNEL_READ_REGISTER _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_READ_REGISTER_CODE, struct hailo_vdma_channel_read_register_params)
|
||||
|
||||
@@ -102,7 +102,7 @@ struct tCompatibleHailoIoctlData
|
||||
tCompatibleHailoIoctlParam Parameters;
|
||||
ULONG_PTR Value;
|
||||
union {
|
||||
hailo_bar_transfer_params BarTransfer;
|
||||
hailo_memory_transfer_params MemoryTransfer;
|
||||
hailo_vdma_channel_enable_params ChannelEnable;
|
||||
hailo_vdma_channel_disable_params ChannelDisable;
|
||||
hailo_vdma_channel_wait_params ChannelWait;
|
||||
|
||||
@@ -4,6 +4,7 @@ add_executable(hailort_service
|
||||
hailort_rpc_service.cpp
|
||||
hailort_service.cpp
|
||||
service_resource_manager.hpp
|
||||
${HAILORT_COMMON_CPP_SOURCES}
|
||||
)
|
||||
target_compile_options(hailort_service PRIVATE ${HAILORT_COMPILE_OPTIONS})
|
||||
set_property(TARGET hailort_service PROPERTY CXX_STANDARD 14)
|
||||
@@ -15,17 +16,28 @@ target_link_libraries(hailort_service
|
||||
target_include_directories(hailort_service
|
||||
PRIVATE
|
||||
${HAILORT_INC_DIR}
|
||||
${HAILORT_COMMON_DIR}
|
||||
${COMMON_INC_DIR}
|
||||
${RPC_DIR}
|
||||
)
|
||||
disable_exceptions(hailort_service)
|
||||
|
||||
# Install systemd unit file
|
||||
set(SYSTEMD_UNIT_DIR "/lib/systemd/system/")
|
||||
set(SYSTEMD_UNIT_DIR "lib/systemd/system/")
|
||||
if(NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(SYSTEMD_UNIT_DIR ${CMAKE_INSTALL_PREFIX}/${SYSTEMD_UNIT_DIR})
|
||||
endif()
|
||||
|
||||
# Install service's environment variables file
|
||||
set(ENV_VARS_FILE_DIR ${CMAKE_INSTALL_SYSCONFDIR}/default/)
|
||||
set(HAILORT_SERVICE_ENV_VARS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/hailort_service)
|
||||
install(
|
||||
FILES "${HAILORT_SERVICE_ENV_VARS_FILE}"
|
||||
DESTINATION "${ENV_VARS_FILE_DIR}"
|
||||
CONFIGURATIONS Release
|
||||
COMPONENT hailort_service
|
||||
)
|
||||
|
||||
# Install systemd unit file
|
||||
set(HAILORT_SERVICE_UNIT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/hailort.service)
|
||||
install(
|
||||
FILES "${HAILORT_SERVICE_UNIT_FILE}"
|
||||
@@ -40,8 +52,15 @@ install(
|
||||
CONFIGURATIONS Release
|
||||
)
|
||||
|
||||
# Create empty directory for hailort log file
|
||||
set(DAEMON_PID_DIR "/run/hailo")
|
||||
add_definitions(-DHAILO_DAEMON_PID_DIR="${DAEMON_PID_DIR}")
|
||||
add_definitions(-DHAILO_DAEMON_PID_FILE="${DAEMON_PID_DIR}/hailort_service.pid")
|
||||
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
# Create empty directory for hailort log file
|
||||
set(HAILORT_LOG_DIR "/var/log/hailo")
|
||||
install(DIRECTORY DESTINATION ${HAILORT_LOG_DIR})
|
||||
|
||||
# Create empty directory for default PID file
|
||||
install(DIRECTORY DESTINATION ${DAEMON_PID_DIR})
|
||||
endif()
|
||||
@@ -4,10 +4,13 @@ Documentation=https://github.com/hailo-ai/hailort
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
EnvironmentFile=/etc/default/hailort_service
|
||||
ExecStart=/usr/local/bin/hailort_service
|
||||
Restart=on-failure
|
||||
RemainAfterExit=yes
|
||||
Environment="HAILORT_LOGGER_PATH=/var/log/hailo"
|
||||
PIDFile=/run/hailo/hailort_service.pid
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStartPost=/bin/sleep 0.1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -65,7 +65,6 @@ grpc::Status HailoRtRpcService::VDevice_create(grpc::ServerContext *, const VDev
|
||||
|
||||
hailo_vdevice_params_t params = {
|
||||
.device_count = params_proto.device_count(),
|
||||
.device_infos = nullptr,
|
||||
.device_ids = device_ids.data(),
|
||||
.scheduling_algorithm = static_cast<hailo_scheduling_algorithm_e>(params_proto.scheduling_algorithm()),
|
||||
.group_id = params_proto.group_id().c_str(),
|
||||
@@ -180,6 +179,19 @@ grpc::Status HailoRtRpcService::VDevice_get_physical_devices_ids(grpc::ServerCon
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::VDevice_get_default_streams_interface(grpc::ServerContext*,
|
||||
const VDevice_get_default_streams_interface_Request* request, VDevice_get_default_streams_interface_Reply* reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<VDevice> vdevice) {
|
||||
return vdevice->get_default_streams_interface();
|
||||
};
|
||||
auto &vdevice_manager = ServiceResourceManager<VDevice>::get_instance();
|
||||
auto stream_interface = vdevice_manager.execute<Expected<hailo_stream_interface_t>>(request->handle(), lambda);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(stream_interface, reply);
|
||||
reply->set_stream_interface(*stream_interface);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_release(grpc::ServerContext*, const Release_Request *request,
|
||||
Release_Reply *reply)
|
||||
{
|
||||
@@ -189,6 +201,22 @@ grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_release(grpc::ServerConte
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
ProtoNamedVStreamParams get_named_params(const std::string &name, const hailo_vstream_params_t ¶ms)
|
||||
{
|
||||
ProtoNamedVStreamParams named_params;
|
||||
named_params.set_name(name);
|
||||
auto proto_params = named_params.mutable_params();
|
||||
auto proto_user_buffer_format = proto_params->mutable_user_buffer_format();
|
||||
proto_user_buffer_format->set_type(params.user_buffer_format.type);
|
||||
proto_user_buffer_format->set_order(params.user_buffer_format.order);
|
||||
proto_user_buffer_format->set_flags(params.user_buffer_format.flags);
|
||||
proto_params->set_timeout_ms(params.timeout_ms);
|
||||
proto_params->set_queue_size(params.queue_size);
|
||||
proto_params->set_vstream_stats_flags(params.vstream_stats_flags);
|
||||
proto_params->set_pipeline_elements_stats_flags(params.pipeline_elements_stats_flags);
|
||||
return named_params;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_make_input_vstream_params(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_make_input_vstream_params_Request *request,
|
||||
ConfiguredNetworkGroup_make_input_vstream_params_Reply *reply)
|
||||
@@ -202,20 +230,10 @@ grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_make_input_vstream_params
|
||||
request->timeout_ms(), request->queue_size(), request->network_name());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_params, reply);
|
||||
auto params_map = reply->mutable_vstream_params_map();
|
||||
auto params_map_impl = params_map->mutable_vstream_params_map();
|
||||
for (auto& name_to_params : expected_params.value()) {
|
||||
NamedVStreamParams named_params;
|
||||
named_params.set_name(name_to_params.first);
|
||||
auto params = name_to_params.second;
|
||||
auto proto_params = named_params.mutable_params();
|
||||
auto proto_user_buffer_format = proto_params->mutable_user_buffer_format();
|
||||
proto_user_buffer_format->set_type(params.user_buffer_format.type);
|
||||
proto_user_buffer_format->set_order(params.user_buffer_format.order);
|
||||
proto_user_buffer_format->set_flags(params.user_buffer_format.flags);
|
||||
proto_params->set_timeout_ms(params.timeout_ms);
|
||||
proto_params->set_queue_size(params.queue_size);
|
||||
proto_params->set_vstream_stats_flags(params.vstream_stats_flags);
|
||||
proto_params->set_pipeline_elements_stats_flags(params.pipeline_elements_stats_flags);
|
||||
params_map->Add(std::move(named_params));
|
||||
auto named_params = get_named_params(name_to_params.first, name_to_params.second);
|
||||
params_map_impl->Add(std::move(named_params));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
@@ -235,20 +253,37 @@ grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_make_output_vstream_param
|
||||
request->timeout_ms(), request->queue_size(), request->network_name());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_params, reply);
|
||||
auto params_map = reply->mutable_vstream_params_map();
|
||||
auto params_map_impl = params_map->mutable_vstream_params_map();
|
||||
for (auto& name_to_params : expected_params.value()) {
|
||||
NamedVStreamParams named_params;
|
||||
named_params.set_name(name_to_params.first);
|
||||
auto params = name_to_params.second;
|
||||
auto proto_params = named_params.mutable_params();
|
||||
auto proto_user_buffer_format = proto_params->mutable_user_buffer_format();
|
||||
proto_user_buffer_format->set_type(params.user_buffer_format.type);
|
||||
proto_user_buffer_format->set_order(params.user_buffer_format.order);
|
||||
proto_user_buffer_format->set_flags(params.user_buffer_format.flags);
|
||||
proto_params->set_timeout_ms(params.timeout_ms);
|
||||
proto_params->set_queue_size(params.queue_size);
|
||||
proto_params->set_vstream_stats_flags(params.vstream_stats_flags);
|
||||
proto_params->set_pipeline_elements_stats_flags(params.pipeline_elements_stats_flags);
|
||||
params_map->Add(std::move(named_params));
|
||||
auto named_params = get_named_params(name_to_params.first, name_to_params.second);
|
||||
params_map_impl->Add(std::move(named_params));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_make_output_vstream_params_groups(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_make_output_vstream_params_groups_Request *request,
|
||||
ConfiguredNetworkGroup_make_output_vstream_params_groups_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, bool quantized,
|
||||
hailo_format_type_t format_type, uint32_t timeout_ms, uint32_t queue_size) {
|
||||
return cng->make_output_vstream_params_groups(quantized, format_type, timeout_ms, queue_size);
|
||||
};
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_params = manager.execute<Expected<std::vector<std::map<std::string, hailo_vstream_params_t>>>>(request->handle(),
|
||||
lambda, request->quantized(), static_cast<hailo_format_type_t>(request->format_type()),
|
||||
request->timeout_ms(), request->queue_size());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_params, reply);
|
||||
auto params_map_vector = reply->mutable_vstream_params_groups();
|
||||
for (auto ¶ms_map : expected_params.value()) {
|
||||
ProtoNamedVStreamParamsMap params_map_proto;
|
||||
auto params_map_impl_proto = params_map_proto.mutable_vstream_params_map();
|
||||
for (auto& name_to_params : params_map) {
|
||||
auto named_params = get_named_params(name_to_params.first, name_to_params.second);
|
||||
params_map_impl_proto->Add(std::move(named_params));
|
||||
}
|
||||
params_map_vector->Add(std::move(params_map_proto));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
@@ -282,7 +317,7 @@ grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_output_vstream_groups
|
||||
auto output_vstream_groups = expected_output_vstream_groups.value();
|
||||
auto groups_proto = reply->mutable_output_vstream_groups();
|
||||
for (auto& group : output_vstream_groups) {
|
||||
VStreamGroup group_proto;
|
||||
ProtoVStreamGroup group_proto;
|
||||
for (auto& name : group) {
|
||||
auto vstream_group_proto = group_proto.mutable_vstream_group();
|
||||
vstream_group_proto->Add(std::move(name));
|
||||
@@ -293,34 +328,39 @@ grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_output_vstream_groups
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
void serialize_vstream_info(const hailo_vstream_info_t &info, ProtoVStreamInfo *info_proto)
|
||||
{
|
||||
info_proto->set_name(std::string(info.name));
|
||||
info_proto->set_network_name(std::string(info.network_name));
|
||||
info_proto->set_direction(static_cast<uint32_t>(info.direction));
|
||||
auto format_proto = info_proto->mutable_format();
|
||||
format_proto->set_flags(info.format.flags);
|
||||
format_proto->set_order(info.format.order);
|
||||
format_proto->set_type(info.format.type);
|
||||
if (info.format.order == HAILO_FORMAT_ORDER_HAILO_NMS) {
|
||||
auto nms_shape_proto = info_proto->mutable_nms_shape();
|
||||
nms_shape_proto->set_number_of_classes(info.nms_shape.number_of_classes);
|
||||
nms_shape_proto->set_max_bbox_per_class(info.nms_shape.max_bboxes_per_class);
|
||||
} else {
|
||||
auto shape_proto = info_proto->mutable_shape();
|
||||
shape_proto->set_height(info.shape.height);
|
||||
shape_proto->set_width(info.shape.width);
|
||||
shape_proto->set_features(info.shape.features);
|
||||
}
|
||||
auto quant_info_proto = info_proto->mutable_quant_info();
|
||||
quant_info_proto->set_qp_zp(info.quant_info.qp_zp);
|
||||
quant_info_proto->set_qp_scale(info.quant_info.qp_scale);
|
||||
quant_info_proto->set_limvals_min(info.quant_info.limvals_min);
|
||||
quant_info_proto->set_limvals_max(info.quant_info.limvals_max);
|
||||
}
|
||||
|
||||
void serialize_vstream_infos(ConfiguredNetworkGroup_get_vstream_infos_Reply *reply,
|
||||
const std::vector<hailo_vstream_info_t> &infos)
|
||||
{
|
||||
auto vstream_infos_proto = reply->mutable_vstream_infos();
|
||||
for (auto& info : infos) {
|
||||
VStreamInfo info_proto;
|
||||
info_proto.set_name(std::string(info.name));
|
||||
info_proto.set_network_name(std::string(info.network_name));
|
||||
info_proto.set_direction(static_cast<uint32_t>(info.direction));
|
||||
auto format_proto = info_proto.mutable_format();
|
||||
format_proto->set_flags(info.format.flags);
|
||||
format_proto->set_order(info.format.order);
|
||||
format_proto->set_type(info.format.type);
|
||||
if (info.format.order == HAILO_FORMAT_ORDER_HAILO_NMS) {
|
||||
auto nms_shape_proto = info_proto.mutable_nms_shape();
|
||||
nms_shape_proto->set_number_of_classes(info.nms_shape.number_of_classes);
|
||||
nms_shape_proto->set_max_bbox_per_class(info.nms_shape.max_bboxes_per_class);
|
||||
} else {
|
||||
auto shape_proto = info_proto.mutable_shape();
|
||||
shape_proto->set_height(info.shape.height);
|
||||
shape_proto->set_width(info.shape.width);
|
||||
shape_proto->set_features(info.shape.features);
|
||||
}
|
||||
auto quant_info_proto = info_proto.mutable_quant_info();
|
||||
quant_info_proto->set_qp_zp(info.quant_info.qp_zp);
|
||||
quant_info_proto->set_qp_scale(info.quant_info.qp_scale);
|
||||
quant_info_proto->set_limvals_min(info.quant_info.limvals_min);
|
||||
quant_info_proto->set_limvals_max(info.quant_info.limvals_max);
|
||||
ProtoVStreamInfo info_proto;
|
||||
serialize_vstream_info(info, &info_proto);
|
||||
vstream_infos_proto->Add(std::move(info_proto));
|
||||
}
|
||||
}
|
||||
@@ -397,6 +437,42 @@ grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_set_scheduler_threshold(g
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_config_params(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_config_params_Request *request,
|
||||
ConfiguredNetworkGroup_get_config_params_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
|
||||
return cng->get_config_params();
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_params = net_group_manager.execute<Expected<ConfigureNetworkParams>>(request->handle(), lambda);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_params, reply);
|
||||
auto net_configure_params = expected_params.value();
|
||||
auto proto_network_configure_params = reply->mutable_params();
|
||||
proto_network_configure_params->set_batch_size(net_configure_params.batch_size);
|
||||
proto_network_configure_params->set_power_mode(net_configure_params.power_mode);
|
||||
proto_network_configure_params->set_latency(net_configure_params.latency);
|
||||
for (const auto &name_stream_params_pair : net_configure_params.stream_params_by_name) {
|
||||
auto proto_name_streams_params = proto_network_configure_params->add_stream_params_map();
|
||||
proto_name_streams_params->set_name(name_stream_params_pair.first);
|
||||
|
||||
auto proto_stream_params = proto_name_streams_params->mutable_params();
|
||||
auto stream_params = name_stream_params_pair.second;
|
||||
proto_stream_params->set_stream_interface(stream_params.stream_interface);
|
||||
proto_stream_params->set_direction(stream_params.direction);
|
||||
}
|
||||
for (const auto &name_network_params_pair : net_configure_params.network_params_by_name) {
|
||||
auto proto_name_network_params = proto_network_configure_params->add_network_params_map();
|
||||
proto_name_network_params->set_name(name_network_params_pair.first);
|
||||
|
||||
auto proto_network_params = proto_name_network_params->mutable_params();
|
||||
auto network_params = name_network_params_pair.second;
|
||||
proto_network_params->set_batch_size(network_params.batch_size);
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStreams_create(grpc::ServerContext *, const VStream_create_Request *request,
|
||||
VStreams_create_Reply *reply)
|
||||
{
|
||||
@@ -493,9 +569,9 @@ grpc::Status HailoRtRpcService::OutputVStream_release(grpc::ServerContext *, con
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_name(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_name_Request *request,
|
||||
ConfiguredNetworkGroup_get_name_Reply *reply)
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_name(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_name_Request *request,
|
||||
ConfiguredNetworkGroup_name_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
|
||||
return cng->name();
|
||||
@@ -568,7 +644,7 @@ grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_all_stream_infos(grpc
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_stream_infos, reply);
|
||||
auto proto_stream_infos = reply->mutable_stream_infos();
|
||||
for (auto& stream_info : expected_stream_infos.value()) {
|
||||
StreamInfo proto_stream_info;
|
||||
ProtoStreamInfo proto_stream_info;
|
||||
if (stream_info.format.order == HAILO_FORMAT_ORDER_HAILO_NMS) {
|
||||
auto proto_nms_info = proto_stream_info.mutable_nms_info();
|
||||
proto_nms_info->set_number_of_classes(stream_info.nms_info.number_of_classes);
|
||||
@@ -626,6 +702,20 @@ grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_latency_measurement(g
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_is_multi_context(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_is_multi_context_Request *request,
|
||||
ConfiguredNetworkGroup_is_multi_context_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
|
||||
return cng->is_multi_context();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto is_multi_context = manager.execute<bool>(request->handle(), lambda);
|
||||
reply->set_is_multi_context(static_cast<bool>(is_multi_context));
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_get_frame_size(grpc::ServerContext*, const VStream_get_frame_size_Request *request,
|
||||
VStream_get_frame_size_Reply *reply)
|
||||
{
|
||||
@@ -673,7 +763,7 @@ grpc::Status HailoRtRpcService::InputVStream_name(grpc::ServerContext*, const VS
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto name = manager.execute<std::string>(request->handle(), lambda);
|
||||
reply->set_name(name);
|
||||
reply->set_status(HAILO_SUCCESS);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
@@ -686,7 +776,33 @@ grpc::Status HailoRtRpcService::OutputVStream_name(grpc::ServerContext*, const V
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto name = manager.execute<std::string>(request->handle(), lambda);
|
||||
reply->set_name(name);
|
||||
reply->set_status(HAILO_SUCCESS);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_network_name(grpc::ServerContext*, const VStream_network_name_Request *request,
|
||||
VStream_network_name_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
return input_vstream->network_name();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto name = manager.execute<std::string>(request->handle(), lambda);
|
||||
reply->set_network_name(name);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_network_name(grpc::ServerContext*, const VStream_network_name_Request *request,
|
||||
VStream_network_name_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<OutputVStream> output_vstream) {
|
||||
return output_vstream->network_name();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto name = manager.execute<std::string>(request->handle(), lambda);
|
||||
reply->set_network_name(name);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
@@ -714,29 +830,91 @@ grpc::Status HailoRtRpcService::OutputVStream_abort(grpc::ServerContext*, const
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_resume(grpc::ServerContext*, const VStream_resume_Request *,
|
||||
VStream_resume_Reply *)
|
||||
grpc::Status HailoRtRpcService::InputVStream_resume(grpc::ServerContext*, const VStream_resume_Request *request,
|
||||
VStream_resume_Reply *reply)
|
||||
{
|
||||
// TODO - HRT-7892
|
||||
// auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
// return input_vstream->resume();
|
||||
// };
|
||||
// auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
// auto status = manager.execute<hailo_status>(request->handle(), lambda);
|
||||
// reply->set_status(status);
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
return input_vstream->resume();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto status = manager.execute<hailo_status>(request->handle(), lambda);
|
||||
reply->set_status(status);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_resume(grpc::ServerContext*, const VStream_resume_Request *,
|
||||
VStream_resume_Reply *)
|
||||
grpc::Status HailoRtRpcService::OutputVStream_resume(grpc::ServerContext*, const VStream_resume_Request *request,
|
||||
VStream_resume_Reply *reply)
|
||||
{
|
||||
// TODO - HRT-7892
|
||||
// auto lambda = [](std::shared_ptr<OutputVStream> output_vstream) {
|
||||
// return output_vstream->resume();
|
||||
// };
|
||||
// auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
// auto status = manager.execute<hailo_status>(request->handle(), lambda);
|
||||
// reply->set_status(status);
|
||||
auto lambda = [](std::shared_ptr<OutputVStream> output_vstream) {
|
||||
return output_vstream->resume();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto status = manager.execute<hailo_status>(request->handle(), lambda);
|
||||
reply->set_status(status);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_get_user_buffer_format(grpc::ServerContext*, const VStream_get_user_buffer_format_Request *request,
|
||||
VStream_get_user_buffer_format_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
return input_vstream->get_user_buffer_format();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto format = manager.execute<hailo_format_t>(request->handle(), lambda);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
|
||||
auto proto_user_buffer_format = reply->mutable_user_buffer_format();
|
||||
proto_user_buffer_format->set_type(format.type);
|
||||
proto_user_buffer_format->set_order(format.order);
|
||||
proto_user_buffer_format->set_flags(format.flags);
|
||||
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_get_user_buffer_format(grpc::ServerContext*, const VStream_get_user_buffer_format_Request *request,
|
||||
VStream_get_user_buffer_format_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<OutputVStream> output_vstream) {
|
||||
return output_vstream->get_user_buffer_format();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto format = manager.execute<hailo_format_t>(request->handle(), lambda);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
|
||||
auto proto_user_buffer_format = reply->mutable_user_buffer_format();
|
||||
proto_user_buffer_format->set_type(format.type);
|
||||
proto_user_buffer_format->set_order(format.order);
|
||||
proto_user_buffer_format->set_flags(format.flags);
|
||||
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_get_info(grpc::ServerContext*, const VStream_get_info_Request *request,
|
||||
VStream_get_info_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
return input_vstream->get_info();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto info = manager.execute<hailo_vstream_info_t>(request->handle(), lambda);
|
||||
auto info_proto = reply->mutable_vstream_info();
|
||||
serialize_vstream_info(info, info_proto);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_get_info(grpc::ServerContext*, const VStream_get_info_Request *request,
|
||||
VStream_get_info_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<OutputVStream> output_vstream) {
|
||||
return output_vstream->get_info();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto info = manager.execute<hailo_vstream_info_t>(request->handle(), lambda);
|
||||
auto info_proto = reply->mutable_vstream_info();
|
||||
serialize_vstream_info(info, info_proto);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
class HailoRtRpcService final : public HailoRtRpc::Service {
|
||||
class HailoRtRpcService final : public ProtoHailoRtRpc::Service {
|
||||
|
||||
public:
|
||||
virtual grpc::Status client_keep_alive(grpc::ServerContext *ctx, const keepalive_Request *request,
|
||||
@@ -45,6 +45,8 @@ public:
|
||||
VDevice_configure_Reply* reply) override;
|
||||
virtual grpc::Status VDevice_get_physical_devices_ids(grpc::ServerContext*, const VDevice_get_physical_devices_ids_Request* request,
|
||||
VDevice_get_physical_devices_ids_Reply* reply) override;
|
||||
virtual grpc::Status VDevice_get_default_streams_interface(grpc::ServerContext*, const VDevice_get_default_streams_interface_Request* request,
|
||||
VDevice_get_default_streams_interface_Reply* reply) override;
|
||||
|
||||
virtual grpc::Status InputVStreams_create(grpc::ServerContext *, const VStream_create_Request *request,
|
||||
VStreams_create_Reply *reply) override;
|
||||
@@ -68,6 +70,10 @@ public:
|
||||
VStream_name_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_name(grpc::ServerContext*, const VStream_name_Request *request,
|
||||
VStream_name_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_network_name(grpc::ServerContext*, const VStream_network_name_Request *request,
|
||||
VStream_network_name_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_network_name(grpc::ServerContext*, const VStream_network_name_Request *request,
|
||||
VStream_network_name_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_abort(grpc::ServerContext*, const VStream_abort_Request *request,
|
||||
VStream_abort_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_abort(grpc::ServerContext*, const VStream_abort_Request *request,
|
||||
@@ -76,7 +82,14 @@ public:
|
||||
VStream_resume_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_resume(grpc::ServerContext*, const VStream_resume_Request *request,
|
||||
VStream_resume_Reply *reply) override;
|
||||
|
||||
virtual grpc::Status InputVStream_get_user_buffer_format(grpc::ServerContext*, const VStream_get_user_buffer_format_Request *request,
|
||||
VStream_get_user_buffer_format_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_get_user_buffer_format(grpc::ServerContext*, const VStream_get_user_buffer_format_Request *request,
|
||||
VStream_get_user_buffer_format_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_get_info(grpc::ServerContext*, const VStream_get_info_Request *request,
|
||||
VStream_get_info_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_get_info(grpc::ServerContext*, const VStream_get_info_Request *request,
|
||||
VStream_get_info_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_release(grpc::ServerContext*, const Release_Request* request,
|
||||
Release_Reply* reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_make_input_vstream_params(grpc::ServerContext*,
|
||||
@@ -85,9 +98,12 @@ public:
|
||||
virtual grpc::Status ConfiguredNetworkGroup_make_output_vstream_params(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_make_output_vstream_params_Request *request,
|
||||
ConfiguredNetworkGroup_make_output_vstream_params_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_name(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_name_Request *request,
|
||||
ConfiguredNetworkGroup_get_name_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_make_output_vstream_params_groups(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_make_output_vstream_params_groups_Request *request,
|
||||
ConfiguredNetworkGroup_make_output_vstream_params_groups_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_name(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_name_Request *request,
|
||||
ConfiguredNetworkGroup_name_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_network_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_network_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_network_infos_Reply *reply) override;
|
||||
@@ -118,6 +134,12 @@ public:
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_latency_measurement(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_latency_measurement_Request *request,
|
||||
ConfiguredNetworkGroup_get_latency_measurement_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_is_multi_context(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_is_multi_context_Request *request,
|
||||
ConfiguredNetworkGroup_is_multi_context_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_config_params(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_config_params_Request *request,
|
||||
ConfiguredNetworkGroup_get_config_params_Reply *reply) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
12
hailort/hailort_service/hailort_service
Normal file
12
hailort/hailort_service/hailort_service
Normal file
@@ -0,0 +1,12 @@
|
||||
# This file contains HailoRT's configurable environment variables for HailoRT Service.
|
||||
# The environment variables are set to their default values.
|
||||
# To change an environment variable's value, follow the steps:
|
||||
# 1. Change the value of the selected environemt variable in this file
|
||||
# 2. Reload systemd unit files by running: `sudo systemctl daemon-reload`
|
||||
# 3. Enable and start service by running: `sudo systemctl enable --now hailort.service`
|
||||
|
||||
[Service]
|
||||
HAILORT_LOGGER_PATH="/var/log/hailo"
|
||||
HAILO_DISABLE_MULTIPLEXER=0
|
||||
HAILO_ENABLE_MULTI_DEVICE_SCHEDULER=0
|
||||
SCHEDULER_MONITOR=0
|
||||
@@ -4,12 +4,11 @@
|
||||
*
|
||||
* @file hailort_service.cpp
|
||||
* @brief main for hailort service
|
||||
* TODO: move to user guide (HRT-7559)
|
||||
* * To run as without daemonize the executable:
|
||||
* To run as without daemonize the executable:
|
||||
* 1) Compile with `./build.sh`
|
||||
* 2) Run `./bin/linux.x86_64.debug/hailort_service standalone`
|
||||
*
|
||||
* * To run as daemon service please follow the steps:
|
||||
* To run as daemon service please follow the steps:
|
||||
* 1) Install the HailoRT:
|
||||
* cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DHAILO_BUILD_SERVICE=1 && sudo cmake --build build --target install
|
||||
*
|
||||
@@ -26,6 +25,7 @@
|
||||
#include "hailort_rpc_service.hpp"
|
||||
#include "rpc/rpc_definitions.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "common/filesystem.hpp"
|
||||
#include "hailo/hailort_common.hpp"
|
||||
|
||||
#include <syslog.h>
|
||||
@@ -44,6 +44,28 @@ void RunService() {
|
||||
server->Wait();
|
||||
}
|
||||
|
||||
void write_pid_to_lock_file()
|
||||
{
|
||||
auto status = hailort::Filesystem::create_directory(HAILO_DAEMON_PID_DIR);
|
||||
if (status != HAILO_SUCCESS) {
|
||||
syslog(LOG_ERR, "Cannot create directory at path, status=%i", status);
|
||||
return;
|
||||
}
|
||||
|
||||
auto locked_file = hailort::LockedFile::create(HAILO_DAEMON_PID_FILE, "wx");
|
||||
if (HAILO_SUCCESS != locked_file.status()) {
|
||||
syslog(LOG_ERR, "Failed to lock pid file for hailort service, status=%i", locked_file.status());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string pid = std::to_string(getpid());
|
||||
auto ret = write(locked_file->get_fd(), pid.c_str(), pid.size());
|
||||
if (-1 == ret) {
|
||||
syslog(LOG_ERR, "Failed to write pid to lock file for hailort service, errno=%i", errno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
bool is_standalone = ((1 < argc) && (strcmp("standalone", argv[1]) == 0));
|
||||
@@ -53,8 +75,9 @@ int main(int argc, char *argv[])
|
||||
syslog(LOG_ERR, "Failed to create daemon with errno %i", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
write_pid_to_lock_file();
|
||||
}
|
||||
RunService();
|
||||
return 0;
|
||||
}
|
||||
@@ -24,6 +24,12 @@ set(HAILORTCLI_CPP_FILES
|
||||
parse_hef_command.cpp
|
||||
graph_printer.cpp
|
||||
mon_command.cpp
|
||||
|
||||
run2/run2_command.cpp
|
||||
run2/network_runner.cpp
|
||||
run2/live_printer.cpp
|
||||
run2/timer_live_track.cpp
|
||||
run2/network_live_track.cpp
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
@@ -61,8 +67,6 @@ target_link_libraries(hailortcli
|
||||
readerwriterqueue
|
||||
DotWriter
|
||||
scheduler_mon_proto)
|
||||
# TODO: Remove microprofile after removing pipeline.cpp from hailortcli sources
|
||||
target_link_libraries(hailortcli microprofile)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(hailortcli Ws2_32 Iphlpapi Shlwapi)
|
||||
|
||||
@@ -31,6 +31,10 @@ BoardConfigReadSubcommand::BoardConfigReadSubcommand(CLI::App &parent_app) :
|
||||
|
||||
hailo_status BoardConfigReadSubcommand::execute_on_device(Device &device)
|
||||
{
|
||||
auto status = validate_specific_device_is_given();
|
||||
CHECK_SUCCESS(status,
|
||||
"'board-config read' command should get a specific device-id.");
|
||||
|
||||
auto buffer = device.read_board_config();
|
||||
CHECK_EXPECTED_AS_STATUS(buffer, "Failed reading board config from device");
|
||||
|
||||
|
||||
@@ -61,3 +61,16 @@ hailo_status DeviceCommand::execute_on_devices(std::vector<std::unique_ptr<Devic
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
hailo_status DeviceCommand::validate_specific_device_is_given()
|
||||
{
|
||||
if ((1 != m_device_params.device_ids.size()) || contains(m_device_params.device_ids, std::string("*"))) {
|
||||
// No specific device-id given, make sure there is only 1 device on the machine.
|
||||
auto scan_res = Device::scan();
|
||||
CHECK_EXPECTED_AS_STATUS(scan_res, "Failed to scan for devices");
|
||||
if (1 != scan_res->size()) {
|
||||
return HAILO_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -64,11 +64,12 @@ public:
|
||||
virtual hailo_status execute() override final;
|
||||
|
||||
protected:
|
||||
hailo_device_params m_device_params;
|
||||
|
||||
virtual hailo_status execute_on_device(Device &device) = 0;
|
||||
hailo_status execute_on_devices(std::vector<std::unique_ptr<Device>> &devices);
|
||||
hailo_status validate_specific_device_is_given();
|
||||
|
||||
private:
|
||||
hailo_device_params m_device_params;
|
||||
};
|
||||
|
||||
#endif /* _HAILO_COMMAND_HPP_ */
|
||||
@@ -72,3 +72,22 @@ void CliCommon::reset_cursor(size_t lines_count)
|
||||
std::cout << FORMAT_CURSOR_UP_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
void CliCommon::clear_lines_down(size_t lines_count)
|
||||
{
|
||||
for (size_t i = 0; i < lines_count; i++) {
|
||||
std::cout << FORMAT_CURSOR_DOWN_CLEAR_LINE;
|
||||
}
|
||||
}
|
||||
|
||||
bool CliCommon::is_positive_number(const std::string &s)
|
||||
{
|
||||
bool is_number = (!s.empty()) && (std::all_of(s.begin(), s.end(), ::isdigit));
|
||||
return is_number && (0 < std::stoi(s));
|
||||
}
|
||||
|
||||
bool CliCommon::is_non_negative_number(const std::string &s)
|
||||
{
|
||||
bool is_number = (!s.empty()) && (std::all_of(s.begin(), s.end(), ::isdigit));
|
||||
return is_number && (0 <= std::stoi(s));
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ using namespace hailort;
|
||||
// http://www.climagic.org/mirrors/VT100_Escape_Codes.html
|
||||
#define FORMAT_CLEAR_LINE "\033[2K\r"
|
||||
#define FORMAT_CURSOR_UP_LINE "\033[F"
|
||||
#define FORMAT_CURSOR_DOWN_CLEAR_LINE "\033[B\33[2K\r"
|
||||
|
||||
class CliCommon final
|
||||
{
|
||||
@@ -31,6 +32,9 @@ public:
|
||||
static std::string duration_to_string(std::chrono::seconds secs);
|
||||
static Expected<std::string> current_time_to_string();
|
||||
static void reset_cursor(size_t number_of_lines);
|
||||
static void clear_lines_down(size_t number_of_lines);
|
||||
static bool is_positive_number(const std::string &s);
|
||||
static bool is_non_negative_number(const std::string &s);
|
||||
};
|
||||
|
||||
// Validators
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
// TODO - HRT-7364 - add CPU subsystem frequency into the device extended info control
|
||||
// and use it for get the timer's frequency
|
||||
#define NN_CORE_TO_TIMER_FREQ_FACTOR (2)
|
||||
#define MERCURY_VPU_CORE_CPU_DEFAULT_FREQ_MHZ (200)
|
||||
|
||||
constexpr int DownloadActionListCommand::INVALID_NUMERIC_VALUE;
|
||||
|
||||
@@ -40,9 +41,17 @@ hailo_status DownloadActionListCommand::execute(Device &device, const std::strin
|
||||
auto curr_time = CliCommon::current_time_to_string();
|
||||
CHECK_EXPECTED_AS_STATUS(curr_time);
|
||||
|
||||
auto chip_arch = device.get_architecture();
|
||||
CHECK_EXPECTED_AS_STATUS(chip_arch);
|
||||
unsigned int clock_cycle = 0;
|
||||
// TODO - HRT-8046 Implement extended device info for mercury
|
||||
if (HAILO_ARCH_MERCURY_VPU == chip_arch.value()) {
|
||||
clock_cycle = MERCURY_VPU_CORE_CPU_DEFAULT_FREQ_MHZ;
|
||||
} else {
|
||||
auto extended_info = device.get_extended_device_information();
|
||||
CHECK_EXPECTED_AS_STATUS(extended_info);
|
||||
const auto clock_cycle = (extended_info->neural_network_core_clock_rate / NN_CORE_TO_TIMER_FREQ_FACTOR) / MHz;
|
||||
clock_cycle = (extended_info->neural_network_core_clock_rate / NN_CORE_TO_TIMER_FREQ_FACTOR) / MHz;
|
||||
}
|
||||
|
||||
ordered_json action_list_json = {
|
||||
{"version", ACTION_LIST_FORMAT_VERSION()},
|
||||
@@ -75,6 +84,10 @@ hailo_status DownloadActionListCommand::set_batch_to_measure(Device &device, uin
|
||||
|
||||
hailo_status DownloadActionListCommand::execute_on_device(Device &device)
|
||||
{
|
||||
auto status = validate_specific_device_is_given();
|
||||
CHECK_SUCCESS(status,
|
||||
"'fw-control action-list' command should get a specific device-id.");
|
||||
|
||||
return execute(device, m_output_file_path);
|
||||
}
|
||||
|
||||
@@ -179,9 +192,9 @@ Expected<ordered_json> DownloadActionListCommand::parse_action_data(uint32_t bas
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__wait_dma_idle_data_t *>(action);
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__wait_dma_idle_data_t);
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_NMS_IDLE:
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__wait_nms_idle_data_t *>(action);
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__wait_nms_idle_data_t);
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_NMS:
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__wait_nms_data_t *>(action);
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__wait_nms_data_t);
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_OUTPUT_CHANNEL_TRANSFER_DONE_INTERRUPT:
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__vdma_dataflow_interrupt_data_t *>(action);
|
||||
@@ -192,8 +205,8 @@ Expected<ordered_json> DownloadActionListCommand::parse_action_data(uint32_t bas
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__module_config_done_interrupt_data_t);
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_APPLICATION_CHANGE_INTERRUPT:
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__application_change_interrupt_data_t *>(action);
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__application_change_interrupt_data_t);
|
||||
data_json = json({});
|
||||
action_length_local = 0;
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_FETCH_CFG_CHANNEL_DESCRIPTORS:
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__fetch_cfg_channel_descriptors_action_data_t *>(action);
|
||||
@@ -283,6 +296,18 @@ Expected<ordered_json> DownloadActionListCommand::parse_action_data(uint32_t bas
|
||||
data_json = json({});
|
||||
action_length_local = 0;
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_OPEN_BOUNDARY_INPUT_CHANNEL:
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__open_boundary_input_channel_data_t *>(action);
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__open_boundary_input_channel_data_t);
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_OPEN_BOUNDARY_OUTPUT_CHANNEL:
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__open_boundary_output_channel_data_t *>(action);
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__open_boundary_output_channel_data_t);
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_ENABLE_NMS:
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__enable_nms_action_t *>(action);
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__enable_nms_action_t);
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT:
|
||||
// Fallthrough
|
||||
// Handling CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT is needed because we compile this file with -Wswitch-enum
|
||||
@@ -326,24 +351,35 @@ Expected<ordered_json> DownloadActionListCommand::parse_single_action(uint32_t b
|
||||
return json.release();
|
||||
}
|
||||
|
||||
Expected<ordered_json> DownloadActionListCommand::parse_context(uint32_t action_list_base_address,
|
||||
uint8_t *context_action_list, uint16_t action_list_size, uint32_t batch_counter)
|
||||
Expected<ordered_json> DownloadActionListCommand::parse_context(Device &device, uint32_t network_group_id,
|
||||
CONTROL_PROTOCOL__context_switch_context_type_t context_type, uint8_t context_index, const std::string &context_name)
|
||||
{
|
||||
uint32_t action_list_base_address = 0;
|
||||
uint32_t batch_counter = 0;
|
||||
|
||||
auto action_list = device.download_context_action_list(network_group_id, context_type, context_index,
|
||||
&action_list_base_address, &batch_counter);
|
||||
CHECK_EXPECTED(action_list);
|
||||
// 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,
|
||||
"Action list size is expected to fit in 2B. actual size is {}", action_list->size());
|
||||
|
||||
ordered_json context_json {
|
||||
{"action_list_base_address", action_list_base_address},
|
||||
{"action_list_size", action_list_size },
|
||||
{"batch_counter", batch_counter}
|
||||
{"action_list_size", action_list->size() },
|
||||
{"batch_counter", batch_counter},
|
||||
{"context_name", context_name},
|
||||
};
|
||||
|
||||
ordered_json action_list_json;
|
||||
uint16_t current_buffer_offset = 0;
|
||||
while (current_buffer_offset < action_list_size) {
|
||||
while (current_buffer_offset < action_list->size()) {
|
||||
bool is_repeated = false;
|
||||
uint8_t num_repeated = 0;
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_t sub_action_type = CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT;
|
||||
uint32_t single_action_length = 0;
|
||||
uint32_t timestamp = 0;
|
||||
auto action_json = parse_single_action(action_list_base_address, context_action_list,
|
||||
auto action_json = parse_single_action(action_list_base_address, action_list->data(),
|
||||
current_buffer_offset, &single_action_length, &is_repeated, &num_repeated, &sub_action_type, ×tamp);
|
||||
CHECK_EXPECTED(action_json);
|
||||
current_buffer_offset = (uint16_t)(current_buffer_offset + single_action_length);
|
||||
@@ -353,7 +389,7 @@ Expected<ordered_json> DownloadActionListCommand::parse_context(uint32_t action_
|
||||
for (uint8_t index_in_repeated_block = 0; index_in_repeated_block < num_repeated; index_in_repeated_block++) {
|
||||
uint32_t sub_action_length = 0;
|
||||
auto repeated_action_json = parse_single_repeated_action(action_list_base_address,
|
||||
context_action_list + current_buffer_offset, current_buffer_offset, &sub_action_length,
|
||||
action_list->data() + current_buffer_offset, current_buffer_offset, &sub_action_length,
|
||||
sub_action_type, timestamp, index_in_repeated_block);
|
||||
CHECK_EXPECTED(repeated_action_json);
|
||||
current_buffer_offset = (uint16_t)(current_buffer_offset + sub_action_length);
|
||||
@@ -361,7 +397,7 @@ Expected<ordered_json> DownloadActionListCommand::parse_context(uint32_t action_
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK_AS_EXPECTED(current_buffer_offset == action_list_size, HAILO_INTERNAL_FAILURE,
|
||||
CHECK_AS_EXPECTED(current_buffer_offset == action_list->size(), HAILO_INTERNAL_FAILURE,
|
||||
"PARSING ERROR ! Reached forbidden memory space");
|
||||
|
||||
context_json["actions"] = action_list_json;
|
||||
@@ -377,16 +413,19 @@ double DownloadActionListCommand::get_accumulator_mean_value(const AccumulatorPt
|
||||
|
||||
Expected<ordered_json> DownloadActionListCommand::parse_network_groups(Device &device, const ConfiguredNetworkGroupVector &network_groups)
|
||||
{
|
||||
const auto number_of_contexts_per_network_group = device.get_number_of_contexts_per_network_group();
|
||||
CHECK_EXPECTED(number_of_contexts_per_network_group);
|
||||
const auto number_of_dynamic_contexts_per_network_group = device.get_number_of_dynamic_contexts_per_network_group();
|
||||
CHECK_EXPECTED(number_of_dynamic_contexts_per_network_group);
|
||||
|
||||
ordered_json network_group_list_json;
|
||||
uint8_t global_context_index = 0;
|
||||
for (uint32_t network_group_index = 0; network_group_index < number_of_contexts_per_network_group->size(); network_group_index++) {
|
||||
for (uint32_t network_group_index = 0; network_group_index < number_of_dynamic_contexts_per_network_group->size(); network_group_index++) {
|
||||
// TODO: HRT-8147 use the real network_group_id instead of network_group_index
|
||||
const uint32_t network_group_id = network_group_index;
|
||||
|
||||
// TODO: network_group_name via Hef::get_network_groups_names (HRT-5997)
|
||||
ordered_json network_group_json = {
|
||||
{"mean_activation_time_ms", INVALID_NUMERIC_VALUE},
|
||||
{"mean_deactivation_time_ms", INVALID_NUMERIC_VALUE},
|
||||
{"network_group_id", network_group_id},
|
||||
{"contexts", json::array()}
|
||||
};
|
||||
// We assume the the order of the network_groups in the ConfiguredNetworkGroupVector and in the action_list
|
||||
@@ -399,25 +438,31 @@ Expected<ordered_json> DownloadActionListCommand::parse_network_groups(Device &d
|
||||
network_groups[network_group_index]->get_deactivation_time_accumulator());
|
||||
}
|
||||
|
||||
const auto num_contexts_in_network_group = number_of_contexts_per_network_group.value()[network_group_index];
|
||||
for (uint8_t i = 0; i < num_contexts_in_network_group; i++) {
|
||||
uint32_t batch_counter = 0;
|
||||
uint32_t base_address = 0;
|
||||
auto action_list = device.download_context_action_list(global_context_index, &base_address, &batch_counter);
|
||||
CHECK_EXPECTED(action_list);
|
||||
// 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,
|
||||
"Action list size is expected to fit in 2B. actual size is {}", action_list->size());
|
||||
auto activation_context_json = parse_context(device, network_group_id,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_ACTIVATION, 0, "activation");
|
||||
CHECK_EXPECTED(activation_context_json);
|
||||
network_group_json["contexts"].emplace_back(activation_context_json.release());
|
||||
|
||||
auto context_json = parse_context(base_address, action_list->data(),
|
||||
static_cast<uint16_t>(action_list->size()), batch_counter);
|
||||
auto preliminary_context_json = parse_context(device, network_group_id,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_PRELIMINARY, 0, "preliminary");
|
||||
CHECK_EXPECTED(preliminary_context_json);
|
||||
network_group_json["contexts"].emplace_back(preliminary_context_json.release());
|
||||
|
||||
const auto dynamic_contexts_count = number_of_dynamic_contexts_per_network_group.value()[network_group_index];
|
||||
for (uint8_t context_index = 0; context_index < dynamic_contexts_count; context_index++) {
|
||||
auto context_json = parse_context(device, network_group_id,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_DYNAMIC, context_index,
|
||||
fmt::format("dynamic_{}", context_index));
|
||||
CHECK_EXPECTED(context_json);
|
||||
|
||||
network_group_json["contexts"].emplace_back(context_json.release());
|
||||
|
||||
// Device::get_number_of_contexts_per_network_group guarantees no overflow
|
||||
global_context_index++;
|
||||
}
|
||||
|
||||
auto batch_switching_context_json = parse_context(device, network_group_id,
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_CONTEXT_TYPE_BATCH_SWITCHING, 0, "batch_switching");
|
||||
CHECK_EXPECTED(batch_switching_context_json);
|
||||
network_group_json["contexts"].emplace_back(batch_switching_context_json.release());
|
||||
|
||||
network_group_list_json.emplace_back(network_group_json);
|
||||
}
|
||||
|
||||
@@ -567,3 +612,13 @@ void to_json(json &j, const CONTEXT_SWITCH_DEFS__add_ddr_pair_info_action_data_t
|
||||
j = json{{"h2d_engine_index", h2d_engine_index}, {"h2d_vdma_channel_index", h2d_vdma_channel_index},
|
||||
{"d2h_engine_index", d2h_engine_index}, {"d2h_vdma_channel_index", d2h_vdma_channel_index}};
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__open_boundary_input_channel_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__open_boundary_output_channel_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
}
|
||||
|
||||
@@ -56,8 +56,9 @@ private:
|
||||
static Expected<ordered_json> parse_single_action(uint32_t base_address, uint8_t *context_action_list,
|
||||
uint32_t current_buffer_offset, uint32_t *action_length, bool *is_repeated, uint8_t *num_repeated,
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_t *sub_action_type, uint32_t *time_stamp);
|
||||
static Expected<ordered_json> parse_context(uint32_t action_list_base_address, uint8_t *context_action_list,
|
||||
uint16_t action_list_size, uint32_t batch_counter);
|
||||
static Expected<ordered_json> parse_context(Device &device, uint32_t network_group_id,
|
||||
CONTROL_PROTOCOL__context_switch_context_type_t context_type, uint8_t context_index,
|
||||
const std::string &context_name);
|
||||
static double get_accumulator_mean_value(const AccumulatorPtr &accumulator, double default_value = INVALID_NUMERIC_VALUE);
|
||||
static Expected<ordered_json> parse_network_groups(Device &device, const ConfiguredNetworkGroupVector &network_groups);
|
||||
};
|
||||
@@ -93,9 +94,12 @@ static std::pair<CONTEXT_SWITCH_DEFS__ACTION_TYPE_t, std::string> mapping[] = {
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_DEACTIVATE_CFG_CHANNEL, "deactivate_cfg_channel"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_REPEATED_ACTION, "repeated_action"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_DMA_IDLE_ACTION, "wait_for_dma_idle_action"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_NMS_IDLE, "wait_for_nms_idle"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_WAIT_FOR_NMS, "wait_for_nms_idle"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_FETCH_CCW_BURSTS, "fetch_ccw_bursts"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_DDR_BUFFERING_RESET, "ddr_buffering_reset"}
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_DDR_BUFFERING_RESET, "ddr_buffering_reset"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_OPEN_BOUNDARY_INPUT_CHANNEL, "open_boundary_input_channel"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_OPEN_BOUNDARY_OUTPUT_CHANNEL, "open_boundary_output_channel"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_ENABLE_NMS, "enable_nms"},
|
||||
};
|
||||
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");
|
||||
@@ -106,10 +110,10 @@ NLOHMANN_JSON_SERIALIZE_ENUM2(CONTEXT_SWITCH_DEFS__ACTION_TYPE_t, mapping);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__repeated_action_header_t, count, last_executed, sub_action_type);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__trigger_sequencer_action_data_t, cluster_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__sequencer_interrupt_data_t, sequencer_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__wait_nms_idle_data_t, aggregator_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__wait_nms_data_t, aggregator_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__module_config_done_interrupt_data_t, module_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__application_change_interrupt_data_t, application_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t, config_stream_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__enable_nms_action_t, nms_unit_index, network_index);
|
||||
|
||||
// Non-default implementations
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__deactivate_vdma_channel_action_data_t &data);
|
||||
@@ -132,5 +136,7 @@ void to_json(json &j, const CONTEXT_SWITCH_DEFS__lcu_interrupt_data_t& data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_cfg_channel_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__deactivate_cfg_channel_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__add_ddr_pair_info_action_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__open_boundary_input_channel_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__open_boundary_output_channel_data_t &data);
|
||||
|
||||
#endif /* _HAILO_DOWNLOAD_ACTION_LIST_COMMAND_HPP_ */
|
||||
|
||||
@@ -18,10 +18,14 @@ FwConfigReadSubcommand::FwConfigReadSubcommand(CLI::App &parent_app) :
|
||||
|
||||
hailo_status FwConfigReadSubcommand::execute_on_device(Device &device)
|
||||
{
|
||||
auto status = validate_specific_device_is_given();
|
||||
CHECK_SUCCESS(status,
|
||||
"'fw-config read' command should get a specific device-id.");
|
||||
|
||||
auto user_config_buffer = device.read_user_config();
|
||||
CHECK_EXPECTED_AS_STATUS(user_config_buffer, "Failed reading user config from device");
|
||||
|
||||
auto status = FwConfigJsonSerializer::deserialize_config(
|
||||
status = FwConfigJsonSerializer::deserialize_config(
|
||||
*reinterpret_cast<USER_CONFIG_header_t*>(user_config_buffer->data()),
|
||||
user_config_buffer->size(), m_output_file);
|
||||
CHECK_SUCCESS(status);
|
||||
|
||||
@@ -114,7 +114,7 @@ static std::string fw_version_string(const hailo_device_identity_t &identity)
|
||||
{
|
||||
std::stringstream os;
|
||||
const auto fw_mode = ((identity.is_release) ? "release" : "develop");
|
||||
// Currently will always return FW_BINARY_TYPE_APP_FIRMWARE as version bit is cleared in HailoRT
|
||||
// TODO: Currently will always return FW_BINARY_TYPE_APP_FIRMWARE as version bit is cleared in HailoRT
|
||||
FW_BINARY_TYPE_t fw_binary_type = FIRMWARE_HEADER_UTILS__get_fw_binary_type(identity.fw_version.revision);
|
||||
auto fw_type = "invalid";
|
||||
if (FW_BINARY_TYPE_CORE_FIRMWARE == fw_binary_type) {
|
||||
@@ -123,7 +123,11 @@ static std::string fw_version_string(const hailo_device_identity_t &identity)
|
||||
fw_type = "app";
|
||||
}
|
||||
os << identity.fw_version.major << "." << identity.fw_version.minor << "."
|
||||
<< identity.fw_version.revision << " (" << fw_mode << "," << fw_type << ")";
|
||||
<< identity.fw_version.revision << " (" << fw_mode << "," << fw_type;
|
||||
if (identity.extended_context_switch_buffer) {
|
||||
os << ",extended context switch buffer";
|
||||
}
|
||||
os << ")";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
@@ -49,8 +49,11 @@ hailo_status write_logs_to_file(Device &device, std::ofstream &ofs, hailo_cpu_id
|
||||
|
||||
hailo_status FwLoggerCommand::execute_on_device(Device &device)
|
||||
{
|
||||
auto status = validate_specific_device_is_given();
|
||||
CHECK_SUCCESS(status,
|
||||
"'fw-logger' command should get a specific device-id");
|
||||
|
||||
auto ofs_flags = std::ios::out | std::ios::binary;
|
||||
hailo_status status = HAILO_UNINITIALIZED;
|
||||
|
||||
if (!m_should_overwrite){
|
||||
ofs_flags |= std::ios::app;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*
|
||||
* HailoRT command line interface.
|
||||
**/
|
||||
#include "run2/run2_command.hpp"
|
||||
#include "hailortcli.hpp"
|
||||
#include "scan_command.hpp"
|
||||
#include "power_measurement_command.hpp"
|
||||
@@ -96,9 +97,9 @@ void add_vdevice_options(CLI::App *app, hailo_vdevice_params &vdevice_params)
|
||||
auto group = app->add_option_group("VDevice Options");
|
||||
auto device_count_option = group->add_option("--device-count", vdevice_params.device_count, "VDevice device count")
|
||||
->check(CLI::PositiveNumber);
|
||||
auto multi_process_option = group->add_flag("--multi-process-service", vdevice_params.multi_process_service,
|
||||
group->add_flag("--multi-process-service", vdevice_params.multi_process_service,
|
||||
"VDevice multi process service");
|
||||
group->add_option("--group-id", vdevice_params.group_id, "VDevice group id")->needs(multi_process_option);
|
||||
group->add_option("--group-id", vdevice_params.group_id, "VDevice group id");
|
||||
group->parse_complete_callback([&vdevice_params, device_count_option](){
|
||||
if (vdevice_params.device_params.device_ids.size() > 0) {
|
||||
// Check either device_count or device_id
|
||||
@@ -136,13 +137,6 @@ void add_device_options(CLI::App *app, hailo_device_params &device_params, bool
|
||||
auto *ip_option = group->add_option("--ip", device_params.device_ids, "IP address of the target")
|
||||
->check(CLI::ValidIPV4);
|
||||
|
||||
auto *device_type_option = group->add_option("-d,--device-type,--target", "ignored.");
|
||||
|
||||
std::vector<DeprecationActionPtr> actions{
|
||||
std::make_shared<OptionDeprecation>(device_type_option),
|
||||
};
|
||||
hailo_deprecate_options(app, actions, false);
|
||||
|
||||
group->parse_complete_callback([&device_params, device_id_option, pcie_bdf_option, ip_option, support_asterisk]()
|
||||
{
|
||||
// Check that only one device id param is given
|
||||
@@ -190,18 +184,10 @@ class HailoRTCLI : public ContainerCommand {
|
||||
public:
|
||||
HailoRTCLI(CLI::App *app) : ContainerCommand(app)
|
||||
{
|
||||
|
||||
m_app->add_flag_callback("-v,--version",
|
||||
[] () {
|
||||
std::cout << "HailoRT-CLI version " <<
|
||||
HAILORT_MAJOR_VERSION << "." << HAILORT_MINOR_VERSION << "." << HAILORT_REVISION_VERSION << std::endl;
|
||||
// throw CLI::Success to stop parsing and not failing require_subcommand(1) we set earlier
|
||||
throw (CLI::Success{});
|
||||
},
|
||||
"Print program version and exit"
|
||||
);
|
||||
m_app->set_version_flag("-v,--version", fmt::format("HailoRT-CLI version {}.{}.{}", HAILORT_MAJOR_VERSION, HAILORT_MINOR_VERSION, HAILORT_REVISION_VERSION));
|
||||
|
||||
add_subcommand<RunCommand>();
|
||||
add_subcommand<Run2Command>();
|
||||
add_subcommand<ScanSubcommand>();
|
||||
add_subcommand<BenchmarkCommand>();
|
||||
add_subcommand<PowerMeasurementSubcommand>();
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "common/filesystem.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#if defined(__GNUC__)
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
@@ -20,8 +23,11 @@ namespace hailort
|
||||
// TODO: Deal with longer networks names - should use HAILO_MAX_NETWORK_NAME_SIZE but its too long for one line
|
||||
constexpr size_t NETWORK_NAME_WIDTH = 40;
|
||||
constexpr size_t STREAM_NAME_WIDTH = 60;
|
||||
constexpr size_t ACTIVE_TIME_WIDTH = 25;
|
||||
constexpr size_t NUMBER_WIDTH = 15;
|
||||
constexpr size_t TERMINAL_DEFAULT_WIDTH = 80;
|
||||
constexpr size_t LINE_LENGTH = 125;
|
||||
constexpr std::chrono::milliseconds EPSILON_TIME(500);
|
||||
|
||||
MonCommand::MonCommand(CLI::App &parent_app) :
|
||||
Command(parent_app.add_subcommand("monitor", "Monitor of networks - Presents information about the running networks. " \
|
||||
@@ -43,7 +49,7 @@ size_t MonCommand::print_networks_info_header()
|
||||
std::cout <<
|
||||
std::setw(NETWORK_NAME_WIDTH) << std::left << "Network" <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << "FPS" <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << "Core%" <<
|
||||
std::setw(ACTIVE_TIME_WIDTH) << std::left << "Active Time (%) " <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << "PID" <<
|
||||
"\n" << std::left << std::string(LINE_LENGTH, '-') << "\n";
|
||||
static const uint32_t header_lines_count = 2;
|
||||
@@ -53,17 +59,21 @@ size_t MonCommand::print_networks_info_header()
|
||||
|
||||
size_t MonCommand::print_networks_info_table(const ProtoMon &mon_message)
|
||||
{
|
||||
const uint32_t NUMBER_OBJECTS_COUNT = 3;
|
||||
auto data_line_len = (NUMBER_WIDTH * NUMBER_OBJECTS_COUNT) + NETWORK_NAME_WIDTH;
|
||||
auto rest_line_len = LINE_LENGTH - data_line_len;
|
||||
|
||||
const std::string &pid = mon_message.pid();
|
||||
for (auto net_info : mon_message.networks_infos()) {
|
||||
auto &net_name = net_info.network_name();
|
||||
auto fps = net_info.fps();
|
||||
auto core = net_info.core_utilization();
|
||||
auto active_time = net_info.active_time();
|
||||
|
||||
std::cout << std::setprecision(1) << std::fixed <<
|
||||
std::setw(NETWORK_NAME_WIDTH) << std::left << net_name <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << fps <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << core <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << pid << "\n";
|
||||
std::setw(ACTIVE_TIME_WIDTH) << std::left << active_time <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << pid << std::string(rest_line_len, ' ') << "\n";
|
||||
}
|
||||
|
||||
return mon_message.networks_infos().size();
|
||||
@@ -110,50 +120,93 @@ size_t MonCommand::print_frames_table(const ProtoMon &mon_message)
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
hailo_status MonCommand::print_table()
|
||||
Expected<uint16_t> get_terminal_line_width()
|
||||
{
|
||||
while (true) {
|
||||
auto epsilon = std::chrono::milliseconds(500);
|
||||
std::chrono::milliseconds time_interval = DEFAULT_SCHEDULER_MON_INTERVAL + epsilon;
|
||||
auto scheduler_mon_files = Filesystem::get_latest_files_in_dir_flat(SCHEDULER_MON_TMP_DIR, time_interval);
|
||||
if (HAILO_SUCCESS != scheduler_mon_files.status() || scheduler_mon_files->empty()) {
|
||||
LOGGER__WARNING("Getting scheduler monitor files failed. Please check the application is running and environment variable '{}' is set to 1.",
|
||||
SCHEDULER_MON_ENV_VAR);
|
||||
return HAILO_NOT_FOUND;
|
||||
struct winsize w;
|
||||
int ret = ioctl(0, TIOCGWINSZ, &w);
|
||||
if (ret != 0) {
|
||||
LOGGER__DEBUG("Failed to get_terminal_line_width, with errno: {}, using default value: {}", errno);
|
||||
return TERMINAL_DEFAULT_WIDTH;
|
||||
}
|
||||
|
||||
uint16_t terminal_line_width = w.ws_col;
|
||||
return terminal_line_width;
|
||||
}
|
||||
|
||||
hailo_status MonCommand::print_table()
|
||||
{
|
||||
std::chrono::milliseconds time_interval = DEFAULT_SCHEDULER_MON_INTERVAL + EPSILON_TIME;
|
||||
auto terminal_line_width_expected = get_terminal_line_width();
|
||||
CHECK_EXPECTED_AS_STATUS(terminal_line_width_expected);
|
||||
auto terminal_line_width = terminal_line_width_expected.release();
|
||||
|
||||
size_t last_run_total_lines_count = 0;
|
||||
bool data_was_printed = false;
|
||||
while (true) {
|
||||
size_t total_lines_count = 0;
|
||||
bool print_warning_msg = true; // Will change to false only if mon directory is valid and there are updated files in it.
|
||||
|
||||
auto mon_dir_valid = Filesystem::is_directory(SCHEDULER_MON_TMP_DIR);
|
||||
CHECK_EXPECTED_AS_STATUS(mon_dir_valid);
|
||||
|
||||
std::vector<ProtoMon> mon_messages;
|
||||
if (mon_dir_valid.value()) {
|
||||
auto scheduler_mon_files = Filesystem::get_latest_files_in_dir_flat(SCHEDULER_MON_TMP_DIR, time_interval);
|
||||
CHECK_EXPECTED_AS_STATUS(scheduler_mon_files);
|
||||
print_warning_msg = scheduler_mon_files->empty();
|
||||
|
||||
mon_messages.reserve(scheduler_mon_files->size());
|
||||
for (const auto &mon_file : scheduler_mon_files.value()) {
|
||||
auto file = LockedFile::create(mon_file, "r");
|
||||
if (HAILO_SUCCESS != file.status()) {
|
||||
LOGGER__ERROR("Failed to open and lock file {}, with status: {}", mon_file, file.status());
|
||||
total_lines_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
ProtoMon mon_message;
|
||||
if (!mon_message.ParseFromFileDescriptor(file->get_fd())) {
|
||||
LOGGER__WARNING("Failed to ParseFromFileDescriptor monitor file {} with errno {}", mon_file, errno);
|
||||
total_lines_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
mon_messages.emplace_back(std::move(mon_message));
|
||||
}
|
||||
}
|
||||
|
||||
size_t total_lines_count = print_networks_info_header();
|
||||
total_lines_count += print_networks_info_header();
|
||||
for (auto &mon_message : mon_messages) {
|
||||
total_lines_count += print_networks_info_table(mon_message);
|
||||
}
|
||||
|
||||
std::cout << "\n\n";
|
||||
std::cout << std::string(terminal_line_width, ' ') << "\n";
|
||||
std::cout << std::string(terminal_line_width, ' ') << "\n";
|
||||
total_lines_count += 2;
|
||||
|
||||
total_lines_count += print_frames_header();
|
||||
for (auto &mon_message : mon_messages) {
|
||||
total_lines_count += print_frames_table(mon_message);
|
||||
}
|
||||
CliCommon::reset_cursor(total_lines_count);
|
||||
|
||||
if (print_warning_msg) {
|
||||
std::cout << "Monitor did not retrieve any files. This occurs when there is no application currently running. If this is not the case, verify that environment variable '" <<
|
||||
SCHEDULER_MON_ENV_VAR << "' is set to 1.\n";
|
||||
total_lines_count++;
|
||||
|
||||
if (data_was_printed) {
|
||||
auto lines_to_clear = last_run_total_lines_count - total_lines_count;
|
||||
CliCommon::clear_lines_down(lines_to_clear);
|
||||
total_lines_count += lines_to_clear;
|
||||
data_was_printed = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
data_was_printed = true;
|
||||
last_run_total_lines_count = total_lines_count;
|
||||
}
|
||||
|
||||
CliCommon::reset_cursor(total_lines_count);
|
||||
std::this_thread::sleep_for(DEFAULT_SCHEDULER_MON_INTERVAL);
|
||||
}
|
||||
|
||||
|
||||
69
hailort/hailortcli/run2/live_printer.cpp
Normal file
69
hailort/hailortcli/run2/live_printer.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file live_printer.cpp
|
||||
* @brief Live printer
|
||||
**/
|
||||
|
||||
#include "live_printer.hpp"
|
||||
#include "../common.hpp"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
using namespace hailort;
|
||||
|
||||
LivePrinter::LivePrinter(std::chrono::milliseconds interval) :
|
||||
m_interval(interval),
|
||||
m_stop_event(Event::create_shared(Event::State::not_signalled)),
|
||||
m_tracks(),
|
||||
m_mutex()
|
||||
{
|
||||
}
|
||||
|
||||
LivePrinter::~LivePrinter()
|
||||
{
|
||||
(void)m_stop_event->signal();
|
||||
if (m_thread.joinable()) {
|
||||
m_thread.join();
|
||||
}
|
||||
print(false);
|
||||
}
|
||||
|
||||
void LivePrinter::add(std::shared_ptr<Track> track)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_tracks.emplace_back(track);
|
||||
}
|
||||
|
||||
void LivePrinter::print(bool reset)
|
||||
{
|
||||
std::stringstream ss;
|
||||
uint32_t count = 0;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
for (auto &track : m_tracks) {
|
||||
count += track->get_text(ss);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << ss.str() << std::flush;
|
||||
if (reset) {
|
||||
CliCommon::reset_cursor(count);
|
||||
//TODO: what aout leftovers from prev line?
|
||||
}
|
||||
}
|
||||
|
||||
void LivePrinter::start()
|
||||
{
|
||||
m_thread = std::thread([this] () {
|
||||
while (true) {
|
||||
print(true);
|
||||
auto status = m_stop_event->wait(m_interval);
|
||||
if (HAILO_TIMEOUT != status) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
43
hailort/hailortcli/run2/live_printer.hpp
Normal file
43
hailort/hailortcli/run2/live_printer.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file live_printer.hpp
|
||||
* @brief Live printer
|
||||
**/
|
||||
|
||||
#ifndef _HAILO_HAILORTCLI_RUN2_LIVE_PRINTER_HPP_
|
||||
#define _HAILO_HAILORTCLI_RUN2_LIVE_PRINTER_HPP_
|
||||
|
||||
#include "hailo/event.hpp"
|
||||
#include <stdint.h>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
class LivePrinter final
|
||||
{
|
||||
public:
|
||||
class Track
|
||||
{
|
||||
public:
|
||||
virtual uint32_t get_text(std::stringstream &ss) = 0;
|
||||
};
|
||||
|
||||
LivePrinter(std::chrono::milliseconds interval);
|
||||
~LivePrinter();
|
||||
void add(std::shared_ptr<Track> track);
|
||||
void print(bool reset);
|
||||
void start();
|
||||
|
||||
private:
|
||||
std::chrono::milliseconds m_interval;
|
||||
hailort::EventPtr m_stop_event;
|
||||
std::vector<std::shared_ptr<Track>> m_tracks;
|
||||
std::thread m_thread;
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
#endif /* _HAILO_HAILORTCLI_RUN2_LIVE_PRINTER_HPP_ */
|
||||
33
hailort/hailortcli/run2/network_live_track.cpp
Normal file
33
hailort/hailortcli/run2/network_live_track.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file network_live_track.cpp
|
||||
* @brief Network live track
|
||||
**/
|
||||
|
||||
#include "network_live_track.hpp"
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
#include <sstream>
|
||||
|
||||
NetworkLiveTrack::NetworkLiveTrack(const std::string &name) :
|
||||
m_name(name), m_count(0), m_last_get_time(std::chrono::steady_clock::now())
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t NetworkLiveTrack::get_text(std::stringstream &ss)
|
||||
{
|
||||
auto elapsed_time = std::chrono::steady_clock::now() - m_last_get_time;
|
||||
auto count = m_count.load();
|
||||
|
||||
auto fps = count / std::chrono::duration<double>(elapsed_time).count();
|
||||
ss << fmt::format("{} - fps: {:.2f}\n", m_name, fps);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NetworkLiveTrack::progress()
|
||||
{
|
||||
m_count++;
|
||||
}
|
||||
29
hailort/hailortcli/run2/network_live_track.hpp
Normal file
29
hailort/hailortcli/run2/network_live_track.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file network_live_track.hpp
|
||||
* @brief Network live track
|
||||
**/
|
||||
|
||||
#include "live_printer.hpp"
|
||||
|
||||
#ifndef _HAILO_HAILORTCLI_RUN2_NETWORK_LIVE_TRACK_HPP_
|
||||
#define _HAILO_HAILORTCLI_RUN2_NETWORK_LIVE_TRACK_HPP_
|
||||
|
||||
class NetworkLiveTrack : public LivePrinter::Track
|
||||
{
|
||||
public:
|
||||
NetworkLiveTrack(const std::string &name);
|
||||
virtual ~NetworkLiveTrack() = default;
|
||||
uint32_t get_text(std::stringstream &ss);
|
||||
void progress();
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::atomic<uint32_t> m_count;
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_last_get_time;
|
||||
};
|
||||
|
||||
#endif /* _HAILO_HAILORTCLI_RUN2_NETWORK_LIVE_TRACK_HPP_ */
|
||||
197
hailort/hailortcli/run2/network_runner.cpp
Normal file
197
hailort/hailortcli/run2/network_runner.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file network_runner.cpp
|
||||
* @brief Run network on hailo device
|
||||
**/
|
||||
|
||||
#include "network_runner.hpp"
|
||||
#include "common/async_thread.hpp"
|
||||
#include "hailort_defaults.hpp" //TODO: not API
|
||||
|
||||
using namespace hailort;
|
||||
|
||||
//TODO: duplicated
|
||||
static hailo_status wait_for_threads(std::vector<AsyncThreadPtr<hailo_status>> &threads)
|
||||
{
|
||||
auto last_error_status = HAILO_SUCCESS;
|
||||
for (auto &thread : threads) {
|
||||
auto thread_status = thread->get();
|
||||
if ((HAILO_SUCCESS != thread_status) && (HAILO_STREAM_ABORTED_BY_USER != thread_status)) {
|
||||
last_error_status = thread_status;
|
||||
LOGGER__ERROR("Thread failed with with status {}", thread_status);
|
||||
}
|
||||
}
|
||||
return last_error_status;
|
||||
}
|
||||
|
||||
VStreamParams::VStreamParams() : name(), params(HailoRTDefaults::get_vstreams_params())
|
||||
{
|
||||
}
|
||||
|
||||
NetworkRunner::NetworkRunner(const NetworkParams ¶ms, const std::string &name,
|
||||
std::vector<InputVStream> &&input_vstreams, std::vector<OutputVStream> &&output_vstreams)
|
||||
: m_params(params), m_name(name), m_input_vstreams(std::move(input_vstreams)),
|
||||
m_output_vstreams(std::move(output_vstreams))
|
||||
{
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<NetworkRunner>> NetworkRunner::create_shared(VDevice &vdevice, const NetworkParams ¶ms)
|
||||
{
|
||||
auto hef = Hef::create(params.hef_path);
|
||||
CHECK_EXPECTED(hef);
|
||||
|
||||
// Get NG's name if single
|
||||
auto net_group_name = params.net_group_name;
|
||||
if (net_group_name.empty()) {
|
||||
auto net_groups_names = hef->get_network_groups_names();
|
||||
CHECK_AS_EXPECTED(net_groups_names.size() == 1, HAILO_INVALID_ARGUMENT, "HEF {} doesn't contain a single NetworkGroup. Pass --name", params.hef_path);
|
||||
net_group_name = net_groups_names[0];
|
||||
}
|
||||
|
||||
auto interface = vdevice.get_default_streams_interface();
|
||||
CHECK_EXPECTED(interface, "Failed to get default streams interface");
|
||||
|
||||
auto cfg_params = hef->create_configure_params(*interface, net_group_name);
|
||||
CHECK_EXPECTED(cfg_params);
|
||||
cfg_params->batch_size = params.batch_size;
|
||||
auto cfgr_net_groups = vdevice.configure(hef.value(), {{net_group_name, cfg_params.value()}});
|
||||
CHECK_EXPECTED(cfgr_net_groups);
|
||||
assert(1 == cfgr_net_groups->size());
|
||||
auto cfgr_net_group = cfgr_net_groups.value()[0];
|
||||
|
||||
CHECK_SUCCESS_AS_EXPECTED(cfgr_net_group->set_scheduler_threshold(params.scheduler_threshold));
|
||||
CHECK_SUCCESS_AS_EXPECTED(cfgr_net_group->set_scheduler_timeout(std::chrono::milliseconds(params.scheduler_timeout_ms)));
|
||||
|
||||
std::map<std::string, hailo_vstream_params_t> vstreams_params;
|
||||
for (auto &vstream_params : params.vstream_params) {
|
||||
vstreams_params.emplace(vstream_params.name, vstream_params.params);
|
||||
}
|
||||
auto vstreams = create_vstreams(*cfgr_net_group, vstreams_params);
|
||||
CHECK_EXPECTED(vstreams);
|
||||
|
||||
auto net_runner = make_shared_nothrow<NetworkRunner>(params, net_group_name, std::move(vstreams->first), std::move(vstreams->second));
|
||||
CHECK_NOT_NULL_AS_EXPECTED(net_runner, HAILO_OUT_OF_HOST_MEMORY);
|
||||
return net_runner;
|
||||
}
|
||||
|
||||
hailo_status NetworkRunner::run_input_vstream(InputVStream &vstream)
|
||||
{
|
||||
auto dataset = Buffer::create(vstream.get_frame_size(), 0xAB);
|
||||
CHECK_EXPECTED_AS_STATUS(dataset);
|
||||
auto last_write_time = std::chrono::steady_clock::now();
|
||||
auto framerate_interval = std::chrono::duration<double>(1) / m_params.framerate;
|
||||
while(true) {
|
||||
auto status = vstream.write(MemoryView(dataset.value()));
|
||||
if (status == HAILO_STREAM_ABORTED_BY_USER) {
|
||||
return status;
|
||||
}
|
||||
CHECK_SUCCESS(status);
|
||||
|
||||
if (m_params.framerate != UNLIMITED_FRAMERATE) {
|
||||
auto elapsed_time = std::chrono::steady_clock::now() - last_write_time;
|
||||
std::this_thread::sleep_for(framerate_interval - elapsed_time);
|
||||
last_write_time = std::chrono::steady_clock::now();
|
||||
}
|
||||
}
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status NetworkRunner::run_output_vstream(OutputVStream &vstream, bool first, std::shared_ptr<NetworkLiveTrack> net_live_track)
|
||||
{
|
||||
auto result = Buffer::create(vstream.get_frame_size());
|
||||
CHECK_EXPECTED_AS_STATUS(result);
|
||||
while(true) {
|
||||
auto status = vstream.read(MemoryView(result.value()));
|
||||
if (status == HAILO_STREAM_ABORTED_BY_USER) {
|
||||
return status;
|
||||
}
|
||||
CHECK_SUCCESS(status);
|
||||
if (first) {
|
||||
net_live_track->progress();
|
||||
}
|
||||
}
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status NetworkRunner::run(Event &shutdown_event, LivePrinter &live_printer)
|
||||
{
|
||||
std::vector<AsyncThreadPtr<hailo_status>> threads;
|
||||
for (auto &input_vstream : m_input_vstreams) {
|
||||
threads.emplace_back(std::make_unique<AsyncThread<hailo_status>>([this, &input_vstream](){
|
||||
return run_input_vstream(input_vstream);
|
||||
}));
|
||||
}
|
||||
|
||||
auto net_live_track = std::make_shared<NetworkLiveTrack>(m_name);
|
||||
live_printer.add(net_live_track);//support progress over multiple outputs
|
||||
|
||||
bool first = true;//TODO: check with multiple outputs
|
||||
for (auto &output_vstream : m_output_vstreams) {
|
||||
threads.emplace_back(std::make_unique<AsyncThread<hailo_status>>([&output_vstream, first, net_live_track](){
|
||||
return run_output_vstream(output_vstream, first, net_live_track);
|
||||
}));
|
||||
first = false;
|
||||
}
|
||||
|
||||
//TODO: signal a barrier that we should start infer and timer. return threads and move stop outside?
|
||||
CHECK_SUCCESS(shutdown_event.wait(HAILO_INFINITE_TIMEOUT));
|
||||
stop();
|
||||
return wait_for_threads(threads);
|
||||
}
|
||||
|
||||
void NetworkRunner::stop()
|
||||
{
|
||||
for (auto &input_vstream : m_input_vstreams) {
|
||||
(void) input_vstream.abort();
|
||||
}
|
||||
for (auto &output_vstream : m_output_vstreams) {
|
||||
(void) output_vstream.abort();
|
||||
}
|
||||
}
|
||||
|
||||
Expected<std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>> NetworkRunner::create_vstreams(
|
||||
ConfiguredNetworkGroup &net_group, const std::map<std::string, hailo_vstream_params_t> ¶ms)
|
||||
{//TODO: support network name
|
||||
size_t match_count = 0;
|
||||
|
||||
std::map<std::string, hailo_vstream_params_t> input_vstreams_params;
|
||||
auto input_vstreams_info = net_group.get_input_vstream_infos();
|
||||
CHECK_EXPECTED(input_vstreams_info);
|
||||
for (auto &input_vstream_info : input_vstreams_info.value()) {
|
||||
auto elem_it = params.find(input_vstream_info.name);
|
||||
if (elem_it != params.end()) {
|
||||
input_vstreams_params.emplace(input_vstream_info.name, elem_it->second);
|
||||
match_count++;
|
||||
}
|
||||
else {
|
||||
input_vstreams_params.emplace(input_vstream_info.name, HailoRTDefaults::get_vstreams_params());
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, hailo_vstream_params_t> output_vstreams_params;
|
||||
auto output_vstreams_info = net_group.get_output_vstream_infos();
|
||||
CHECK_EXPECTED(output_vstreams_info);
|
||||
for (auto &output_vstream_info : output_vstreams_info.value()) {
|
||||
auto elem_it = params.find(output_vstream_info.name);
|
||||
if (elem_it != params.end()) {
|
||||
output_vstreams_params.emplace(output_vstream_info.name, elem_it->second);
|
||||
match_count++;
|
||||
}
|
||||
else {
|
||||
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");
|
||||
|
||||
auto input_vstreams = VStreamsBuilder::create_input_vstreams(net_group, input_vstreams_params);
|
||||
CHECK_EXPECTED(input_vstreams);
|
||||
|
||||
auto output_vstreams = VStreamsBuilder::create_output_vstreams(net_group, output_vstreams_params);
|
||||
CHECK_EXPECTED(output_vstreams);
|
||||
|
||||
return {{input_vstreams.release(), output_vstreams.release()}};//TODO: move? copy elision?
|
||||
}
|
||||
72
hailort/hailortcli/run2/network_runner.hpp
Normal file
72
hailort/hailortcli/run2/network_runner.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file network_runner.hpp
|
||||
* @brief Run network on hailo device
|
||||
**/
|
||||
|
||||
#ifndef _HAILO_HAILORTCLI_RUN2_NETWORK_RUNNER_HPP_
|
||||
#define _HAILO_HAILORTCLI_RUN2_NETWORK_RUNNER_HPP_
|
||||
|
||||
#include "hailo/vdevice.hpp"
|
||||
#include "hailo/vstream.hpp"
|
||||
#include "hailo/event.hpp"
|
||||
#include "hailo/network_group.hpp"
|
||||
#include "hailo/expected.hpp"
|
||||
|
||||
#include "live_printer.hpp"
|
||||
#include "network_live_track.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
constexpr uint32_t UNLIMITED_FRAMERATE = 0;
|
||||
|
||||
struct VStreamParams
|
||||
{
|
||||
VStreamParams();
|
||||
|
||||
std::string name;
|
||||
hailo_vstream_params_t params;
|
||||
};
|
||||
|
||||
struct NetworkParams
|
||||
{
|
||||
std::string hef_path;
|
||||
std::string net_group_name;
|
||||
std::vector<VStreamParams> vstream_params;
|
||||
|
||||
// Network parameters
|
||||
uint16_t batch_size;
|
||||
uint32_t scheduler_threshold;
|
||||
uint32_t scheduler_timeout_ms;
|
||||
|
||||
// Run parameters
|
||||
uint32_t framerate;
|
||||
};
|
||||
|
||||
class NetworkRunner
|
||||
{
|
||||
public:
|
||||
NetworkRunner(const NetworkParams ¶ms, const std::string &name,
|
||||
std::vector<hailort::InputVStream> &&input_vstreams, std::vector<hailort::OutputVStream> &&output_vstreams);
|
||||
static hailort::Expected<std::shared_ptr<NetworkRunner>> create_shared(hailort::VDevice &vdevice, const NetworkParams ¶ms);
|
||||
hailo_status run(hailort::Event &shutdown_event, LivePrinter &live_printer);
|
||||
void stop();
|
||||
|
||||
private:
|
||||
static hailort::Expected<std::pair<std::vector<hailort::InputVStream>, std::vector<hailort::OutputVStream>>> create_vstreams(
|
||||
hailort::ConfiguredNetworkGroup &net_group, const std::map<std::string, hailo_vstream_params_t> ¶ms);
|
||||
hailo_status run_input_vstream(hailort::InputVStream &vstream);
|
||||
static hailo_status run_output_vstream(hailort::OutputVStream &vstream, bool first, std::shared_ptr<NetworkLiveTrack> net_live_track);
|
||||
|
||||
|
||||
const NetworkParams &m_params;//TODO: copy instead of ref?
|
||||
std::string m_name;
|
||||
std::vector<hailort::InputVStream> m_input_vstreams;
|
||||
std::vector<hailort::OutputVStream> m_output_vstreams;
|
||||
};
|
||||
|
||||
#endif /* _HAILO_HAILORTCLI_RUN2_NETWORK_RUNNER_HPP_ */
|
||||
348
hailort/hailortcli/run2/run2_command.cpp
Normal file
348
hailort/hailortcli/run2/run2_command.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file run2_command.cpp
|
||||
* @brief Run inference on hailo device
|
||||
**/
|
||||
|
||||
#include "run2_command.hpp"
|
||||
#include "live_printer.hpp"
|
||||
#include "timer_live_track.hpp"
|
||||
#include "network_runner.hpp"
|
||||
|
||||
#include "common/async_thread.hpp"
|
||||
#include "hailo/vdevice.hpp"
|
||||
#include "hailo/hef.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
using namespace hailort;
|
||||
|
||||
constexpr uint32_t DEFAULT_TIME_TO_RUN_SECONDS = 5;
|
||||
|
||||
/** VStreamNameValidator */
|
||||
class VStreamNameValidator : public CLI::Validator {
|
||||
public:
|
||||
VStreamNameValidator(const CLI::Option *hef_path_option, const CLI::Option *net_group_name_option);
|
||||
private:
|
||||
static std::vector<std::string> get_values(const std::string &hef_path, const std::string &net_group_name);
|
||||
};
|
||||
|
||||
VStreamNameValidator::VStreamNameValidator(const CLI::Option *hef_path_option, const CLI::Option *net_group_name_option) : Validator("VSTREAM") {
|
||||
func_ = [](std::string&) {
|
||||
//TODO: support?
|
||||
return std::string();
|
||||
};
|
||||
autocomplete_func_ = [hef_path_option, net_group_name_option](const std::string&) {
|
||||
// TODO: remove existing names from prev user input
|
||||
return get_values(hef_path_option->as<std::string>(), net_group_name_option->as<std::string>());
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<std::string> VStreamNameValidator::get_values(const std::string &hef_path, const std::string &net_group_name)
|
||||
{
|
||||
auto hef = Hef::create(hef_path);
|
||||
if (!hef.has_value()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// TODO: duplicate
|
||||
auto actual_net_group_name = net_group_name;
|
||||
if (actual_net_group_name.empty()) {
|
||||
auto net_groups_names = hef->get_network_groups_names();
|
||||
if (net_groups_names.size() != 1) {
|
||||
return {};
|
||||
}
|
||||
actual_net_group_name = net_groups_names[0];
|
||||
}
|
||||
|
||||
auto vstreams_info = hef->get_all_vstream_infos(actual_net_group_name);
|
||||
if (!vstreams_info.has_value()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> names;
|
||||
for (auto &vstream_info : vstreams_info.value()) {
|
||||
names.emplace_back(vstream_info.name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/** VStreamApp */
|
||||
class VStreamApp : public CLI::App
|
||||
{
|
||||
public:
|
||||
VStreamApp(const std::string &description, const std::string &name, CLI::Option *hef_path_option, CLI::Option *net_group_name_option);
|
||||
const VStreamParams& get_params();
|
||||
|
||||
private:
|
||||
CLI::Option* add_flag_callback(CLI::App *app, const std::string &name, const std::string &description,
|
||||
std::function<void(bool)> function);
|
||||
|
||||
VStreamParams m_params;
|
||||
};
|
||||
|
||||
VStreamApp::VStreamApp(const std::string &description, const std::string &name, CLI::Option *hef_path_option,
|
||||
CLI::Option *net_group_name_option) : CLI::App(description, name), m_params()
|
||||
{
|
||||
add_option("name", m_params.name, "vStream name")
|
||||
->check(VStreamNameValidator(hef_path_option, net_group_name_option));
|
||||
|
||||
auto format_opt_group = add_option_group("Format");
|
||||
format_opt_group->add_option("--type", m_params.params.user_buffer_format.type, "Format type")
|
||||
->transform(HailoCheckedTransformer<hailo_format_type_t>({
|
||||
{ "auto", HAILO_FORMAT_TYPE_AUTO },
|
||||
{ "uint8", HAILO_FORMAT_TYPE_UINT8 },
|
||||
{ "uint16", HAILO_FORMAT_TYPE_UINT16 },
|
||||
{ "float32", HAILO_FORMAT_TYPE_FLOAT32 }
|
||||
}))
|
||||
->default_val("auto");
|
||||
|
||||
format_opt_group->add_option("--order", m_params.params.user_buffer_format.order, "Format order")
|
||||
->transform(HailoCheckedTransformer<hailo_format_order_t>({
|
||||
{ "auto", HAILO_FORMAT_ORDER_AUTO },
|
||||
{ "nhwc", HAILO_FORMAT_ORDER_NHWC },
|
||||
{ "nhcw",HAILO_FORMAT_ORDER_NHCW },
|
||||
{ "fcr", HAILO_FORMAT_ORDER_FCR },
|
||||
{ "f8cr", HAILO_FORMAT_ORDER_F8CR },
|
||||
{ "nhw", HAILO_FORMAT_ORDER_NHW },
|
||||
{ "nc", HAILO_FORMAT_ORDER_NC },
|
||||
{ "bayer_rgb", HAILO_FORMAT_ORDER_BAYER_RGB },
|
||||
{ "12_bit_bayer_rgb", HAILO_FORMAT_ORDER_12_BIT_BAYER_RGB },
|
||||
{ "hailo_nms", HAILO_FORMAT_ORDER_HAILO_NMS },
|
||||
{ "nchw", HAILO_FORMAT_ORDER_NCHW },
|
||||
{ "yuy2", HAILO_FORMAT_ORDER_YUY2 },
|
||||
{ "nv12", HAILO_FORMAT_ORDER_NV12 },
|
||||
{ "nv21", HAILO_FORMAT_ORDER_NV21 }
|
||||
}))
|
||||
->default_val("auto");
|
||||
|
||||
add_flag_callback(format_opt_group, "-q,--quantized,!--no-quantized", "Whether or not data is quantized",
|
||||
[this](bool result){
|
||||
m_params.params.user_buffer_format.flags = result ?
|
||||
m_params.params.user_buffer_format.flags | HAILO_FORMAT_FLAGS_QUANTIZED :
|
||||
static_cast<hailo_format_flags_t>(m_params.params.user_buffer_format.flags & (~HAILO_FORMAT_FLAGS_QUANTIZED));})
|
||||
->run_callback_for_default()
|
||||
->default_val(true); // default_val() must be after run_callback_for_default()
|
||||
}
|
||||
|
||||
const VStreamParams& VStreamApp::get_params()
|
||||
{
|
||||
//TODO: instead of copy do a move + call reset()? change func name to move_params? same for NetworkParams/NetworkApp class
|
||||
return m_params;
|
||||
}
|
||||
|
||||
CLI::Option* VStreamApp::add_flag_callback(CLI::App *app, const std::string &name, const std::string &description,
|
||||
std::function<void(bool)> function)
|
||||
{
|
||||
// get_option doesn't support multiple names so taking the first one
|
||||
auto first_name = name.substr(0, name.find(','));
|
||||
auto wrap_function = [app, function, first_name](std::int64_t){function(app->get_option(first_name)->as<bool>());};
|
||||
return app->add_flag_function(name, wrap_function, description);
|
||||
}
|
||||
|
||||
/** NetworkGroupNameValidator */
|
||||
class NetworkGroupNameValidator : public CLI::Validator {
|
||||
public:
|
||||
NetworkGroupNameValidator(const CLI::Option *hef_path_option);
|
||||
};
|
||||
|
||||
NetworkGroupNameValidator::NetworkGroupNameValidator(const CLI::Option *hef_path_option) : Validator("NETWORK_GROUP") {
|
||||
func_ = [](std::string&) {
|
||||
//TODO: support?
|
||||
return std::string();
|
||||
};
|
||||
autocomplete_func_ = [hef_path_option](const std::string&) -> std::vector<std::string>{
|
||||
auto hef = Hef::create(hef_path_option->as<std::string>());
|
||||
if (!hef.has_value()) {
|
||||
return {};
|
||||
}
|
||||
return hef->get_network_groups_names();
|
||||
};
|
||||
}
|
||||
|
||||
/** NetworkApp */
|
||||
class NetworkApp : public CLI::App
|
||||
{
|
||||
public:
|
||||
NetworkApp(const std::string &description, const std::string &name);
|
||||
const NetworkParams& get_params();
|
||||
|
||||
private:
|
||||
void add_vstream_app_subcom(CLI::Option *hef_path_option, CLI::Option *net_group_name_option);
|
||||
NetworkParams m_params;
|
||||
};
|
||||
|
||||
NetworkApp::NetworkApp(const std::string &description, const std::string &name) : CLI::App(description, name), m_params()
|
||||
{
|
||||
auto hef_path_option = add_option("hef", m_params.hef_path, "HEF file path")->check(CLI::ExistingFile);
|
||||
auto net_group_name_option = add_option("--name", m_params.net_group_name, "Network group name")
|
||||
->default_val("")
|
||||
->needs(hef_path_option)
|
||||
->check(NetworkGroupNameValidator(hef_path_option));
|
||||
// NOTE: callbacks/params aren't called/updated before auto-completion (even after changing the order in App.hpp - at least for 2 jumps)
|
||||
auto net_params = add_option_group("Network Group Parameters");
|
||||
net_params->add_option("--batch-size", m_params.batch_size, "Batch size")->default_val(HAILO_DEFAULT_BATCH_SIZE);
|
||||
net_params->add_option("--scheduler-threshold", m_params.scheduler_threshold, "Scheduler threshold")->default_val(0);
|
||||
net_params->add_option("--scheduler-timeout", m_params.scheduler_timeout_ms, "Scheduler timeout in milliseconds")->default_val(0);
|
||||
|
||||
auto run_params = add_option_group("Run Parameters");
|
||||
run_params->add_option("--framerate", m_params.framerate, "Input vStreams framerate")->default_val(UNLIMITED_FRAMERATE);
|
||||
|
||||
add_vstream_app_subcom(hef_path_option, net_group_name_option);
|
||||
}
|
||||
|
||||
void NetworkApp::add_vstream_app_subcom(CLI::Option *hef_path_option, CLI::Option *net_group_name_option)
|
||||
{
|
||||
auto vstream_app = std::make_shared<VStreamApp>("Set vStream", "set-vstream", hef_path_option, net_group_name_option);
|
||||
vstream_app->immediate_callback();
|
||||
vstream_app->callback([this, vstream_app, hef_path_option, net_group_name_option]() {
|
||||
m_params.vstream_params.push_back(vstream_app->get_params());
|
||||
|
||||
// Throw an error if anything is left over and should not be.
|
||||
_process_extras();
|
||||
|
||||
// NOTE: calling "net_app->clear(); m_params = NetworkParams();" is not sufficient because default values
|
||||
// need to be re-set. we can override clear and reset them but there might be other issues as well
|
||||
// and this one feels less hacky ATM
|
||||
remove_subcommand(vstream_app.get());
|
||||
// Remove from parsed_subcommands_ as well (probably a bug in CLI11)
|
||||
parsed_subcommands_.erase(std::remove_if(
|
||||
parsed_subcommands_.begin(), parsed_subcommands_.end(),
|
||||
[vstream_app](auto x){return x == vstream_app.get();}),
|
||||
parsed_subcommands_.end());
|
||||
add_vstream_app_subcom(hef_path_option, net_group_name_option);
|
||||
});
|
||||
|
||||
// Must set fallthrough to support nested repeated subcommands.
|
||||
vstream_app->fallthrough();
|
||||
add_subcommand(vstream_app);
|
||||
}
|
||||
|
||||
const NetworkParams& NetworkApp::get_params()
|
||||
{
|
||||
return m_params;
|
||||
}
|
||||
|
||||
/** Run2 */
|
||||
class Run2 : public CLI::App
|
||||
{
|
||||
public:
|
||||
Run2();
|
||||
|
||||
const std::vector<NetworkParams>& get_network_params();
|
||||
std::chrono::seconds get_time_to_run();
|
||||
|
||||
private:
|
||||
void add_net_app_subcom();
|
||||
std::vector<NetworkParams> m_network_params;
|
||||
uint32_t m_time_to_run;
|
||||
};
|
||||
|
||||
Run2::Run2() : CLI::App("Run networks (preview)", "run2")
|
||||
{
|
||||
add_net_app_subcom();
|
||||
add_option("-t,--time-to-run", m_time_to_run, "Time to run (seconds)")
|
||||
->default_val(DEFAULT_TIME_TO_RUN_SECONDS)
|
||||
->check(CLI::PositiveNumber);
|
||||
}
|
||||
|
||||
void Run2::add_net_app_subcom()
|
||||
{
|
||||
auto net_app = std::make_shared<NetworkApp>("Set network", "set-net");
|
||||
net_app->immediate_callback();
|
||||
net_app->callback([this, net_app]() {
|
||||
m_network_params.push_back(net_app->get_params());
|
||||
|
||||
// Throw an error if anything is left over and should not be.
|
||||
_process_extras();
|
||||
|
||||
// NOTE: calling "net_app->clear(); m_params = NetworkParams();" is not sufficient because default values
|
||||
// need to be re-set. we can override clear and reset them but there might be other issues as well
|
||||
// and this one feels less hacky ATM
|
||||
remove_subcommand(net_app.get());
|
||||
// Remove from parsed_subcommands_ as well (probably a bug in CLI11)
|
||||
parsed_subcommands_.erase(std::remove_if(
|
||||
parsed_subcommands_.begin(), parsed_subcommands_.end(),
|
||||
[net_app](auto x){return x == net_app.get();}),
|
||||
parsed_subcommands_.end());
|
||||
add_net_app_subcom();
|
||||
});
|
||||
// NOTE: fallthrough() is not a must here but it is also not working (causing only a single vstream param
|
||||
// instead of >1). Debug - App.hpp::void _parse(std::vector<std::string> &args)
|
||||
add_subcommand(net_app);
|
||||
}
|
||||
|
||||
const std::vector<NetworkParams>& Run2::get_network_params()
|
||||
{
|
||||
return m_network_params;
|
||||
}
|
||||
|
||||
std::chrono::seconds Run2::get_time_to_run()
|
||||
{
|
||||
return std::chrono::seconds(m_time_to_run);
|
||||
}
|
||||
|
||||
/** Run2Command */
|
||||
Run2Command::Run2Command(CLI::App &parent_app) : Command(parent_app.add_subcommand(std::make_shared<Run2>()))
|
||||
{
|
||||
}
|
||||
|
||||
static hailo_status wait_for_threads(std::vector<AsyncThreadPtr<hailo_status>> &threads)
|
||||
{
|
||||
auto last_error_status = HAILO_SUCCESS;
|
||||
for (auto& thread : threads) {
|
||||
auto thread_status = thread->get();
|
||||
if ((HAILO_SUCCESS != thread_status) && (HAILO_STREAM_ABORTED_BY_USER != thread_status)) {
|
||||
last_error_status = thread_status;
|
||||
LOGGER__ERROR("Thread failed with with status {}", thread_status);
|
||||
}
|
||||
}
|
||||
return last_error_status;
|
||||
}
|
||||
|
||||
hailo_status Run2Command::execute()
|
||||
{
|
||||
Run2 *app = reinterpret_cast<Run2*>(m_app);
|
||||
|
||||
if (0 == app->get_network_params().size()) {
|
||||
LOGGER__ERROR("Nothing to run");
|
||||
return HAILO_INVALID_OPERATION;
|
||||
}
|
||||
if (1 == app->get_network_params().size()) {
|
||||
LOGGER__WARN("\"hailortcli run2\" is in preview. It is recommended to use \"hailortcli run\" command for a single network group");
|
||||
}
|
||||
|
||||
// TODO: support multi-device. maybe get all by default?
|
||||
hailo_vdevice_params_t vdevice_params = {};
|
||||
CHECK_SUCCESS(hailo_init_vdevice_params(&vdevice_params));
|
||||
auto vdevice = VDevice::create(vdevice_params);
|
||||
CHECK_EXPECTED_AS_STATUS(vdevice);
|
||||
|
||||
// create network runners
|
||||
std::vector<std::shared_ptr<NetworkRunner>> net_runners;
|
||||
for (auto &net_params : app->get_network_params()) {
|
||||
auto net_runner = NetworkRunner::create_shared(*vdevice->get(), net_params);
|
||||
CHECK_EXPECTED_AS_STATUS(net_runner);
|
||||
net_runners.emplace_back(net_runner.release());
|
||||
}
|
||||
LivePrinter live_printer(std::chrono::seconds(1));
|
||||
live_printer.add(std::make_shared<TimerLiveTrack>(app->get_time_to_run()));
|
||||
|
||||
auto shutdown_event = Event::create(Event::State::not_signalled);
|
||||
CHECK_EXPECTED_AS_STATUS(shutdown_event);
|
||||
std::vector<AsyncThreadPtr<hailo_status>> threads;
|
||||
for (auto &net_runner : net_runners) {
|
||||
threads.emplace_back(std::make_unique<AsyncThread<hailo_status>>([&net_runner, &shutdown_event, &live_printer](){
|
||||
return net_runner->run(shutdown_event.value(), live_printer);
|
||||
}));
|
||||
}
|
||||
// TODO: wait for all nets before starting timer. start() should update TimerLiveTrack to start. or maybe append here but first in vector...
|
||||
live_printer.start();
|
||||
std::this_thread::sleep_for(app->get_time_to_run());
|
||||
shutdown_event->signal();
|
||||
return wait_for_threads(threads);
|
||||
}
|
||||
23
hailort/hailortcli/run2/run2_command.hpp
Normal file
23
hailort/hailortcli/run2/run2_command.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file run2_command.hpp
|
||||
* @brief Run inference on hailo device
|
||||
**/
|
||||
|
||||
#ifndef _HAILO_HAILORTCLI_RUN2_RUN2_COMMAND_HPP_
|
||||
#define _HAILO_HAILORTCLI_RUN2_RUN2_COMMAND_HPP_
|
||||
|
||||
#include "../command.hpp"
|
||||
|
||||
class Run2Command : public Command {
|
||||
public:
|
||||
explicit Run2Command(CLI::App &parent_app);
|
||||
|
||||
hailo_status execute() override;
|
||||
private:
|
||||
};
|
||||
|
||||
#endif /* _HAILO_HAILORTCLI_RUN2_RUN2_COMMAND_HPP_ */
|
||||
31
hailort/hailortcli/run2/timer_live_track.cpp
Normal file
31
hailort/hailortcli/run2/timer_live_track.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file timer_live_track.cpp
|
||||
* @brief Timer live track
|
||||
**/
|
||||
|
||||
#include "timer_live_track.hpp"
|
||||
#include "../common.hpp"
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
#include <sstream>
|
||||
|
||||
TimerLiveTrack::TimerLiveTrack(std::chrono::milliseconds duration) :
|
||||
m_duration(duration), m_start(std::chrono::steady_clock::now())
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t TimerLiveTrack::get_text(std::stringstream &ss)
|
||||
{
|
||||
static const uint32_t MAX_PROGRESS_BAR_WIDTH = 20;
|
||||
auto elapsed_time = std::chrono::steady_clock::now() - m_start;
|
||||
auto eta = std::chrono::seconds(std::max<int32_t>(0, static_cast<int32_t>(std::round(std::chrono::duration<double>(m_duration - elapsed_time).count())))); // std::chrono::round is from C++17
|
||||
auto elapsed_percentage = std::min<uint32_t>(100, static_cast<uint32_t>(std::round(std::chrono::duration<double>(100 * elapsed_time / m_duration).count())));
|
||||
auto progress_bar_width = std::max<uint32_t>(1, std::min<uint32_t>(MAX_PROGRESS_BAR_WIDTH,
|
||||
static_cast<uint32_t>(std::round(std::chrono::duration<double>(MAX_PROGRESS_BAR_WIDTH * elapsed_time / m_duration).count()))));
|
||||
|
||||
ss << fmt::format("[{:=>{}}{:{}}] {:>3}% {}\n", '>', progress_bar_width, "", MAX_PROGRESS_BAR_WIDTH - progress_bar_width, elapsed_percentage, CliCommon::duration_to_string(eta));
|
||||
return 1;
|
||||
}
|
||||
27
hailort/hailortcli/run2/timer_live_track.hpp
Normal file
27
hailort/hailortcli/run2/timer_live_track.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file timer_live_track.hpp
|
||||
* @brief Timer live track
|
||||
**/
|
||||
|
||||
#include "live_printer.hpp"
|
||||
|
||||
#ifndef _HAILO_HAILORTCLI_RUN2_TIMER_LIVE_TRACK_HPP_
|
||||
#define _HAILO_HAILORTCLI_RUN2_TIMER_LIVE_TRACK_HPP_
|
||||
|
||||
class TimerLiveTrack : public LivePrinter::Track
|
||||
{
|
||||
public:
|
||||
TimerLiveTrack(std::chrono::milliseconds duration);
|
||||
virtual ~TimerLiveTrack() = default;
|
||||
virtual uint32_t get_text(std::stringstream &ss) override;
|
||||
|
||||
private:
|
||||
std::chrono::milliseconds m_duration;
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_start;
|
||||
};
|
||||
|
||||
#endif /* _HAILO_HAILORTCLI_RUN2_TIMER_LIVE_TRACK_HPP_ */
|
||||
@@ -19,6 +19,7 @@
|
||||
#endif
|
||||
#include "common.hpp"
|
||||
|
||||
#include "common/string_utils.hpp"
|
||||
#include "common/file_utils.hpp"
|
||||
#include "common/async_thread.hpp"
|
||||
#include "common/barrier.hpp"
|
||||
@@ -29,8 +30,11 @@
|
||||
#include "hailo/vstream.hpp"
|
||||
#include "hailo/vdevice.hpp"
|
||||
|
||||
#include "spdlog/fmt/fmt.h"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
#include <signal.h>
|
||||
#include <condition_variable>
|
||||
std::condition_variable wait_for_exit_cv;
|
||||
@@ -48,6 +52,9 @@ constexpr std::chrono::milliseconds TIME_TO_WAIT_FOR_CONFIG(300);
|
||||
constexpr std::chrono::milliseconds TIME_TO_WAIT_FOR_CONFIG(30000);
|
||||
#define HAILORTCLI_DEFAULT_VSTREAM_TIMEOUT_MS (HAILO_DEFAULT_VSTREAM_TIMEOUT_MS * 100)
|
||||
#endif /* ifndef HAILO_EMULATOR */
|
||||
static const char *RUNTIME_DATA_OUTPUT_PATH_HEF_PLACE_HOLDER = "<hef>";
|
||||
static const char *RUNTIME_DATA_BATCH_TO_MEASURE_OPT_LAST = "last";
|
||||
static const char *RUNTIME_DATA_BATCH_TO_MEASURE_OPT_DEFAULT = "2";
|
||||
|
||||
#ifndef _MSC_VER
|
||||
void user_signal_handler_func(int signum)
|
||||
@@ -86,7 +93,17 @@ bool should_measure_pipeline_stats(const inference_runner_params& params)
|
||||
bool use_batch_to_measure_opt(const inference_runner_params& params)
|
||||
{
|
||||
return params.runtime_data.collect_runtime_data &&
|
||||
(params.runtime_data.batch_to_measure != RUNTIME_DATA_IGNORE_BATCH_TO_MEASURE_OPT);
|
||||
(params.runtime_data.batch_to_measure_str != RUNTIME_DATA_BATCH_TO_MEASURE_OPT_LAST);
|
||||
}
|
||||
|
||||
// We assume that hef_place_holder_regex is valid
|
||||
std::string format_runtime_data_output_path(const std::string &base_output_path, const std::string &hef_path,
|
||||
const std::string &hef_place_holder_regex = RUNTIME_DATA_OUTPUT_PATH_HEF_PLACE_HOLDER,
|
||||
const std::string &hef_suffix = ".hef")
|
||||
{
|
||||
const auto hef_basename = Filesystem::basename(hef_path);
|
||||
const auto hef_no_suffix = Filesystem::remove_suffix(hef_basename, hef_suffix);
|
||||
return std::regex_replace(base_output_path, std::regex(hef_place_holder_regex), hef_no_suffix);
|
||||
}
|
||||
|
||||
static void add_run_command_params(CLI::App *run_subcommand, inference_runner_params& params)
|
||||
@@ -118,7 +135,7 @@ static void add_run_command_params(CLI::App *run_subcommand, inference_runner_pa
|
||||
auto total_batch_size = run_subcommand->add_option("--batch-size", params.batch_size,
|
||||
"Inference batch (should be a divisor of --frames-count if provided).\n"
|
||||
"This batch applies to the whole network_group. for differential batch per network, see --net-batch-size")
|
||||
->check(CLI::PositiveNumber)
|
||||
->check(CLI::NonNegativeNumber)
|
||||
->default_val(HAILO_DEFAULT_BATCH_SIZE);
|
||||
|
||||
run_subcommand->add_option("--net-batch-size", params.batch_per_network,
|
||||
@@ -208,16 +225,16 @@ static void add_run_command_params(CLI::App *run_subcommand, inference_runner_pa
|
||||
auto *collect_runtime_data_subcommand = run_subcommand->add_subcommand("collect-runtime-data",
|
||||
"Collect runtime data to be used by the Profiler");
|
||||
static const char *JSON_SUFFIX = ".json";
|
||||
collect_runtime_data_subcommand->add_option("--output-path",
|
||||
params.runtime_data.runtime_data_output_path, "Runtime data output file path")
|
||||
->default_val("runtime_data.json")
|
||||
collect_runtime_data_subcommand->add_option("--output-path", params.runtime_data.runtime_data_output_path,
|
||||
fmt::format("Runtime data output file path\n'{}' will be replaced with the current running hef",
|
||||
RUNTIME_DATA_OUTPUT_PATH_HEF_PLACE_HOLDER))
|
||||
->default_val(fmt::format("runtime_data_{}.json", RUNTIME_DATA_OUTPUT_PATH_HEF_PLACE_HOLDER))
|
||||
->check(FileSuffixValidator(JSON_SUFFIX));
|
||||
std::stringstream batch_to_measure_help;
|
||||
batch_to_measure_help << "Batch to be measured " << std::endl
|
||||
<< "The last batch will be measured if " << RUNTIME_DATA_IGNORE_BATCH_TO_MEASURE_OPT << " is provided";
|
||||
collect_runtime_data_subcommand->add_option("--batch-to-measure",
|
||||
params.runtime_data.batch_to_measure, batch_to_measure_help.str())
|
||||
->default_val(RUNTIME_DATA_DEFAULT_BATCH_TO_MEASURE_OPT);
|
||||
collect_runtime_data_subcommand->add_option("--batch-to-measure", params.runtime_data.batch_to_measure_str,
|
||||
fmt::format("Batch to be measured (non-negative integer)\nThe last batch will be measured if '{}' is provided",
|
||||
RUNTIME_DATA_BATCH_TO_MEASURE_OPT_LAST))
|
||||
->default_val(RUNTIME_DATA_BATCH_TO_MEASURE_OPT_DEFAULT)
|
||||
->check(UintOrKeywordValidator(RUNTIME_DATA_BATCH_TO_MEASURE_OPT_LAST));
|
||||
collect_runtime_data_subcommand->parse_complete_callback([¶ms]() {
|
||||
// If this subcommand was parsed, then we need to download runtime_data
|
||||
params.runtime_data.collect_runtime_data = true;
|
||||
@@ -257,7 +274,7 @@ static void add_run_command_params(CLI::App *run_subcommand, inference_runner_pa
|
||||
"--sampling-period requires --measure-power or --measure-current");
|
||||
PARSE_CHECK(power_averaging_factor->empty() || has_oneof_measure_flags,
|
||||
"--averaging-period factor --measure-power or --measure-current");
|
||||
PARSE_CHECK(((0 != params.time_to_run) || (0 == (params.frames_count % params.batch_size))),
|
||||
PARSE_CHECK(((0 != params.time_to_run) || (HAILO_DEFAULT_BATCH_SIZE == params.batch_size) || (0 == (params.frames_count % params.batch_size))),
|
||||
"--batch-size should be a divisor of --frames-count if provided");
|
||||
// TODO HRT-5363 support multiple devices
|
||||
PARSE_CHECK((params.vdevice_params.device_count == 1) || params.csv_output.empty() ||
|
||||
@@ -278,12 +295,15 @@ static void add_run_command_params(CLI::App *run_subcommand, inference_runner_pa
|
||||
PARSE_CHECK(!(params.vdevice_params.multi_process_service && is_hw_only),
|
||||
"--hw-only mode is not supported for multi process service");
|
||||
|
||||
if (use_batch_to_measure_opt(params) &&
|
||||
(0 != params.frames_count) && (params.frames_count < params.runtime_data.batch_to_measure)) {
|
||||
if (use_batch_to_measure_opt(params)) {
|
||||
// This cast is ok because we validate params.runtime_data.batch_to_measure_str with UintOrKeywordValidator
|
||||
params.runtime_data.batch_to_measure = static_cast<uint16_t>(std::stoi(params.runtime_data.batch_to_measure_str));
|
||||
if ((0 != params.frames_count) && (params.frames_count < params.runtime_data.batch_to_measure)) {
|
||||
LOGGER__WARNING("--frames-count ({}) is smaller than --batch-to-measure ({}), "
|
||||
"hence timestamps will not be updated in runtime data", params.frames_count,
|
||||
params.runtime_data.batch_to_measure);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -385,7 +405,7 @@ hailo_status send_loop(const inference_runner_params ¶ms, SendObject &send_o
|
||||
auto status = send_object.write(MemoryView(
|
||||
const_cast<uint8_t*>(input_buffer->data()) + offset,
|
||||
send_object.get_frame_size()));
|
||||
if (HAILO_STREAM_INTERNAL_ABORT == status) {
|
||||
if (HAILO_STREAM_ABORTED_BY_USER == status) {
|
||||
LOGGER__DEBUG("Input stream was aborted!");
|
||||
return status;
|
||||
}
|
||||
@@ -401,7 +421,7 @@ hailo_status send_loop(const inference_runner_params ¶ms, SendObject &send_o
|
||||
template<typename RecvObject>
|
||||
hailo_status recv_loop(const inference_runner_params ¶ms, RecvObject &recv_object,
|
||||
std::shared_ptr<NetworkProgressBar> progress_bar, Barrier &barrier, LatencyMeter &overall_latency_meter,
|
||||
std::map<std::string, BufferPtr> &dst_data, std::atomic_size_t &received_frames_count, uint32_t output_idx, bool show_progress,
|
||||
std::map<std::string, BufferPtr> &dst_data, std::atomic_size_t &received_frames_count, bool show_progress,
|
||||
uint16_t batch_size)
|
||||
{
|
||||
uint32_t num_of_batches = ((0 == params.time_to_run) ? (params.frames_count / batch_size) : UINT32_MAX);
|
||||
@@ -410,13 +430,14 @@ hailo_status recv_loop(const inference_runner_params ¶ms, RecvObject &recv_o
|
||||
barrier.arrive_and_wait();
|
||||
}
|
||||
for (int j = 0; j < batch_size; j++) {
|
||||
auto status = recv_object.read(MemoryView(*dst_data[recv_object.name()]));
|
||||
auto dst_buffer = MemoryView(*dst_data[recv_object.name()]);
|
||||
auto status = recv_object.read(dst_buffer);
|
||||
if (HAILO_SUCCESS != status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (params.measure_overall_latency) {
|
||||
overall_latency_meter.add_end_sample(output_idx, std::chrono::steady_clock::now().time_since_epoch());
|
||||
overall_latency_meter.add_end_sample(recv_object.name(), std::chrono::steady_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
if (show_progress && params.show_progress) {
|
||||
@@ -433,13 +454,6 @@ hailo_status abort_streams(std::vector<std::reference_wrapper<SendObject>> &send
|
||||
std::vector<std::reference_wrapper<RecvObject>> &recv_objects)
|
||||
{
|
||||
auto status = HAILO_SUCCESS; // Best effort
|
||||
for (auto &input_stream : send_objects) {
|
||||
auto abort_status = input_stream.get().abort();
|
||||
if (HAILO_SUCCESS != abort_status) {
|
||||
LOGGER__ERROR("Failed to abort input stream {}", input_stream.get().name());
|
||||
status = abort_status;
|
||||
}
|
||||
}
|
||||
for (auto &output_stream : recv_objects) {
|
||||
auto abort_status = output_stream.get().abort();
|
||||
if (HAILO_SUCCESS != abort_status) {
|
||||
@@ -447,6 +461,13 @@ hailo_status abort_streams(std::vector<std::reference_wrapper<SendObject>> &send
|
||||
status = abort_status;
|
||||
}
|
||||
}
|
||||
for (auto &input_stream : send_objects) {
|
||||
auto abort_status = input_stream.get().abort();
|
||||
if (HAILO_SUCCESS != abort_status) {
|
||||
LOGGER__ERROR("Failed to abort input stream {}", input_stream.get().name());
|
||||
status = abort_status;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -549,15 +570,18 @@ std::pair<std::string, uint16_t> get_network_to_batch(const std::string &name_to
|
||||
|
||||
uint16_t get_batch_size(const inference_runner_params ¶ms, const std::string &network_name)
|
||||
{
|
||||
uint16_t batch_size = params.batch_size;
|
||||
|
||||
/* params.batch_per_network is a partial list of networks.
|
||||
If a network is not in it, it gets the network_group_batch (params.batch_size) */
|
||||
for (auto &name_to_batch_str : params.batch_per_network) {
|
||||
auto name_to_batch = get_network_to_batch(name_to_batch_str);
|
||||
if (network_name == name_to_batch.first) {
|
||||
return name_to_batch.second;
|
||||
batch_size = name_to_batch.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return params.batch_size;
|
||||
return (HAILO_DEFAULT_BATCH_SIZE == batch_size ? 1 : batch_size);
|
||||
}
|
||||
|
||||
Expected<std::map<std::string, ConfigureNetworkParams>> get_configure_params(const inference_runner_params ¶ms, hailort::Hef &hef, hailo_stream_interface_t interface)
|
||||
@@ -620,12 +644,12 @@ static hailo_status run_streaming_impl(std::shared_ptr<ConfiguredNetworkGroup> c
|
||||
if (params.measure_overall_latency) {
|
||||
CHECK((send_objects.size() == 1), HAILO_INVALID_OPERATION, "Overall latency measurement not support multiple inputs network");
|
||||
}
|
||||
std::set<uint32_t> output_channels;
|
||||
for (uint32_t output_channel_index = 0; output_channel_index < recv_objects.size(); output_channel_index++) {
|
||||
output_channels.insert(output_channel_index);
|
||||
std::set<std::string> output_names;
|
||||
for (auto &output : recv_objects) {
|
||||
output_names.insert(output.get().name());
|
||||
}
|
||||
|
||||
LatencyMeter overall_latency_meter(output_channels, OVERALL_LATENCY_TIMESTAMPS_LIST_LENGTH);
|
||||
LatencyMeter overall_latency_meter(output_names, OVERALL_LATENCY_TIMESTAMPS_LIST_LENGTH);
|
||||
Barrier barrier(send_objects.size() + recv_objects.size());
|
||||
|
||||
std::vector<std::atomic_size_t> frames_recieved_per_output(recv_objects.size());
|
||||
@@ -648,9 +672,9 @@ static hailo_status run_streaming_impl(std::shared_ptr<ConfiguredNetworkGroup> c
|
||||
auto &frames_recieved = frames_recieved_per_output[output_index];
|
||||
results.emplace_back(std::make_unique<AsyncThread<hailo_status>>(
|
||||
[network_progress_bar, params, &recv_object, &output_buffers, first, &barrier, &overall_latency_meter,
|
||||
&frames_recieved, output_index, batch_size]() {
|
||||
&frames_recieved, batch_size]() {
|
||||
auto res = recv_loop(params, recv_object.get(), network_progress_bar, barrier, overall_latency_meter,
|
||||
output_buffers, frames_recieved, output_index, first, batch_size);
|
||||
output_buffers, frames_recieved, first, batch_size);
|
||||
if (HAILO_SUCCESS != res) {
|
||||
barrier.terminate();
|
||||
}
|
||||
@@ -685,7 +709,7 @@ static hailo_status run_streaming_impl(std::shared_ptr<ConfiguredNetworkGroup> c
|
||||
auto error_status = HAILO_SUCCESS;
|
||||
for (auto& result : results) {
|
||||
auto status = result->get();
|
||||
if (HAILO_STREAM_INTERNAL_ABORT == status) {
|
||||
if (HAILO_STREAM_ABORTED_BY_USER == status) {
|
||||
continue;
|
||||
}
|
||||
if (HAILO_SUCCESS != status) {
|
||||
@@ -1051,7 +1075,7 @@ static Expected<std::vector<std::map<std::string, BufferPtr>>> create_dataset(
|
||||
return results;
|
||||
}
|
||||
|
||||
Expected<InferResult> activate_network_group_and_run(
|
||||
Expected<InferResult> activate_and_run_single_device(
|
||||
Device &device,
|
||||
const std::vector<std::shared_ptr<ConfiguredNetworkGroup>> &network_groups,
|
||||
const inference_runner_params ¶ms)
|
||||
@@ -1164,7 +1188,7 @@ Expected<InferResult> run_command_hef_single_device(const inference_runner_param
|
||||
}
|
||||
#endif
|
||||
|
||||
auto inference_result = activate_network_group_and_run(*device, network_group_list.value(), params);
|
||||
auto inference_result = activate_and_run_single_device(*device, network_group_list.value(), params);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// TODO: Support on windows (HRT-5919)
|
||||
@@ -1179,8 +1203,10 @@ Expected<InferResult> run_command_hef_single_device(const inference_runner_param
|
||||
}
|
||||
|
||||
if (params.runtime_data.collect_runtime_data) {
|
||||
DownloadActionListCommand::execute(*device, params.runtime_data.runtime_data_output_path,
|
||||
network_group_list.value(), params.hef_path);
|
||||
const auto runtime_data_output_path = format_runtime_data_output_path(
|
||||
params.runtime_data.runtime_data_output_path, params.hef_path);
|
||||
DownloadActionListCommand::execute(*device, runtime_data_output_path, network_group_list.value(),
|
||||
params.hef_path);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1188,6 +1214,100 @@ Expected<InferResult> run_command_hef_single_device(const inference_runner_param
|
||||
return inference_result;
|
||||
}
|
||||
|
||||
|
||||
Expected<InferResult> activate_and_run_vdevice(
|
||||
std::vector<std::reference_wrapper<Device>> &physical_devices,
|
||||
bool scheduler_is_used,
|
||||
const std::vector<std::shared_ptr<ConfiguredNetworkGroup>> &network_groups,
|
||||
const inference_runner_params ¶ms)
|
||||
{
|
||||
std::unique_ptr<ActivatedNetworkGroup> activated_network_group;
|
||||
if (!scheduler_is_used) {
|
||||
auto activated_net_group_exp = activate_network_group(*network_groups[0]);
|
||||
CHECK_EXPECTED(activated_net_group_exp, "Failed activate network_group");
|
||||
activated_network_group = activated_net_group_exp.release();
|
||||
}
|
||||
|
||||
auto input_dataset = create_dataset(network_groups, params);
|
||||
CHECK_EXPECTED(input_dataset, "Failed creating input dataset");
|
||||
|
||||
hailo_power_measurement_types_t measurement_type = HAILO_POWER_MEASUREMENT_TYPES__MAX_ENUM;
|
||||
bool should_measure_power = false;
|
||||
if (params.power_measurement.measure_power) {
|
||||
measurement_type = HAILO_POWER_MEASUREMENT_TYPES__POWER;
|
||||
should_measure_power = true;
|
||||
} else if (params.power_measurement.measure_current) {
|
||||
measurement_type = HAILO_POWER_MEASUREMENT_TYPES__CURRENT;
|
||||
should_measure_power = true;
|
||||
}
|
||||
|
||||
std::map<std::string, std::shared_ptr<LongPowerMeasurement>> power_measurements;
|
||||
if (should_measure_power) {
|
||||
for (auto &device : physical_devices) {
|
||||
auto long_power_measurement_exp = PowerMeasurementSubcommand::start_power_measurement(device,
|
||||
HAILO_DVM_OPTIONS_AUTO,
|
||||
measurement_type, params.power_measurement.sampling_period, params.power_measurement.averaging_factor);
|
||||
CHECK_EXPECTED(long_power_measurement_exp, "Failed starting power measurement on device {}", device.get().get_dev_id());
|
||||
auto long_power_measurement_p = make_shared_nothrow<LongPowerMeasurement>(long_power_measurement_exp.release());
|
||||
CHECK_NOT_NULL_AS_EXPECTED(long_power_measurement_p, HAILO_OUT_OF_HOST_MEMORY);
|
||||
power_measurements.emplace(device.get().get_dev_id(), std::move(long_power_measurement_p));
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, std::shared_ptr<TemperatureMeasurement>> temp_measurements;
|
||||
if (params.measure_temp) {
|
||||
for (auto &device : physical_devices) {
|
||||
auto temp_measure = make_shared_nothrow<TemperatureMeasurement>(device);
|
||||
CHECK_NOT_NULL_AS_EXPECTED(temp_measure, HAILO_OUT_OF_HOST_MEMORY);
|
||||
auto status = temp_measure->start_measurement();
|
||||
CHECK_SUCCESS_AS_EXPECTED(status, "Failed starting temperature measurement on device {}", device.get().get_dev_id());
|
||||
temp_measurements.emplace(device.get().get_dev_id(), std::move(temp_measure));
|
||||
}
|
||||
}
|
||||
|
||||
auto infer_result = run_inference(network_groups, input_dataset.value(), params);
|
||||
CHECK_EXPECTED(infer_result, "Error failed running inference");
|
||||
|
||||
InferResult inference_result(infer_result.release());
|
||||
inference_result.initialize_measurements(physical_devices);
|
||||
|
||||
if (should_measure_power) {
|
||||
auto status = HAILO_SUCCESS;
|
||||
for (auto &power_measure_pair : power_measurements) {
|
||||
auto measurement_status = power_measure_pair.second->stop();
|
||||
if (HAILO_SUCCESS != measurement_status) {
|
||||
// The returned status will be the last non-success status.
|
||||
status = measurement_status;
|
||||
LOGGER__ERROR("Failed stopping power measurement on device {} with status {}", power_measure_pair.first, measurement_status);
|
||||
} else {
|
||||
auto set_measurement_status = HAILO_UNINITIALIZED;
|
||||
if (params.power_measurement.measure_current) {
|
||||
set_measurement_status = inference_result.set_current_measurement(power_measure_pair.first, std::move(power_measure_pair.second));
|
||||
} else {
|
||||
set_measurement_status = inference_result.set_power_measurement(power_measure_pair.first, std::move(power_measure_pair.second));
|
||||
}
|
||||
if (HAILO_SUCCESS != set_measurement_status) {
|
||||
status = set_measurement_status;
|
||||
LOGGER__ERROR("Failed setting power measurement to inference result with status {}", set_measurement_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK_SUCCESS_AS_EXPECTED(status);
|
||||
}
|
||||
|
||||
if (params.measure_temp) {
|
||||
for(const auto &temp_measure_pair : temp_measurements) {
|
||||
temp_measure_pair.second->stop_measurement();
|
||||
auto temp_measure_p = make_shared_nothrow<TempMeasurementData>(temp_measure_pair.second->get_data());
|
||||
CHECK_NOT_NULL_AS_EXPECTED(temp_measure_p, HAILO_OUT_OF_HOST_MEMORY);
|
||||
auto status = inference_result.set_temp_measurement(temp_measure_pair.first, std::move(temp_measure_p));
|
||||
CHECK_SUCCESS_AS_EXPECTED(status);
|
||||
}
|
||||
}
|
||||
|
||||
return inference_result;
|
||||
}
|
||||
|
||||
Expected<InferResult> run_command_hef_vdevice(const inference_runner_params ¶ms)
|
||||
{
|
||||
auto hef = Hef::create(params.hef_path.c_str());
|
||||
@@ -1221,33 +1341,6 @@ Expected<InferResult> run_command_hef_vdevice(const inference_runner_params &par
|
||||
auto vdevice = VDevice::create(vdevice_params);
|
||||
CHECK_EXPECTED(vdevice, "Failed creating vdevice");
|
||||
|
||||
// VDevice always has Pcie devices
|
||||
auto configure_params = get_configure_params(params, hef.value(), hailo_stream_interface_t::HAILO_STREAM_INTERFACE_PCIE);
|
||||
CHECK_EXPECTED(configure_params);
|
||||
|
||||
auto network_group_list = vdevice.value()->configure(hef.value(), configure_params.value());
|
||||
CHECK_EXPECTED(network_group_list, "Failed configure vdevice from hef");
|
||||
|
||||
std::unique_ptr<ActivatedNetworkGroup> activated_network_group;
|
||||
if (!scheduler_is_used) {
|
||||
auto activated_net_group_exp = activate_network_group(*network_group_list.value()[0]);
|
||||
CHECK_EXPECTED(activated_net_group_exp, "Failed activate network_group");
|
||||
activated_network_group = activated_net_group_exp.release();
|
||||
}
|
||||
|
||||
auto input_dataset = create_dataset(network_group_list.value(), params);
|
||||
CHECK_EXPECTED(input_dataset, "Failed creating input dataset");
|
||||
|
||||
hailo_power_measurement_types_t measurement_type = HAILO_POWER_MEASUREMENT_TYPES__MAX_ENUM;
|
||||
bool should_measure_power = false;
|
||||
if (params.power_measurement.measure_power) {
|
||||
measurement_type = HAILO_POWER_MEASUREMENT_TYPES__POWER;
|
||||
should_measure_power = true;
|
||||
} else if (params.power_measurement.measure_current) {
|
||||
measurement_type = HAILO_POWER_MEASUREMENT_TYPES__CURRENT;
|
||||
should_measure_power = true;
|
||||
}
|
||||
|
||||
std::vector<std::reference_wrapper<Device>> physical_devices;
|
||||
if (!params.vdevice_params.multi_process_service) {
|
||||
auto expected_physical_devices = vdevice.value()->get_physical_devices();
|
||||
@@ -1255,29 +1348,14 @@ Expected<InferResult> run_command_hef_vdevice(const inference_runner_params &par
|
||||
physical_devices = expected_physical_devices.value();
|
||||
}
|
||||
|
||||
std::map<std::string, std::shared_ptr<LongPowerMeasurement>> power_measurements;
|
||||
if (should_measure_power) {
|
||||
for (auto &device : physical_devices) {
|
||||
auto long_power_measurement_exp = PowerMeasurementSubcommand::start_power_measurement(device,
|
||||
HAILO_DVM_OPTIONS_AUTO,
|
||||
measurement_type, params.power_measurement.sampling_period, params.power_measurement.averaging_factor);
|
||||
CHECK_EXPECTED(long_power_measurement_exp, "Failed starting power measurement on device {}", device.get().get_dev_id());
|
||||
auto long_power_measurement_p = make_shared_nothrow<LongPowerMeasurement>(long_power_measurement_exp.release());
|
||||
CHECK_NOT_NULL_AS_EXPECTED(long_power_measurement_p, HAILO_OUT_OF_HOST_MEMORY);
|
||||
power_measurements.emplace(device.get().get_dev_id(), std::move(long_power_measurement_p));
|
||||
}
|
||||
}
|
||||
auto interface = vdevice.value()->get_default_streams_interface();
|
||||
CHECK_EXPECTED(interface, "Failed to get default streams interface");
|
||||
|
||||
std::map<std::string, std::shared_ptr<TemperatureMeasurement>> temp_measurements;
|
||||
if (params.measure_temp) {
|
||||
for (auto &device : physical_devices) {
|
||||
auto temp_measure = make_shared_nothrow<TemperatureMeasurement>(device);
|
||||
CHECK_NOT_NULL_AS_EXPECTED(temp_measure, HAILO_OUT_OF_HOST_MEMORY);
|
||||
status = temp_measure->start_measurement();
|
||||
CHECK_SUCCESS_AS_EXPECTED(status, "Failed starting temperature measurement on device {}", device.get().get_dev_id());
|
||||
temp_measurements.emplace(device.get().get_dev_id(), std::move(temp_measure));
|
||||
}
|
||||
}
|
||||
auto configure_params = get_configure_params(params, hef.value(), *interface);
|
||||
CHECK_EXPECTED(configure_params);
|
||||
|
||||
auto network_group_list = vdevice.value()->configure(hef.value(), configure_params.value());
|
||||
CHECK_EXPECTED(network_group_list, "Failed configure vdevice from hef");
|
||||
|
||||
#if defined(__GNUC__)
|
||||
for (auto &device : physical_devices) {
|
||||
@@ -1289,7 +1367,8 @@ Expected<InferResult> run_command_hef_vdevice(const inference_runner_params &par
|
||||
}
|
||||
#endif
|
||||
|
||||
auto infer_result = run_inference(network_group_list.value(), input_dataset.value(), params);
|
||||
auto infer_result = activate_and_run_vdevice(physical_devices, scheduler_is_used, network_group_list.value(), params);
|
||||
CHECK_EXPECTED(infer_result, "Error failed running inference");
|
||||
|
||||
#if defined(__GNUC__)
|
||||
for (auto &device : physical_devices) {
|
||||
@@ -1305,51 +1384,15 @@ Expected<InferResult> run_command_hef_vdevice(const inference_runner_params &par
|
||||
}
|
||||
|
||||
if (params.runtime_data.collect_runtime_data) {
|
||||
DownloadActionListCommand::execute(device.get(), params.runtime_data.runtime_data_output_path,
|
||||
network_group_list.value(), params.hef_path);
|
||||
const auto runtime_data_output_path = format_runtime_data_output_path(
|
||||
params.runtime_data.runtime_data_output_path, params.hef_path);
|
||||
DownloadActionListCommand::execute(device.get(), runtime_data_output_path, network_group_list.value(),
|
||||
params.hef_path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CHECK_EXPECTED(infer_result, "Error failed running inference");
|
||||
|
||||
InferResult inference_result(infer_result.release());
|
||||
inference_result.initialize_measurements(physical_devices);
|
||||
|
||||
if (should_measure_power) {
|
||||
for (auto &power_measure_pair : power_measurements) {
|
||||
auto measurement_status = power_measure_pair.second->stop();
|
||||
if (HAILO_SUCCESS != measurement_status) {
|
||||
// The returned status will be the last non-success status.
|
||||
status = measurement_status;
|
||||
LOGGER__ERROR("Failed stopping power measurement on device {} with status {}", power_measure_pair.first, measurement_status);
|
||||
} else {
|
||||
auto set_measurement_status = HAILO_UNINITIALIZED;
|
||||
if (params.power_measurement.measure_current) {
|
||||
set_measurement_status = inference_result.set_current_measurement(power_measure_pair.first, std::move(power_measure_pair.second));
|
||||
} else {
|
||||
set_measurement_status = inference_result.set_power_measurement(power_measure_pair.first, std::move(power_measure_pair.second));
|
||||
}
|
||||
if (HAILO_SUCCESS != set_measurement_status) {
|
||||
status = set_measurement_status;
|
||||
LOGGER__ERROR("Failed setting power measurement to inference result with status {}", set_measurement_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK_SUCCESS_AS_EXPECTED(status);
|
||||
}
|
||||
|
||||
if (params.measure_temp) {
|
||||
for(const auto &temp_measure_pair : temp_measurements) {
|
||||
temp_measure_pair.second->stop_measurement();
|
||||
auto temp_measure_p = make_shared_nothrow<TempMeasurementData>(temp_measure_pair.second->get_data());
|
||||
CHECK_NOT_NULL_AS_EXPECTED(temp_measure_p, HAILO_OUT_OF_HOST_MEMORY);
|
||||
status = inference_result.set_temp_measurement(temp_measure_pair.first, std::move(temp_measure_p));
|
||||
CHECK_SUCCESS_AS_EXPECTED(status);
|
||||
}
|
||||
}
|
||||
|
||||
return inference_result;
|
||||
return infer_result;
|
||||
}
|
||||
|
||||
Expected<bool> use_vdevice(const hailo_vdevice_params ¶ms)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define _HAILO_RUN_COMMAND_HPP_
|
||||
|
||||
#include "hailortcli.hpp"
|
||||
#include "common.hpp"
|
||||
#include "power_measurement_command.hpp"
|
||||
#include "temp_measurement.hpp"
|
||||
#include "CLI/CLI.hpp"
|
||||
@@ -44,12 +45,10 @@ struct pipeline_stats_measurement_params {
|
||||
std::string pipeline_stats_output_path;
|
||||
};
|
||||
|
||||
static constexpr uint16_t RUNTIME_DATA_IGNORE_BATCH_TO_MEASURE_OPT = std::numeric_limits<uint16_t>::max();
|
||||
static constexpr uint16_t RUNTIME_DATA_DEFAULT_BATCH_TO_MEASURE_OPT = 2;
|
||||
|
||||
struct runtime_data_params {
|
||||
bool collect_runtime_data;
|
||||
std::string runtime_data_output_path;
|
||||
std::string batch_to_measure_str;
|
||||
uint16_t batch_to_measure;
|
||||
};
|
||||
|
||||
@@ -91,6 +90,26 @@ private:
|
||||
inference_runner_params m_params;
|
||||
};
|
||||
|
||||
class UintOrKeywordValidator : public CLI::Validator {
|
||||
public:
|
||||
UintOrKeywordValidator(const std::string &keyword) {
|
||||
name_ = "UINT_OR_KEYWORD";
|
||||
func_ = [keyword](const std::string &s) {
|
||||
if (s == keyword) {
|
||||
// s is the allowed keyword
|
||||
return std::string(); // Success
|
||||
}
|
||||
|
||||
if (CliCommon::is_non_negative_number(s)) {
|
||||
// s is an int
|
||||
return std::string(); // Success
|
||||
}
|
||||
|
||||
return std::string("should be a positive integer or '" + keyword + "'.");
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class InputNameToFilePairValidator : public CLI::Validator {
|
||||
public:
|
||||
InputNameToFilePairValidator() : CLI::Validator("InputNameToFilePair"), m_first_run(true), m_must_fail(false) {
|
||||
@@ -143,7 +162,7 @@ public:
|
||||
auto batch_size = key_value_pair_str.substr(first_delimiter + 1);
|
||||
auto network_name = key_value_pair_str.substr(0, first_delimiter);
|
||||
// Batch size must be a positive number
|
||||
if (!is_positive_number(batch_size)) {
|
||||
if (!CliCommon::is_positive_number(batch_size)) {
|
||||
m_must_fail = true;
|
||||
return std::string("Failed parsing batch size (" + batch_size + ") for network (" + network_name + "). batch should be a positive number.");
|
||||
}
|
||||
@@ -151,13 +170,8 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
private:
|
||||
bool is_positive_number(const std::string &s)
|
||||
{
|
||||
bool is_number = (!s.empty()) && (std::all_of(s.begin(), s.end(), ::isdigit));
|
||||
return is_number && (0 < std::stoi(s));
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_must_fail;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,12 +16,6 @@
|
||||
ScanSubcommand::ScanSubcommand(CLI::App &parent_app) :
|
||||
Command(parent_app.add_subcommand("scan", "Shows all available devices"))
|
||||
{
|
||||
auto *device_type_option = m_app->add_option("-d,--device-type,--target", "ignored.");
|
||||
std::vector<DeprecationActionPtr> actions{
|
||||
std::make_shared<OptionDeprecation>(device_type_option),
|
||||
};
|
||||
hailo_deprecate_options(m_app, actions, false);
|
||||
|
||||
// Ethernet options
|
||||
auto *eth_options_group = m_app->add_option_group("Ethernet Device Options");
|
||||
auto *interface_ip_option = eth_options_group->add_option("--interface-ip", m_interface_ip_addr,
|
||||
|
||||
@@ -157,6 +157,10 @@ SensorDumpConfigSubcommand::SensorDumpConfigSubcommand(CLI::App &parent_app) :
|
||||
|
||||
hailo_status SensorDumpConfigSubcommand::execute_on_device(Device &device)
|
||||
{
|
||||
auto status = validate_specific_device_is_given();
|
||||
CHECK_SUCCESS(status,
|
||||
"'sensor-config get-config' command should get a specific device-id.");
|
||||
|
||||
return device.sensor_dump_config(m_section_index, m_output_file_path);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0.0)
|
||||
# set(CMAKE_C_CLANG_TIDY "clang-tidy;-checks=*")
|
||||
|
||||
set(HAILORT_MAJOR_VERSION 4)
|
||||
set(HAILORT_MINOR_VERSION 10)
|
||||
set(HAILORT_MINOR_VERSION 12)
|
||||
set(HAILORT_REVISION_VERSION 0)
|
||||
|
||||
# Add the cmake folder so the modules there are found
|
||||
@@ -25,6 +25,10 @@ target_include_directories(hef_proto
|
||||
$<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)
|
||||
add_library(scheduler_mon_proto ${PROTO_SCHEDULER_MON_SRC} ${PROTO_SCHEDULER_MON_HEADR})
|
||||
target_link_libraries(scheduler_mon_proto libprotobuf-lite)
|
||||
|
||||
@@ -8,7 +8,7 @@ if(NOT CMAKE_HOST_UNIX)
|
||||
message(FATAL_ERROR "Only unix hosts are supported, stopping build")
|
||||
endif()
|
||||
|
||||
find_package(HailoRT 4.10.0 EXACT REQUIRED)
|
||||
find_package(HailoRT 4.12.0 EXACT REQUIRED)
|
||||
|
||||
# GST_PLUGIN_DEFINE needs PACKAGE to be defined
|
||||
set(GST_HAILO_PACKAGE_NAME "hailo")
|
||||
@@ -37,7 +37,7 @@ set_target_properties(gsthailo PROPERTIES
|
||||
)
|
||||
|
||||
target_compile_options(gsthailo PRIVATE
|
||||
-Werror -Wall -Wextra -Wconversion -O3 -DNDEBUG # TODO support debug/release builds
|
||||
-Werror -Wall -Wextra -Wconversion
|
||||
-DVERSION="${GST_HAILO_VERSION}"
|
||||
-DPACKAGE="${GST_HAILO_PACKAGE_NAME}")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Compiling the plugin:
|
||||
cmake -H. -Bbuild
|
||||
cmake --build build
|
||||
cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build --config release
|
||||
|
||||
Using the plugin:
|
||||
The plugin is dependent on libhailort which is included in the `hailort/lib/` directory.
|
||||
|
||||
@@ -48,11 +48,13 @@ using namespace hailort;
|
||||
#define DEFAULT_VDEVICE_KEY (0)
|
||||
#define MIN_VALID_VDEVICE_KEY (1)
|
||||
|
||||
#define HAILO_SUPPORTED_FORMATS "{ RGB, RGBA, YUY2 }"
|
||||
#define HAILO_SUPPORTED_FORMATS "{ RGB, RGBA, YUY2, NV12, NV21 }"
|
||||
#define HAILO_VIDEO_CAPS GST_VIDEO_CAPS_MAKE(HAILO_SUPPORTED_FORMATS)
|
||||
|
||||
#define HAILO_DEFAULT_SCHEDULER_TIMEOUT_MS (0)
|
||||
#define HAILO_DEFAULT_SCHEDULER_THRESHOLD (1)
|
||||
#define HAILO_DEFAULT_SCHEDULER_THRESHOLD (0)
|
||||
|
||||
#define HAILO_DEFAULT_MULTI_PROCESS_SERVICE (false)
|
||||
|
||||
#define GST_CHECK(cond, ret_val, element, domain, ...) \
|
||||
do { \
|
||||
|
||||
@@ -79,6 +79,7 @@ enum
|
||||
PROP_SCHEDULING_ALGORITHM,
|
||||
PROP_SCHEDULER_TIMEOUT_MS,
|
||||
PROP_SCHEDULER_THRESHOLD,
|
||||
PROP_MULTI_PROCESS_SERVICE,
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(GstHailoNet, gst_hailonet, GST_TYPE_BIN);
|
||||
@@ -150,8 +151,8 @@ static void gst_hailonet_class_init(GstHailoNetClass *klass)
|
||||
"Gets values from the enum GstHailoSchedulingAlgorithms. "
|
||||
"Using Model Scheduler algorithm different than HAILO_SCHEDULING_ALGORITHM_NONE, excludes the property 'is-active'. "
|
||||
"When using the same VDevice across multiple hailonets, all should have the same 'scheduling-algorithm'. "
|
||||
"Currently only supported with 1 device (e.g. device-count=1).",
|
||||
GST_TYPE_SCHEDULING_ALGORITHM, HAILO_SCHEDULING_ALGORITHM_NONE,
|
||||
"To run with more than one device, set env variable 'HAILO_ENABLE_MULTI_DEVICE_SCHEDULER' to 1.",
|
||||
GST_TYPE_SCHEDULING_ALGORITHM, HAILO_SCHEDULING_ALGORITHM_ROUND_ROBIN,
|
||||
(GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||
g_object_class_install_property(gobject_class, PROP_SCHEDULER_TIMEOUT_MS,
|
||||
g_param_spec_uint("scheduler-timeout-ms", "Timeout for for scheduler in ms", "The maximum time period that may pass before getting run time from the scheduler,"
|
||||
@@ -160,7 +161,10 @@ static void gst_hailonet_class_init(GstHailoNetClass *klass)
|
||||
g_object_class_install_property(gobject_class, PROP_SCHEDULER_THRESHOLD,
|
||||
g_param_spec_uint("scheduler-threshold", "Frames threshold for scheduler", "The minimum number of send requests required before the hailonet is considered ready to get run time from the scheduler.",
|
||||
HAILO_DEFAULT_SCHEDULER_THRESHOLD, std::numeric_limits<uint32_t>::max(), HAILO_DEFAULT_SCHEDULER_THRESHOLD, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||
|
||||
g_object_class_install_property(gobject_class, PROP_MULTI_PROCESS_SERVICE,
|
||||
g_param_spec_boolean("multi-process-service", "Should run over HailoRT service", "Controls wether to run HailoRT over its service. "
|
||||
"To use this property, the service should be active and scheduling-algorithm should be set. Defaults to false.",
|
||||
HAILO_DEFAULT_MULTI_PROCESS_SERVICE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||
// See information about the "flush" signal in the element description
|
||||
g_signal_new(
|
||||
"flush",
|
||||
@@ -170,13 +174,19 @@ static void gst_hailonet_class_init(GstHailoNetClass *klass)
|
||||
);
|
||||
}
|
||||
|
||||
std::string create_name(std::string prefix, uint32_t id)
|
||||
{
|
||||
return prefix + std::to_string(id);
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<HailoNetImpl>> HailoNetImpl::create(GstHailoNet *element)
|
||||
{
|
||||
if (nullptr == element) {
|
||||
return make_unexpected(HAILO_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
GstElement *hailosend = gst_element_factory_make("hailosend", "hailosend");
|
||||
auto hailosend_name = create_name("hailosend", HailoNetImpl::m_hailonet_count);
|
||||
GstElement *hailosend = gst_element_factory_make("hailosend", hailosend_name.c_str());
|
||||
if (nullptr == hailosend) {
|
||||
GST_ELEMENT_ERROR(element, RESOURCE, FAILED, ("Failed creating hailosend element in bin!"), (NULL));
|
||||
return make_unexpected(HAILO_INTERNAL_FAILURE);
|
||||
@@ -184,7 +194,8 @@ Expected<std::unique_ptr<HailoNetImpl>> HailoNetImpl::create(GstHailoNet *elemen
|
||||
|
||||
g_object_set(hailosend, "qos", FALSE, NULL);
|
||||
|
||||
GstElement *queue = gst_element_factory_make("queue", "hailo_infer_q_0");
|
||||
auto hailoqueue_name = create_name("hailoqueue", HailoNetImpl::m_hailonet_count);
|
||||
GstElement *queue = gst_element_factory_make("queue", hailoqueue_name.c_str());
|
||||
if (nullptr == queue) {
|
||||
GST_ELEMENT_ERROR(element, RESOURCE, FAILED, ("Failed creating queue element in bin!"), (NULL));
|
||||
gst_object_unref(hailosend);
|
||||
@@ -192,12 +203,13 @@ Expected<std::unique_ptr<HailoNetImpl>> HailoNetImpl::create(GstHailoNet *elemen
|
||||
}
|
||||
|
||||
// Passing 0 disables the features here
|
||||
g_object_set(queue, "max-size-time", 0, NULL);
|
||||
g_object_set(queue, "max-size-bytes", 0, NULL);
|
||||
g_object_set(queue, "max-size-time", (guint64)0, NULL);
|
||||
g_object_set(queue, "max-size-bytes", (guint)0, NULL);
|
||||
g_signal_connect(queue, "overrun", G_CALLBACK(gst_hailonet_inner_queue_overrun_callback), nullptr);
|
||||
g_signal_connect(queue, "underrun", G_CALLBACK(gst_hailonet_inner_queue_underrun_callback), nullptr);
|
||||
|
||||
GstElement *hailorecv = gst_element_factory_make("hailorecv", "hailorecv");
|
||||
auto hailorecv_name = create_name("hailorecv", HailoNetImpl::m_hailonet_count);
|
||||
GstElement *hailorecv = gst_element_factory_make("hailorecv", hailorecv_name.c_str());
|
||||
if (nullptr == hailorecv) {
|
||||
GST_ELEMENT_ERROR(element, RESOURCE, FAILED, ("Failed creating hailorecv element in bin!"), (NULL));
|
||||
gst_object_unref(hailosend);
|
||||
@@ -375,7 +387,7 @@ void HailoNetImpl::set_property(GObject *object, guint property_id, const GValue
|
||||
{
|
||||
gboolean new_is_active = g_value_get_boolean(value);
|
||||
|
||||
if (HAILO_SCHEDULING_ALGORITHM_NONE != m_props.m_scheduling_algorithm.get()) {
|
||||
if (m_props.m_scheduling_algorithm.was_changed() && (HAILO_SCHEDULING_ALGORITHM_NONE != m_props.m_scheduling_algorithm.get())) {
|
||||
g_error("scheduling-algorithm different than HAILO_SCHEDULING_ALGORITHM_NONE in combination with 'is-active' is not supported.");
|
||||
break;
|
||||
}
|
||||
@@ -438,6 +450,13 @@ void HailoNetImpl::set_property(GObject *object, guint property_id, const GValue
|
||||
}
|
||||
m_props.m_scheduler_threshold = g_value_get_uint(value);
|
||||
break;
|
||||
case PROP_MULTI_PROCESS_SERVICE:
|
||||
if (m_was_configured) {
|
||||
g_warning("The network was already configured so changing the multi-process-service property will not take place!");
|
||||
break;
|
||||
}
|
||||
m_props.m_multi_process_service = g_value_get_boolean(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||
break;
|
||||
@@ -505,6 +524,9 @@ void HailoNetImpl::get_property(GObject *object, guint property_id, GValue *valu
|
||||
case PROP_SCHEDULER_THRESHOLD:
|
||||
g_value_set_uint(value, m_props.m_scheduler_threshold.get());
|
||||
break;
|
||||
case PROP_MULTI_PROCESS_SERVICE:
|
||||
g_value_set_boolean(value, m_props.m_multi_process_service.get());
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
|
||||
break;
|
||||
@@ -516,12 +538,18 @@ hailo_status HailoNetImpl::set_hef()
|
||||
m_net_group_handle = make_unique_nothrow<NetworkGroupHandle>(GST_ELEMENT(m_element));
|
||||
GST_CHECK(nullptr != m_net_group_handle, HAILO_OUT_OF_HOST_MEMORY, m_element, RESOURCE, "Failed allocating memory for network handle!");
|
||||
|
||||
hailo_status status = m_net_group_handle->set_hef(m_props.m_device_id.get(), m_props.m_device_count.get(), m_props.m_vdevice_key.get(),
|
||||
m_props.m_scheduling_algorithm.get(), m_props.m_hef_path.get());
|
||||
hailo_status status = m_net_group_handle->set_hef(m_props.m_device_id.get(), m_props.m_device_count.get(),
|
||||
m_props.m_vdevice_key.get(), m_props.m_scheduling_algorithm.get(), static_cast<bool>(m_props.m_multi_process_service.get()),
|
||||
m_props.m_hef_path.get());
|
||||
if (HAILO_SUCCESS != status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (m_props.m_multi_process_service.get()) {
|
||||
GST_CHECK(m_props.m_scheduling_algorithm.get() != HAILO_SCHEDULING_ALGORITHM_NONE,
|
||||
HAILO_INVALID_OPERATION, m_element, RESOURCE, "To use multi-process-service please set scheduling-algorithm.");
|
||||
}
|
||||
|
||||
if (nullptr == m_props.m_network_name.get()) {
|
||||
// TODO: HRT-4957
|
||||
GST_CHECK(m_net_group_handle->hef()->get_network_groups_names().size() == 1, HAILO_INVALID_ARGUMENT, m_element, RESOURCE,
|
||||
@@ -541,7 +569,7 @@ hailo_status HailoNetImpl::set_hef()
|
||||
GST_CHECK(1 == input_vstream_infos->size(), HAILO_INVALID_OPERATION, m_element, RESOURCE, "hailonet element supports only HEFs with one input for now!");
|
||||
|
||||
auto input_vstream_info = input_vstream_infos.value()[0];
|
||||
GST_HAILOSEND(m_hailosend)->impl->set_input_vstream_infos(std::move(input_vstream_infos.release()));
|
||||
GST_HAILOSEND(m_hailosend)->impl->set_input_vstream_infos(input_vstream_infos.release());
|
||||
GST_HAILOSEND(m_hailosend)->impl->set_batch_size(m_props.m_batch_size.get());
|
||||
|
||||
GstBufferPool *pool = gst_buffer_pool_new();
|
||||
@@ -661,7 +689,11 @@ hailo_status HailoNetImpl::abort_streams()
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
return m_net_group_handle->abort_streams();
|
||||
auto status = GST_HAILOSEND(m_hailosend)->impl->abort_vstreams();
|
||||
GST_CHECK_SUCCESS(status, m_element, RESOURCE, "Failed aborting input VStreams of hailosend, status = %d", status);
|
||||
status = GST_HAILORECV(m_hailorecv)->impl->abort_vstreams();
|
||||
GST_CHECK_SUCCESS(status, m_element, RESOURCE, "Failed aborting output VStreams of hailorecv, status = %d", status);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status HailoNetImpl::deactivate_network_group()
|
||||
@@ -834,13 +866,8 @@ static GstStateChangeReturn gst_hailonet_change_state(GstElement *element, GstSt
|
||||
}
|
||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
||||
{
|
||||
// VStreams are destructed in hailosend's/hailorecv's GST_STATE_CHANGE_READY_TO_NULL (which calls 'clear_abort' on low-level streams)
|
||||
// We abort streams again because deactivation of the activated network group calls flush, and it can fail on timeout unless we call abort
|
||||
hailo_status status = hailonet->abort_streams();
|
||||
GST_CHECK(HAILO_SUCCESS == status, GST_STATE_CHANGE_FAILURE, element, RESOURCE, "Aborting streams has failed, status = %d\n", status);
|
||||
|
||||
if (HAILO_SCHEDULING_ALGORITHM_NONE == hailonet->get_props().m_scheduling_algorithm.get()) {
|
||||
status = hailonet->deactivate_network_group();
|
||||
auto status = hailonet->deactivate_network_group();
|
||||
GST_CHECK(HAILO_SUCCESS == status, GST_STATE_CHANGE_FAILURE, element, RESOURCE, "Deactivating network group failed, status = %d\n", status);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,8 +52,9 @@ struct HailoNetProperties final
|
||||
{
|
||||
public:
|
||||
HailoNetProperties() : m_device_id(nullptr), m_hef_path(nullptr), m_network_name(nullptr), m_batch_size(HAILO_DEFAULT_BATCH_SIZE),
|
||||
m_is_active(false), m_device_count(0), m_vdevice_key(DEFAULT_VDEVICE_KEY), m_scheduling_algorithm(HAILO_SCHEDULING_ALGORITHM_NONE),
|
||||
m_scheduler_timeout_ms(HAILO_DEFAULT_SCHEDULER_TIMEOUT_MS), m_scheduler_threshold(HAILO_DEFAULT_SCHEDULER_THRESHOLD)
|
||||
m_is_active(false), m_device_count(0), m_vdevice_key(DEFAULT_VDEVICE_KEY), m_scheduling_algorithm(HAILO_SCHEDULING_ALGORITHM_ROUND_ROBIN),
|
||||
m_scheduler_timeout_ms(HAILO_DEFAULT_SCHEDULER_TIMEOUT_MS), m_scheduler_threshold(HAILO_DEFAULT_SCHEDULER_THRESHOLD),
|
||||
m_multi_process_service(HAILO_DEFAULT_MULTI_PROCESS_SERVICE)
|
||||
{}
|
||||
|
||||
HailoElemProperty<gchar*> m_device_id;
|
||||
@@ -66,6 +67,7 @@ public:
|
||||
HailoElemProperty<hailo_scheduling_algorithm_t> m_scheduling_algorithm;
|
||||
HailoElemProperty<guint32> m_scheduler_timeout_ms;
|
||||
HailoElemProperty<guint32> m_scheduler_threshold;
|
||||
HailoElemProperty<gboolean> m_multi_process_service;
|
||||
};
|
||||
|
||||
class HailoNetImpl final
|
||||
|
||||
@@ -308,6 +308,15 @@ hailo_status HailoRecvImpl::clear_vstreams()
|
||||
return OutputVStream::clear(m_output_vstreams);
|
||||
}
|
||||
|
||||
hailo_status HailoRecvImpl::abort_vstreams()
|
||||
{
|
||||
for (auto& output_vstream : m_output_vstreams) {
|
||||
auto status = output_vstream.abort();
|
||||
GST_CHECK_SUCCESS(status, m_element, STREAM, "Failed aborting output vstream %s, status = %d", output_vstream.name().c_str(), status);
|
||||
}
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
static void gst_hailorecv_init(GstHailoRecv *self)
|
||||
{
|
||||
auto hailorecv_impl = HailoRecvImpl::create(self);
|
||||
@@ -343,6 +352,8 @@ static GstStateChangeReturn gst_hailorecv_change_state(GstElement *element, GstS
|
||||
}
|
||||
|
||||
if (GST_STATE_CHANGE_READY_TO_NULL == transition) {
|
||||
auto status = GST_HAILORECV(element)->impl->abort_vstreams();
|
||||
GST_CHECK(HAILO_SUCCESS == status, GST_STATE_CHANGE_FAILURE, element, STREAM, "Aborting output vstreams failed, status = %d\n", status);
|
||||
// Cleanup all of hailorecv memory
|
||||
GST_HAILORECV(element)->impl.reset();
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
GstFlowReturn handle_frame(GstVideoFilter *filter, GstVideoFrame *frame);
|
||||
hailo_status set_output_vstreams(std::vector<OutputVStream> &&output_vstreams, uint32_t batch_size);
|
||||
hailo_status clear_vstreams();
|
||||
hailo_status abort_vstreams();
|
||||
|
||||
private:
|
||||
hailo_status read_from_vstreams(bool should_print_latency);
|
||||
|
||||
@@ -176,6 +176,19 @@ hailo_status HailoSendImpl::write_to_vstreams(void *buf, size_t size)
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t get_height_by_order(const hailo_vstream_info_t &input_vstream_info)
|
||||
{
|
||||
auto original_height = input_vstream_info.shape.height;
|
||||
switch (input_vstream_info.format.order) {
|
||||
case HAILO_FORMAT_ORDER_NV12:
|
||||
case HAILO_FORMAT_ORDER_NV21:
|
||||
return original_height * 2;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return original_height;
|
||||
}
|
||||
|
||||
GstCaps *HailoSendImpl::get_caps(GstBaseTransform */*trans*/, GstPadDirection /*direction*/, GstCaps *caps, GstCaps */*filter*/)
|
||||
{
|
||||
GST_DEBUG_OBJECT(m_element, "transform_caps");
|
||||
@@ -192,6 +205,7 @@ GstCaps *HailoSendImpl::get_caps(GstBaseTransform */*trans*/, GstPadDirection /*
|
||||
|
||||
const gchar *format = nullptr;
|
||||
switch (m_input_vstream_infos[0].format.order) {
|
||||
case HAILO_FORMAT_ORDER_RGB4:
|
||||
case HAILO_FORMAT_ORDER_NHWC:
|
||||
if (m_input_vstream_infos[0].shape.features == RGBA_FEATURES_SIZE) {
|
||||
format = "RGBA";
|
||||
@@ -234,7 +248,7 @@ GstCaps *HailoSendImpl::get_caps(GstBaseTransform */*trans*/, GstPadDirection /*
|
||||
GstCaps *new_caps = gst_caps_new_simple("video/x-raw",
|
||||
"format", G_TYPE_STRING, format,
|
||||
"width", G_TYPE_INT, m_input_vstream_infos[0].shape.width,
|
||||
"height", G_TYPE_INT, m_input_vstream_infos[0].shape.height,
|
||||
"height", G_TYPE_INT, get_height_by_order(m_input_vstream_infos[0]),
|
||||
NULL);
|
||||
return gst_caps_intersect(caps, new_caps);
|
||||
}
|
||||
@@ -254,6 +268,15 @@ hailo_status HailoSendImpl::clear_vstreams()
|
||||
return InputVStream::clear(m_input_vstreams);
|
||||
}
|
||||
|
||||
hailo_status HailoSendImpl::abort_vstreams()
|
||||
{
|
||||
for (auto& input_vstream : m_input_vstreams) {
|
||||
auto status = input_vstream.abort();
|
||||
GST_CHECK_SUCCESS(status, m_element, STREAM, "Failed aborting input vstream %s, status = %d", input_vstream.name().c_str(), status);
|
||||
}
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
static void gst_hailosend_init(GstHailoSend *self)
|
||||
{
|
||||
auto hailosend_impl = HailoSendImpl::create(self);
|
||||
@@ -303,6 +326,8 @@ static GstStateChangeReturn gst_hailosend_change_state(GstElement *element, GstS
|
||||
}
|
||||
|
||||
if (GST_STATE_CHANGE_READY_TO_NULL == transition) {
|
||||
auto status = GST_HAILOSEND(element)->impl->abort_vstreams();
|
||||
GST_CHECK(HAILO_SUCCESS == status, GST_STATE_CHANGE_FAILURE, element, STREAM, "Aborting input vstreams failed, status = %d\n", status);
|
||||
// Cleanup all of hailosend memory
|
||||
GST_HAILOSEND(element)->impl.reset();
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
void set_input_vstream_infos(std::vector<hailo_vstream_info_t> &&input_vstream_infos);
|
||||
void set_input_vstreams(std::vector<InputVStream> &&input_vstreams);
|
||||
hailo_status clear_vstreams();
|
||||
hailo_status abort_vstreams();
|
||||
|
||||
void set_batch_size(uint32_t batch_size)
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ NetworkGroupActivationManager NetworkGroupHandle::m_net_group_activation_manager
|
||||
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> create_shared_vdevice(const void *element, const std::string &device_id,
|
||||
uint32_t vdevice_key, hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
uint32_t vdevice_key, hailo_scheduling_algorithm_t scheduling_algorithm, bool multi_process_service)
|
||||
{
|
||||
// If passing device_id, than device_count must be 1
|
||||
const auto device_count = 1;
|
||||
@@ -43,6 +43,7 @@ Expected<std::shared_ptr<VDevice>> create_shared_vdevice(const void *element, co
|
||||
params.device_count = device_count;
|
||||
params.device_ids = &(device_id_expected.value());
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
params.multi_process_service = multi_process_service;
|
||||
if (vdevice_key == DEFAULT_VDEVICE_KEY) {
|
||||
params.group_id = HAILO_UNIQUE_VDEVICE_GROUP_ID;
|
||||
} else {
|
||||
@@ -51,12 +52,12 @@ Expected<std::shared_ptr<VDevice>> create_shared_vdevice(const void *element, co
|
||||
}
|
||||
auto vdevice = VDevice::create(params);
|
||||
GST_CHECK_EXPECTED(vdevice, element, RESOURCE, "Failed creating vdevice, status = %d", vdevice.status());
|
||||
std::shared_ptr<VDevice> vdevice_ptr = std::move(vdevice.release());
|
||||
std::shared_ptr<VDevice> vdevice_ptr = vdevice.release();
|
||||
return vdevice_ptr;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> create_shared_vdevice(const void *element, uint16_t device_count, uint32_t vdevice_key,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, bool multi_process_service)
|
||||
{
|
||||
auto device_id = std::to_string(vdevice_key);
|
||||
hailo_vdevice_params_t params = {};
|
||||
@@ -65,14 +66,15 @@ Expected<std::shared_ptr<VDevice>> create_shared_vdevice(const void *element, ui
|
||||
params.device_count = device_count;
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
params.group_id = device_id.c_str();
|
||||
params.multi_process_service = multi_process_service;
|
||||
auto vdevice = VDevice::create(params);
|
||||
GST_CHECK_EXPECTED(vdevice, element, RESOURCE, "Failed creating vdevice, status = %d", vdevice.status());
|
||||
std::shared_ptr<VDevice> vdevice_ptr = std::move(vdevice.release());
|
||||
std::shared_ptr<VDevice> vdevice_ptr = vdevice.release();
|
||||
return vdevice_ptr;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> create_unique_vdevice(const void *element, uint16_t device_count,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, bool multi_process_service)
|
||||
{
|
||||
hailo_vdevice_params_t params = {};
|
||||
auto status = hailo_init_vdevice_params(¶ms);
|
||||
@@ -81,43 +83,44 @@ Expected<std::shared_ptr<VDevice>> create_unique_vdevice(const void *element, ui
|
||||
params.device_count = device_count;
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
params.group_id = HAILO_UNIQUE_VDEVICE_GROUP_ID;
|
||||
params.multi_process_service = multi_process_service;
|
||||
auto vdevice = VDevice::create(params);
|
||||
GST_CHECK_EXPECTED(vdevice, element, RESOURCE, "Failed creating vdevice, status = %d", vdevice.status());
|
||||
std::shared_ptr<VDevice> vdevice_ptr = std::move(vdevice.release());
|
||||
std::shared_ptr<VDevice> vdevice_ptr = vdevice.release();
|
||||
return vdevice_ptr;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> NetworkGroupHandle::create_vdevice(const void *element, const std::string &device_id, uint16_t device_count,
|
||||
uint32_t vdevice_key, hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
uint32_t vdevice_key, hailo_scheduling_algorithm_t scheduling_algorithm, bool multi_process_service)
|
||||
{
|
||||
if (!device_id.empty()) {
|
||||
auto result = create_shared_vdevice(element, device_id, vdevice_key, scheduling_algorithm);
|
||||
auto result = create_shared_vdevice(element, device_id, vdevice_key, scheduling_algorithm, multi_process_service);
|
||||
GST_CHECK_EXPECTED(result, element, RESOURCE, "Failed creating vdevice, status = %d", result.status());
|
||||
m_vdevices.insert(result.value());
|
||||
return result;
|
||||
}
|
||||
if (DEFAULT_VDEVICE_KEY != vdevice_key) {
|
||||
auto result = create_shared_vdevice(element, device_count, vdevice_key, scheduling_algorithm);
|
||||
auto result = create_shared_vdevice(element, device_count, vdevice_key, scheduling_algorithm, multi_process_service);
|
||||
GST_CHECK_EXPECTED(result, element, RESOURCE, "Failed creating vdevice, status = %d", result.status());
|
||||
m_vdevices.insert(result.value());
|
||||
return result;
|
||||
}
|
||||
auto result = create_unique_vdevice(element, device_count, scheduling_algorithm);
|
||||
auto result = create_unique_vdevice(element, device_count, scheduling_algorithm, multi_process_service);
|
||||
GST_CHECK_EXPECTED(result, element, RESOURCE, "Failed creating vdevice, status = %d", result.status());
|
||||
m_vdevices.insert(result.value());
|
||||
return result;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> NetworkGroupHandle::create_vdevice(const std::string &device_id, uint16_t device_count, uint32_t vdevice_key,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, bool multi_process_service)
|
||||
{
|
||||
auto expected_device = create_vdevice(m_element, device_id, device_count, vdevice_key, scheduling_algorithm);
|
||||
auto expected_device = create_vdevice(m_element, device_id, device_count, vdevice_key, scheduling_algorithm, multi_process_service);
|
||||
GST_CHECK_EXPECTED(expected_device, m_element, RESOURCE, "Failed creating vdevice, status = %d", expected_device.status());
|
||||
return expected_device;
|
||||
}
|
||||
|
||||
hailo_status NetworkGroupHandle::set_hef(const char *device_id, uint16_t device_count, uint32_t vdevice_key,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, const char *hef_path)
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, bool multi_process_service, const char *hef_path)
|
||||
{
|
||||
if (0 == device_count) {
|
||||
device_count = HAILO_DEFAULT_DEVICE_COUNT;
|
||||
@@ -125,7 +128,7 @@ hailo_status NetworkGroupHandle::set_hef(const char *device_id, uint16_t device_
|
||||
|
||||
std::string device_id_str = (nullptr == device_id) ? "" : device_id;
|
||||
|
||||
auto vdevice = create_vdevice(device_id_str, device_count, vdevice_key, scheduling_algorithm);
|
||||
auto vdevice = create_vdevice(device_id_str, device_count, vdevice_key, scheduling_algorithm, multi_process_service);
|
||||
GST_CHECK_EXPECTED_AS_STATUS(vdevice, m_element, RESOURCE, "Failed creating vdevice, status = %d", vdevice.status());
|
||||
m_vdevice = vdevice.release();
|
||||
|
||||
@@ -141,7 +144,7 @@ hailo_status NetworkGroupHandle::set_hef(const char *device_id, uint16_t device_
|
||||
auto hef = Hef::create(hef_path);
|
||||
GST_CHECK_EXPECTED_AS_STATUS(hef, m_element, RESOURCE, "Failed reading hef file %s, status = %d", hef_path, hef.status());
|
||||
|
||||
m_hef = make_shared_nothrow<Hef>(std::move(hef.release()));
|
||||
m_hef = make_shared_nothrow<Hef>(hef.release());
|
||||
GST_CHECK(nullptr != m_hef, HAILO_OUT_OF_HOST_MEMORY, m_element, RESOURCE, "Allocating memory for HEF has failed!");
|
||||
|
||||
return HAILO_SUCCESS;
|
||||
@@ -149,7 +152,7 @@ hailo_status NetworkGroupHandle::set_hef(const char *device_id, uint16_t device_
|
||||
|
||||
hailo_status NetworkGroupHandle::configure_network_group(const char *net_group_name, hailo_scheduling_algorithm_t scheduling_algorithm, uint16_t batch_size)
|
||||
{
|
||||
auto net_groups_params_map = get_configure_params(*m_hef, net_group_name, batch_size);
|
||||
auto net_groups_params_map = get_configure_params(*m_hef, *m_vdevice, net_group_name, batch_size);
|
||||
GST_CHECK_EXPECTED_AS_STATUS(net_groups_params_map, m_element, RESOURCE, "Failed getting configure params, status = %d", net_groups_params_map.status());
|
||||
|
||||
auto expected_cng = m_net_group_config_manager.configure_network_group(m_element, m_shared_device_id, scheduling_algorithm,
|
||||
@@ -185,12 +188,27 @@ Expected<std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>> Netwo
|
||||
"Inserting network name to configured networks has failed, status = %d", status);
|
||||
}
|
||||
|
||||
auto input_params_map = m_cng->make_input_vstream_params(true, HAILO_FORMAT_TYPE_AUTO, HAILO_DEFAULT_VSTREAM_TIMEOUT_MS,
|
||||
auto expected_input_vstream_infos = hef()->get_input_vstream_infos(network_name);
|
||||
GST_CHECK_EXPECTED(expected_input_vstream_infos, m_element, RESOURCE, "Failed getting input vstream infos, status = %d",
|
||||
expected_input_vstream_infos.status());
|
||||
auto expected_input_params_map = m_cng->make_input_vstream_params(true, HAILO_FORMAT_TYPE_AUTO, HAILO_DEFAULT_VSTREAM_TIMEOUT_MS,
|
||||
HAILO_DEFAULT_VSTREAM_QUEUE_SIZE, m_network_name);
|
||||
GST_CHECK_EXPECTED(input_params_map, m_element, RESOURCE, "Failed making input vstream params, status = %d",
|
||||
input_params_map.status());
|
||||
GST_CHECK_EXPECTED(expected_input_params_map, m_element, RESOURCE, "Failed making input vstream params, status = %d",
|
||||
expected_input_params_map.status());
|
||||
|
||||
auto input_vstreams = VStreamsBuilder::create_input_vstreams(*m_cng, input_params_map.release());
|
||||
// In RGB formats, Gstreamer is padding each row to 4.
|
||||
auto &&input_params_map = expected_input_params_map.release();
|
||||
auto &&input_infos = expected_input_vstream_infos.release();
|
||||
for (auto &input_info : input_infos) {
|
||||
if (input_params_map.count(input_info.name)) {
|
||||
auto &input_params = input_params_map[input_info.name];
|
||||
if (input_info.format.order == HAILO_FORMAT_ORDER_NHWC) {
|
||||
input_params.user_buffer_format.order = HAILO_FORMAT_ORDER_RGB4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto input_vstreams = VStreamsBuilder::create_input_vstreams(*m_cng, input_params_map);
|
||||
GST_CHECK_EXPECTED(input_vstreams, m_element, RESOURCE, "Failed creating input vstreams, status = %d", input_vstreams.status());
|
||||
|
||||
// TODO: HRT-4095
|
||||
@@ -220,17 +238,22 @@ Expected<std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>> Netwo
|
||||
GST_CHECK_EXPECTED(output_vstreams, m_element, RESOURCE, "Failed creating output vstreams, status = %d", output_vstreams.status());
|
||||
|
||||
return std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>(
|
||||
std::move(input_vstreams.release()), std::move(output_vstreams.release()));
|
||||
input_vstreams.release(), output_vstreams.release());
|
||||
}
|
||||
|
||||
Expected<NetworkGroupsParamsMap> NetworkGroupHandle::get_configure_params(Hef &hef, const char *net_group_name, uint16_t batch_size)
|
||||
Expected<NetworkGroupsParamsMap> NetworkGroupHandle::get_configure_params(Hef &hef, const VDevice &vdevice,
|
||||
const char *net_group_name, uint16_t batch_size)
|
||||
{
|
||||
auto params = hef.create_configure_params(HAILO_STREAM_INTERFACE_PCIE, net_group_name);
|
||||
auto stream_interface = vdevice.get_default_streams_interface();
|
||||
GST_CHECK_EXPECTED(stream_interface, m_element, RESOURCE,
|
||||
"Failed default stream interface configure params, status = %d", stream_interface.status());
|
||||
|
||||
auto params = hef.create_configure_params(*stream_interface, net_group_name);
|
||||
GST_CHECK_EXPECTED(params, m_element, RESOURCE, "Failed creating configure params, status = %d", params.status());
|
||||
params->batch_size = batch_size;
|
||||
|
||||
NetworkGroupsParamsMap net_groups_params_map;
|
||||
net_groups_params_map[net_group_name] = std::move(params.release());
|
||||
net_groups_params_map[net_group_name] = params.release();
|
||||
return net_groups_params_map;
|
||||
}
|
||||
|
||||
@@ -243,39 +266,6 @@ hailo_status NetworkGroupHandle::activate_network_group()
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status NetworkGroupHandle::abort_streams()
|
||||
{
|
||||
if (nullptr == m_cng) {
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status final_status = HAILO_SUCCESS;
|
||||
auto input_streams = m_cng->get_input_streams_by_network(m_network_name);
|
||||
GST_CHECK_EXPECTED_AS_STATUS(input_streams, m_element, RESOURCE, "Getting input streams by network name %s failed, status = %d",
|
||||
m_network_name.c_str(), input_streams.status());
|
||||
|
||||
for (auto &input_stream : input_streams.value()) {
|
||||
hailo_status status = input_stream.get().abort();
|
||||
if (HAILO_SUCCESS != status) {
|
||||
g_warning("Abort of input stream %s has failed, status = %d", input_stream.get().name().c_str(), status);
|
||||
final_status = status;
|
||||
}
|
||||
}
|
||||
|
||||
auto output_streams = m_cng->get_output_streams_by_network(m_network_name);
|
||||
GST_CHECK_EXPECTED_AS_STATUS(output_streams, m_element, RESOURCE, "Getting output streams by network name %s failed, status = %d",
|
||||
m_network_name.c_str(), output_streams.status());
|
||||
|
||||
for (auto &output_stream : output_streams.value()) {
|
||||
hailo_status status = output_stream.get().abort();
|
||||
if (HAILO_SUCCESS != status) {
|
||||
g_warning("Abort of output stream %s has failed, status = %d", output_stream.get().name().c_str(), status);
|
||||
final_status = status;
|
||||
}
|
||||
}
|
||||
return final_status;
|
||||
}
|
||||
|
||||
Expected<bool> NetworkGroupHandle::remove_network_group()
|
||||
{
|
||||
bool was_network_deactivated = false;
|
||||
@@ -407,7 +397,7 @@ Expected<std::shared_ptr<ActivatedNetworkGroup>> NetworkGroupActivationManager::
|
||||
GST_CHECK_EXPECTED(activated_network_group, element, RESOURCE, "Failed activating network group, status = %d",
|
||||
activated_network_group.status());
|
||||
|
||||
std::shared_ptr<ActivatedNetworkGroup> ang = std::move(activated_network_group.release());
|
||||
std::shared_ptr<ActivatedNetworkGroup> ang = activated_network_group.release();
|
||||
m_activated_net_groups[NetworkGroupConfigManager::get_configure_string(device_id, hef_hash, net_group_name, batch_size)] = ang;
|
||||
|
||||
return ang;
|
||||
|
||||
@@ -80,12 +80,11 @@ public:
|
||||
m_vdevice(nullptr), m_hef(nullptr), m_cng(nullptr), m_ang(nullptr) {}
|
||||
|
||||
hailo_status set_hef(const char *device_id, uint16_t device_count, uint32_t vdevice_key, hailo_scheduling_algorithm_t scheduling_algorithm,
|
||||
const char *hef_path);
|
||||
bool multi_process_service, const char *hef_path);
|
||||
hailo_status configure_network_group(const char *net_group_name, hailo_scheduling_algorithm_t scheduling_algorithm, uint16_t batch_size);
|
||||
Expected<std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>> create_vstreams(const char *network_name,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, const std::vector<hailo_format_with_name_t> &output_formats);
|
||||
hailo_status activate_network_group();
|
||||
hailo_status abort_streams();
|
||||
Expected<bool> remove_network_group();
|
||||
|
||||
hailo_status set_scheduler_timeout(const char *network_name, uint32_t timeout_ms);
|
||||
@@ -98,11 +97,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Expected<NetworkGroupsParamsMap> get_configure_params(Hef &hef, const char *net_group_name, uint16_t batch_size);
|
||||
Expected<NetworkGroupsParamsMap> get_configure_params(Hef &hef, const VDevice &vdevice, const char *net_group_name,
|
||||
uint16_t batch_size);
|
||||
static Expected<std::shared_ptr<VDevice>> create_vdevice(const void *element, const std::string &device_id, uint16_t device_count,
|
||||
uint32_t vdevice_key, hailo_scheduling_algorithm_t scheduling_algorithm);
|
||||
uint32_t vdevice_key, hailo_scheduling_algorithm_t scheduling_algorithm, bool multi_process_service);
|
||||
Expected<std::shared_ptr<VDevice>> create_vdevice(const std::string &device_id, uint16_t device_count, uint32_t vdevice_key,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm);
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, bool multi_process_service);
|
||||
|
||||
static std::unordered_set<std::shared_ptr<VDevice>> m_vdevices;
|
||||
static NetworkGroupConfigManager m_net_group_config_manager;
|
||||
|
||||
@@ -1,9 +1 @@
|
||||
add_subdirectory(src)
|
||||
|
||||
# copy files to venv
|
||||
if(HAILO_BUILD_PYHAILORT_VENV)
|
||||
add_custom_target(pyhailort_venv ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:_pyhailort> ${CMAKE_CURRENT_LIST_DIR}/platform/hailo_platform/pyhailort/
|
||||
)
|
||||
add_dependencies(pyhailort_venv _pyhailort)
|
||||
endif()
|
||||
@@ -1,4 +1,4 @@
|
||||
from hailo_platform import (HEF, PcieDevice, ConfigureParams, InferVStreams, InputVStreamParams,
|
||||
from hailo_platform import (HEF, VDevice, ConfigureParams, InferVStreams, InputVStreamParams,
|
||||
OutputVStreamParams, FormatType)
|
||||
from hailo_platform.pyhailort.pyhailort import HailoStreamInterface
|
||||
import numpy as np
|
||||
@@ -12,7 +12,7 @@ def parse_args():
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
with PcieDevice() as target:
|
||||
with VDevice() as target:
|
||||
hef = HEF(args.hef_path)
|
||||
configure_params = ConfigureParams.create_from_hef(hef, interface=HailoStreamInterface.PCIe)
|
||||
network_groups = target.configure(hef, configure_params)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import argparse
|
||||
from multiprocessing import Process
|
||||
|
||||
import time
|
||||
import numpy as np
|
||||
from hailo_platform import (HEF, PcieDevice, HailoStreamInterface, ConfigureParams, InputVStreamParams, InputVStreams,
|
||||
|
||||
from multiprocessing import Process
|
||||
from hailo_platform import (HEF, VDevice, HailoStreamInterface, ConfigureParams, InputVStreamParams, InputVStreams,
|
||||
OutputVStreamParams, OutputVStreams)
|
||||
|
||||
def send(configured_network, num_frames):
|
||||
@@ -45,17 +46,24 @@ def main():
|
||||
args = parse_args()
|
||||
hef = HEF(args.hef_path)
|
||||
|
||||
with PcieDevice() as device:
|
||||
with VDevice() as device:
|
||||
configure_params = ConfigureParams.create_from_hef(hef, interface=HailoStreamInterface.PCIe)
|
||||
network_group = device.configure(hef, configure_params)[0]
|
||||
network_group_params = network_group.create_params()
|
||||
send_process = Process(target=send, args=(network_group, args.num_frames))
|
||||
recv_process = Process(target=recv_all, args=(network_group, args.num_frames))
|
||||
|
||||
time_before = time.time()
|
||||
recv_process.start()
|
||||
send_process.start()
|
||||
with network_group.activate(network_group_params):
|
||||
send_process.join()
|
||||
recv_process.join()
|
||||
|
||||
fps = args.num_frames / (time.time() - time_before)
|
||||
|
||||
print('Inference ran successfully')
|
||||
print(f'FPS: {fps}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -26,7 +26,7 @@ from hailo_platform.pyhailort.pyhailort import (HEF, ConfigureParams,
|
||||
InputVStreams, OutputVStreams,
|
||||
InferVStreams, HailoStreamDirection, HailoFormatFlags, HailoCpuId, Device, VDevice,
|
||||
DvmTypes, PowerMeasurementTypes, SamplingPeriod, AveragingFactor, MeasurementBufferIndex,
|
||||
HailoRTException)
|
||||
HailoRTException, YOLOv5PostProcessingOp)
|
||||
|
||||
def _verify_pyhailort_lib_exists():
|
||||
python_version = "".join(str(i) for i in sys.version_info[:2])
|
||||
@@ -62,4 +62,4 @@ __all__ = ['EthernetDevice', 'DvmTypes', 'PowerMeasurementTypes',
|
||||
'MipiIspImageInOrder', 'MipiIspImageOutDataType', 'join_drivers_path', 'IspLightFrequency', 'HailoPowerMode',
|
||||
'Endianness', 'HailoStreamInterface', 'InputVStreamParams', 'OutputVStreamParams',
|
||||
'InputVStreams', 'OutputVStreams', 'InferVStreams', 'HailoStreamDirection', 'HailoFormatFlags', 'HailoCpuId',
|
||||
'Device', 'VDevice', 'HailoRTException']
|
||||
'Device', 'VDevice', 'HailoRTException', 'YOLOv5PostProcessingOp']
|
||||
|
||||
@@ -50,17 +50,19 @@ class HailoHWObject(object):
|
||||
@property
|
||||
def name(self):
|
||||
"""str: The name of this target. Valid values are defined by :class:`~hailo_platform.pyhailort.hw_object.InferenceTargets`"""
|
||||
# self._logger.warning("HailoHWObject name property is deprecated! Please use VDevice object with device_id.")
|
||||
return type(self).NAME
|
||||
|
||||
@property
|
||||
def is_hardware(self):
|
||||
"""bool: Indicates this target runs on a physical hardware device."""
|
||||
# TODO: SDK should implement in Target
|
||||
# self._logger.warning("HailoHWObject is_hardware property is deprecated! Please use VDevice object, or derive from it.")
|
||||
return type(self).IS_HARDWARE
|
||||
|
||||
@property
|
||||
def device_id(self):
|
||||
"""Getter for the device_id.
|
||||
|
||||
Returns:
|
||||
str: A string ID of the device. BDF for PCIe devices, IP address for Ethernet devices, "Core" for core devices.
|
||||
"""
|
||||
@@ -72,12 +74,14 @@ class HailoHWObject(object):
|
||||
Returns:
|
||||
list of str: Sorted list of the output layer names.
|
||||
"""
|
||||
# self._logger.warning("HailoHWObject sorted_output_layer_names property is deprecated! Please use ConfiguredNetwork get_sorted_output_names.")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to sorted_output_layer_names is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0].get_sorted_output_names()
|
||||
|
||||
@contextmanager
|
||||
def use_device(self, *args, **kwargs):
|
||||
# self._logger.warning("HailoHWObject use_device context manager is deprecated! Please use VDevice object.")
|
||||
"""A context manager that wraps the usage of the device (deprecated)."""
|
||||
self._is_device_used = True
|
||||
yield
|
||||
@@ -89,6 +93,7 @@ class HailoHWObject(object):
|
||||
Returns:
|
||||
dict: Keys are device output names and values are lists of layers' names.
|
||||
"""
|
||||
# self._logger.warning("HailoHWObject get_output_device_layer_to_original_layer_map function is deprecated!")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to layer names is only allowed when there is a single loaded network group")
|
||||
return {stream_info.name : self._loaded_network_groups[0].get_vstream_names_from_stream_name(stream_info.name)
|
||||
@@ -100,6 +105,7 @@ class HailoHWObject(object):
|
||||
Returns:
|
||||
dict: Keys are the names of the layers and values are device outputs names.
|
||||
"""
|
||||
# self._logger.warning("HailoHWObject get_original_layer_to_device_layer_map function is deprecated!")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to layer names is only allowed when there is a single loaded network group")
|
||||
return {vstream_info.name : self._loaded_network_groups[0].get_stream_names_from_vstream_name(vstream_info.name)
|
||||
@@ -108,24 +114,31 @@ class HailoHWObject(object):
|
||||
@property
|
||||
def device_input_layers(self):
|
||||
"""Get a list of the names of the device's inputs."""
|
||||
# self._logger.warning("HailoHWObject device_input_layers function is deprecated! Please use ConfiguredNetwork object.")
|
||||
return [layer.name for layer in self.get_input_stream_infos()]
|
||||
|
||||
@property
|
||||
def device_output_layers(self):
|
||||
"""Get a list of the names of the device's outputs."""
|
||||
# self._logger.warning("HailoHWObject device_output_layers function is deprecated! Please use ConfiguredNetwork object.")
|
||||
return [layer.name for layer in self.get_output_stream_infos()]
|
||||
|
||||
def hef_loaded(self):
|
||||
"""Return True if this object has loaded the model HEF to the hardware device."""
|
||||
# TODO: SDK should implement in Target
|
||||
# self._logger.warning("HailoHWObject hef_loaded function is deprecated! Please use VDevice object, or derive from it.")
|
||||
return self._hef_loaded
|
||||
|
||||
def outputs_count(self):
|
||||
"""Return the amount of output tensors that are returned from the hardware device for every
|
||||
input image.
|
||||
"""
|
||||
# self._logger.warning("HailoHWObject outputs_count function is deprecated! Please use ConfiguredNetwork object.")
|
||||
return len(self.get_output_vstream_infos())
|
||||
|
||||
def _clear_shapes(self):
|
||||
# TODO: SDK should implement in Target
|
||||
# self._logger.warning("HailoHWObject _clear_shapes function is deprecated! Please use ConfiguredNetwork object.")
|
||||
self._hw_consts = None
|
||||
|
||||
@property
|
||||
@@ -135,6 +148,7 @@ class HailoHWObject(object):
|
||||
Returns:
|
||||
str: Model name.
|
||||
"""
|
||||
# self._logger.warning("HailoHWObject model_name property is deprecated! Please use ConfiguredNetwork object.")
|
||||
if len(self._loaded_network_groups) == 1:
|
||||
return self._loaded_network_groups[0].name
|
||||
raise HailoHWObjectException(
|
||||
@@ -146,6 +160,7 @@ class HailoHWObject(object):
|
||||
Returns:
|
||||
Tuple of output shapes, sorted by the output names.
|
||||
"""
|
||||
# self._logger.warning("HailoHWObject get_output_shapes function is deprecated! Please use ConfiguredNetwork object.")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Calling get_output_shapes is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0].get_output_shapes()
|
||||
@@ -166,7 +181,6 @@ class HailoChipObject(HailoHWObject):
|
||||
def control(self):
|
||||
""":class:`HailoControl <hailo_platform.pyhailort.control_object.HailoControl>`: Returns
|
||||
the control object of this device, which implements the control API of the Hailo device.
|
||||
|
||||
.. attention:: Use the low level control API with care.
|
||||
"""
|
||||
if self._control_object is None:
|
||||
@@ -181,6 +195,7 @@ class HailoChipObject(HailoHWObject):
|
||||
Returns:
|
||||
dict of :obj:'numpy.dtype': where the key is model input_layer name, and the value is dtype as the device expect to get for this input.
|
||||
"""
|
||||
# self._logger.warning("HailoChipObject get_all_input_layers_dtype function is deprecated! Please use ConfiguredNetwork object.")
|
||||
return {stream.name: HailoRTTransformUtils.get_dtype(stream.data_bytes) for stream in self.get_input_stream_infos()}
|
||||
|
||||
def get_input_vstream_infos(self, network_name=None):
|
||||
@@ -193,7 +208,7 @@ class HailoChipObject(HailoHWObject):
|
||||
If there is exactly one configured network group, returns a list of
|
||||
:obj:`hailo_platform.pyhailort._pyhailort.VStreamInfo`: with all the information objects of all input vstreams
|
||||
"""
|
||||
|
||||
# self._logger.warning("HailoChipObject get_input_vstream_infos function is deprecated! Please use ConfiguredNetwork object.")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to network vstream info is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0].get_input_vstream_infos(network_name=network_name)
|
||||
@@ -208,7 +223,7 @@ class HailoChipObject(HailoHWObject):
|
||||
If there is exactly one configured network group, returns a list of
|
||||
:obj:`hailo_platform.pyhailort._pyhailort.VStreamInfo`: with all the information objects of all output vstreams
|
||||
"""
|
||||
|
||||
# self._logger.warning("HailoChipObject get_output_vstream_infos function is deprecated! Please use ConfiguredNetwork object.")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to network vstream info is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0].get_output_vstream_infos(network_name=network_name)
|
||||
@@ -223,7 +238,7 @@ class HailoChipObject(HailoHWObject):
|
||||
If there is exactly one configured network group, returns a list of
|
||||
:obj:`hailo_platform.pyhailort._pyhailort.VStreamInfo`: with all the information objects of all input and output vstreams
|
||||
"""
|
||||
|
||||
# self._logger.warning("HailoChipObject get_all_vstream_infos function is deprecated! Please use ConfiguredNetwork object.")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to network vstream info is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0].get_all_vstream_infos(network_name=network_name)
|
||||
@@ -239,6 +254,7 @@ class HailoChipObject(HailoHWObject):
|
||||
:obj:`hailo_platform.pyhailort._pyhailort.VStreamInfo`: with information objects
|
||||
of all input low-level streams.
|
||||
"""
|
||||
# self._logger.warning("HailoChipObject get_input_stream_infos function is deprecated! Please use ConfiguredNetwork object.")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to network stream info is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0].get_input_stream_infos(network_name=network_name)
|
||||
@@ -254,6 +270,7 @@ class HailoChipObject(HailoHWObject):
|
||||
:obj:`hailo_platform.pyhailort._pyhailort.VStreamInfo`: with information objects
|
||||
of all output low-level streams.
|
||||
"""
|
||||
# self._logger.warning("HailoChipObject get_output_stream_infos function is deprecated! Please use ConfiguredNetwork object.")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to network stream info is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0].get_output_stream_infos(network_name=network_name)
|
||||
@@ -268,7 +285,7 @@ class HailoChipObject(HailoHWObject):
|
||||
If there is exactly one configured network group, returns a list of
|
||||
:obj:`hailo_platform.pyhailort._pyhailort.StreamInfo`: with all the information objects of all input and output streams
|
||||
"""
|
||||
|
||||
# self._logger.warning("HailoChipObject get_all_stream_infos function is deprecated! Please use ConfiguredNetwork object.")
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoHWObjectException("Access to network stream info is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0].get_all_stream_infos(network_name=network_name)
|
||||
@@ -276,7 +293,6 @@ class HailoChipObject(HailoHWObject):
|
||||
@property
|
||||
def loaded_network_groups(self):
|
||||
"""Getter for the property _loaded_network_groups.
|
||||
|
||||
Returns:
|
||||
list of :obj:`ConfiguredNetwork`: List of the the configured network groups loaded on the device.
|
||||
"""
|
||||
@@ -290,7 +306,6 @@ class HailoChipObject(HailoHWObject):
|
||||
|
||||
def configure(self, hef, configure_params_by_name={}):
|
||||
"""Configures target device from HEF object.
|
||||
|
||||
Args:
|
||||
hef (:class:`~hailo_platform.pyhailort.pyhailort.HEF`): HEF to configure the device from
|
||||
configure_params_by_name (dict, optional): Maps between each net_group_name to configure_params. If not provided, default params will be applied
|
||||
@@ -313,6 +328,7 @@ class HailoChipObject(HailoHWObject):
|
||||
Returns:
|
||||
Tuple of integers representing the input_shape.
|
||||
"""
|
||||
# self._logger.warning("HailoChipObject get_input_shape function is deprecated! Please use ConfiguredNetwork object.")
|
||||
if name is None:
|
||||
name = self.get_input_vstream_infos()[0].name
|
||||
|
||||
@@ -332,6 +348,7 @@ class HailoChipObject(HailoHWObject):
|
||||
Returns:
|
||||
int: The index of the layer name in the output list.
|
||||
"""
|
||||
# self._logger.warning("HailoChipObject get_index_from_name function is deprecated! Please use ConfiguredNetwork object.")
|
||||
try:
|
||||
return self.sorted_output_layer_names.index(name)
|
||||
except ValueError:
|
||||
@@ -383,7 +400,6 @@ class EthernetDevice(HailoChipObject):
|
||||
self._control_object = None
|
||||
|
||||
self._open_device()
|
||||
|
||||
self._id = "{}".format(self._remote_ip)
|
||||
identity = self._control_object._identify_info
|
||||
self._hw_arch = BoardInformation.get_hw_arch_str(identity.device_architecture)
|
||||
@@ -398,6 +414,7 @@ class EthernetDevice(HailoChipObject):
|
||||
Returns:
|
||||
list of str: IPs of scanned devices.
|
||||
"""
|
||||
# default_logger().warning("EthernetDevice scan_devices method is deprecated! Please use scan() of Device object.")
|
||||
udp_scanner = HailoUdpScan()
|
||||
return udp_scanner.scan_devices(interface_name, timeout_seconds=timeout_seconds)
|
||||
|
||||
@@ -418,6 +435,7 @@ class EthernetDevice(HailoChipObject):
|
||||
@property
|
||||
def remote_ip(self):
|
||||
"""Return the IP of the remote device."""
|
||||
# self._logger.warning("EthernetDevice remote_ip method is deprecated! Please use Device object.")
|
||||
return self._remote_ip
|
||||
|
||||
|
||||
@@ -437,6 +455,7 @@ class PcieDevice(HailoChipObject):
|
||||
:func:`PcieDevice.scan_devices` to get list of all available devices.
|
||||
"""
|
||||
super(PcieDevice, self).__init__()
|
||||
# self._logger.warning("PcieDevice deprecated! Please use VDevice object.")
|
||||
|
||||
gc.collect()
|
||||
# PcieDevice __del__ function tries to release self._device.
|
||||
@@ -460,6 +479,7 @@ class PcieDevice(HailoChipObject):
|
||||
Returns:
|
||||
list of :obj:`hailo_platform.pyhailort.pyhailort.PcieDeviceInfo`
|
||||
"""
|
||||
# default_logger().warning("PcieDevice scan_devices method is deprecated! Please use scan() of Device object.")
|
||||
return InternalPcieDevice.scan_devices()
|
||||
|
||||
def _open_device(self, device_info):
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from enum import Enum, IntEnum
|
||||
import re
|
||||
import signal
|
||||
import struct
|
||||
import pkg_resources
|
||||
@@ -123,7 +122,7 @@ class ExceptionWrapper(object):
|
||||
raise HailoRTInvalidFrameException("An invalid frame was received")
|
||||
if string_error_code == "HAILO_TIMEOUT":
|
||||
raise HailoRTTimeout("Received a timeout - hailort has failed because a timeout had occurred")
|
||||
if string_error_code == "HAILO_STREAM_ABORTED":
|
||||
if string_error_code == "HAILO_STREAM_ABORTED_BY_HW":
|
||||
raise HailoRTStreamAborted("Stream aborted due to an external event")
|
||||
|
||||
if string_error_code == "HAILO_INVALID_OPERATION":
|
||||
@@ -1076,6 +1075,7 @@ class HailoRTTransformUtils(object):
|
||||
|
||||
class InternalEthernetDevice(object):
|
||||
def __init__(self, address, port, response_timeout_seconds=10, max_number_of_attempts=3):
|
||||
# default_logger().warning("InternalEthernetDevice is deprecated! Please use Device object.")
|
||||
self.device = None
|
||||
self._address = address
|
||||
self._port = port
|
||||
@@ -1104,6 +1104,7 @@ class PcieDeviceInfo(_pyhailort.PcieDeviceInfo):
|
||||
|
||||
def __init__(self, bus, device, func, domain=None):
|
||||
super(PcieDeviceInfo, self).__init__()
|
||||
# default_logger().warning("PcieDeviceInfo is deprecated! Please use Device object with device_id.")
|
||||
self.bus = bus
|
||||
self.device = device
|
||||
self.func = func
|
||||
@@ -1140,6 +1141,7 @@ class PcieDeviceInfo(_pyhailort.PcieDeviceInfo):
|
||||
|
||||
class InternalPcieDevice(object):
|
||||
def __init__(self, device_info=None):
|
||||
# self._logger.warning("InternalPcieDevice deprecated! Please use Device object.")
|
||||
self.device = None
|
||||
if device_info is None:
|
||||
device_info = InternalPcieDevice.scan_devices()[0]
|
||||
@@ -1233,7 +1235,7 @@ class HailoFormatFlags(_pyhailort.FormatFlags):
|
||||
|
||||
SUPPORTED_PROTOCOL_VERSION = 2
|
||||
SUPPORTED_FW_MAJOR = 4
|
||||
SUPPORTED_FW_MINOR = 10
|
||||
SUPPORTED_FW_MINOR = 12
|
||||
SUPPORTED_FW_REVISION = 0
|
||||
|
||||
MEGA_MULTIPLIER = 1000.0 * 1000.0
|
||||
@@ -1250,9 +1252,11 @@ class DeviceArchitectureTypes(IntEnum):
|
||||
|
||||
class BoardInformation(object):
|
||||
def __init__(self, protocol_version, fw_version_major, fw_version_minor, fw_version_revision,
|
||||
logger_version, board_name, is_release, device_architecture, serial_number, part_number, product_name):
|
||||
logger_version, board_name, is_release, extended_context_switch_buffer, device_architecture,
|
||||
serial_number, part_number, product_name):
|
||||
self.protocol_version = protocol_version
|
||||
self.firmware_version = HailoFirmwareVersion.construct_from_params(fw_version_major, fw_version_minor, fw_version_revision, is_release, HailoFirmwareType.APP)
|
||||
self.firmware_version = HailoFirmwareVersion.construct_from_params(fw_version_major, fw_version_minor, fw_version_revision, is_release,
|
||||
extended_context_switch_buffer, HailoFirmwareType.APP)
|
||||
self.logger_version = logger_version
|
||||
self.board_name = board_name
|
||||
self.is_release = is_release
|
||||
@@ -1303,8 +1307,9 @@ class BoardInformation(object):
|
||||
raise HailoRTException("Unsupported device architecture.")
|
||||
|
||||
class CoreInformation(object):
|
||||
def __init__(self, fw_version_major, fw_version_minor, fw_version_revision, is_release):
|
||||
self.firmware_version = HailoFirmwareVersion.construct_from_params(fw_version_major, fw_version_minor, fw_version_revision, is_release, HailoFirmwareType.CORE)
|
||||
def __init__(self, fw_version_major, fw_version_minor, fw_version_revision, is_release, extended_context_switch_buffer):
|
||||
self.firmware_version = HailoFirmwareVersion.construct_from_params(fw_version_major, fw_version_minor, fw_version_revision, is_release,
|
||||
extended_context_switch_buffer, HailoFirmwareType.CORE)
|
||||
self.is_release = is_release
|
||||
|
||||
def __str__(self):
|
||||
@@ -1456,17 +1461,20 @@ class HailoFirmwareType(Enum):
|
||||
|
||||
class HailoFirmwareVersion(object):
|
||||
"""Represents a Hailo chip firmware version."""
|
||||
DEV_BIT = 0x80000000
|
||||
CORE_BIT = 0x08000000
|
||||
EXTENDED_CONTEXT_SWITCH_BUFFER_BIT = 0x40000000
|
||||
DEV_BIT = 0x80000000
|
||||
FW_VERSION_FORMAT = '<III'
|
||||
|
||||
def __init__(self, firmware_version_buffer, is_release, fw_type):
|
||||
def __init__(self, firmware_version_buffer, is_release, extended_context_switch_buffer, fw_type):
|
||||
"""Initialize a new Hailo Firmware Version object.
|
||||
|
||||
Args:
|
||||
firmware_version_buffer (str): A buffer containing the firmware version struct.
|
||||
is_release (bool, optional): Flag indicating if firmware is at develop/release mode.
|
||||
None indicates unknown
|
||||
extended_context_switch_buffer (bool): Flag indicating if firmware has an extended context switch buffer.
|
||||
fw_type (HailoFirmwareType): Firmware type
|
||||
"""
|
||||
self.major, self.minor, self.revision = struct.unpack(
|
||||
self.FW_VERSION_FORMAT,
|
||||
@@ -1474,21 +1482,24 @@ class HailoFirmwareVersion(object):
|
||||
|
||||
self.fw_type = fw_type
|
||||
self.mode = HailoFirmwareMode.RELEASE if is_release else HailoFirmwareMode.DEVELOP
|
||||
self.extended_context_switch_buffer = extended_context_switch_buffer
|
||||
|
||||
self.revision &= ~(self.CORE_BIT | self.DEV_BIT)
|
||||
self.revision &= ~(self.CORE_BIT | self.EXTENDED_CONTEXT_SWITCH_BUFFER_BIT | self.DEV_BIT)
|
||||
|
||||
def __str__(self):
|
||||
"""Returns:
|
||||
str: Firmware version in a human readable format.
|
||||
"""
|
||||
return '{}.{}.{} ({},{})'.format(self.major, self.minor, self.revision, self.mode.value, self.fw_type.value)
|
||||
return '{}.{}.{} ({},{}{})'.format(self.major, self.minor, self.revision, self.mode.value, self.fw_type.value,
|
||||
',extended context switch buffer' if self.extended_context_switch_buffer else '')
|
||||
|
||||
@classmethod
|
||||
def construct_from_params(cls, major, minor, revision, is_release, fw_type):
|
||||
def construct_from_params(cls, major, minor, revision, is_release, extended_context_switch_buffer, fw_type):
|
||||
"""Returns:
|
||||
class HailoFirmwareVersion : with the given Firmware version.
|
||||
"""
|
||||
return cls(struct.pack(HailoFirmwareVersion.FW_VERSION_FORMAT, major, minor, revision), is_release, fw_type)
|
||||
return cls(struct.pack(HailoFirmwareVersion.FW_VERSION_FORMAT, major, minor, revision), is_release,
|
||||
extended_context_switch_buffer, fw_type)
|
||||
|
||||
@property
|
||||
def comparable_value(self):
|
||||
@@ -1538,14 +1549,6 @@ class SupportedFeatures(object):
|
||||
def _is_feature_enabled(self, feature):
|
||||
return (self.supported_features & feature) != 0
|
||||
|
||||
def _enum_to_dict(enum):
|
||||
return {k: v for k, v in enum.__dict__.items() if not re.match("__(.*)", str(k)) and isinstance(v, enum)}
|
||||
|
||||
def _get_buffer_index_enum_member(index):
|
||||
for name, member in _enum_to_dict(MeasurementBufferIndex).items():
|
||||
if int(member) == index:
|
||||
return member
|
||||
raise HailoRTException("Invalid index")
|
||||
|
||||
class Control:
|
||||
"""The control object of this device, which implements the control API of the Hailo device.
|
||||
@@ -1675,11 +1678,10 @@ class Control:
|
||||
with ExceptionWrapper():
|
||||
return self._device.power_measurement(dvm, measurement_type)
|
||||
|
||||
def start_power_measurement(self, delay=None, averaging_factor=AveragingFactor.AVERAGE_256, sampling_period=SamplingPeriod.PERIOD_1100us):
|
||||
def start_power_measurement(self, averaging_factor=AveragingFactor.AVERAGE_256, sampling_period=SamplingPeriod.PERIOD_1100us):
|
||||
"""Start performing a long power measurement.
|
||||
|
||||
Args:
|
||||
delay: Unused parameter. Will be removed in future versions.
|
||||
averaging_factor (:class:`~hailo_platform.pyhailort.pyhailort.AveragingFactor`):
|
||||
Number of samples per time period, sensor configuration value.
|
||||
sampling_period (:class:`~hailo_platform.pyhailort.pyhailort.SamplingPeriod`):
|
||||
@@ -1691,9 +1693,6 @@ class Control:
|
||||
calculated by the firmware is "average of averages", because it averages values
|
||||
that have already been averaged by the sensor.
|
||||
"""
|
||||
# TODO: Remove deprecated arg
|
||||
if delay is not None:
|
||||
self._logger.warning("Passing 'delay' to 'start_power_measurement()' is deprecated and will be removed in future versions")
|
||||
with ExceptionWrapper():
|
||||
return self._device.start_power_measurement(averaging_factor, sampling_period)
|
||||
|
||||
@@ -1727,11 +1726,6 @@ class Control:
|
||||
This function can perform measurements for more than just power. For all supported measurement types
|
||||
view :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes`
|
||||
"""
|
||||
# TODO: Remove deprecated arg
|
||||
if isinstance(buffer_index, int):
|
||||
self._logger.warning("Passing integer as 'buffer_index' to 'set_power_measurement()' is deprecated. One should pass "
|
||||
":class:`~hailo_platform.pyhailort.pyhailort.MeasurementBufferIndex` as 'buffer_index' instead.")
|
||||
buffer_index = _get_buffer_index_enum_member(buffer_index)
|
||||
with ExceptionWrapper():
|
||||
return self._device.set_power_measurement(buffer_index, dvm, measurement_type)
|
||||
|
||||
@@ -1760,11 +1754,6 @@ class Control:
|
||||
if ((self._identify_info.device_architecture != DeviceArchitectureTypes.HAILO8) and
|
||||
(self._identify_info.device_architecture != DeviceArchitectureTypes.HAILO8L)):
|
||||
raise HailoRTException("Invalid device architecture: {}".format(self._identify_info.device_architecture))
|
||||
# TODO: Remove deprecated arg
|
||||
if isinstance(buffer_index, int):
|
||||
self._logger.warning("Passing integer as 'buffer_index' to 'get_power_measurement()' is deprecated. One should pass "
|
||||
":class:`~hailo_platform.pyhailort.pyhailort.MeasurementBufferIndex` as 'buffer_index' instead.")
|
||||
buffer_index = _get_buffer_index_enum_member(buffer_index)
|
||||
with ExceptionWrapper():
|
||||
return self._device.get_power_measurement(buffer_index, should_clear)
|
||||
|
||||
@@ -1822,8 +1811,9 @@ class Control:
|
||||
response = self._device.identify()
|
||||
board_information = BoardInformation(response.protocol_version, response.fw_version.major,
|
||||
response.fw_version.minor, response.fw_version.revision, response.logger_version,
|
||||
response.board_name, response.is_release, int(response.device_architecture), response.serial_number,
|
||||
response.part_number, response.product_name)
|
||||
response.board_name, response.is_release, response.extended_context_switch_buffer,
|
||||
int(response.device_architecture), response.serial_number, response.part_number,
|
||||
response.product_name)
|
||||
return board_information
|
||||
|
||||
def core_identify(self):
|
||||
@@ -1835,7 +1825,7 @@ class Control:
|
||||
with ExceptionWrapper():
|
||||
response = self._device.core_identify()
|
||||
core_information = CoreInformation(response.fw_version.major, response.fw_version.minor,
|
||||
response.fw_version.revision, response.is_release)
|
||||
response.fw_version.revision, response.is_release, response.extended_context_switch_buffer)
|
||||
return core_information
|
||||
|
||||
def set_fw_logger(self, level, interface_mask):
|
||||
@@ -2190,7 +2180,6 @@ class Control:
|
||||
return self._device
|
||||
|
||||
|
||||
# TODO: HRT-7718 - implement more functionalities from hw_object.py
|
||||
class Device:
|
||||
""" Hailo device object representation. """
|
||||
|
||||
@@ -2213,6 +2202,7 @@ class Device:
|
||||
"""
|
||||
gc.collect()
|
||||
|
||||
self._logger = default_logger()
|
||||
# Device __del__ function tries to release self._device.
|
||||
# to avoid AttributeError if the __init__ func fails, we set it to None first.
|
||||
# https://stackoverflow.com/questions/6409644/is-del-called-on-an-object-that-doesnt-complete-init
|
||||
@@ -2286,47 +2276,66 @@ class Device:
|
||||
"""
|
||||
return self._control_object
|
||||
|
||||
def read_log(self, count, cpu_id):
|
||||
"""
|
||||
Returns:
|
||||
Returns buffer with debug log data.
|
||||
|
||||
Args:
|
||||
count (int): bytes count to read
|
||||
cpu_id (HailoCpuId): cpu id
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.read_log(count, cpu_id)
|
||||
|
||||
@property
|
||||
def loaded_network_groups(self):
|
||||
"""Getter for the property _loaded_network_groups.
|
||||
|
||||
Returns:
|
||||
list of :obj:`ConfiguredNetwork`: List of the the configured network groups loaded on the device.
|
||||
"""
|
||||
return self._loaded_network_groups
|
||||
|
||||
@property
|
||||
def _loaded_network_group(self):
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoRTException("Access to network group is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0]
|
||||
|
||||
|
||||
class VDevice(object):
|
||||
"""Hailo virtual device representation."""
|
||||
|
||||
def __init__(self, params=None, device_infos=None, *, device_ids=None):
|
||||
def __init__(self, params=None, *, device_ids=None):
|
||||
|
||||
"""Create the Hailo virtual device object.
|
||||
|
||||
Args:
|
||||
params (:obj:`hailo_platform.pyhailort.pyhailort.VDeviceParams`, optional): VDevice params, call
|
||||
:func:`VDevice.create_params` to get default params. Excludes 'device_ids' and 'device_infos'.
|
||||
device_infos (list of :obj:`hailo_platform.pyhailort.pyhailort.PcieDeviceInfo`, optional):
|
||||
Deprecated - one should use device_ids instead. If given - pcie devices infos to create VDevice from,
|
||||
call :func:`PcieDevice.scan_devices` to get list of all available devices. Excludes 'params' and 'device_ids.
|
||||
device_ids (list of str, optional): devices ids to create VDevice from, call :func:`_Device.scan` to get
|
||||
list of all available devices. Excludes 'params' and 'device_infos'.
|
||||
:func:`VDevice.create_params` to get default params. Excludes 'device_ids'.
|
||||
device_ids (list of str, optional): devices ids to create VDevice from, call :func:`Device.scan` to get
|
||||
list of all available devices. Excludes 'params'.
|
||||
"""
|
||||
gc.collect()
|
||||
|
||||
# VDevice __del__ function tries to release self._vdevice.
|
||||
# to avoid AttributeError if the __init__ func fails, we set it to None first.
|
||||
# https://stackoverflow.com/questions/6409644/is-del-called-on-an-object-that-doesnt-complete-init
|
||||
self._vdevice = None
|
||||
|
||||
self._id = "VDevice"
|
||||
self._params = params
|
||||
|
||||
# Convert device_infos to device_ids
|
||||
if device_infos is not None:
|
||||
if device_ids is not None:
|
||||
raise HailoRTException("VDevice can by ids from either device_ids or device_infos. Both parameters were passed to the c'tor")
|
||||
|
||||
logger = default_logger()
|
||||
logger.warning("Warning - passing device_infos is deprecated. One should pass device_ids.")
|
||||
device_ids = [str(device_info) for device_info in device_infos]
|
||||
device_infos = None
|
||||
self._loaded_network_groups = []
|
||||
self._creation_pid = os.getpid()
|
||||
|
||||
self._device_ids = device_ids
|
||||
if self._device_ids is not None:
|
||||
if self._params is not None:
|
||||
raise HailoRTException("VDevice can be created from params or device ids/infos. Both parameters were passed to the c'tor")
|
||||
raise HailoRTException("VDevice can be created from params or device ids. Both parameters were passed to the c'tor")
|
||||
|
||||
self._vdevice = None
|
||||
self._loaded_network_groups = []
|
||||
self._open_vdevice()
|
||||
|
||||
self._creation_pid = os.getpid()
|
||||
|
||||
def _open_vdevice(self):
|
||||
if self._device_ids is not None:
|
||||
with ExceptionWrapper():
|
||||
@@ -2382,19 +2391,6 @@ class VDevice(object):
|
||||
phys_dev_infos = self.get_physical_devices_ids()
|
||||
return [Device(dev_id) for dev_id in phys_dev_infos]
|
||||
|
||||
def get_physical_devices_infos(self):
|
||||
"""Deprecated: :func:`VDevice.get_physical_devices_infos` is deprecated. One should use
|
||||
(:func:`VDevice.get_physical_devices_ids`) instead.
|
||||
|
||||
Gets the physical devices infos.
|
||||
|
||||
Return:
|
||||
list of :obj:`~hailo_platform.pyhailort.pyhailort.PcieDeviceInfo`: The underlying physical devices infos.
|
||||
"""
|
||||
logger = default_logger()
|
||||
logger.warning("Warning - VDevice.get_physical_devices_infos() is deprecated. One should use VDevice.get_physical_devices_ids.")
|
||||
return [PcieDeviceInfo.from_string(dev_id) for dev_id in self.get_physical_devices_ids()]
|
||||
|
||||
def get_physical_devices_ids(self):
|
||||
"""Gets the physical devices ids.
|
||||
|
||||
@@ -2404,6 +2400,22 @@ class VDevice(object):
|
||||
with ExceptionWrapper():
|
||||
return self._vdevice.get_physical_devices_ids()
|
||||
|
||||
@property
|
||||
def loaded_network_groups(self):
|
||||
"""Getter for the property _loaded_network_groups.
|
||||
|
||||
Returns:
|
||||
list of :obj:`ConfiguredNetwork`: List of the the configured network groups loaded on the device.
|
||||
"""
|
||||
return self._loaded_network_groups
|
||||
|
||||
@property
|
||||
def _loaded_network_group(self):
|
||||
if len(self._loaded_network_groups) != 1:
|
||||
raise HailoRTException("Access to network group is only allowed when there is a single loaded network group")
|
||||
return self._loaded_network_groups[0]
|
||||
|
||||
|
||||
class InputVStreamParams(object):
|
||||
"""Parameters of an input virtual stream (host to device)."""
|
||||
|
||||
@@ -2883,3 +2895,14 @@ class OutputVStreams(object):
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._vstreams.values())
|
||||
|
||||
class YOLOv5PostProcessingOp(object):
|
||||
|
||||
def __init__(self, anchors, shapes, formats, quant_infos, image_height, image_width, confidence_threshold, iou_threshold, num_of_classes,
|
||||
should_dequantize, max_boxes, should_sigmoid, one_class_per_bbox=True):
|
||||
|
||||
self._op = _pyhailort.YOLOv5PostProcessingOp.create(anchors, shapes, formats, quant_infos, image_height, image_width, confidence_threshold,
|
||||
iou_threshold, num_of_classes, should_dequantize, max_boxes, should_sigmoid, one_class_per_bbox)
|
||||
|
||||
def execute(self, net_flow_tensors):
|
||||
return self._op.execute(net_flow_tensors)
|
||||
@@ -49,12 +49,6 @@ class HailoDeviceCmdUtil(CmdUtilsBaseUtil):
|
||||
|
||||
|
||||
def validate_args(self, args):
|
||||
if args.target == HailoCLITargets.udp.value:
|
||||
if not args.ip:
|
||||
self._parser.error('When using --target udp, you must supply --ip')
|
||||
if args.board_location:
|
||||
self._parser.error("When using --target udp, you must not supply --board-location")
|
||||
|
||||
if args.board_location:
|
||||
all_devices = InternalPcieDevice.scan_devices()
|
||||
if args.board_location not in all_devices:
|
||||
@@ -62,8 +56,6 @@ class HailoDeviceCmdUtil(CmdUtilsBaseUtil):
|
||||
.format(args.board_location))
|
||||
|
||||
def add_target_args(self, args_parser):
|
||||
args_parser.add_argument('--target', type=str, choices=[t.value for t in HailoCLITargets],
|
||||
default=None, help='Device type to use')
|
||||
args_parser.add_argument('--ip', type=str, default=None, help='IP address of the target (udp)')
|
||||
args_parser.add_argument('-s', '--board-location', help=PcieDeviceInfo.BOARD_LOCATION_HELP_STRING,
|
||||
type=PcieDeviceInfo.argument_type)
|
||||
|
||||
@@ -76,6 +76,12 @@ class UDPRateLimiterCLI(HailortCliUtil):
|
||||
super().__init__(parser, 'udp-rate-limiter')
|
||||
|
||||
|
||||
class VersionCLI(HailortCliUtil):
|
||||
"""CLI tool for hailort version."""
|
||||
def __init__(self, parser):
|
||||
super().__init__(parser, '--version')
|
||||
|
||||
|
||||
class TutorialRequired(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ from hailo_platform.tools.hailocli.base_utils import HailortCliUtil, Helper, Hai
|
||||
from hailo_platform.tools.hailocli.hailocli_commands import (FWUpdaterCLI, SSBUpdaterCLI, ControlCommandCLI, ScanCommandCLI,
|
||||
LoggerCommandCLI, MeasurePowerCommandCLI, RunCommandCLI, SensorConfigCommandCLI,
|
||||
FWConfigCommandCLI, BenchmarkCommandCLI, UDPRateLimiterCLI, MonitorCommandCLI, ParseHEFCommandCLI, TutorialRunnerCLI)
|
||||
from hailo_platform.common.logger.logger import default_logger
|
||||
|
||||
# Note: PlatformCommands are external dependencies in phase2-sdk/demos repo; don't change!
|
||||
class PlatformCommands:
|
||||
@@ -19,8 +18,6 @@ class PlatformCommands:
|
||||
'fw-update': ('Firmware update tool', FWUpdaterCLI),
|
||||
'ssb-update': ('Second stage boot update tool', SSBUpdaterCLI),
|
||||
'fw-config': ('Firmware configuration tool', FWConfigCommandCLI),
|
||||
'udp-limiter': ('Alias to udp-rate-limiter. Deprecated.', UDPRateLimiterCLI),
|
||||
'udp': ('Alias to udp-rate-limiter. Deprecated.', UDPRateLimiterCLI),
|
||||
'udp-rate-limiter': ('Limit UDP rate', UDPRateLimiterCLI),
|
||||
'fw-control': ('Useful firmware control operations', ControlCommandCLI),
|
||||
'fw-logger': ('Download fw logs to a file', LoggerCommandCLI),
|
||||
@@ -32,6 +29,7 @@ class PlatformCommands:
|
||||
'parse-hef': (' Parse HEF to get information about its components', ParseHEFCommandCLI),
|
||||
'measure-power': ('Measures power consumption', MeasurePowerCommandCLI),
|
||||
'tutorial': ('Runs the tutorials in jupyter notebook', TutorialRunnerCLI),
|
||||
#'--version': ('Print program version and exit', VersionCLI)
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
@@ -79,10 +77,6 @@ class PlatformCommands:
|
||||
return self.INVALID_COMMAND_EXIT_CODE
|
||||
|
||||
command_name = argv[0]
|
||||
# TODO: Remove deprecation warning
|
||||
if command_name in ['udp', 'udp-limiter']:
|
||||
logger = default_logger()
|
||||
logger.warning("Warning - running '{}' command is deprecated, support will be removed in future versions. Use 'udp-rate-limiter' instead.".format(command_name))
|
||||
if (command_name in commands) and isinstance(commands[command_name], HailortCliUtil):
|
||||
# HailortCliUtil just passes the rest of the argv to hailortcli
|
||||
try :
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
"\n",
|
||||
"**Requirements:**\n",
|
||||
"\n",
|
||||
"* Run the notebook inside the Python virtual environment: ```source hailo_virtualenv/bin/activate```"
|
||||
"* Run the notebook inside the Python virtual environment: ```source hailo_virtualenv/bin/activate```\n",
|
||||
"\n",
|
||||
"It is recommended to use the command ``hailo tutorial`` (when inside the virtualenv) to open a Jupyter server that contains the tutorials."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
"\n",
|
||||
"**Attention:**\n",
|
||||
"\n",
|
||||
"* These examples should run in a different process than the one that performs the actual inference.\n"
|
||||
"* These examples should run in a different process than the one that performs the actual inference.\n",
|
||||
"\n",
|
||||
"It is recommended to use the command ``hailo tutorial`` (when inside the virtualenv) to open a Jupyter server that contains the tutorials."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,12 +4,11 @@ contextlib2==0.6.0.post1
|
||||
distlib==0.3.4
|
||||
filelock==3.4.1
|
||||
future==0.18.2
|
||||
importlib-metadata==3.7.3
|
||||
importlib-metadata==5.1.0
|
||||
importlib-resources==5.1.2
|
||||
netaddr==0.8.0
|
||||
netifaces==0.10.9
|
||||
numpy==1.19.4
|
||||
numpy==1.23.3
|
||||
typing_extensions==4.1.1
|
||||
verboselogs==1.7
|
||||
virtualenv==20.4.3
|
||||
zipp==3.4.1
|
||||
|
||||
@@ -23,6 +23,7 @@ def _get_pyhailort_lib_path():
|
||||
|
||||
with open(conf_file_path, "r") as conf_file:
|
||||
content = json.load(conf_file)
|
||||
# TODO (HRT-8637): change this hard-coded path
|
||||
return f"../hailo_platform/pyhailort/_pyhailort*{content['py_version']}*{content['arch']}*.{extension}"
|
||||
|
||||
def _get_package_paths():
|
||||
@@ -56,7 +57,7 @@ if __name__ == "__main__":
|
||||
"netifaces",
|
||||
"verboselogs",
|
||||
# Pinned versions
|
||||
"numpy==1.19.4",
|
||||
"numpy==1.23.3",
|
||||
],
|
||||
name="hailort",
|
||||
package_data={
|
||||
@@ -68,6 +69,6 @@ if __name__ == "__main__":
|
||||
"linux_aarch64",
|
||||
],
|
||||
url="https://hailo.ai/",
|
||||
version="4.10.0",
|
||||
version="4.12.0",
|
||||
zip_safe=False,
|
||||
)
|
||||
|
||||
@@ -3,6 +3,10 @@ cmake_minimum_required(VERSION 3.0.0)
|
||||
option(HAILO_BUILD_PYHAILORT_INTERNAL OFF)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
if(NOT DEFINED PYBIND11_PYTHON_VERSION)
|
||||
message(FATAL_ERROR "PYBIND11_PYTHON_VERSION is not defined. To build _pyhailort, pass python version")
|
||||
endif()
|
||||
|
||||
string(REPLACE "." "" dpython ${PYBIND11_PYTHON_VERSION}) # E.g "3.5" -> "35"
|
||||
if(${dpython} LESS "38")
|
||||
set(m_flag "m")
|
||||
@@ -45,11 +49,24 @@ exclude_archive_libs_symbols(_pyhailort)
|
||||
|
||||
if (HAILO_BUILD_PYHAILORT_INTERNAL)
|
||||
add_subdirectory(internal)
|
||||
# copy files to venv
|
||||
if(HAILO_BUILD_PYHAILORT_VENV)
|
||||
# copy files to a path the venv will look for
|
||||
add_custom_target(pyhailort_internal_venv ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:_pyhailort_internal> ${PROJECT_SOURCE_DIR}/platform_internals/hailo_platform_internals/pyhailort/
|
||||
)
|
||||
add_dependencies(pyhailort_internal_venv _pyhailort_internal)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# TODO (HRT-8637): change this hard-coded path
|
||||
set(HAILO_PYHAILORT_TARGET_DIR ${CMAKE_CURRENT_LIST_DIR}/../platform/hailo_platform/pyhailort/)
|
||||
|
||||
# copy files to a path the venv and whl will look for
|
||||
message(STATUS "Copying _pyhailort artifacts into " ${HAILO_PYHAILORT_TARGET_DIR})
|
||||
add_custom_target(pyhailort_venv ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:_pyhailort> ${HAILO_PYHAILORT_TARGET_DIR}
|
||||
)
|
||||
add_dependencies(pyhailort_venv _pyhailort)
|
||||
|
||||
install(TARGETS _pyhailort
|
||||
LIBRARY DESTINATION ${HAILO_PYHAILORT_TARGET_DIR}
|
||||
CONFIGURATIONS Release
|
||||
)
|
||||
@@ -469,6 +469,12 @@ const char *DeviceWrapper::get_dev_id() const
|
||||
return device().get_dev_id();
|
||||
}
|
||||
|
||||
void DeviceWrapper::set_sleep_state(hailo_sleep_state_t sleep_state)
|
||||
{
|
||||
auto status = device().set_sleep_state(sleep_state);
|
||||
VALIDATE_STATUS(status);
|
||||
}
|
||||
|
||||
void DeviceWrapper::add_to_python_module(py::module &m)
|
||||
{
|
||||
py::class_<DeviceWrapper>(m, "Device")
|
||||
@@ -533,6 +539,7 @@ void DeviceWrapper::add_to_python_module(py::module &m)
|
||||
|
||||
.def("set_notification_callback", &DeviceWrapper::set_notification_callback)
|
||||
.def("remove_notification_callback", &DeviceWrapper::remove_notification_callback)
|
||||
.def("set_sleep_state", &DeviceWrapper::set_sleep_state)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ public:
|
||||
void direct_write_memory(uint32_t address, py::bytes buffer);
|
||||
py::bytes direct_read_memory(uint32_t address, uint32_t size);
|
||||
const char *get_dev_id() const;
|
||||
void set_sleep_state(hailo_sleep_state_t sleep_state);
|
||||
|
||||
static void add_to_python_module(py::module &m);
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ target_link_libraries(_pyhailort_internal PRIVATE
|
||||
hef_proto
|
||||
spdlog::spdlog
|
||||
readerwriterqueue
|
||||
microprofile
|
||||
scheduler_mon_proto)
|
||||
if(HAILO_BUILD_SERVICE)
|
||||
target_link_libraries(_pyhailort_internal PRIVATE grpc++_unsecure hailort_rpc_grpc_proto)
|
||||
|
||||
@@ -13,10 +13,163 @@
|
||||
|
||||
#include "hailo/hailort.h"
|
||||
#include "transform_internal.hpp"
|
||||
#include "bindings_common.hpp"
|
||||
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
static const uint32_t TEST_NUM_OF_CLASSES2 = 80;
|
||||
|
||||
py::array PyhailortInternal::get_yolov5_post_process_expected_buffer()
|
||||
{
|
||||
static const uint32_t DETECTION_CLASS_ID_1 = 0;
|
||||
static const float32_t CLASS_ID_1_DETECTION_COUNT = 5;
|
||||
static const uint32_t DETECTION_CLASS_ID_3 = 2;
|
||||
static const float32_t CLASS_ID_3_DETECTION_COUNT = 2;
|
||||
static const uint32_t DETECTION_CLASS_ID_8 = 7;
|
||||
static const float32_t CLASS_ID_8_DETECTION_COUNT = 1;
|
||||
static const uint32_t DETECTION_CLASS_ID_26 = 25;
|
||||
static const float32_t CLASS_ID_26_DETECTION_COUNT = 1;
|
||||
|
||||
static const hailo_bbox_float32_t bbox1_0 = {
|
||||
/*.y_min =*/ 0.5427529811859131f,
|
||||
/*.x_min =*/ 0.2485126256942749f,
|
||||
/*.y_max =*/ 0.6096446067f,
|
||||
/*.x_max =*/ 0.27035075984f,
|
||||
/*.score =*/ 0.7761699557304382f,
|
||||
};
|
||||
|
||||
static const hailo_bbox_float32_t bbox1_1 = {
|
||||
/*.y_min =*/ 0.5454554557800293f,
|
||||
/*.x_min =*/ 0.33257606625556948f,
|
||||
/*.y_max =*/ 0.7027952075f,
|
||||
/*.x_max =*/ 0.40901548415f,
|
||||
/*.score =*/ 0.7637669444084168f,
|
||||
};
|
||||
|
||||
static const hailo_bbox_float32_t bbox1_2 = {
|
||||
/*.y_min =*/ 0.5521867275238037f,
|
||||
/*.x_min =*/ 0.19988654553890229f,
|
||||
/*.y_max =*/ 0.60256312787f,
|
||||
/*.x_max =*/ 0.21917282976f,
|
||||
/*.score =*/ 0.7451231479644775f,
|
||||
};
|
||||
|
||||
static const hailo_bbox_float32_t bbox1_3 = {
|
||||
/*.y_min =*/ 0.5514537692070007f,
|
||||
/*.x_min =*/ 0.2693796157836914f,
|
||||
/*.y_max =*/ 0.60397491604f,
|
||||
/*.x_max =*/ 0.28537025302f,
|
||||
/*.score =*/ 0.3756354749202728f,
|
||||
};
|
||||
|
||||
static const hailo_bbox_float32_t bbox1_4 = {
|
||||
/*.y_min =*/ 0.553998589515686f,
|
||||
/*.x_min =*/ 0.18612079322338105f,
|
||||
/*.y_max =*/ 0.58339602686f,
|
||||
/*.x_max =*/ 0.2008818537f,
|
||||
/*.score =*/ 0.3166312277317047f,
|
||||
};
|
||||
|
||||
static const hailo_bbox_float32_t bbox3_0 = {
|
||||
/*.y_min =*/ 0.5026738047599793f,
|
||||
/*.x_min =*/ -0.005611047148704529f,
|
||||
/*.y_max =*/ 0.65071095526f,
|
||||
/*.x_max =*/ 0.13888412714f,
|
||||
/*.score =*/ 0.5734351277351379f,
|
||||
};
|
||||
|
||||
static const hailo_bbox_float32_t bbox3_1 = {
|
||||
/*.y_min =*/ 0.5620155334472656f,
|
||||
/*.x_min =*/ 0.16757474839687348f,
|
||||
/*.y_max =*/ 0.58410947769f,
|
||||
/*.x_max =*/ 0.19325175508f,
|
||||
/*.score =*/ 0.4062519371509552f,
|
||||
};
|
||||
|
||||
static const hailo_bbox_float32_t bbox8_0 = {
|
||||
/*.y_min =*/ 0.5028372406959534f,
|
||||
/*.x_min =*/ -0.0017736181616783143f,
|
||||
/*.y_max =*/ 0.65114967525f,
|
||||
/*.x_max =*/ 0.13592261821f,
|
||||
/*.score =*/ 0.4223918318748474f,
|
||||
};
|
||||
|
||||
static const hailo_bbox_float32_t bbox26_0 = {
|
||||
/*.y_min =*/ 0.5854946374893189f,
|
||||
/*.x_min =*/ 0.2693060040473938f,
|
||||
/*.y_max =*/ 0.68259389698f,
|
||||
/*.x_max =*/ 0.38090330362f,
|
||||
/*.score =*/ 0.6338639259338379f,
|
||||
};
|
||||
|
||||
static const uint32_t DETECTION_COUNT = 9;
|
||||
auto buffer_size = (DETECTION_COUNT * sizeof(hailo_bbox_float32_t)) + (TEST_NUM_OF_CLASSES2 * sizeof(float32_t));
|
||||
auto buffer_expected = hailort::Buffer::create(buffer_size, 0);
|
||||
// CATCH_REQUIRE_EXPECTED(buffer_expected);
|
||||
auto buffer = buffer_expected.release();
|
||||
|
||||
size_t offset = 0;
|
||||
for (uint32_t class_index = 0; class_index < TEST_NUM_OF_CLASSES2; class_index++) {
|
||||
if (DETECTION_CLASS_ID_1 == class_index) {
|
||||
memcpy(buffer.data() + offset, &CLASS_ID_1_DETECTION_COUNT, sizeof(CLASS_ID_1_DETECTION_COUNT));
|
||||
offset += sizeof(CLASS_ID_1_DETECTION_COUNT);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox1_0, sizeof(bbox1_0));
|
||||
offset += sizeof(bbox1_0);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox1_1, sizeof(bbox1_1));
|
||||
offset += sizeof(bbox1_1);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox1_2, sizeof(bbox1_2));
|
||||
offset += sizeof(bbox1_2);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox1_3, sizeof(bbox1_3));
|
||||
offset += sizeof(bbox1_3);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox1_4, sizeof(bbox1_4));
|
||||
offset += sizeof(bbox1_4);
|
||||
}
|
||||
else if (DETECTION_CLASS_ID_3 == class_index) {
|
||||
memcpy(buffer.data() + offset, &CLASS_ID_3_DETECTION_COUNT, sizeof(CLASS_ID_3_DETECTION_COUNT));
|
||||
offset += sizeof(CLASS_ID_3_DETECTION_COUNT);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox3_0, sizeof(bbox3_0));
|
||||
offset += sizeof(bbox3_0);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox3_1, sizeof(bbox3_1));
|
||||
offset += sizeof(bbox3_1);
|
||||
}
|
||||
else if (DETECTION_CLASS_ID_8 == class_index) {
|
||||
memcpy(buffer.data() + offset, &CLASS_ID_8_DETECTION_COUNT, sizeof(CLASS_ID_8_DETECTION_COUNT));
|
||||
offset += sizeof(CLASS_ID_8_DETECTION_COUNT);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox8_0, sizeof(bbox8_0));
|
||||
offset += sizeof(bbox8_0);
|
||||
}
|
||||
else if (DETECTION_CLASS_ID_26 == class_index) {
|
||||
memcpy(buffer.data() + offset, &CLASS_ID_26_DETECTION_COUNT, sizeof(CLASS_ID_26_DETECTION_COUNT));
|
||||
offset += sizeof(CLASS_ID_26_DETECTION_COUNT);
|
||||
|
||||
memcpy(buffer.data() + offset, &bbox26_0, sizeof(bbox26_0));
|
||||
offset += sizeof(bbox26_0);
|
||||
}
|
||||
else {
|
||||
offset += sizeof(float32_t);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: The ownership of the buffer is transferred to Python wrapped as a py::array.
|
||||
// When the py::array isn't referenced anymore in Python and is destructed, the py::capsule's dtor
|
||||
// is called too (and it deletes the raw buffer)
|
||||
auto type = py::dtype(HailoRTBindingsCommon::convert_format_type_to_string(HAILO_FORMAT_TYPE_FLOAT32));
|
||||
auto shape = *py::array::ShapeContainer({buffer.size()});
|
||||
const auto unmanaged_addr = buffer.release();
|
||||
return py::array(type, shape, unmanaged_addr,
|
||||
py::capsule(unmanaged_addr, [](void *p) { delete reinterpret_cast<uint8_t*>(p); }));
|
||||
}
|
||||
|
||||
void PyhailortInternal::demux_output_buffer(
|
||||
py::bytes src, const hailo_format_t &src_format, const hailo_3d_image_shape_t &src_shape,
|
||||
std::map<std::string, py::array> dst_buffers, const LayerInfo &mux_layer_info)
|
||||
@@ -108,17 +261,15 @@ bool PyhailortInternal::is_output_transformation_required(
|
||||
|
||||
py::list PyhailortInternal::get_all_layers_info(const HefWrapper &hef, const std::string &net_group_name)
|
||||
{
|
||||
auto network_gorup_metadata = hef.hef_ptr()->pimpl->get_network_group_metadata(net_group_name);
|
||||
VALIDATE_EXPECTED(network_gorup_metadata);
|
||||
auto network_group_metadata = hef.hef_ptr()->pimpl->get_network_group_metadata(net_group_name);
|
||||
VALIDATE_EXPECTED(network_group_metadata);
|
||||
|
||||
auto layers_info = network_gorup_metadata->get_all_layer_infos();
|
||||
VALIDATE_EXPECTED(layers_info);
|
||||
|
||||
return py::cast(layers_info.release());
|
||||
return py::cast(network_group_metadata->get_all_layer_infos());
|
||||
}
|
||||
|
||||
PYBIND11_MODULE(_pyhailort_internal, m) {
|
||||
ControlWrapper::add_to_python_module(m);
|
||||
m.def("get_yolov5_post_process_expected_buffer", &PyhailortInternal::get_yolov5_post_process_expected_buffer);
|
||||
m.def("demux_output_buffer", &PyhailortInternal::demux_output_buffer);
|
||||
m.def("transform_input_buffer", &PyhailortInternal::transform_input_buffer);
|
||||
m.def("transform_output_buffer", &PyhailortInternal::transform_output_buffer);
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace hailort
|
||||
|
||||
class PyhailortInternal {
|
||||
public:
|
||||
static py::array get_yolov5_post_process_expected_buffer();
|
||||
static void demux_output_buffer(py::bytes src, const hailo_format_t &src_format, const hailo_3d_image_shape_t &src_shape,
|
||||
std::map<std::string, py::array> dst_buffers, const LayerInfo &mux_layer_info);
|
||||
static void transform_input_buffer(py::array src, const hailo_format_t &src_format, const hailo_3d_image_shape_t &src_shape,
|
||||
|
||||
102
hailort/libhailort/bindings/python/src/net_flow_api.hpp
Normal file
102
hailort/libhailort/bindings/python/src/net_flow_api.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file net_flow_api.hpp
|
||||
* @brief Defines binding to a HailoRT++ ops usage over Python.
|
||||
**/
|
||||
|
||||
#ifndef _HAILO_NET_FLOW_API_HPP_
|
||||
#define _HAILO_NET_FLOW_API_HPP_
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "hailo/hailort.hpp"
|
||||
#include "bindings_common.hpp"
|
||||
#include "net_flow/ops/yolo_post_processing.hpp"
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
namespace net_flow
|
||||
{
|
||||
|
||||
class YOLOv5PostProcessingOpWrapper
|
||||
{
|
||||
public:
|
||||
static YOLOv5PostProcessingOpWrapper create(const std::vector<std::vector<int>> &anchors,
|
||||
const std::vector<hailo_3d_image_shape_t> &shapes, const std::vector<hailo_format_t> &formats,
|
||||
const std::vector<hailo_quant_info_t> &quant_infos, float32_t image_height, float32_t image_width, float32_t confidence_threshold,
|
||||
float32_t iou_threshold, uint32_t num_of_classes, bool should_dequantize, uint32_t max_boxes, bool should_sigmoid,
|
||||
bool one_class_per_bbox=true)
|
||||
{
|
||||
auto op = YOLOv5PostProcessingOp::create(anchors, shapes, formats, quant_infos, image_height, image_width,
|
||||
confidence_threshold, iou_threshold, num_of_classes, should_dequantize, max_boxes, should_sigmoid, one_class_per_bbox);
|
||||
VALIDATE_EXPECTED(op);
|
||||
|
||||
return YOLOv5PostProcessingOpWrapper(op.release(), num_of_classes, max_boxes);
|
||||
}
|
||||
|
||||
static void add_to_python_module(py::module &m)
|
||||
{
|
||||
py::class_<YOLOv5PostProcessingOpWrapper>(m, "YOLOv5PostProcessingOp")
|
||||
.def("create", &YOLOv5PostProcessingOpWrapper::create)
|
||||
.def("execute",[](YOLOv5PostProcessingOpWrapper &self, const std::vector<py::array> &tensors)
|
||||
{
|
||||
std::vector<MemoryView> data_views;
|
||||
data_views.reserve(tensors.size());
|
||||
for (auto &tensor : tensors) {
|
||||
data_views.push_back(MemoryView(const_cast<void*>(reinterpret_cast<const void*>(tensor.data())), tensor.nbytes()));
|
||||
}
|
||||
|
||||
hailo_nms_info_t nms_info = {
|
||||
self.m_num_of_classes,
|
||||
self.m_max_boxes,
|
||||
sizeof(hailo_bbox_float32_t),
|
||||
1,
|
||||
false,
|
||||
hailo_nms_defuse_info_t()
|
||||
};
|
||||
hailo_format_t output_format = {
|
||||
HAILO_FORMAT_TYPE_FLOAT32,
|
||||
HAILO_FORMAT_ORDER_HAILO_NMS,
|
||||
HAILO_FORMAT_FLAGS_QUANTIZED,
|
||||
};
|
||||
|
||||
auto buffer = Buffer::create(HailoRTCommon::get_nms_host_frame_size(nms_info, output_format), 0);
|
||||
VALIDATE_STATUS(buffer.status());
|
||||
auto status = self.m_post_processing_op.execute<float32_t>(data_views, MemoryView(buffer.value().data(), buffer.value().size()));
|
||||
VALIDATE_STATUS(status);
|
||||
|
||||
// Note: The ownership of the buffer is transferred to Python wrapped as a py::array.
|
||||
// When the py::array isn't referenced anymore in Python and is destructed, the py::capsule's dtor
|
||||
// is called too (and it deletes the raw buffer)
|
||||
auto type = py::dtype(HailoRTBindingsCommon::convert_format_type_to_string(HAILO_FORMAT_TYPE_FLOAT32));
|
||||
auto shape = *py::array::ShapeContainer({buffer.value().size()});
|
||||
const auto unmanaged_addr = buffer.release().release();
|
||||
return py::array(type, shape, unmanaged_addr,
|
||||
py::capsule(unmanaged_addr, [](void *p) { delete reinterpret_cast<uint8_t*>(p); }));
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
YOLOv5PostProcessingOpWrapper(YOLOv5PostProcessingOp &&post_processing_op, uint32_t num_of_classes, uint32_t max_bboxes)
|
||||
: m_post_processing_op(post_processing_op),
|
||||
m_num_of_classes(num_of_classes),
|
||||
m_max_boxes(max_bboxes) {}
|
||||
|
||||
YOLOv5PostProcessingOp m_post_processing_op;
|
||||
uint32_t m_num_of_classes = 0;
|
||||
uint32_t m_max_boxes = 0;
|
||||
};
|
||||
|
||||
void NetFlow_api_initialize_python_module(py::module &m)
|
||||
{
|
||||
YOLOv5PostProcessingOpWrapper::add_to_python_module(m);
|
||||
}
|
||||
|
||||
|
||||
} /* namespace net_flow */
|
||||
} /* namespace hailort */
|
||||
|
||||
#endif /* _HAILO_NET_FLOW_API_HPP_ */
|
||||
@@ -15,6 +15,7 @@ using namespace std;
|
||||
#include "vdevice_api.hpp"
|
||||
#include "device_api.hpp"
|
||||
#include "quantization_api.hpp"
|
||||
#include "net_flow_api.hpp"
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "utils.h"
|
||||
@@ -157,8 +158,6 @@ private:
|
||||
|
||||
#endif
|
||||
|
||||
// End of temp hack for hlpcie
|
||||
|
||||
static void validate_versions_match()
|
||||
{
|
||||
hailo_version_t libhailort_version = {};
|
||||
@@ -324,7 +323,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
py::class_<hailo_debug_notification_message_t>(m, "DebugNotificationMessage")
|
||||
.def_readonly("connection_status", &hailo_debug_notification_message_t::connection_status)
|
||||
.def_readonly("connection_type", &hailo_debug_notification_message_t::connection_type)
|
||||
.def_readonly("pcie_is_active", &hailo_debug_notification_message_t::pcie_is_active)
|
||||
.def_readonly("vdma_is_active", &hailo_debug_notification_message_t::vdma_is_active)
|
||||
.def_readonly("host_port", &hailo_debug_notification_message_t::host_port)
|
||||
.def_readonly("host_ip_addr", &hailo_debug_notification_message_t::host_ip_addr)
|
||||
;
|
||||
@@ -393,6 +392,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
.def_readonly("logger_version", &hailo_device_identity_t::logger_version)
|
||||
.def_readonly("board_name_length", &hailo_device_identity_t::board_name_length)
|
||||
.def_readonly("is_release", &hailo_device_identity_t::is_release)
|
||||
.def_readonly("extended_context_switch_buffer", &hailo_device_identity_t::extended_context_switch_buffer)
|
||||
.def_readonly("device_architecture", &hailo_device_identity_t::device_architecture)
|
||||
.def_property_readonly("board_name", [](const hailo_device_identity_t& board_info) -> py::str {
|
||||
return py::str(board_info.board_name, board_info.board_name_length);
|
||||
@@ -413,6 +413,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
|
||||
py::class_<hailo_core_information_t>(m, "CoreInformation")
|
||||
.def_readonly("is_release", &hailo_core_information_t::is_release)
|
||||
.def_readonly("extended_context_switch_buffer", &hailo_core_information_t::extended_context_switch_buffer)
|
||||
.def_readonly("fw_version", &hailo_core_information_t::fw_version)
|
||||
;
|
||||
|
||||
@@ -534,6 +535,10 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
.value("RGB888", HAILO_FORMAT_ORDER_RGB888)
|
||||
.value("NCHW", HAILO_FORMAT_ORDER_NCHW)
|
||||
.value("YUY2", HAILO_FORMAT_ORDER_YUY2)
|
||||
.value("NV12", HAILO_FORMAT_ORDER_NV12)
|
||||
.value("YYUV", HAILO_FORMAT_ORDER_HAILO_YYUV)
|
||||
.value("NV21", HAILO_FORMAT_ORDER_NV21)
|
||||
.value("YYVU", HAILO_FORMAT_ORDER_HAILO_YYVU)
|
||||
;
|
||||
|
||||
py::enum_<hailo_format_flags_t>(m, "FormatFlags", py::arithmetic())
|
||||
@@ -792,6 +797,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
)
|
||||
.def_static("default", []() {
|
||||
auto orig_params = HailoRTDefaults::get_vdevice_params();
|
||||
orig_params.scheduling_algorithm = HAILO_SCHEDULING_ALGORITHM_NONE;
|
||||
VDeviceParamsWrapper params_wrapper{orig_params, ""};
|
||||
return params_wrapper;
|
||||
});
|
||||
@@ -942,6 +948,10 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
.value("CPU1", HAILO_CPU_ID_1)
|
||||
;
|
||||
|
||||
py::enum_<hailo_sleep_state_t>(m, "SleepState")
|
||||
.value("SLEEP_STATE_SLEEPING", HAILO_SLEEP_STATE_SLEEPING)
|
||||
.value("SLEEP_STATE_AWAKE", HAILO_SLEEP_STATE_AWAKE)
|
||||
;
|
||||
|
||||
py::class_<uint32_t>(m, "HailoRTDefaults")
|
||||
.def_static("HAILO_INFINITE", []() { return HAILO_INFINITE;} )
|
||||
@@ -1066,6 +1076,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
VStream_api_initialize_python_module(m);
|
||||
VDevice_api_initialize_python_module(m);
|
||||
DeviceWrapper::add_to_python_module(m);
|
||||
hailort::net_flow::NetFlow_api_initialize_python_module(m);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
TrafficControlUtilWrapper::add_to_python_module(m);
|
||||
|
||||
@@ -49,7 +49,18 @@ public:
|
||||
|
||||
static VDeviceWrapper create_from_ids(const std::vector<std::string> &device_ids)
|
||||
{
|
||||
return VDeviceWrapper(device_ids);
|
||||
auto device_ids_vector = HailoRTCommon::to_device_ids_vector(device_ids);
|
||||
VALIDATE_EXPECTED(device_ids_vector);
|
||||
|
||||
hailo_vdevice_params_t params = {};
|
||||
auto status = hailo_init_vdevice_params(¶ms);
|
||||
VALIDATE_STATUS(status);
|
||||
|
||||
params.device_ids = device_ids_vector->data();
|
||||
params.device_count = static_cast<uint32_t>(device_ids_vector->size());
|
||||
params.scheduling_algorithm = HAILO_SCHEDULING_ALGORITHM_NONE;
|
||||
|
||||
return VDeviceWrapper(params);
|
||||
}
|
||||
|
||||
VDeviceWrapper(const hailo_vdevice_params_t ¶ms)
|
||||
@@ -60,14 +71,6 @@ public:
|
||||
m_vdevice = vdevice_expected.release();
|
||||
};
|
||||
|
||||
VDeviceWrapper(const std::vector<std::string> &device_ids)
|
||||
{
|
||||
auto vdevice_expected = VDevice::create(device_ids);
|
||||
VALIDATE_EXPECTED(vdevice_expected);
|
||||
|
||||
m_vdevice = vdevice_expected.release();
|
||||
}
|
||||
|
||||
py::list get_physical_devices_ids() const
|
||||
{
|
||||
const auto phys_devs_ids = m_vdevice->get_physical_devices_ids();
|
||||
|
||||
@@ -3,38 +3,31 @@
|
||||
- gcc
|
||||
- g++
|
||||
python_versions:
|
||||
- version: '3.6'
|
||||
installation: deb
|
||||
package_name: python3.6-dev
|
||||
- version: '3.7'
|
||||
installation: deb
|
||||
package_name: python3.7-dev
|
||||
- version: '3.8'
|
||||
installation: deb
|
||||
package_name: python3.8-dev
|
||||
- version: '3.9'
|
||||
installation: deb
|
||||
package_name: python3.9-dev
|
||||
- version: '3.10'
|
||||
installation: deb
|
||||
package_name: python3.10-dev
|
||||
- name: linux.aarch64
|
||||
required_packages:
|
||||
- gcc-aarch64-linux-gnu
|
||||
- g++-aarch64-linux-gnu
|
||||
python_versions:
|
||||
- version: '3.6'
|
||||
installation: manual
|
||||
package_name: http://launchpadlibrarian.net/362976109/libpython3.6-dev_3.6.5-3_arm64.deb
|
||||
package_dest: /usr/include/aarch64-linux-gnu
|
||||
- version: '3.7'
|
||||
installation: manual
|
||||
package_name: http://launchpadlibrarian.net/450463692/libpython3.7-dev_3.7.5-2~18.04_arm64.deb
|
||||
package_dest: /usr/include/aarch64-linux-gnu
|
||||
- version: '3.8'
|
||||
installation: manual
|
||||
package_name: https://launchpad.net/ubuntu/+source/python3.8/3.8.2-1ubuntu1/+build/18834117/+files/libpython3.8-dev_3.8.2-1ubuntu1_arm64.deb
|
||||
package_dest: /usr/include/aarch64-linux-gnu
|
||||
- version: '3.9'
|
||||
installation: manual
|
||||
package_name: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa/+build/23779329/+files/libpython3.9-dev_3.9.13-1+bionic1_arm64.deb
|
||||
package_name: https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa/+build/24906233/+files/libpython3.9-dev_3.9.16-1+bionic1_arm64.deb
|
||||
package_dest: /usr/include/aarch64-linux-gnu
|
||||
- version: '3.10'
|
||||
installation: manual
|
||||
package_name: https://launchpadlibrarian.net/569418529/libpython3.10-dev_3.10.0-5_arm64.deb
|
||||
package_dest: /usr/include/aarch64-linux-gnu
|
||||
- name: linux.armv7l
|
||||
required_packages:
|
||||
|
||||
@@ -2,23 +2,9 @@ cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
project(hailort-examples)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
find_package(HailoRT 4.10.0 EXACT REQUIRED)
|
||||
|
||||
add_library(example_base INTERFACE)
|
||||
target_link_libraries(example_base INTERFACE HailoRT::libhailort Threads::Threads)
|
||||
|
||||
if(WIN32)
|
||||
target_compile_options(example_base INTERFACE /W4 /WX /DWIN32_LEAN_AND_MEAN /DNOMINMAX /wd4201 /wd4251)
|
||||
else()
|
||||
target_compile_options(example_base INTERFACE -Werror -Wall -Wextra -Wconversion -O3 -DNDEBUG) # TODO support debug/release builds
|
||||
endif()
|
||||
|
||||
add_subdirectory(cpp)
|
||||
add_subdirectory(c)
|
||||
|
||||
set_target_properties(${EXAMPLES_CPP_TARGETS} PROPERTIES CXX_STANDARD 14)
|
||||
|
||||
add_custom_target(hailort_examples DEPENDS ${EXAMPLES_C_TARGETS} ${EXAMPLES_CPP_TARGETS})
|
||||
# We add a costum target in order to compile all of the hailort examples
|
||||
add_custom_target(hailort_examples)
|
||||
add_dependencies(hailort_examples c_hailort_examples cpp_hailort_examples)
|
||||
@@ -15,9 +15,9 @@ The following examples are provided, demonstrating the HailoRT API:
|
||||
- Get the networks information to create the vstreams for each network.
|
||||
- The data is sent to the device via input vstreams and received via output vstreams.
|
||||
- The data is transformed before sent and after receiving in a different thread using the virtual stream pipeline.
|
||||
- `switch_network_groups_example` - Demonstrates how to work with multiple HEFs using virtual streams and HailoRT scheduler for automatic network group switching.
|
||||
- `switch_network_groups_example` - Demonstrates how to work with multiple HEFs using virtual streams and HailoRT Model Scheduler for automatic network group switching.
|
||||
- This example uses pcie devices.
|
||||
- `switch_single_io_network_groups_manually_example` - Demonstrates how to work with multiple single input single output HEFs, switching the created network groups manually, using virtual streams.
|
||||
- `switch_network_groups_manually_example` - Demonstrates how to work with multiple single input single output HEFs, switching the created network groups manually, using virtual streams.
|
||||
- `data_quantization_example` - Demonstrates how to set input/output stream params so as to allow for custom quantization:
|
||||
- Input streams may be marked as quantized, so that input data will not to be automatically quantized by the HailoRT library.
|
||||
- Output streams may be marked as quantized, so that output data will remain quantized (as it is after exiting the device by default), and won't be 'de-quantized' by the HailoRT library.
|
||||
@@ -31,13 +31,13 @@ The following examples are provided, demonstrating the HailoRT API:
|
||||
- `vstreams_example` - Basic inference of a shortcut network, same as `vstreams_example` C example, uses HailoRT C++ api.
|
||||
- `multi_device_example` - Basic inference of a shortcut network over multiple devices, same as `multi_device_example` C example, uses HailoRT C++ api.
|
||||
- `multi_network_vstream_example` - Demonstrates how to work with multiple networks in a network group, same as `multi_network_vstream_example ` C example, uses HailoRT C++ api.
|
||||
- `switch_network_groups_example` - Demonstrates how to work with multiple HEFs using virtual streams and HailoRT scheduler, same as `switch_network_groups_example ` C example, uses HailoRT C++ api.
|
||||
- `switch_network_groups_example` - Demonstrates how to work with multiple HEFs using virtual streams and HailoRT Model Scheduler, same as `switch_network_groups_example ` C example, uses HailoRT C++ api.
|
||||
- `switch_network_groups_manually_example` -Demonstrates how to work with multiple HEFs, switching the running network_groups manually, with performance optimizations for I/O threads re-usage instead of re-creation at each network group activation. Uses C++ api.
|
||||
- `infer_streams_example` - Basic inference of a shortcut network, same as `raw_streams_example` C example, uses HailoRT C++ api.
|
||||
- `infer_pipeline_example` - Basic inference of a shortcut network using inference pipeline (blocking) api.
|
||||
- same as `infer_pipeline_example` C example, uses HailoRT C++ api.
|
||||
- `raw_streams_example` - Basic inference of a shortcut network, same as `raw_streams_example` C example, uses HailoRT C++ api.
|
||||
- `multi_process_example` - Demonstrates how to work with HailoRT as a service and using the HailoRT scheduler for network groups switching.
|
||||
- `multi_process_example` - Demonstrates how to work with HailoRT as a service and using the HailoRT Model Scheduler for network groups switching.
|
||||
Using the script `multi_process_example.sh` one can specify the number of processes to run each hef, see `multi_process_example.sh -h` for more information.
|
||||
|
||||
## Compiling with CMake
|
||||
@@ -49,9 +49,21 @@ cmake --build build --config release
|
||||
> **_NOTE:_** Write permissions are required to compile the examples from their current directory.
|
||||
If this is not the case, copy the examples directory to another location with the required permissions.
|
||||
|
||||
In order to compile a specific example, add the example name as target with a c/cpp prefix:
|
||||
```sh
|
||||
cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build --config release --target cpp_vstreams_example
|
||||
```
|
||||
|
||||
## Running the examples
|
||||
One can run the example using the following commands, from the examples directory:
|
||||
|
||||
Before running an example, download the HEFs using the [download script](../../scripts/download_hefs.sh):
|
||||
```sh
|
||||
../../scripts/download_hefs.sh
|
||||
```
|
||||
|
||||
To run an example, use (from this examples directory):
|
||||
|
||||
```sh
|
||||
build/<c/cpp>/<example_name> [params..]
|
||||
build/<c/cpp>/<example_name>/<example_name> [params..]
|
||||
```
|
||||
|
||||
@@ -1,43 +1,23 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
file(GLOB_RECURSE C_EXAMPLE_SOURCES "*.c")
|
||||
SET_SOURCE_FILES_PROPERTIES(${C_EXAMPLE_SOURCES} PROPERTIES LANGUAGE C)
|
||||
add_subdirectory(data_quantization_example)
|
||||
add_subdirectory(raw_streams_example)
|
||||
add_subdirectory(vstreams_example)
|
||||
add_subdirectory(infer_pipeline_example)
|
||||
add_subdirectory(multi_network_vstream_example)
|
||||
add_subdirectory(switch_network_groups_example)
|
||||
add_subdirectory(switch_network_groups_manually_example)
|
||||
add_subdirectory(multi_device_example)
|
||||
add_subdirectory(power_measurement_example)
|
||||
|
||||
add_executable(c_data_quantization_example data_quantization_example.c)
|
||||
target_link_libraries(c_data_quantization_example PRIVATE example_base)
|
||||
|
||||
add_executable(c_raw_streams_example raw_streams_example.c)
|
||||
target_link_libraries(c_raw_streams_example PRIVATE example_base)
|
||||
|
||||
add_executable(c_vstreams_example vstreams_example.c)
|
||||
target_link_libraries(c_vstreams_example PRIVATE example_base)
|
||||
|
||||
add_executable(c_infer_pipeline_example infer_pipeline_example.c)
|
||||
target_link_libraries(c_infer_pipeline_example PRIVATE example_base)
|
||||
|
||||
add_executable(c_multi_network_vstream_example multi_network_vstream_example.c)
|
||||
target_link_libraries(c_multi_network_vstream_example PRIVATE example_base)
|
||||
|
||||
add_executable(c_switch_network_groups_example switch_network_groups_example.c)
|
||||
target_link_libraries(c_switch_network_groups_example PRIVATE example_base)
|
||||
|
||||
add_executable(c_switch_single_io_network_groups_manually_example switch_single_io_network_groups_manually_example.c)
|
||||
target_link_libraries(c_switch_single_io_network_groups_manually_example PRIVATE example_base)
|
||||
|
||||
add_executable(c_multi_device_example multi_device_example.c)
|
||||
target_link_libraries(c_multi_device_example PRIVATE example_base)
|
||||
|
||||
add_executable(c_power_measurement_example power_measurement_example.c)
|
||||
target_link_libraries(c_power_measurement_example PRIVATE example_base)
|
||||
|
||||
set(EXAMPLES_C_TARGETS
|
||||
add_custom_target(c_hailort_examples)
|
||||
add_dependencies(c_hailort_examples
|
||||
c_data_quantization_example
|
||||
c_raw_streams_example
|
||||
c_vstreams_example
|
||||
c_infer_pipeline_example
|
||||
c_multi_network_vstream_example
|
||||
c_switch_network_groups_example
|
||||
c_switch_single_io_network_groups_manually_example
|
||||
c_switch_network_groups_manually_example
|
||||
c_multi_device_example
|
||||
c_power_measurement_example
|
||||
PARENT_SCOPE)
|
||||
c_power_measurement_example)
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
find_package(HailoRT 4.12.0 EXACT REQUIRED)
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(data_quantization_example.c PROPERTIES LANGUAGE C)
|
||||
|
||||
add_executable(c_data_quantization_example data_quantization_example.c)
|
||||
target_link_libraries(c_data_quantization_example PRIVATE HailoRT::libhailort Threads::Threads)
|
||||
target_include_directories(c_data_quantization_example PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../common")
|
||||
|
||||
if(WIN32)
|
||||
target_compile_options(c_data_quantization_example PRIVATE
|
||||
/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)
|
||||
/wd4201 /wd4251
|
||||
)
|
||||
endif()
|
||||
@@ -255,7 +255,6 @@ int main(int argc, char **argv)
|
||||
hailo_output_vstream output_vstreams[MAX_EDGE_LAYERS] = {NULL};
|
||||
size_t input_vstreams_size = MAX_EDGE_LAYERS;
|
||||
size_t output_vstreams_size = MAX_EDGE_LAYERS;
|
||||
hailo_activated_network_group activated_network_group = NULL;
|
||||
quantization_args_t quant_args;
|
||||
|
||||
parse_arguments(argc, argv, &quant_args);
|
||||
@@ -282,16 +281,12 @@ int main(int argc, char **argv)
|
||||
&output_vstreams_size,quant_args);
|
||||
REQUIRE_SUCCESS(status, l_release_hef, "Failed creating virtual streams");
|
||||
|
||||
status = hailo_activate_network_group(network_group, NULL, &activated_network_group);
|
||||
REQUIRE_SUCCESS(status, l_release_vstreams, "Failed activate network group");
|
||||
|
||||
status = infer(input_vstreams, input_vstreams_size, output_vstreams, output_vstreams_size, quant_args);
|
||||
REQUIRE_SUCCESS(status, l_deactivate_network_group, "Inference failure");
|
||||
REQUIRE_SUCCESS(status, l_release_vstreams, "Inference failure");
|
||||
|
||||
printf("Inference ran successfully\n");
|
||||
status = HAILO_SUCCESS;
|
||||
l_deactivate_network_group:
|
||||
(void)hailo_deactivate_network_group(activated_network_group);
|
||||
|
||||
l_release_vstreams:
|
||||
(void)hailo_release_output_vstreams(output_vstreams, output_vstreams_size);
|
||||
(void)hailo_release_input_vstreams(input_vstreams, input_vstreams_size);
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
find_package(HailoRT 4.12.0 EXACT REQUIRED)
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(infer_pipeline_example.c PROPERTIES LANGUAGE C)
|
||||
|
||||
add_executable(c_infer_pipeline_example infer_pipeline_example.c)
|
||||
target_link_libraries(c_infer_pipeline_example PRIVATE HailoRT::libhailort Threads::Threads)
|
||||
target_include_directories(c_infer_pipeline_example PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../common")
|
||||
|
||||
if(WIN32)
|
||||
target_compile_options(c_infer_pipeline_example PRIVATE
|
||||
/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)
|
||||
/wd4201 /wd4251
|
||||
)
|
||||
endif()
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "string.h"
|
||||
#include "hailo_thread.h"
|
||||
#include "hailo/hailort.h"
|
||||
|
||||
#define MAX_NUM_OF_DEVICES (5)
|
||||
@@ -114,7 +113,7 @@ int main(int argc, char **argv)
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to create eth_device");
|
||||
|
||||
status = hailo_create_hef_file(&hef, HEF_FILE);
|
||||
REQUIRE_SUCCESS(status, l_release_vdevice, "Failed reading hef file");
|
||||
REQUIRE_SUCCESS(status, l_release_device, "Failed reading hef file");
|
||||
|
||||
status = hailo_init_configure_params(hef, HAILO_STREAM_INTERFACE_ETH, &config_params);
|
||||
REQUIRE_SUCCESS(status, l_release_hef, "Failed initializing configure parameters");
|
||||
@@ -154,7 +153,7 @@ l_deactivate_network_group:
|
||||
(void)hailo_deactivate_network_group(activated_network_group);
|
||||
l_release_hef:
|
||||
(void) hailo_release_hef(hef);
|
||||
l_release_vdevice:
|
||||
l_release_device:
|
||||
(void) hailo_release_device(device);
|
||||
l_exit:
|
||||
return status;
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
find_package(HailoRT 4.12.0 EXACT REQUIRED)
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(multi_device_example.c PROPERTIES LANGUAGE C)
|
||||
|
||||
add_executable(c_multi_device_example multi_device_example.c)
|
||||
target_link_libraries(c_multi_device_example PRIVATE HailoRT::libhailort Threads::Threads)
|
||||
target_include_directories(c_multi_device_example PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../common")
|
||||
|
||||
if(WIN32)
|
||||
target_compile_options(c_multi_device_example PRIVATE
|
||||
/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)
|
||||
/wd4201 /wd4251
|
||||
)
|
||||
endif()
|
||||
@@ -139,7 +139,6 @@ int main()
|
||||
hailo_output_vstream_params_by_name_t output_vstream_params[MAX_EDGE_LAYERS] = {0};
|
||||
size_t input_vstreams_size = MAX_EDGE_LAYERS;
|
||||
size_t output_vstreams_size = MAX_EDGE_LAYERS;
|
||||
hailo_activated_network_group activated_network_group = NULL;
|
||||
hailo_input_vstream input_vstreams[MAX_EDGE_LAYERS] = {NULL};
|
||||
hailo_output_vstream output_vstreams[MAX_EDGE_LAYERS] = {NULL};
|
||||
|
||||
@@ -183,16 +182,11 @@ int main()
|
||||
status = hailo_create_output_vstreams(network_group, output_vstream_params, output_vstreams_size, output_vstreams);
|
||||
REQUIRE_SUCCESS(status, l_release_input_vstream, "Failed creating output virtual streams\n");
|
||||
|
||||
status = hailo_activate_network_group(network_group, NULL, &activated_network_group);
|
||||
REQUIRE_SUCCESS(status, l_release_output_vstream, "Failed activate network group");
|
||||
|
||||
status = infer(input_vstreams, input_vstreams_size, output_vstreams, output_vstreams_size);
|
||||
REQUIRE_SUCCESS(status, l_deactivate_network_group, "Inference failure");
|
||||
REQUIRE_SUCCESS(status, l_release_output_vstream, "Inference failure");
|
||||
|
||||
printf("Inference ran successfully\n");
|
||||
status = HAILO_SUCCESS;
|
||||
l_deactivate_network_group:
|
||||
(void)hailo_deactivate_network_group(activated_network_group);
|
||||
l_release_output_vstream:
|
||||
(void)hailo_release_output_vstreams(output_vstreams, output_vstreams_size);
|
||||
l_release_input_vstream:
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
find_package(HailoRT 4.12.0 EXACT REQUIRED)
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(multi_network_vstream_example.c PROPERTIES LANGUAGE C)
|
||||
|
||||
add_executable(c_multi_network_vstream_example multi_network_vstream_example.c)
|
||||
target_link_libraries(c_multi_network_vstream_example PRIVATE HailoRT::libhailort Threads::Threads)
|
||||
target_include_directories(c_multi_network_vstream_example PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../common")
|
||||
|
||||
if(WIN32)
|
||||
target_compile_options(c_multi_network_vstream_example PRIVATE
|
||||
/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)
|
||||
/wd4201 /wd4251
|
||||
)
|
||||
endif()
|
||||
@@ -171,6 +171,8 @@ int main()
|
||||
status = hailo_init_vdevice_params(¶ms);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed init vdevice_params");
|
||||
|
||||
/* Scheduler does not support different batches for different networks within the same network group */
|
||||
params.scheduling_algorithm = HAILO_SCHEDULING_ALGORITHM_NONE;
|
||||
params.device_count = DEVICE_COUNT;
|
||||
status = hailo_create_vdevice(¶ms, &vdevice);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to create vdevice");
|
||||
@@ -233,6 +235,7 @@ int main()
|
||||
|
||||
printf("Inference ran successfully\n");
|
||||
status = HAILO_SUCCESS;
|
||||
|
||||
l_deactivate_network_group:
|
||||
(void)hailo_deactivate_network_group(activated_network_group);
|
||||
l_release_vstreams:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user