v4.10.0
v4.10.0
This commit is contained in:
committed by
GitHub
parent
8295c0685f
commit
d61a3bc83f
BIN
.hailort.png
BIN
.hailort.png
Binary file not shown.
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 1.4 MiB |
@@ -8,6 +8,11 @@ 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)
|
||||
@@ -51,7 +56,8 @@ elseif(UNIX)
|
||||
set(HAILORT_COMPILE_OPTIONS ${HAILORT_COMPILE_OPTIONS} -Werror -Wall -Wextra
|
||||
# TODO: remove me warnings
|
||||
-Wno-conversion
|
||||
-Wno-deprecated-declarations
|
||||
-Wno-deprecated-declarations # On c structures with deprecated attribute, clang generates implicit move ctor
|
||||
# that causes a warning
|
||||
-Wno-inconsistent-missing-override
|
||||
)
|
||||
else()
|
||||
|
||||
@@ -23,6 +23,8 @@ 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 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).
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
"temperature_orange_threshold": {"size": 1, "deserialize_as": "int"},
|
||||
"temperature_orange_hysteresis_threshold": {"size": 1, "deserialize_as": "int"},
|
||||
"temperature_throttling_enable": {"size": 1, "deserialize_as": "bool"},
|
||||
"overcurrent_monitoring_orange_threshold_enable": {"size": 1, "deserialize_as": "bool"}
|
||||
"deprecated__overcurrent_monitoring_orange_threshold_enable": {"size": 1, "deserialize_as": "bool"},
|
||||
"overcurrent_throttling_enable": {"size": 1, "deserialize_as": "bool"}
|
||||
}
|
||||
},
|
||||
"control":
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"temperature_red_hysteresis_threshold": {"$ref": "#/definitions/int8_t"},
|
||||
"temperature_orange_threshold": {"$ref": "#/definitions/int8_t"},
|
||||
"temperature_orange_hysteresis_threshold": {"$ref": "#/definitions/int8_t"},
|
||||
"overcurrent_monitoring_orange_threshold_enable": {"type": "boolean"}
|
||||
"deprecated__overcurrent_monitoring_orange_threshold_enable": {"type": "boolean"}
|
||||
}
|
||||
},
|
||||
"control":
|
||||
|
||||
@@ -40,6 +40,20 @@ extern "C" {
|
||||
(((cluster_index) << CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_SHIFT) & CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_CLUSTER_INDEX_MASK)
|
||||
|
||||
|
||||
#define CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__VDMA_CHANNEL_INDEX_MASK (0x1f)
|
||||
#define CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__ENGINE_INDEX_MASK (0x60)
|
||||
#define CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__ENGINE_INDEX_SHIFT (5)
|
||||
|
||||
#define CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__SET(dst, engine_index, vdma_channel_index) do { \
|
||||
(dst) = (vdma_channel_index) | ((engine_index) << CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__ENGINE_INDEX_SHIFT);\
|
||||
} while (0)
|
||||
|
||||
#define CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__READ(src, engine_index, vdma_channel_index) do {\
|
||||
(engine_index) = ((src) & CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__ENGINE_INDEX_MASK) >> \
|
||||
CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__ENGINE_INDEX_SHIFT; \
|
||||
(vdma_channel_index) = ((src) & CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__VDMA_CHANNEL_INDEX_MASK); \
|
||||
} while (0)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint16_t core_bytes_per_buffer;
|
||||
@@ -86,6 +100,7 @@ typedef enum __attribute__((packed)) {
|
||||
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,
|
||||
|
||||
/* Must be last */
|
||||
CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT
|
||||
@@ -141,12 +156,12 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint16_t descriptors_count;
|
||||
uint8_t cfg_channel_number;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
} CONTEXT_SWITCH_DEFS__fetch_cfg_channel_descriptors_action_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t ccw_bursts;
|
||||
uint8_t cfg_channel_number;
|
||||
uint8_t config_stream_index;
|
||||
} CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -172,7 +187,7 @@ typedef struct {
|
||||
} CONTEXT_SWITCH_DEFS__disable_lcu_action_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t edge_layer_direction;
|
||||
bool is_inter_context;
|
||||
uint8_t host_buffer_type; // CONTROL_PROTOCOL__HOST_BUFFER_TYPE_t
|
||||
@@ -180,7 +195,7 @@ typedef struct {
|
||||
} CONTEXT_SWITCH_DEFS__deactivate_vdma_channel_action_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t edge_layer_direction;
|
||||
bool is_inter_context;
|
||||
bool is_single_context_network_group;
|
||||
@@ -189,7 +204,7 @@ typedef struct {
|
||||
} CONTEXT_SWITCH_DEFS__validate_vdma_channel_action_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
uint8_t network_index;
|
||||
uint32_t frame_periph_size;
|
||||
@@ -199,14 +214,14 @@ typedef struct {
|
||||
} CONTEXT_SWITCH_DEFS__fetch_data_action_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
bool is_dummy_stream;
|
||||
} CONTEXT_SWITCH_DEFS__change_vdma_to_stream_mapping_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t h2d_vdma_channel_index;
|
||||
uint8_t d2h_vdma_channel_index;
|
||||
uint8_t h2d_packed_vdma_channel_id;
|
||||
uint8_t d2h_packed_vdma_channel_id;
|
||||
uint8_t network_index;
|
||||
uint32_t descriptors_per_frame;
|
||||
uint16_t programmed_descriptors_count;
|
||||
@@ -218,7 +233,7 @@ typedef struct {
|
||||
} CONTEXT_SWITCH_DEFS__lcu_interrupt_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
} CONTEXT_SWITCH_DEFS__vdma_dataflow_interrupt_data_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -235,7 +250,7 @@ typedef struct {
|
||||
} CONTEXT_SWITCH_DEFS__wait_nms_idle_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
bool is_inter_context;
|
||||
} CONTEXT_SWITCH_DEFS__wait_dma_idle_data_t;
|
||||
@@ -250,16 +265,17 @@ typedef struct {
|
||||
|
||||
/* edge layers structs */
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
uint8_t vdma_channel_index;
|
||||
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 {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t network_index;
|
||||
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
@@ -267,48 +283,55 @@ typedef struct {
|
||||
} CONTEXT_SWITCH_DEFS__activate_inter_context_input_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
uint8_t vdma_channel_index;
|
||||
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
|
||||
uint64_t host_descriptors_base_address;
|
||||
uint8_t desc_list_depth;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
uint32_t initial_credit_size;
|
||||
uint8_t connected_d2h_packed_vdma_channel_id;
|
||||
} CONTEXT_SWITCH_DEFS__activate_ddr_buffer_input_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
uint8_t vdma_channel_index;
|
||||
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
|
||||
uint32_t frame_credits_in_bytes;
|
||||
uint16_t desc_page_size;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
} CONTEXT_SWITCH_DEFS__activate_boundary_output_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
uint8_t vdma_channel_index;
|
||||
uint8_t network_index;
|
||||
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
} CONTEXT_SWITCH_DEFS__activate_inter_context_output_data_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t stream_index;
|
||||
uint8_t vdma_channel_index;
|
||||
CONTEXT_SWITCH_DEFS__stream_reg_info_t stream_reg_info;
|
||||
uint32_t frame_credits_in_bytes;
|
||||
uint64_t host_descriptors_base_address;
|
||||
uint16_t desc_page_size;
|
||||
uint8_t desc_list_depth;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
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 channel_index;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t config_stream_index;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
} CONTEXT_SWITCH_DEFS__activate_cfg_channel_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t channel_index;
|
||||
uint8_t packed_vdma_channel_id;
|
||||
uint8_t config_stream_index;
|
||||
} CONTEXT_SWITCH_DEFS__deactivate_cfg_channel_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -35,13 +35,14 @@ extern "C" {
|
||||
#define CONTROL_PROTOCOL__MAX_SERIAL_NUMBER_LENGTH (16)
|
||||
#define CONTROL_PROTOCOL__MAX_PART_NUMBER_LENGTH (16)
|
||||
#define CONTROL_PROTOCOL__MAX_PRODUCT_NAME_LENGTH (42)
|
||||
#define CONTROL_PROTOCOL__MAX_CONTEXT_SWITCH_APPLICATIONS (8)
|
||||
#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 (32)
|
||||
#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)
|
||||
#define CONTROL_PROTOCOL__MAX_VDMA_ENGINES_COUNT (3)
|
||||
/* Tightly coupled with the sizeof PROCESS_MONITOR__detection_results_t
|
||||
and HAILO_SOC_PM_VALUES_BYTES_LENGTH */
|
||||
#define PM_RESULTS_LENGTH (24)
|
||||
@@ -52,6 +53,8 @@ extern "C" {
|
||||
/* Tightly coupled to HAILO_MAX_TEMPERATURE_THROTTLING_LEVELS_NUMBER */
|
||||
#define MAX_TEMPERATURE_THROTTLING_LEVELS_NUMBER (4)
|
||||
|
||||
#define MAX_OVERCURRENT_THROTTLING_LEVELS_NUMBER (8)
|
||||
|
||||
#define CONTROL_PROTOCOL__MAX_NUMBER_OF_POWER_MEASUREMETS (4)
|
||||
#define CONTROL_PROTOCOL__DEFAULT_INIT_SAMPLING_PERIOD_US (CONTROL_PROTOCOL__PERIOD_1100US)
|
||||
#define CONTROL_PROTOCOL__DEFAULT_INIT_AVERAGING_FACTOR (CONTROL_PROTOCOL__AVERAGE_FACTOR_1)
|
||||
@@ -143,7 +146,7 @@ extern "C" {
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_CORE_IDENTIFY, true, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_D2H_EVENT_MANAGER_SET_HOST_INFO, false, CPU_ID_APP_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_D2H_EVENT_MANAGER_SEND_EVENT_HOST_INFO, false, CPU_ID_APP_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_SWITCH_APPLICATION, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_SWITCH_APPLICATION /* obsolete */, false, CPU_ID_CORE_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_GET_CHIP_TEMPERATURE, false, CPU_ID_APP_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_READ_BOARD_CONFIG, true, CPU_ID_APP_CPU)\
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_WRITE_BOARD_CONFIG, true, CPU_ID_APP_CPU)\
|
||||
@@ -169,6 +172,7 @@ extern "C" {
|
||||
CONTROL_PROTOCOL__OPCODE_X(HAILO_CONTROL_OPCODE_CORE_PREVIOUS_SYSTEM_STATE, false, CPU_ID_CORE_CPU)\
|
||||
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)\
|
||||
|
||||
typedef enum {
|
||||
#define CONTROL_PROTOCOL__OPCODE_X(name, is_critical, cpu_id) name,
|
||||
@@ -353,7 +357,8 @@ typedef struct {
|
||||
|
||||
typedef enum {
|
||||
CONTROL_PROTOCOL__HAILO8_A0 = 0,
|
||||
CONTROL_PROTOCOL__HAILO8_B0,
|
||||
CONTROL_PROTOCOL__HAILO8,
|
||||
CONTROL_PROTOCOL__HAILO8L,
|
||||
CONTROL_PROTOCOL__MERCURY_CA,
|
||||
CONTROL_PROTOCOL__MERCURY_VPU,
|
||||
/* Must be last!! */
|
||||
@@ -877,10 +882,10 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8_t dynamic_contexts_count;
|
||||
uint32_t host_boundary_channels_bitmap;
|
||||
uint8_t cfg_channel_numbers[CONTROL_PROTOCOL__MAX_CFG_CHANNELS];
|
||||
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;
|
||||
uint16_t batch_size[CONTROL_PROTOCOL__MAX_NETWORKS_PER_NETWORK_GROUP];
|
||||
} CONTROL_PROTOCOL__application_header_t;
|
||||
@@ -888,8 +893,6 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t context_switch_version_length;
|
||||
uint32_t context_switch_version;
|
||||
uint32_t validation_features_length;
|
||||
CONTROL_PROTOCOL__VALIDATION_FEATURE_LIST_t validation_features;
|
||||
uint32_t application_count_length;
|
||||
uint8_t application_count;
|
||||
uint32_t application_header_length;
|
||||
@@ -906,7 +909,6 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__CONTEXT_SWITCH_VERSION_t context_switch_version;
|
||||
CONTROL_PROTOCOL__VALIDATION_FEATURE_LIST_t validation_features;
|
||||
uint8_t application_count;
|
||||
CONTROL_PROTOCOL__application_header_t application_header[CONTROL_PROTOCOL__MAX_CONTEXT_SWITCH_APPLICATIONS];
|
||||
} CONTROL_PROTOCOL__context_switch_main_header_t;
|
||||
@@ -969,6 +971,7 @@ typedef enum {
|
||||
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,
|
||||
@@ -1054,27 +1057,23 @@ 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 stream_index;
|
||||
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 {
|
||||
uint64_t host_descriptors_base_address;
|
||||
uint8_t desc_list_depth;
|
||||
} CONTROL_PROTOCOL__host_desc_address_info_t;
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
uint32_t frame_credits_in_bytes;
|
||||
uint16_t desc_page_size;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
} CONTROL_PROTOCOL__network_boundary_output_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -1084,9 +1083,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
uint32_t frame_credits_in_bytes;
|
||||
CONTROL_PROTOCOL__host_desc_address_info_t host_desc_address_info;
|
||||
uint16_t desc_page_size;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
uint32_t buffered_rows_count;
|
||||
} CONTROL_PROTOCOL__ddr_buffer_output_t;
|
||||
|
||||
@@ -1097,7 +1094,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
uint16_t desc_page_size;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t host_buffer_info;
|
||||
uint32_t initial_credit_size;
|
||||
} CONTROL_PROTOCOL__network_boundary_input_t;
|
||||
|
||||
@@ -1109,8 +1106,10 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
CONTROL_PROTOCOL__edge_layer_common_info_t common_info;
|
||||
CONTROL_PROTOCOL__host_desc_address_info_t host_desc_address_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 {
|
||||
@@ -1121,6 +1120,12 @@ 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
|
||||
#pragma warning(push)
|
||||
@@ -1133,8 +1138,8 @@ typedef struct {
|
||||
uint8_t is_last_control_per_context;
|
||||
uint32_t cfg_channels_count_length;
|
||||
uint8_t cfg_channels_count;
|
||||
uint32_t config_buffer_infos_length;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t config_buffer_infos[CONTROL_PROTOCOL__MAX_CFG_CHANNELS];
|
||||
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;
|
||||
@@ -1209,14 +1214,14 @@ typedef struct {
|
||||
/* Must be first */
|
||||
CONTROL_PROTOCOL__ACTION_HEADER_t header;
|
||||
uint16_t descriptors_count;
|
||||
uint8_t cfg_channel_handle;
|
||||
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 cfg_channel_handle;
|
||||
uint8_t config_stream_index;
|
||||
} CONTROL_PROTOCOL__FETCH_CCW_BURSTS_ACTION_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -1283,7 +1288,9 @@ typedef struct {
|
||||
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;
|
||||
@@ -1299,6 +1306,11 @@ typedef struct {
|
||||
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;
|
||||
@@ -1360,6 +1372,8 @@ typedef struct {
|
||||
uint8_t application_index;
|
||||
uint32_t dynamic_batch_size_length;
|
||||
uint16_t dynamic_batch_size;
|
||||
uint32_t keep_nn_config_during_reset_length;
|
||||
uint8_t keep_nn_config_during_reset;
|
||||
} CONTROL_PROTOCOL__change_context_switch_status_request_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -1371,13 +1385,6 @@ typedef struct {
|
||||
uint8_t interrupt_sub_index;
|
||||
} CONTROL_PROTOCOL__set_dataflow_interrupt_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t application_index_length;
|
||||
uint8_t application_index;
|
||||
uint32_t dynamic_batch_size_length;
|
||||
uint16_t dynamic_batch_size;
|
||||
} CONTROL_PROTOCOL__switch_application_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t connection_type_length;
|
||||
uint8_t connection_type;
|
||||
@@ -1429,6 +1436,8 @@ typedef struct {
|
||||
CONTROL_PROTOCOL_fuse_info_t fuse_info;
|
||||
uint32_t pd_info_length;
|
||||
uint8_t pd_info[PM_RESULTS_LENGTH];
|
||||
uint32_t partial_clusters_layout_bitmap_length;
|
||||
uint32_t partial_clusters_layout_bitmap;
|
||||
} CONTROL_PROTOCOL__get_extended_device_information_response_t;
|
||||
|
||||
/* Tightly coupled to hailo_throttling_level_t */
|
||||
@@ -1446,8 +1455,8 @@ typedef struct {
|
||||
uint8_t current_overcurrent_zone;
|
||||
uint32_t red_overcurrent_threshold_length;
|
||||
float32_t red_overcurrent_threshold;
|
||||
uint32_t orange_overcurrent_threshold_length;
|
||||
float32_t orange_overcurrent_threshold;
|
||||
uint32_t overcurrent_throttling_active_length;
|
||||
bool overcurrent_throttling_active;
|
||||
uint32_t temperature_throttling_active_length;
|
||||
bool temperature_throttling_active;
|
||||
uint32_t current_temperature_zone_length;
|
||||
@@ -1464,6 +1473,10 @@ typedef struct {
|
||||
int32_t red_temperature_threshold;
|
||||
uint32_t red_hysteresis_temperature_threshold_length;
|
||||
int32_t red_hysteresis_temperature_threshold;
|
||||
uint32_t requested_overcurrent_clock_freq_length;
|
||||
uint32_t requested_overcurrent_clock_freq;
|
||||
uint32_t requested_temperature_clock_freq_length;
|
||||
uint32_t requested_temperature_clock_freq;
|
||||
} CONTROL_PROTOCOL__get_health_information_response_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -1659,7 +1672,6 @@ typedef union {
|
||||
CONTROL_PROTOCOL__d2h_event_manager_send_host_info_event_request_t d2h_event_manager_send_host_info_event_request;
|
||||
CONTROL_PROTOCOL__read_board_config_request_t read_board_config_request;
|
||||
CONTROL_PROTOCOL__write_board_config_request_t write_board_config_request;
|
||||
CONTROL_PROTOCOL__switch_application_request_t switch_application_request;
|
||||
CONTROL_PROTOCOL__config_context_switch_breakpoint_request_t config_context_switch_breakpoint_request;
|
||||
CONTROL_PROTOCOL__get_context_switch_breakpoint_status_request_t get_context_switch_breakpoint_status_request;
|
||||
CONTROL_PROTOCOL__enable_debugging_request_t enable_debugging_request;
|
||||
@@ -1713,7 +1725,7 @@ typedef struct {
|
||||
bool is_first_control_per_context;
|
||||
bool is_last_control_per_context;
|
||||
uint8_t cfg_channels_count;
|
||||
CONTROL_PROTOCOL__host_buffer_info_t config_buffer_infos[CONTROL_PROTOCOL__MAX_CFG_CHANNELS];
|
||||
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;
|
||||
|
||||
@@ -102,10 +102,10 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint32_t overcurrent_zone;
|
||||
float32_t exceeded_alert_threshold;
|
||||
float32_t sampled_current_during_alert;
|
||||
bool is_last_overcurrent_violation_reached;
|
||||
} D2H_EVENT_health_monitor_overcurrent_alert_event_message_t;
|
||||
|
||||
#define D2H_EVENT_HEALTH_MONITOR_OVERCURRENT_ALERT_EVENT_PARAMETER_COUNT (2)
|
||||
#define D2H_EVENT_HEALTH_MONITOR_OVERCURRENT_ALERT_EVENT_PARAMETER_COUNT (4)
|
||||
|
||||
/* D2H_EVENT_health_monitor_lcu_ecc_error_event_message_t should be the same as hailo_health_monitor_lcu_ecc_error_notification_message_t */
|
||||
typedef struct {
|
||||
|
||||
@@ -108,6 +108,9 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(HAILO_STATUS_UPDATE_CLOCK_CORE_CPU_FAILED)\
|
||||
FIRMWARE_STATUS__X(HAILO_STATUS_CONTROL_ETH_INIT_FAILED)\
|
||||
FIRMWARE_STATUS__X(HAILO_STATUS_SEMAPHORE_INIT_FAILED)\
|
||||
FIRMWARE_STATUS__X(HAILO_STATUS_DRAM_DMA_SERVICE_INIT_FAILED)\
|
||||
FIRMWARE_STATUS__X(HAILO_STATUS_VDMA_SERVICE_INIT_FAILED)\
|
||||
FIRMWARE_STATUS__X(HAILO_STATUS_ERROR_HANDLING_STACK_OVERFLOW)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__DATAFLOW)\
|
||||
FIRMWARE_STATUS__X(HAILO_DATAFLOW_STATUS_INVALID_PARAMETER)\
|
||||
@@ -399,6 +402,8 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_CFG_CHANNELS_COUNT_LENGTH)\
|
||||
FIRMWARE_STATUS__X(CONTROL_PROTOCOL_STATUS_INVALID_DYNAMIC_BATCH_SIZE_LENGTH)\
|
||||
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_MODULE__X(FIRMWARE_MODULE__POWER_MEASUREMENT)\
|
||||
FIRMWARE_STATUS__X(HAILO_POWER_MEASUREMENT_STATUS_POWER_INIT_ERROR)\
|
||||
@@ -735,6 +740,11 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_CFG_CHANNELS_COUNT)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_HOST_BUFFER_TYPE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_BURST_CREDITS_TASK_IS_NOT_IDLE)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_KERNEL_COUNT_OVERFLOW)\
|
||||
FIRMWARE_STATUS__X(CONTEXT_SWITCH_STATUS_INVALID_CONFIG_STREAM_INDEX)\
|
||||
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_MODULE__X(FIRMWARE_MODULE__D2H_EVENT_MANAGER)\
|
||||
FIRMWARE_STATUS__X(HAILO_D2H_EVENT_MANAGER_STATUS_MESSAGE_HIGH_PRIORITY_QUEUE_CREATE_FAILED)\
|
||||
@@ -774,7 +784,7 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(HEALTH_MONITOR_QUEUEING_OVERCURRENT_MESSAGE_FAILED)\
|
||||
FIRMWARE_STATUS__X(HEALTH_MONITOR_QUEUEING_CORE_RESET_MESSAGE_FAILED)\
|
||||
FIRMWARE_STATUS__X(HEALTH_MONITOR_QUEUEING_SOFT_RESET_MESSAGE_FAILED)\
|
||||
FIRMWARE_STATUS__X(HEALTH_MONITOR_INVALID_OVERCURRENT_OVERCURRENT_ZONE)\
|
||||
FIRMWARE_STATUS__X(HEALTH_MONITOR_INVALID_OVERCURRENT_OVERCURRENT_ZONE) /* DEPRECATED -*/\
|
||||
FIRMWARE_STATUS__X(HEALTH_MONITOR_INVALID_MESSAGE_TYPE)\
|
||||
FIRMWARE_STATUS__X(HEALTH_MONITOR_INVALID_TEMPERATURE_ALARM_TYPE) /* DEPRECATED - See TEMPERATURE_PROTECTION */\
|
||||
FIRMWARE_STATUS__X(HEALTH_MONITOR_SETUP_SAFETY_INTERRUPTS_FAILED)\
|
||||
@@ -843,7 +853,7 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(GPIO_BAD_PINMUX_GROUP)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__OVERCURRENT_PROTECTION)\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_INVALID_ALERT_THRESHOLD_VALUE)\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_INVALID_ALERT_THRESHOLD_VALUE) /* DEPRECATED */\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_INVALID_SAMPLING_PERIOD_VALUE)\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_INVALID_AVERAGING_FACTOR_VALUE)\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_UNSUPPORTED_SENSOR_TYPE)\
|
||||
@@ -851,7 +861,7 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_ALREADY_ACTIVE)\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_IS_NOT_ACTIVE)\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_INVALID_BOARD_CONFIG_VALUES)\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_NULL_POINTER_PASSED)\
|
||||
FIRMWARE_STATUS__X(OVERCURRENT_PROTECTION_NULL_POINTER_PASSED) /* DEPRECATED */\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__POWER)\
|
||||
FIRMWARE_STATUS__X(POWER_INVALID_CONVERSION_TYPE)\
|
||||
@@ -908,6 +918,7 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(DDR_BUFFER_STATUS_TRYING_TO_CHANGE_STATE_TO_INFER_WHILE_ALREADY_DURING_INFER)\
|
||||
FIRMWARE_STATUS__X(DDR_BUFFER_STATUS_NO_DDR_PAIRS_TO_RUN_INFER_ON)\
|
||||
FIRMWARE_STATUS__X(DDR_BUFFER_STATUS_INFER_REACHED_TIMEOUT)\
|
||||
FIRMWARE_STATUS__X(DDR_BUFFER_STATUS_OVERFLOW_IN_DESCRIPTORS_PER_BATCH)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__PL320)\
|
||||
FIRMWARE_STATUS__X(PL320_MAILBOX_BUSY)\
|
||||
@@ -984,6 +995,8 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(VDMA_SERVICE_STATUS_INITIAL_DESC_BIGGER_THAN_TOTAL)\
|
||||
FIRMWARE_STATUS__X(VDMA_SERVICE_STATUS_INVALID_INITIAL_CREDIT_SIZE)\
|
||||
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_MODULE__X(FIRMWARE_MODULE__MEMORY_LOGGER)\
|
||||
FIRMWARE_STATUS__X(MEMORY_LOGGER_STATUS_DEBUG_INSUFFICIENT_MEMORY)\
|
||||
@@ -1007,6 +1020,13 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_TOTAL_DESCS_COUNT_MUST_BE_POWER_OF_2)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_INVALID_DESCS_COUNT)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_DESC_PER_INTERRUPT_NOT_IN_MASK)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_STATUS_INVALID_ENGINE_INDEX)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_STATUS_INVALID_QM_INDEX)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_STATUS_INVALID_CHANNEL_TYPE)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_STATUS_INVALID_PERIPH_BYTES_PER_BUFFER)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_STATUS_INVALID_BYTES_IN_PATTERN)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_STATUS_INVALID_STREAM_INDEX)\
|
||||
FIRMWARE_STATUS__X(DRAM_DMA_SERVICE_STATUS_INVALID_CHANNEL_INDEX)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__NN_CORE_SERVICE)\
|
||||
FIRMWARE_STATUS__X(NN_CORE_SERVICE_STATUS_INVALID_ARG_PASSED)\
|
||||
@@ -1020,6 +1040,7 @@ Updating rules:
|
||||
FIRMWARE_STATUS__X(DATA_STREAM_WRAPPER_STATUS_INVALID_STREAM_INDEX)\
|
||||
FIRMWARE_STATUS__X(DATA_STREAM_MANAGER_STATUS_INVALID_CREDIT_TYPE)\
|
||||
FIRMWARE_STATUS__X(DATA_STREAM_MANAGER_WRAPPER_STATUS_INVALID_HOST_BUFFER_TYPE)\
|
||||
FIRMWARE_STATUS__X(DATA_STREAM_MANAGER_STATUS_BATCH_CREDITS_OVERFLOW)\
|
||||
\
|
||||
FIRMWARE_MODULE__X(FIRMWARE_MODULE__BURST_CREDITS_TASK)\
|
||||
FIRMWARE_STATUS__X(BURST_CREDITS_TASK_STATUS_TRYING_TO_ADD_ACTION_WHILE_NOT_IN_IDLE_STATE)\
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
|
||||
/** Start of modifications for the open source file. **/
|
||||
#include "stdint.h"
|
||||
typedef uint8_t MD5_SUM_t[16];
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
typedef uint8_t MD5_SUM_t[MD5_DIGEST_LENGTH];
|
||||
/* Any 32-bit or wider unsigned integer data type will do */
|
||||
typedef size_t MD5_u32plus;
|
||||
/** End of modifications. **/
|
||||
|
||||
@@ -69,6 +69,19 @@ typedef enum {
|
||||
SOC__NN_CLOCK_100MHz = 100 * 1000 * 1000
|
||||
} SOC__NN_CLOCK_HZ_t;
|
||||
|
||||
typedef enum {
|
||||
SOC__CPU_CLOCK_200MHz = SOC__NN_CLOCK_400MHz >> 1,
|
||||
SOC__CPU_CLOCK_187MHz = SOC__NN_CLOCK_375MHz >> 1,
|
||||
SOC__CPU_CLOCK_175MHz = SOC__NN_CLOCK_350MHz >> 1,
|
||||
SOC__CPU_CLOCK_162MHz = SOC__NN_CLOCK_325MHz >> 1,
|
||||
SOC__CPU_CLOCK_150MHz = SOC__NN_CLOCK_300MHz >> 1,
|
||||
SOC__CPU_CLOCK_137MHz = SOC__NN_CLOCK_275MHz >> 1,
|
||||
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_HZ_t;
|
||||
|
||||
typedef enum {
|
||||
WD_SERVICE_MODE_HW_SW = 0,
|
||||
WD_SERVICE_MODE_HW_ONLY,
|
||||
|
||||
@@ -99,6 +99,18 @@
|
||||
PP_HASCOMMA(PP_COMMA __VA_ARGS__ ()),\
|
||||
PP_NARG_(__VA_ARGS__, PP_RSEQ_N()))
|
||||
|
||||
#define PP_ISEMPTY(...) \
|
||||
_PP_ISEMPTY( \
|
||||
PP_HASCOMMA(__VA_ARGS__), \
|
||||
PP_HASCOMMA(PP_COMMA __VA_ARGS__), \
|
||||
PP_HASCOMMA(__VA_ARGS__ (/*empty*/)), \
|
||||
PP_HASCOMMA(PP_COMMA __VA_ARGS__ (/*empty*/)) \
|
||||
)
|
||||
|
||||
#define PP_PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4
|
||||
#define _PP_ISEMPTY(_0, _1, _2, _3) PP_HASCOMMA(PP_PASTE5(_PP_IS_EMPTY_CASE_, _0, _1, _2, _3))
|
||||
#define _PP_IS_EMPTY_CASE_0001 ,
|
||||
|
||||
#define UNUSED0(...)
|
||||
#define UNUSED1(x) (void)(x)
|
||||
#define UNUSED2(x,y) (void)(x),(void)(y)
|
||||
@@ -111,4 +123,6 @@
|
||||
#define ALL_UNUSED_IMPL(nargs) ALL_UNUSED_IMPL_(nargs)
|
||||
#define ALL_UNUSED(...) ALL_UNUSED_IMPL( PP_NARG(__VA_ARGS__))(__VA_ARGS__ )
|
||||
|
||||
#define MICROSECONDS_IN_MILLISECOND (1000)
|
||||
|
||||
#endif /* __UTILS_H__ */
|
||||
|
||||
@@ -2,22 +2,29 @@ cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
# Set firmware version
|
||||
add_definitions( -DFIRMWARE_VERSION_MAJOR=4 )
|
||||
add_definitions( -DFIRMWARE_VERSION_MINOR=8 )
|
||||
add_definitions( -DFIRMWARE_VERSION_REVISION=1 )
|
||||
add_definitions( -DFIRMWARE_VERSION_MINOR=10 )
|
||||
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}/libhailort/cmake/execute_cmake.cmake)
|
||||
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=Release
|
||||
-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 ${CMAKE_BUILD_TYPE} --target install ${CMAKE_EXTRA_BUILD_ARGS}
|
||||
--config ${PRE_BUILD_BUILD_TYPE} --target install ${CMAKE_EXTRA_BUILD_ARGS}
|
||||
PARALLEL_BUILD
|
||||
)
|
||||
|
||||
@@ -53,13 +60,24 @@ endif()
|
||||
add_subdirectory(external/protobuf/cmake EXCLUDE_FROM_ALL)
|
||||
if(NOT MSVC)
|
||||
set_target_properties(libprotobuf PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_target_properties(libprotobuf-lite PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
if(HAILO_BUILD_SERVICE)
|
||||
if(CMAKE_HOST_UNIX)
|
||||
set(HAILO_GRPC_CPP_PLUGIN_EXECUTABLE "${HAILO_PRE_BUILD_BUILD_TOOLS}/build_grpc/grpc_cpp_plugin")
|
||||
else()
|
||||
set(HAILO_GRPC_CPP_PLUGIN_EXECUTABLE "${HAILO_PRE_BUILD_BUILD_TOOLS}/build_grpc/${PRE_BUILD_BUILD_TYPE}/grpc_cpp_plugin.exe")
|
||||
endif()
|
||||
endif()
|
||||
set(HAILO_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>)
|
||||
|
||||
set(HAILORT_INC_DIR ${PROJECT_SOURCE_DIR}/hailort/libhailort/include)
|
||||
set(HAILORT_SRC_DIR ${PROJECT_SOURCE_DIR}/hailort/libhailort/src)
|
||||
set(HAILORT_COMMON_DIR ${PROJECT_SOURCE_DIR}/hailort/)
|
||||
set(COMMON_INC_DIR ${PROJECT_SOURCE_DIR}/common/include)
|
||||
set(DRIVER_INC_DIR ${PROJECT_SOURCE_DIR}/hailort/drivers/common)
|
||||
set(RPC_DIR ${PROJECT_SOURCE_DIR}/hailort/rpc)
|
||||
|
||||
if(HAILO_BUILD_PYBIND)
|
||||
if(NOT PYTHON_EXECUTABLE AND PYBIND11_PYTHON_VERSION)
|
||||
@@ -87,6 +105,17 @@ if(CMAKE_SYSTEM_NAME STREQUAL QNX)
|
||||
target_compile_definitions(pevents PRIVATE -DWFMO)
|
||||
endif()
|
||||
|
||||
if(HAILO_BUILD_SERVICE)
|
||||
set(BUILD_TESTING OFF) # disabe abseil tests
|
||||
set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library")
|
||||
# The following is an awful hack needed in order to force grpc to use our libprotobuf+liborotoc targets
|
||||
# ('formal' options are to let grpc recompile it which causes a name conflict,
|
||||
# or let it use find_package and take the risk it will use a different installed lib)
|
||||
set(gRPC_PROTOBUF_PROVIDER "hack" CACHE STRING "Provider of protobuf library")
|
||||
add_subdirectory(external/grpc EXCLUDE_FROM_ALL)
|
||||
add_subdirectory(rpc)
|
||||
endif()
|
||||
|
||||
# microprofile
|
||||
if(HAILO_MICROPROFILE)
|
||||
add_library(microprofile STATIC EXCLUDE_FROM_ALL external/microprofile/microprofile.cpp)
|
||||
@@ -114,6 +143,10 @@ add_subdirectory(common)
|
||||
add_subdirectory(libhailort)
|
||||
add_subdirectory(hailortcli)
|
||||
|
||||
if(HAILO_BUILD_SERVICE)
|
||||
add_subdirectory(hailort_service)
|
||||
endif()
|
||||
|
||||
if(HAILO_WIN_DRIVER)
|
||||
add_subdirectory(drivers/win)
|
||||
add_subdirectory(packaging)
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
| Package | Copyright (c) | License | Version | Notes | References |
|
||||
|:---------------------------------|:----------------------------------|:-------------------|:---------------|:-------------------------------------------|:------------------------------------------------------------------------------|
|
||||
| CLI11 | University of Cincinnati | 3-Clause BSD | 1.7 | Cloned entire package | https://github.com/CLIUtils/CLI11 |
|
||||
| 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.11.4 | Cloned entire package | https://github.com/protocolbuffers/protobuf |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| readerwriterqueue | Cameron Desrochers | Simplified BSD | 1.0.3 | Cloned entire package | https://github.com/cameron314/readerwriterqueue |
|
||||
| DotWriter | John Vilk | MIT License | master | Cloned entire package (forked) | https://github.com/jvilk/DotWriter |
|
||||
| DotWriter | John Vilk | MIT License | master | Fork | https://github.com/hailo-ai/DotWriter |
|
||||
| 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,7 @@ FUNCTION(disable_exceptions target)
|
||||
if(WIN32)
|
||||
# TODO: Find the right flag for windows (-fno-exceptions equivalent)
|
||||
elseif(UNIX)
|
||||
target_compile_options(libhailort PRIVATE -fno-exceptions)
|
||||
target_compile_options(${target} PRIVATE -fno-exceptions)
|
||||
else()
|
||||
message(FATAL_ERROR "Unexpeced host, stopping build")
|
||||
endif()
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
@@ -27,7 +26,7 @@ public:
|
||||
explicit AsyncThread(std::function<T(void)> func) :
|
||||
m_result(),
|
||||
m_thread([this, func]() {
|
||||
m_result.store(func());
|
||||
m_result = func();
|
||||
})
|
||||
{}
|
||||
|
||||
@@ -46,14 +45,15 @@ public:
|
||||
if (m_thread.joinable()) {
|
||||
m_thread.join();
|
||||
}
|
||||
return m_result.load();
|
||||
return std::move(m_result);
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<T> m_result;
|
||||
T m_result;
|
||||
std::thread m_thread;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
using AsyncThreadPtr = std::unique_ptr<AsyncThread<T>>;
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
CB_DEQUEUE(m_circ, 1);
|
||||
}
|
||||
|
||||
T& front()
|
||||
T &front()
|
||||
{
|
||||
return m_array[CB_TAIL(m_circ)];
|
||||
}
|
||||
@@ -102,6 +102,11 @@ public:
|
||||
return 0 == CB_AVAIL(m_circ, CB_HEAD(m_circ), CB_TAIL(m_circ));
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return CB_PROG(m_circ, CB_HEAD(m_circ), CB_TAIL(m_circ));
|
||||
}
|
||||
|
||||
private:
|
||||
circbuf_t m_circ;
|
||||
std::vector<T> m_array;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "hailo/expected.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#include <dirent.h>
|
||||
@@ -29,7 +30,10 @@ public:
|
||||
Filesystem() = delete;
|
||||
|
||||
static Expected<std::vector<std::string>> get_files_in_dir_flat(const std::string &dir_path);
|
||||
static Expected<std::vector<std::string>> get_latest_files_in_dir_flat(const std::string &dir_path, std::chrono::milliseconds time_interval);
|
||||
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 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());
|
||||
@@ -92,6 +96,37 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
// TODO: HRT-7304 - Add support for windows
|
||||
#if defined(__GNUC__)
|
||||
class TempFile {
|
||||
public:
|
||||
static Expected<TempFile> create(const std::string &file_name, const std::string &file_directory = "");
|
||||
~TempFile();
|
||||
|
||||
std::string name() const;
|
||||
|
||||
private:
|
||||
TempFile(const char *path);
|
||||
|
||||
std::string m_path;
|
||||
};
|
||||
|
||||
class LockedFile {
|
||||
public:
|
||||
// The mode param is the string containing the file access mode, compatible with `fopen` function.
|
||||
static Expected<LockedFile> create(const std::string &file_path, const std::string &mode);
|
||||
~LockedFile();
|
||||
|
||||
int get_fd() const;
|
||||
|
||||
private:
|
||||
LockedFile(FILE *fp, int fd);
|
||||
|
||||
FILE *m_fp;
|
||||
int m_fd;
|
||||
};
|
||||
#endif
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
#endif /* _OS_FILESYSTEM_HPP_ */
|
||||
|
||||
@@ -13,11 +13,13 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
const char *Filesystem::SEPARATOR = "/";
|
||||
const std::string UNIQUE_TMP_FILE_SUFFIX = "XXXXXX\0";
|
||||
|
||||
Expected<Filesystem::DirWalker> Filesystem::DirWalker::create(const std::string &dir_path)
|
||||
{
|
||||
@@ -85,6 +87,61 @@ Expected<std::vector<std::string>> Filesystem::get_files_in_dir_flat(const std::
|
||||
static_assert(false, "Unsupported Platform!");
|
||||
#endif
|
||||
|
||||
Expected<time_t> Filesystem::get_file_modified_time(const std::string &file_path)
|
||||
{
|
||||
struct stat attr;
|
||||
auto res = stat(file_path.c_str(), &attr);
|
||||
CHECK_AS_EXPECTED((0 == res), HAILO_INTERNAL_FAILURE, "stat() failed on file {}, with errno {}", file_path, errno);
|
||||
auto last_modification_time = attr.st_mtime;
|
||||
return last_modification_time;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
|
||||
Expected<std::vector<std::string>> Filesystem::get_latest_files_in_dir_flat(const std::string &dir_path,
|
||||
std::chrono::milliseconds time_interval)
|
||||
{
|
||||
std::time_t curr_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
const std::string dir_path_with_sep = has_suffix(dir_path, SEPARATOR) ? dir_path : dir_path + SEPARATOR;
|
||||
|
||||
auto dir = DirWalker::create(dir_path_with_sep);
|
||||
CHECK_EXPECTED(dir);
|
||||
|
||||
std::vector<std::string> files;
|
||||
struct dirent *entry = nullptr;
|
||||
while ((entry = dir->next_file()) != nullptr) {
|
||||
if (entry->d_type != DT_REG) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string file_path = dir_path_with_sep + std::string(entry->d_name);
|
||||
auto file_modified_time = get_file_modified_time(file_path);
|
||||
CHECK_EXPECTED(file_modified_time);
|
||||
|
||||
auto time_diff_sec = std::difftime(curr_time, file_modified_time.value());
|
||||
auto time_diff_millisec = time_diff_sec * 1000;
|
||||
if (time_diff_millisec <= static_cast<double>(time_interval.count())) {
|
||||
files.emplace_back(file_path);
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
#elif defined(__QNX__)
|
||||
Expected<std::vector<std::string>> Filesystem::get_latest_files_in_dir_flat(const std::string &dir_path,
|
||||
std::chrono::milliseconds time_interval)
|
||||
{
|
||||
// TODO: HRT-7643
|
||||
(void)dir_path;
|
||||
(void)time_interval;
|
||||
return make_unexpected(HAILO_NOT_IMPLEMENTED);
|
||||
}
|
||||
// Unsupported Platform
|
||||
#else
|
||||
static_assert(false, "Unsupported Platform!");
|
||||
#endif // __linux__
|
||||
|
||||
Expected<bool> Filesystem::is_directory(const std::string &path)
|
||||
{
|
||||
struct stat path_stat{};
|
||||
@@ -94,4 +151,75 @@ Expected<bool> Filesystem::is_directory(const std::string &path)
|
||||
return S_ISDIR(path_stat.st_mode);
|
||||
}
|
||||
|
||||
hailo_status Filesystem::create_directory(const std::string &dir_path)
|
||||
{
|
||||
auto ret_val = mkdir(dir_path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO );
|
||||
CHECK((ret_val == 0) || (errno == EEXIST), HAILO_FILE_OPERATION_FAILURE, "Failed to create directory {}", dir_path);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
Expected<TempFile> TempFile::create(const std::string &file_name, const std::string &file_directory)
|
||||
{
|
||||
if (!file_directory.empty()) {
|
||||
auto status = Filesystem::create_directory(file_directory);
|
||||
CHECK_SUCCESS_AS_EXPECTED(status);
|
||||
}
|
||||
|
||||
std::string file_path = file_directory + file_name + UNIQUE_TMP_FILE_SUFFIX;
|
||||
char *fname = static_cast<char*>(std::malloc(sizeof(char) * (file_path.length() + 1)));
|
||||
std::strncpy(fname, file_path.c_str(), file_path.length() + 1);
|
||||
|
||||
int fd = mkstemp(fname);
|
||||
CHECK_AS_EXPECTED((-1 != fd), HAILO_FILE_OPERATION_FAILURE, "Failed to create tmp file {}, with errno {}", file_path, errno);
|
||||
close(fd);
|
||||
|
||||
return TempFile(fname);
|
||||
}
|
||||
|
||||
TempFile::TempFile(const char *path) : m_path(path)
|
||||
{}
|
||||
|
||||
TempFile::~TempFile()
|
||||
{
|
||||
// TODO: Guarantee file deletion upon unexpected program termination.
|
||||
std::remove(m_path.c_str());
|
||||
}
|
||||
|
||||
std::string TempFile::name() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
Expected<LockedFile> LockedFile::create(const std::string &file_path, const std::string &mode)
|
||||
{
|
||||
auto fp = fopen(file_path.c_str(), mode.c_str());
|
||||
CHECK_AS_EXPECTED((nullptr != fp), HAILO_OPEN_FILE_FAILURE, "Failed opening file: {}, with errno: {}", file_path, errno);
|
||||
|
||||
int fd = fileno(fp);
|
||||
int done = flock(fd, LOCK_EX | LOCK_NB);
|
||||
if (-1 == done) {
|
||||
LOGGER__ERROR("Failed to flock file: {}, with errno: {}", file_path, errno);
|
||||
fclose(fp);
|
||||
return make_unexpected(HAILO_FILE_OPERATION_FAILURE);
|
||||
}
|
||||
|
||||
return LockedFile(fp, fd);
|
||||
}
|
||||
|
||||
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);
|
||||
fclose(m_fp);
|
||||
}
|
||||
}
|
||||
|
||||
int LockedFile::get_fd() const
|
||||
{
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
@@ -129,7 +129,9 @@ hailo_status Socket::pton(int af, const char *src, void *dst)
|
||||
CHECK_ARG_NOT_NULL(dst);
|
||||
|
||||
inet_rc = inet_pton(af, reinterpret_cast<const char*>(src), dst);
|
||||
CHECK(1 == inet_rc, HAILO_ETH_FAILURE, "Could not convert string ip address to sockaddr struct");
|
||||
if (1 != inet_rc) {
|
||||
return HAILO_ETH_FAILURE;
|
||||
}
|
||||
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ hailo_status EthernetUtils::get_interface_from_board_ip(const char *board_ip, ch
|
||||
|
||||
struct in_addr board_ip_struct{};
|
||||
auto status = Socket::pton(AF_INET, board_ip, &board_ip_struct);
|
||||
CHECK_SUCCESS(status);
|
||||
CHECK_SUCCESS(status, "Invalid board ip address {}", board_ip);
|
||||
|
||||
for (const auto& network_interface : network_interfaces.value()) {
|
||||
auto arp_table = ArpTable::create(network_interface.index());
|
||||
|
||||
@@ -120,6 +120,22 @@ Expected<std::vector<std::string>> Filesystem::get_files_in_dir_flat(const std::
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
Expected<std::vector<std::string>> Filesystem::get_latest_files_in_dir_flat(const std::string &dir_path, std::chrono::milliseconds time_interval)
|
||||
{
|
||||
// TODO: HRT-7304
|
||||
(void)dir_path;
|
||||
(void)time_interval;
|
||||
return make_unexpected(HAILO_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
Expected<time_t> Filesystem::get_file_modified_time(const std::string &file_path)
|
||||
{
|
||||
// TODO: HRT-7304
|
||||
(void)file_path;
|
||||
return make_unexpected(HAILO_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
Expected<bool> Filesystem::is_directory(const std::string &path)
|
||||
{
|
||||
if (path.length() > MAX_PATH) {
|
||||
|
||||
@@ -138,7 +138,9 @@ hailo_status Socket::pton(int af, const char *src, void *dst)
|
||||
CHECK_EXPECTED_AS_STATUS(module_wrapper);
|
||||
|
||||
inet_result = inet_pton(af, src, dst);
|
||||
CHECK(1 == inet_result, HAILO_ETH_FAILURE, "Failed inet_pton. WSALE={}", WSAGetLastError());
|
||||
if (1 != inet_result) {
|
||||
return HAILO_ETH_FAILURE;
|
||||
}
|
||||
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "common/string_utils.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -71,4 +72,17 @@ Expected<uint8_t> StringUtils::to_uint8(const std::string &str, int base)
|
||||
return static_cast<uint8_t>(number.value());
|
||||
}
|
||||
|
||||
std::string StringUtils::to_hex_string(const uint8_t *array, size_t size, bool uppercase, const std::string &delimiter)
|
||||
{
|
||||
std::stringstream stream;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
const auto hex_byte = uppercase ? fmt::format("{:02X}", array[i]) : fmt::format("{:02x}", array[i]);
|
||||
stream << hex_byte;
|
||||
if (i != (size - 1)) {
|
||||
stream << delimiter;
|
||||
}
|
||||
}
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
@@ -21,6 +21,8 @@ public:
|
||||
static Expected<int32_t> to_int32(const std::string &str, int base);
|
||||
static Expected<uint8_t> to_uint8(const std::string &str, int base);
|
||||
static Expected<uint32_t> to_uint32(const std::string &str, int base);
|
||||
|
||||
static std::string to_hex_string(const uint8_t *array, size_t size, bool uppercase, const std::string &delimiter="");
|
||||
};
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
@@ -221,6 +222,46 @@ _ISEMPTY( \
|
||||
} while(0)
|
||||
#define CHECK_SUCCESS_AS_EXPECTED(status, ...) _CHECK_SUCCESS_AS_EXPECTED(status, ISEMPTY(__VA_ARGS__), "" __VA_ARGS__)
|
||||
|
||||
#ifdef HAILO_SUPPORT_MULTI_PROCESS
|
||||
#define _CHECK_SUCCESS_AS_RPC_STATUS(status, reply, is_default, fmt, ...) \
|
||||
do { \
|
||||
const auto &__check_success_status = (status); \
|
||||
if (__check_success_status != HAILO_SUCCESS) { \
|
||||
reply->set_status(static_cast<uint32_t>(__check_success_status)); \
|
||||
LOGGER__ERROR( \
|
||||
_CONSTRUCT_MSG(is_default, "CHECK_SUCCESS_AS_RPC_STATUS failed with status={}", fmt, __check_success_status, ##__VA_ARGS__) \
|
||||
); \
|
||||
return grpc::Status::OK; \
|
||||
} \
|
||||
} while(0)
|
||||
#define CHECK_SUCCESS_AS_RPC_STATUS(status, reply, ...) _CHECK_SUCCESS_AS_RPC_STATUS(status, reply, ISEMPTY(__VA_ARGS__), "" __VA_ARGS__)
|
||||
|
||||
#define CHECK_EXPECTED_AS_RPC_STATUS(expected, reply, ...) CHECK_SUCCESS_AS_RPC_STATUS(expected.status(), reply, __VA_ARGS__)
|
||||
|
||||
#define _CHECK_AS_RPC_STATUS(cond, reply, ret_val, ...) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
reply->set_status(ret_val); \
|
||||
LOGGER__ERROR( \
|
||||
_CONSTRUCT_MSG(is_default, "CHECK_AS_RPC_STATUS failed with status={}", fmt, ret_val, ##__VA_ARGS__) \
|
||||
); \
|
||||
return grpc::Status::OK; \
|
||||
} \
|
||||
} 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) \
|
||||
do { \
|
||||
if (!status.ok()) { \
|
||||
LOGGER__ERROR("CHECK_GRPC_STATUS failed with error massage: {}.", status.error_message()); \
|
||||
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))
|
||||
#endif
|
||||
|
||||
#define _CHECK_EXPECTED(obj, is_default, fmt, ...) \
|
||||
do { \
|
||||
const auto &__check_expected_obj = (obj); \
|
||||
@@ -244,6 +285,15 @@ _ISEMPTY( \
|
||||
} while(0)
|
||||
#define CHECK_EXPECTED_AS_STATUS(obj, ...) _CHECK_EXPECTED_AS_STATUS(obj, ISEMPTY(__VA_ARGS__), "" __VA_ARGS__)
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define IGNORE_DEPRECATION_WARNINGS_BEGIN _Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
|
||||
#define IGNORE_DEPRECATION_WARNINGS_END _Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define IGNORE_DEPRECATION_WARNINGS_BEGIN
|
||||
#define IGNORE_DEPRECATION_WARNINGS_END
|
||||
#endif
|
||||
|
||||
constexpr bool is_powerof2(size_t v) {
|
||||
// bit trick
|
||||
return (v & (v - 1)) == 0;
|
||||
@@ -271,6 +321,18 @@ static uint32_t get_max_value_of_unordered_map(const std::unordered_map<K, V> &m
|
||||
return max_count;
|
||||
}
|
||||
|
||||
template<class K, class V>
|
||||
static uint32_t get_min_value_of_unordered_map(const std::unordered_map<K, V> &map)
|
||||
{
|
||||
uint32_t min_count = UINT32_MAX;
|
||||
for (auto &name_counter_pair : map) {
|
||||
if (name_counter_pair.second < min_count) {
|
||||
min_count = name_counter_pair.second;
|
||||
}
|
||||
}
|
||||
return min_count;
|
||||
}
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
#endif /* HAILO_UTILS_H_ */
|
||||
@@ -8,9 +8,10 @@
|
||||
|
||||
// This value is not easily changeable.
|
||||
// For example: the channel interrupts ioctls assume we have up to 32 channels
|
||||
#define MAX_VDMA_CHANNELS (32)
|
||||
#define SIZE_OF_VDMA_DESCRIPTOR (16)
|
||||
#define VDMA_DEST_CHANNELS_START (16)
|
||||
#define MAX_VDMA_CHANNELS_PER_ENGINE (32)
|
||||
#define MAX_VDMA_ENGINES (3)
|
||||
#define SIZE_OF_VDMA_DESCRIPTOR (16)
|
||||
#define VDMA_DEST_CHANNELS_START (16)
|
||||
|
||||
#define CHANNEL_IRQ_TIMESTAMPS_SIZE (128 * 2) // Should be same as MAX_IRQ_TIMESTAMPS_SIZE (hailort_driver.hpp)
|
||||
#define CHANNEL_IRQ_TIMESTAMPS_SIZE_MASK (CHANNEL_IRQ_TIMESTAMPS_SIZE - 1)
|
||||
@@ -56,12 +57,13 @@ typedef uint8_t bool;
|
||||
|
||||
#define HAILO_GENERAL_IOCTL_MAGIC 'g'
|
||||
#define HAILO_VDMA_IOCTL_MAGIC 'v'
|
||||
#define HAILO_WINDOWS_IOCTL_MAGIC 'w'
|
||||
#define HAILO_NON_LINUX_IOCTL_MAGIC 'w'
|
||||
|
||||
#elif defined(__QNX__) // #ifdef _MSC_VER
|
||||
#include <devctl.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
// defines for devctl
|
||||
#define _IOW_ __DIOF
|
||||
#define _IOR_ __DIOT
|
||||
@@ -69,6 +71,7 @@ typedef uint8_t bool;
|
||||
#define _IO_ __DION
|
||||
#define HAILO_GENERAL_IOCTL_MAGIC _DCMD_ALL
|
||||
#define HAILO_VDMA_IOCTL_MAGIC _DCMD_MISC
|
||||
#define HAILO_NON_LINUX_IOCTL_MAGIC _DCMD_PROC
|
||||
|
||||
#else // #ifdef _MSC_VER
|
||||
#error "unsupported platform!"
|
||||
@@ -103,13 +106,24 @@ enum hailo_allocation_mode {
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_BUFFER_MAP */
|
||||
struct hailo_vdma_buffer_map_params {
|
||||
#if defined(__linux__) || defined(_MSC_VER)
|
||||
void* user_address; // in
|
||||
#elif defined(__QNX__)
|
||||
shm_handle_t shared_memory_handle; // in
|
||||
#else
|
||||
#error "unsupported platform!"
|
||||
#endif // __linux__
|
||||
size_t size; // in
|
||||
enum hailo_dma_data_direction data_direction; // in
|
||||
uintptr_t allocated_buffer_handle; // in
|
||||
size_t mapped_handle; // out
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_BUFFER_UNMAP */
|
||||
struct hailo_vdma_buffer_unmap_params {
|
||||
size_t mapped_handle;
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_DESC_LIST_CREATE */
|
||||
struct hailo_desc_list_create_params {
|
||||
size_t desc_count; // in
|
||||
@@ -118,8 +132,8 @@ struct hailo_desc_list_create_params {
|
||||
uint64_t dma_address; // out
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_WINDOWS_DESC_LIST_MMAP */
|
||||
struct hailo_windows_desc_list_mmap_params {
|
||||
/* structure used in ioctl HAILO_NON_LINUX_DESC_LIST_MMAP */
|
||||
struct hailo_non_linux_desc_list_mmap_params {
|
||||
uintptr_t desc_handle; // in
|
||||
size_t size; // in
|
||||
void* user_address; // out
|
||||
@@ -135,7 +149,8 @@ struct hailo_desc_list_bind_vdma_buffer_params {
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_ENABLE */
|
||||
struct hailo_vdma_channel_enable_params {
|
||||
uint32_t channel_index; // in
|
||||
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.
|
||||
@@ -146,28 +161,39 @@ struct hailo_vdma_channel_enable_params {
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_DISABLE */
|
||||
struct hailo_vdma_channel_disable_params {
|
||||
uint32_t channel_index; // in
|
||||
uint8_t engine_index; // in
|
||||
uint8_t channel_index; // in
|
||||
uint64_t channel_handle; // in
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_WAIT_INT */
|
||||
struct hailo_vdma_channel_wait_params {
|
||||
uint32_t channel_index; // in
|
||||
uint64_t channel_handle; // in
|
||||
uint64_t timeout_ms; // in
|
||||
struct hailo_channel_interrupt_timestamp *timestamps; // out
|
||||
uint32_t timestamps_count; // inout
|
||||
uint8_t engine_index; // in
|
||||
uint8_t channel_index; // in
|
||||
uint64_t channel_handle; // in
|
||||
uint64_t timeout_ms; // in
|
||||
uint32_t timestamps_count; // inout
|
||||
// In linux send address to local buffer because there isnt room on stack for array
|
||||
#if defined(__linux__)
|
||||
struct hailo_channel_interrupt_timestamp *timestamps; // out
|
||||
#elif defined(__QNX__) || defined(_MSC_VER)
|
||||
struct hailo_channel_interrupt_timestamp timestamps[CHANNEL_IRQ_TIMESTAMPS_SIZE]; // out
|
||||
#else
|
||||
#error "unsupported platform!"
|
||||
#endif // __linux__
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_ABORT */
|
||||
struct hailo_vdma_channel_abort_params {
|
||||
uint32_t channel_index; // in
|
||||
uint8_t engine_index; // in
|
||||
uint8_t channel_index; // in
|
||||
uint64_t channel_handle; // in
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_CLEAR_ABORT */
|
||||
struct hailo_vdma_channel_clear_abort_params {
|
||||
uint32_t channel_index; // in
|
||||
uint8_t engine_index; // in
|
||||
uint8_t channel_index; // in
|
||||
uint64_t channel_handle; // in
|
||||
};
|
||||
|
||||
@@ -215,12 +241,24 @@ struct hailo_bar_transfer_params {
|
||||
uint8_t buffer[MAX_BAR_TRANSFER_LENGTH]; // in/out
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_REGISTERS */
|
||||
struct hailo_channel_registers_params {
|
||||
enum hailo_transfer_direction transfer_direction; // in
|
||||
off_t offset; // in
|
||||
size_t size; // in
|
||||
uint32_t data; // in/out
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_READ_REGISTER */
|
||||
struct hailo_vdma_channel_read_register_params {
|
||||
uint8_t engine_index; // in
|
||||
uint8_t channel_index; // in
|
||||
enum hailo_dma_data_direction direction; // in
|
||||
size_t offset; // in
|
||||
size_t reg_size; // in, can be either 1, 2 or 4
|
||||
uint32_t data; // out
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_CHANNEL_WRITE_REGISTER */
|
||||
struct hailo_vdma_channel_write_register_params {
|
||||
uint8_t engine_index; // in
|
||||
uint8_t channel_index; // in
|
||||
enum hailo_dma_data_direction direction; // in
|
||||
size_t offset; // in
|
||||
size_t reg_size; // in, can be either 1, 2 or 4
|
||||
uint32_t data; // in
|
||||
};
|
||||
|
||||
/* structure used in ioctl HAILO_VDMA_BUFFER_SYNC */
|
||||
@@ -267,6 +305,10 @@ struct hailo_device_properties {
|
||||
enum hailo_board_type board_type;
|
||||
enum hailo_allocation_mode allocation_mode;
|
||||
enum hailo_dma_type dma_type;
|
||||
size_t dma_engines_count;
|
||||
#ifdef __QNX__
|
||||
pid_t resource_manager_pid;
|
||||
#endif // __QNX__
|
||||
};
|
||||
|
||||
struct hailo_driver_info {
|
||||
@@ -331,7 +373,8 @@ enum hailo_vdma_ioctl_code {
|
||||
HAILO_VDMA_CHANNEL_WAIT_INT_CODE,
|
||||
HAILO_VDMA_CHANNEL_ABORT_CODE,
|
||||
HAILO_VDMA_CHANNEL_CLEAR_ABORT_CODE,
|
||||
HAILO_VDMA_CHANNEL_REGISTERS_CODE,
|
||||
HAILO_VDMA_CHANNEL_READ_REGISTER_CODE,
|
||||
HAILO_VDMA_CHANNEL_WRITE_REGISTER_CODE,
|
||||
HAILO_VDMA_BUFFER_MAP_CODE,
|
||||
HAILO_VDMA_BUFFER_UNMAP_CODE,
|
||||
HAILO_VDMA_BUFFER_SYNC_CODE,
|
||||
@@ -348,19 +391,20 @@ enum hailo_vdma_ioctl_code {
|
||||
HAILO_VDMA_IOCTL_MAX_NR,
|
||||
};
|
||||
|
||||
#define HAILO_VDMA_CHANNEL_ENABLE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_ENABLE_CODE, struct hailo_vdma_channel_enable_params)
|
||||
#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_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_REGISTERS _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_REGISTERS_CODE, struct hailo_channel_registers_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)
|
||||
#define HAILO_VDMA_CHANNEL_WRITE_REGISTER _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CHANNEL_WRITE_REGISTER_CODE, struct hailo_vdma_channel_write_register_params)
|
||||
|
||||
#define HAILO_VDMA_BUFFER_MAP _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_MAP_CODE, struct hailo_vdma_buffer_map_params)
|
||||
#define HAILO_VDMA_BUFFER_UNMAP _IO_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_UNMAP_CODE)
|
||||
#define HAILO_VDMA_BUFFER_MAP _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_MAP_CODE, struct hailo_vdma_buffer_map_params)
|
||||
#define HAILO_VDMA_BUFFER_UNMAP _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_UNMAP_CODE, struct hailo_vdma_buffer_unmap_params)
|
||||
#define HAILO_VDMA_BUFFER_SYNC _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_BUFFER_SYNC_CODE, struct hailo_vdma_buffer_sync_params)
|
||||
|
||||
#define HAILO_DESC_LIST_CREATE _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_CREATE_CODE, struct hailo_desc_list_create_params)
|
||||
#define HAILO_DESC_LIST_RELEASE _IO_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_RELEASE_CODE)
|
||||
#define HAILO_DESC_LIST_RELEASE _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_RELEASE_CODE, uintptr_t)
|
||||
#define HAILO_DESC_LIST_BIND_VDMA_BUFFER _IOR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_DESC_LIST_BIND_VDMA_BUFFER_CODE, struct hailo_desc_list_bind_vdma_buffer_params)
|
||||
|
||||
#define HAILO_VDMA_LOW_MEMORY_BUFFER_ALLOC _IOWR_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_LOW_MEMORY_BUFFER_ALLOC_CODE, struct hailo_allocate_low_memory_buffer_params)
|
||||
@@ -372,14 +416,14 @@ enum hailo_vdma_ioctl_code {
|
||||
#define HAILO_VDMA_CONTINUOUS_BUFFER_FREE _IO_(HAILO_VDMA_IOCTL_MAGIC, HAILO_VDMA_CONTINUOUS_BUFFER_FREE_CODE)
|
||||
|
||||
|
||||
enum hailo_windows_ioctl_code {
|
||||
HAILO_WINDOWS_DESC_LIST_MMAP_CODE,
|
||||
enum hailo_non_linux_ioctl_code {
|
||||
HAILO_NON_LINUX_DESC_LIST_MMAP_CODE,
|
||||
|
||||
// Must be last
|
||||
HAILO_WINDOWS_IOCTL_MAX_NR,
|
||||
HAILO_NON_LINUX_IOCTL_MAX_NR,
|
||||
};
|
||||
|
||||
#define HAILO_WINDOWS_DESC_LIST_MMAP _IOWR_(HAILO_WINDOWS_IOCTL_MAGIC, HAILO_WINDOWS_DESC_LIST_MMAP_CODE, struct hailo_windows_desc_list_mmap_params)
|
||||
#define HAILO_NON_LINUX_DESC_LIST_MMAP _IOWR_(HAILO_NON_LINUX_IOCTL_MAGIC, HAILO_NON_LINUX_DESC_LIST_MMAP_CODE, struct hailo_non_linux_desc_list_mmap_params)
|
||||
|
||||
|
||||
#endif /* _HAILO_IOCTL_COMMON_H_ */
|
||||
|
||||
@@ -75,7 +75,7 @@ struct tCompatibleHailoIoctlParam
|
||||
|
||||
#define HAILO_GENERAL_IOCTL_MAGIC 0
|
||||
#define HAILO_VDMA_IOCTL_MAGIC 1
|
||||
#define HAILO_WINDOWS_IOCTL_MAGIC 2
|
||||
#define HAILO_NON_LINUX_IOCTL_MAGIC 2
|
||||
|
||||
|
||||
|
||||
@@ -111,13 +111,16 @@ struct tCompatibleHailoIoctlData
|
||||
hailo_vdma_buffer_sync_params VdmaBufferSync;
|
||||
hailo_fw_control FirmwareControl;
|
||||
hailo_vdma_buffer_map_params VdmaBufferMap;
|
||||
hailo_vdma_buffer_unmap_params VdmaBufferUnmap;
|
||||
hailo_desc_list_create_params DescListCreate;
|
||||
uintptr_t DescListReleaseParam;
|
||||
hailo_desc_list_bind_vdma_buffer_params DescListBind;
|
||||
hailo_d2h_notification D2HNotification;
|
||||
hailo_device_properties DeviceProperties;
|
||||
hailo_driver_info DriverInfo;
|
||||
hailo_channel_registers_params ChannelRegisters;
|
||||
hailo_windows_desc_list_mmap_params DescListMmap;
|
||||
hailo_vdma_channel_read_register_params ChannelRegisterRead;
|
||||
hailo_vdma_channel_write_register_params ChannelRegisterWrite;
|
||||
hailo_non_linux_desc_list_mmap_params DescListMmap;
|
||||
hailo_read_log_params ReadLog;
|
||||
hailo_mark_as_in_use_params MarkAsInUse;
|
||||
} Buffer;
|
||||
|
||||
47
hailort/hailort_service/CMakeLists.txt
Normal file
47
hailort/hailort_service/CMakeLists.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
add_executable(hailort_service
|
||||
hailort_rpc_service.cpp
|
||||
hailort_service.cpp
|
||||
service_resource_manager.hpp
|
||||
)
|
||||
target_compile_options(hailort_service PRIVATE ${HAILORT_COMPILE_OPTIONS})
|
||||
set_property(TARGET hailort_service PROPERTY CXX_STANDARD 14)
|
||||
target_link_libraries(hailort_service
|
||||
libhailort
|
||||
spdlog::spdlog
|
||||
grpc++_unsecure
|
||||
hailort_rpc_grpc_proto)
|
||||
target_include_directories(hailort_service
|
||||
PRIVATE
|
||||
${HAILORT_INC_DIR}
|
||||
${COMMON_INC_DIR}
|
||||
${RPC_DIR}
|
||||
)
|
||||
disable_exceptions(hailort_service)
|
||||
|
||||
# Install systemd unit file
|
||||
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()
|
||||
|
||||
set(HAILORT_SERVICE_UNIT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/hailort.service)
|
||||
install(
|
||||
FILES "${HAILORT_SERVICE_UNIT_FILE}"
|
||||
DESTINATION "${SYSTEMD_UNIT_DIR}"
|
||||
CONFIGURATIONS Release
|
||||
COMPONENT hailort_service
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS hailort_service
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
CONFIGURATIONS Release
|
||||
)
|
||||
|
||||
# Create empty directory for hailort log file
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(HAILORT_LOG_DIR "/var/log/hailo")
|
||||
install(DIRECTORY DESTINATION ${HAILORT_LOG_DIR})
|
||||
endif()
|
||||
13
hailort/hailort_service/hailort.service
Normal file
13
hailort/hailort_service/hailort.service
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=HailoRT service
|
||||
Documentation=https://github.com/hailo-ai/hailort
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart=/usr/local/bin/hailort_service
|
||||
Restart=on-failure
|
||||
RemainAfterExit=yes
|
||||
Environment="HAILORT_LOGGER_PATH=/var/log/hailo"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
744
hailort/hailort_service/hailort_rpc_service.cpp
Normal file
744
hailort/hailort_service/hailort_rpc_service.cpp
Normal file
@@ -0,0 +1,744 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file hailort_rpc_service.cpp
|
||||
* @brief Implementation of the hailort rpc service
|
||||
**/
|
||||
|
||||
#include "hailort_rpc_service.hpp"
|
||||
#include "rpc/rpc_definitions.hpp"
|
||||
#include "service_resource_manager.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "hailo/network_group.hpp"
|
||||
#include "hailo/vdevice.hpp"
|
||||
#include "hailo/vstream.hpp"
|
||||
#include "hailo/hailort_common.hpp"
|
||||
#include <syslog.h>
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
grpc::Status HailoRtRpcService::client_keep_alive(grpc::ServerContext *ctx, const keepalive_Request *request,
|
||||
empty*)
|
||||
{
|
||||
auto client_id = request->process_id();
|
||||
while (!ctx->IsCancelled()) {
|
||||
sleep(hailort::HAILO_KEEPALIVE_INTERVAL_SEC);
|
||||
}
|
||||
LOGGER__INFO("Client disconnected, pid: {}", client_id);
|
||||
syslog(LOG_NOTICE, "Client disconnected, pid: %i", client_id);
|
||||
ServiceResourceManager<OutputVStream>::get_instance().release_by_pid(client_id);
|
||||
ServiceResourceManager<InputVStream>::get_instance().release_by_pid(client_id);
|
||||
ServiceResourceManager<ConfiguredNetworkGroup>::get_instance().release_by_pid(client_id);
|
||||
ServiceResourceManager<VDevice>::get_instance().release_by_pid(client_id);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::get_service_version(grpc::ServerContext*, const get_service_version_Request*,
|
||||
get_service_version_Reply *reply)
|
||||
{
|
||||
hailo_version_t service_version = {};
|
||||
auto status = hailo_get_library_version(&service_version);
|
||||
CHECK_SUCCESS_AS_RPC_STATUS(status, reply);
|
||||
auto hailo_version_proto = reply->mutable_hailo_version();
|
||||
hailo_version_proto->set_major_version(service_version.major);
|
||||
hailo_version_proto->set_minor_version(service_version.minor);
|
||||
hailo_version_proto->set_revision_version(service_version.revision);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::VDevice_create(grpc::ServerContext *, const VDevice_create_Request *request,
|
||||
VDevice_create_Reply *reply)
|
||||
{
|
||||
// Deserialization
|
||||
const auto params_proto = request->hailo_vdevice_params();
|
||||
std::vector<hailo_device_id_t> device_ids;
|
||||
device_ids.reserve(params_proto.device_ids().size());
|
||||
for (auto device_id_str : params_proto.device_ids()) {
|
||||
auto device_id_struct = HailoRTCommon::to_device_id(device_id_str);
|
||||
CHECK_SUCCESS_AS_RPC_STATUS(device_id_struct.status(), reply);
|
||||
device_ids.push_back(device_id_struct.release());
|
||||
}
|
||||
|
||||
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(),
|
||||
.multi_process_service = false
|
||||
};
|
||||
|
||||
auto vdevice = VDevice::create(params);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(vdevice, reply);
|
||||
|
||||
auto &manager = ServiceResourceManager<VDevice>::get_instance();
|
||||
auto handle = manager.register_resource(request->pid(), std::move(vdevice.release()));
|
||||
reply->set_handle(handle);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::VDevice_release(grpc::ServerContext*, const Release_Request *request,
|
||||
Release_Reply *reply)
|
||||
{
|
||||
auto &manager = ServiceResourceManager<VDevice>::get_instance();
|
||||
auto status = manager.release_resource(request->handle());
|
||||
reply->set_status(static_cast<uint32_t>(status));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::VDevice_configure(grpc::ServerContext*, const VDevice_configure_Request *request,
|
||||
VDevice_configure_Reply *reply)
|
||||
{
|
||||
auto hef_as_string = request->hef();
|
||||
auto hef_memview = MemoryView::create_const(hef_as_string.c_str(), hef_as_string.length());
|
||||
auto hef = Hef::create(hef_memview);
|
||||
CHECK_SUCCESS_AS_RPC_STATUS(hef.status(), reply);
|
||||
|
||||
NetworkGroupsParamsMap configure_params_map;
|
||||
for (auto &name_configure_params_pair : request->configure_params_map()) {
|
||||
ConfigureNetworkParams network_configure_params;
|
||||
auto proto_configure_params = name_configure_params_pair.params();
|
||||
network_configure_params.batch_size = static_cast<uint16_t>(proto_configure_params.batch_size());
|
||||
network_configure_params.power_mode = static_cast<hailo_power_mode_t>(proto_configure_params.power_mode());
|
||||
network_configure_params.latency = static_cast<hailo_latency_measurement_flags_t>(proto_configure_params.latency());
|
||||
|
||||
// Init streams params
|
||||
for (auto &proto_name_streams_params_pair : proto_configure_params.stream_params_map()) {
|
||||
auto proto_streams_params = proto_name_streams_params_pair.params();
|
||||
auto stream_direction = static_cast<hailo_stream_direction_t>(proto_streams_params.direction());
|
||||
hailo_stream_parameters_t stream_params;
|
||||
if (stream_direction == HAILO_H2D_STREAM) {
|
||||
stream_params = {
|
||||
.stream_interface = static_cast<hailo_stream_interface_t>(proto_streams_params.stream_interface()),
|
||||
.direction = stream_direction,
|
||||
{.pcie_input_params = {
|
||||
.reserved = 0
|
||||
}}
|
||||
};
|
||||
} else {
|
||||
stream_params = {
|
||||
.stream_interface = static_cast<hailo_stream_interface_t>(proto_streams_params.stream_interface()),
|
||||
.direction = stream_direction,
|
||||
{.pcie_output_params = {
|
||||
.reserved = 0
|
||||
}}
|
||||
};
|
||||
}
|
||||
network_configure_params.stream_params_by_name.insert({proto_name_streams_params_pair.name(), stream_params});
|
||||
}
|
||||
|
||||
// Init networks params
|
||||
for (auto &proto_name_network_params_pair : proto_configure_params.network_params_map()) {
|
||||
auto proto_network_params = proto_name_network_params_pair.params();
|
||||
hailo_network_parameters_t net_params {
|
||||
.batch_size = static_cast<uint16_t>(proto_network_params.batch_size())
|
||||
};
|
||||
|
||||
network_configure_params.network_params_by_name.insert({proto_name_network_params_pair.name(), net_params});
|
||||
}
|
||||
|
||||
configure_params_map.insert({name_configure_params_pair.name(), network_configure_params});
|
||||
}
|
||||
|
||||
auto lambda = [](std::shared_ptr<VDevice> vdevice, Hef &hef, NetworkGroupsParamsMap &configure_params_map) {
|
||||
return vdevice->configure(hef, configure_params_map);
|
||||
};
|
||||
auto &vdevice_manager = ServiceResourceManager<VDevice>::get_instance();
|
||||
auto networks = vdevice_manager.execute<Expected<ConfiguredNetworkGroupVector>>(request->handle(), lambda, hef.release(), configure_params_map);
|
||||
CHECK_SUCCESS_AS_RPC_STATUS(networks.status(), reply);
|
||||
|
||||
auto &networks_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
for (auto network : networks.value()) {
|
||||
auto handle = networks_manager.register_resource(request->pid(), network);
|
||||
reply->add_networks_handles(handle);
|
||||
}
|
||||
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::VDevice_get_physical_devices_ids(grpc::ServerContext*,
|
||||
const VDevice_get_physical_devices_ids_Request* request, VDevice_get_physical_devices_ids_Reply* reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<VDevice> vdevice) {
|
||||
return vdevice->get_physical_devices_ids();
|
||||
};
|
||||
auto &vdevice_manager = ServiceResourceManager<VDevice>::get_instance();
|
||||
auto expected_devices_ids = vdevice_manager.execute<Expected<std::vector<std::string>>>(request->handle(), lambda);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_devices_ids, reply);
|
||||
auto devices_ids = expected_devices_ids.value();
|
||||
auto devices_ids_proto = reply->mutable_devices_ids();
|
||||
for (auto &device_id : devices_ids) {
|
||||
devices_ids_proto->Add(std::move(device_id));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_release(grpc::ServerContext*, const Release_Request *request,
|
||||
Release_Reply *reply)
|
||||
{
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto status = manager.release_resource(request->handle());
|
||||
reply->set_status(static_cast<uint32_t>(status));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, bool quantized,
|
||||
hailo_format_type_t format_type, uint32_t timeout_ms, uint32_t queue_size, std::string network_name) {
|
||||
return cng->make_input_vstream_params(quantized, format_type, timeout_ms, queue_size, network_name);
|
||||
};
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_params = manager.execute<Expected<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(), request->network_name());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_params, reply);
|
||||
auto params_map = reply->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));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_make_output_vstream_params(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_make_output_vstream_params_Request *request,
|
||||
ConfiguredNetworkGroup_make_output_vstream_params_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, std::string network_name) {
|
||||
return cng->make_output_vstream_params(quantized, format_type, timeout_ms, queue_size, network_name);
|
||||
};
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_params = manager.execute<Expected<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(), request->network_name());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_params, reply);
|
||||
auto params_map = reply->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));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_default_stream_interface(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_default_stream_interface_Request *request,
|
||||
ConfiguredNetworkGroup_get_default_stream_interface_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
|
||||
return cng->get_default_streams_interface();
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_stream_interface = net_group_manager.execute<Expected<hailo_stream_interface_t>>(request->handle(), lambda);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_stream_interface, reply);
|
||||
reply->set_stream_interface(static_cast<uint32_t>(expected_stream_interface.value()));
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_output_vstream_groups(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_output_vstream_groups_Request *request,
|
||||
ConfiguredNetworkGroup_get_output_vstream_groups_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
|
||||
return cng->get_output_vstream_groups();
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_output_vstream_groups = net_group_manager.execute<Expected<std::vector<std::vector<std::string>>>>(request->handle(), lambda);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_output_vstream_groups, reply);
|
||||
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;
|
||||
for (auto& name : group) {
|
||||
auto vstream_group_proto = group_proto.mutable_vstream_group();
|
||||
vstream_group_proto->Add(std::move(name));
|
||||
}
|
||||
groups_proto->Add(std::move(group_proto));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
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);
|
||||
vstream_infos_proto->Add(std::move(info_proto));
|
||||
}
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_input_vstream_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_vstream_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_vstream_infos_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, std::string network_name) {
|
||||
return cng->get_input_vstream_infos(network_name);
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_vstream_infos = net_group_manager.execute<Expected<std::vector<hailo_vstream_info_t>>>(request->handle(), lambda, request->network_name());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_vstream_infos, reply);
|
||||
serialize_vstream_infos(reply, expected_vstream_infos.value());
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_output_vstream_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_vstream_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_vstream_infos_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, std::string network_name) {
|
||||
return cng->get_output_vstream_infos(network_name);
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_vstream_infos = net_group_manager.execute<Expected<std::vector<hailo_vstream_info_t>>>(request->handle(), lambda, request->network_name());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_vstream_infos, reply);
|
||||
serialize_vstream_infos(reply, expected_vstream_infos.value());
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_all_vstream_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_vstream_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_vstream_infos_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, std::string network_name) {
|
||||
return cng->get_all_vstream_infos(network_name);
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_vstream_infos = net_group_manager.execute<Expected<std::vector<hailo_vstream_info_t>>>(request->handle(), lambda, request->network_name());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_vstream_infos, reply);
|
||||
serialize_vstream_infos(reply, expected_vstream_infos.value());
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_set_scheduler_timeout(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_set_scheduler_timeout_Request *request,
|
||||
ConfiguredNetworkGroup_set_scheduler_timeout_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, std::chrono::milliseconds timeout_ms) {
|
||||
return cng->set_scheduler_timeout(timeout_ms);
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto status = net_group_manager.execute<hailo_status>(request->handle(), lambda, static_cast<std::chrono::milliseconds>(request->timeout_ms()));
|
||||
reply->set_status(status);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_set_scheduler_threshold(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_set_scheduler_threshold_Request *request,
|
||||
ConfiguredNetworkGroup_set_scheduler_threshold_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, uint32_t threshold, std::string network_name) {
|
||||
return cng->set_scheduler_threshold(threshold, network_name);
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto status = net_group_manager.execute<hailo_status>(request->handle(), lambda, request->threshold(),
|
||||
request->network_name());
|
||||
reply->set_status(status);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStreams_create(grpc::ServerContext *, const VStream_create_Request *request,
|
||||
VStreams_create_Reply *reply)
|
||||
{
|
||||
std::map<std::string, hailo_vstream_params_t> inputs_params;
|
||||
for (auto& param_proto : request->vstreams_params()) {
|
||||
auto vstream_params_proto = param_proto.params();
|
||||
auto user_buffer_format_proto = vstream_params_proto.user_buffer_format();
|
||||
hailo_format_t format;
|
||||
format.flags = hailo_format_flags_t(user_buffer_format_proto.flags());
|
||||
format.order = hailo_format_order_t(user_buffer_format_proto.order());
|
||||
format.type = hailo_format_type_t(user_buffer_format_proto.type());
|
||||
hailo_vstream_params_t params = {
|
||||
.user_buffer_format = format,
|
||||
.timeout_ms = vstream_params_proto.timeout_ms(),
|
||||
.queue_size = vstream_params_proto.queue_size(),
|
||||
.vstream_stats_flags = hailo_vstream_stats_flags_t(vstream_params_proto.vstream_stats_flags()),
|
||||
.pipeline_elements_stats_flags = hailo_pipeline_elem_stats_flags_t(vstream_params_proto.pipeline_elements_stats_flags())
|
||||
};
|
||||
inputs_params.emplace(param_proto.name(), std::move(params));
|
||||
}
|
||||
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, const std::map<std::string, hailo_vstream_params_t> &inputs_params) {
|
||||
return cng->create_input_vstreams(inputs_params);
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto vstreams_expected = net_group_manager.execute<Expected<std::vector<InputVStream>>>(request->net_group(), lambda, inputs_params);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(vstreams_expected, reply);
|
||||
auto vstreams = vstreams_expected.release();
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto client_pid = request->pid();
|
||||
|
||||
for (size_t i = 0; i < vstreams.size(); i++) {
|
||||
auto handle = manager.register_resource(client_pid, make_shared_nothrow<InputVStream>(std::move(vstreams[i])));
|
||||
reply->add_handles(handle);
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_release(grpc::ServerContext *, const Release_Request *request,
|
||||
Release_Reply *reply)
|
||||
{
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto status = manager.release_resource(request->handle());
|
||||
reply->set_status(static_cast<uint32_t>(status));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStreams_create(grpc::ServerContext *, const VStream_create_Request *request,
|
||||
VStreams_create_Reply *reply)
|
||||
{
|
||||
std::map<std::string, hailo_vstream_params_t> output_params;
|
||||
for (auto& param_proto : request->vstreams_params()) {
|
||||
auto vstream_params_proto = param_proto.params();
|
||||
auto user_buffer_format_proto = vstream_params_proto.user_buffer_format();
|
||||
hailo_format_t format;
|
||||
format.flags = hailo_format_flags_t(user_buffer_format_proto.flags());
|
||||
format.order = hailo_format_order_t(user_buffer_format_proto.order());
|
||||
format.type = hailo_format_type_t(user_buffer_format_proto.type());
|
||||
hailo_vstream_params_t params = {
|
||||
.user_buffer_format = format,
|
||||
.timeout_ms = vstream_params_proto.timeout_ms(),
|
||||
.queue_size = vstream_params_proto.queue_size(),
|
||||
.vstream_stats_flags = hailo_vstream_stats_flags_t(vstream_params_proto.vstream_stats_flags()),
|
||||
.pipeline_elements_stats_flags = hailo_pipeline_elem_stats_flags_t(vstream_params_proto.pipeline_elements_stats_flags())
|
||||
};
|
||||
output_params.emplace(param_proto.name(), std::move(params));
|
||||
}
|
||||
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, const std::map<std::string, hailo_vstream_params_t> &output_params) {
|
||||
return cng->create_output_vstreams(output_params);
|
||||
};
|
||||
auto &net_group_manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto vstreams_expected = net_group_manager.execute<Expected<std::vector<OutputVStream>>>(request->net_group(), lambda, output_params);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(vstreams_expected, reply);
|
||||
auto vstreams = vstreams_expected.release();
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto client_pid = request->pid();
|
||||
|
||||
for (size_t i = 0; i < vstreams.size(); i++) {
|
||||
auto handle = manager.register_resource(client_pid, make_shared_nothrow<OutputVStream>(std::move(vstreams[i])));
|
||||
reply->add_handles(handle);
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_release(grpc::ServerContext *, const Release_Request *request,
|
||||
Release_Reply *reply)
|
||||
{
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto status = manager.release_resource(request->handle());
|
||||
reply->set_status(static_cast<uint32_t>(status));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_name(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_name_Request *request,
|
||||
ConfiguredNetworkGroup_get_name_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
|
||||
return cng->name();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto network_group_name = manager.execute<std::string>(request->handle(), lambda);
|
||||
reply->set_network_group_name(network_group_name);
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_write(grpc::ServerContext*, const InputVStream_write_Request *request,
|
||||
InputVStream_write_Reply *reply)
|
||||
{
|
||||
auto buffer_expected = Buffer::create_shared(request->data().length());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(buffer_expected, reply);
|
||||
std::vector<uint8_t> data(request->data().begin(), request->data().end());
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream, const MemoryView &buffer) {
|
||||
return input_vstream->write(std::move(buffer));
|
||||
};
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto status = manager.execute<hailo_status>(request->handle(), lambda, MemoryView::create_const(data.data(), data.size()));
|
||||
CHECK_SUCCESS_AS_RPC_STATUS(status, reply, "VStream write failed");
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_network_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_network_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_network_infos_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
|
||||
return cng->get_network_infos();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_network_infos = manager.execute<Expected<std::vector<hailo_network_info_t>>>(request->handle(), lambda);
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_network_infos, reply);
|
||||
auto infos_proto = reply->mutable_network_infos();
|
||||
for (auto& info : expected_network_infos.value()) {
|
||||
infos_proto->Add(std::string(info.name));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_read(grpc::ServerContext*, const OutputVStream_read_Request *request,
|
||||
OutputVStream_read_Reply *reply)
|
||||
{
|
||||
std::vector<uint8_t> data(request->size());
|
||||
auto lambda = [](std::shared_ptr<OutputVStream> output_vstream, MemoryView &buffer) {
|
||||
return output_vstream->read(std::move(buffer));
|
||||
};
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto status = manager.execute<hailo_status>(request->handle(), lambda, MemoryView(data.data(), data.size()));
|
||||
CHECK_SUCCESS_AS_RPC_STATUS(status, reply, "VStream read failed");
|
||||
reply->set_data(data.data(), data.size());
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_all_stream_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_all_stream_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_all_stream_infos_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng) {
|
||||
return cng->get_all_stream_infos();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_stream_infos = manager.execute<Expected<std::vector<hailo_stream_info_t>>>(request->handle(), lambda);
|
||||
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;
|
||||
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);
|
||||
proto_nms_info->set_max_bboxes_per_class(stream_info.nms_info.max_bboxes_per_class);
|
||||
proto_nms_info->set_bbox_size(stream_info.nms_info.bbox_size);
|
||||
proto_nms_info->set_chunks_per_frame(stream_info.nms_info.chunks_per_frame);
|
||||
proto_nms_info->set_is_defused(stream_info.nms_info.is_defused);
|
||||
auto proto_nms_info_defuse_info = proto_nms_info->mutable_defuse_info();
|
||||
proto_nms_info_defuse_info->set_class_group_index(stream_info.nms_info.defuse_info.class_group_index);
|
||||
proto_nms_info_defuse_info->set_original_name(std::string(stream_info.nms_info.defuse_info.original_name));
|
||||
} else {
|
||||
auto proto_stream_shape = proto_stream_info.mutable_stream_shape();
|
||||
auto proto_stream_shape_shape = proto_stream_shape->mutable_shape();
|
||||
proto_stream_shape_shape->set_height(stream_info.shape.height);
|
||||
proto_stream_shape_shape->set_width(stream_info.shape.width);
|
||||
proto_stream_shape_shape->set_features(stream_info.shape.features);
|
||||
auto proto_stream_shape_hw_shape = proto_stream_shape->mutable_hw_shape();
|
||||
proto_stream_shape_hw_shape->set_height(stream_info.hw_shape.height);
|
||||
proto_stream_shape_hw_shape->set_width(stream_info.hw_shape.width);
|
||||
proto_stream_shape_hw_shape->set_features(stream_info.hw_shape.features);
|
||||
}
|
||||
proto_stream_info.set_hw_data_bytes(stream_info.hw_data_bytes);
|
||||
proto_stream_info.set_hw_frame_size(stream_info.hw_frame_size);
|
||||
auto proto_stream_info_format = proto_stream_info.mutable_format();
|
||||
proto_stream_info_format->set_type(stream_info.format.type);
|
||||
proto_stream_info_format->set_order(stream_info.format.order);
|
||||
proto_stream_info_format->set_flags(stream_info.format.flags);
|
||||
proto_stream_info.set_direction(static_cast<uint32_t>(stream_info.direction));
|
||||
proto_stream_info.set_index(stream_info.index);
|
||||
proto_stream_info.set_name(stream_info.name);
|
||||
auto proto_quant_info = proto_stream_info.mutable_quant_info();
|
||||
proto_quant_info->set_qp_zp(stream_info.quant_info.qp_zp);
|
||||
proto_quant_info->set_qp_scale(stream_info.quant_info.qp_scale);
|
||||
proto_quant_info->set_limvals_min(stream_info.quant_info.limvals_min);
|
||||
proto_quant_info->set_limvals_max(stream_info.quant_info.limvals_max);
|
||||
proto_stream_info.set_is_mux(stream_info.is_mux);
|
||||
proto_stream_infos->Add(std::move(proto_stream_info));
|
||||
}
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::ConfiguredNetworkGroup_get_latency_measurement(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_latency_measurement_Request *request,
|
||||
ConfiguredNetworkGroup_get_latency_measurement_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<ConfiguredNetworkGroup> cng, const std::string &network_name) {
|
||||
return cng->get_latency_measurement(network_name);
|
||||
};
|
||||
auto &manager = ServiceResourceManager<ConfiguredNetworkGroup>::get_instance();
|
||||
auto expected_latency_result = manager.execute<Expected<LatencyMeasurementResult>>(request->handle(), lambda, request->network_name());
|
||||
CHECK_EXPECTED_AS_RPC_STATUS(expected_latency_result, reply);
|
||||
reply->set_avg_hw_latency(static_cast<uint32_t>(expected_latency_result.value().avg_hw_latency.count()));
|
||||
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)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
return input_vstream->get_frame_size();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto frame_size = manager.execute<size_t>(request->handle(), lambda);
|
||||
reply->set_frame_size(static_cast<uint32_t>(frame_size));
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_get_frame_size(grpc::ServerContext*, const VStream_get_frame_size_Request *request,
|
||||
VStream_get_frame_size_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<OutputVStream> output_vstream) {
|
||||
return output_vstream->get_frame_size();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto frame_size = manager.execute<size_t>(request->handle(), lambda);
|
||||
reply->set_frame_size(static_cast<uint32_t>(frame_size));
|
||||
reply->set_status(static_cast<uint32_t>(HAILO_SUCCESS));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_flush(grpc::ServerContext*, const InputVStream_flush_Request *request,
|
||||
InputVStream_flush_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
return input_vstream->flush();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto flush_status = manager.execute<hailo_status>(request->handle(), lambda);
|
||||
reply->set_status(static_cast<uint32_t>(flush_status));
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_name(grpc::ServerContext*, const VStream_name_Request *request,
|
||||
VStream_name_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
return input_vstream->name();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<InputVStream>::get_instance();
|
||||
auto name = manager.execute<std::string>(request->handle(), lambda);
|
||||
reply->set_name(name);
|
||||
reply->set_status(HAILO_SUCCESS);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_name(grpc::ServerContext*, const VStream_name_Request *request,
|
||||
VStream_name_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<OutputVStream> output_vstream) {
|
||||
return output_vstream->name();
|
||||
};
|
||||
auto &manager = ServiceResourceManager<OutputVStream>::get_instance();
|
||||
auto name = manager.execute<std::string>(request->handle(), lambda);
|
||||
reply->set_name(name);
|
||||
reply->set_status(HAILO_SUCCESS);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::InputVStream_abort(grpc::ServerContext*, const VStream_abort_Request *request,
|
||||
VStream_abort_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<InputVStream> input_vstream) {
|
||||
return input_vstream->abort();
|
||||
};
|
||||
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_abort(grpc::ServerContext*, const VStream_abort_Request *request,
|
||||
VStream_abort_Reply *reply)
|
||||
{
|
||||
auto lambda = [](std::shared_ptr<OutputVStream> output_vstream) {
|
||||
return output_vstream->abort();
|
||||
};
|
||||
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_resume(grpc::ServerContext*, const VStream_resume_Request *,
|
||||
VStream_resume_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);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
grpc::Status HailoRtRpcService::OutputVStream_resume(grpc::ServerContext*, const VStream_resume_Request *,
|
||||
VStream_resume_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);
|
||||
return grpc::Status::OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
125
hailort/hailort_service/hailort_rpc_service.hpp
Normal file
125
hailort/hailort_service/hailort_rpc_service.hpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file hailort_rpc_service.hpp
|
||||
* @brief TODO
|
||||
**/
|
||||
|
||||
#ifndef HAILO_HAILORT_RPC_SERVICE_HPP_
|
||||
#define HAILO_HAILORT_RPC_SERVICE_HPP_
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4244 4267 4127)
|
||||
#else
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
#include <grpcpp/grpcpp.h>
|
||||
#include "hailort_rpc.grpc.pb.h"
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#else
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
class HailoRtRpcService final : public HailoRtRpc::Service {
|
||||
|
||||
public:
|
||||
virtual grpc::Status client_keep_alive(grpc::ServerContext *ctx, const keepalive_Request *request,
|
||||
empty*) override;
|
||||
|
||||
virtual grpc::Status get_service_version(grpc::ServerContext *, const get_service_version_Request *request,
|
||||
get_service_version_Reply *reply) override;
|
||||
|
||||
virtual grpc::Status VDevice_create(grpc::ServerContext *, const VDevice_create_Request *request,
|
||||
VDevice_create_Reply *reply) override;
|
||||
virtual grpc::Status VDevice_release(grpc::ServerContext *, const Release_Request *request,
|
||||
Release_Reply* reply) override;
|
||||
virtual grpc::Status VDevice_configure(grpc::ServerContext*, const VDevice_configure_Request* request,
|
||||
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 InputVStreams_create(grpc::ServerContext *, const VStream_create_Request *request,
|
||||
VStreams_create_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_release(grpc::ServerContext * , const Release_Request *request,
|
||||
Release_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStreams_create(grpc::ServerContext *, const VStream_create_Request *request,
|
||||
VStreams_create_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_release(grpc::ServerContext *, const Release_Request *request,
|
||||
Release_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_write(grpc::ServerContext*, const InputVStream_write_Request *request,
|
||||
InputVStream_write_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_read(grpc::ServerContext*, const OutputVStream_read_Request *request,
|
||||
OutputVStream_read_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_get_frame_size(grpc::ServerContext*, const VStream_get_frame_size_Request *request,
|
||||
VStream_get_frame_size_Reply *reply) override;
|
||||
virtual grpc::Status OutputVStream_get_frame_size(grpc::ServerContext*, const VStream_get_frame_size_Request *request,
|
||||
VStream_get_frame_size_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_flush(grpc::ServerContext*, const InputVStream_flush_Request *request,
|
||||
InputVStream_flush_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_name(grpc::ServerContext*, const VStream_name_Request *request,
|
||||
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_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,
|
||||
VStream_abort_Reply *reply) override;
|
||||
virtual grpc::Status InputVStream_resume(grpc::ServerContext*, const VStream_resume_Request *request,
|
||||
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 ConfiguredNetworkGroup_release(grpc::ServerContext*, const Release_Request* request,
|
||||
Release_Reply* reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_make_input_vstream_params(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_make_input_vstream_params_Request *request,
|
||||
ConfiguredNetworkGroup_make_input_vstream_params_Reply *reply) override;
|
||||
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_get_network_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_network_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_network_infos_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_all_stream_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_all_stream_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_all_stream_infos_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_default_stream_interface(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_default_stream_interface_Request *request,
|
||||
ConfiguredNetworkGroup_get_default_stream_interface_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_output_vstream_groups(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_output_vstream_groups_Request *request,
|
||||
ConfiguredNetworkGroup_get_output_vstream_groups_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_input_vstream_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_vstream_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_vstream_infos_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_all_vstream_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_vstream_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_vstream_infos_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_set_scheduler_timeout(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_set_scheduler_timeout_Request *request,
|
||||
ConfiguredNetworkGroup_set_scheduler_timeout_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_set_scheduler_threshold(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_set_scheduler_threshold_Request *request,
|
||||
ConfiguredNetworkGroup_set_scheduler_threshold_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_output_vstream_infos(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_vstream_infos_Request *request,
|
||||
ConfiguredNetworkGroup_get_vstream_infos_Reply *reply) override;
|
||||
virtual grpc::Status ConfiguredNetworkGroup_get_latency_measurement(grpc::ServerContext*,
|
||||
const ConfiguredNetworkGroup_get_latency_measurement_Request *request,
|
||||
ConfiguredNetworkGroup_get_latency_measurement_Reply *reply) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // HAILO_HAILORT_RPC_SERVICE_HPP_
|
||||
60
hailort/hailort_service/hailort_service.cpp
Normal file
60
hailort/hailort_service/hailort_service.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
*
|
||||
* @file hailort_service.cpp
|
||||
* @brief main for hailort service
|
||||
* TODO: move to user guide (HRT-7559)
|
||||
* * 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:
|
||||
* 1) Install the HailoRT:
|
||||
* cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DHAILO_BUILD_SERVICE=1 && sudo cmake --build build --target install
|
||||
*
|
||||
* 2) Reload systemd manager configuration:
|
||||
* sudo systemctl daemon-reload
|
||||
*
|
||||
* 3) Enable and start the service
|
||||
* sudo systemctl enable --now hailort.service
|
||||
*
|
||||
* 4) Stop service
|
||||
* sudo systemctl stop hailort.service
|
||||
*/
|
||||
|
||||
#include "hailort_rpc_service.hpp"
|
||||
#include "rpc/rpc_definitions.hpp"
|
||||
#include "common/utils.hpp"
|
||||
#include "hailo/hailort_common.hpp"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
void RunService() {
|
||||
std::string server_address(hailort::HAILO_DEFAULT_UDS_ADDR);
|
||||
hailort::HailoRtRpcService service;
|
||||
|
||||
grpc::ServerBuilder builder;
|
||||
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
|
||||
builder.SetMaxReceiveMessageSize(-1);
|
||||
builder.RegisterService(&service);
|
||||
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
|
||||
chmod(hailort::HAILO_DEFAULT_SERVICE_ADDR.c_str(), S_IROTH | S_IWOTH | S_IRUSR | S_IWUSR);
|
||||
server->Wait();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
bool is_standalone = ((1 < argc) && (strcmp("standalone", argv[1]) == 0));
|
||||
if (!is_standalone) {
|
||||
int ret = daemon(0,0);
|
||||
if (ret < 0) {
|
||||
syslog(LOG_ERR, "Failed to create daemon with errno %i", errno);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
RunService();
|
||||
return 0;
|
||||
}
|
||||
113
hailort/hailort_service/service_resource_manager.hpp
Normal file
113
hailort/hailort_service/service_resource_manager.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file service_resource_manager.hpp
|
||||
* @brief manages handles for resource objects.
|
||||
*
|
||||
**/
|
||||
|
||||
#ifndef HAILO_SERVICE_RESOURCE_MANAGER_HPP_
|
||||
#define HAILO_SERVICE_RESOURCE_MANAGER_HPP_
|
||||
|
||||
#include "hailo/expected.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
template<class T>
|
||||
struct Resource {
|
||||
Resource(uint32_t pid, std::shared_ptr<T> resource)
|
||||
: pid(pid), resource(std::move(resource))
|
||||
{}
|
||||
std::shared_timed_mutex resource_mutex;
|
||||
uint32_t pid;
|
||||
std::shared_ptr<T> resource;
|
||||
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class ServiceResourceManager
|
||||
{
|
||||
public:
|
||||
static ServiceResourceManager& get_instance()
|
||||
{
|
||||
static ServiceResourceManager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
template<class K, class Func, typename... Args>
|
||||
K execute(uint32_t key, Func &lambda, Args... args)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
auto resource_expected = resource_lookup(key);
|
||||
assert(resource_expected);
|
||||
|
||||
auto resource = resource_expected.release();
|
||||
std::shared_lock<std::shared_timed_mutex> resource_lock(resource->resource_mutex);
|
||||
lock.unlock();
|
||||
K ret = lambda(resource->resource, args...);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t register_resource(uint32_t pid, std::shared_ptr<T> const &resource)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
// Create a new resource and register
|
||||
auto index = m_current_handle_index;
|
||||
m_resources.emplace(m_current_handle_index++, std::make_shared<Resource<T>>(pid, std::move(resource)));
|
||||
return index;
|
||||
}
|
||||
|
||||
hailo_status release_resource(uint32_t key)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
auto found = m_resources.find(key);
|
||||
CHECK(found != m_resources.end(), HAILO_NOT_FOUND, "Failed to release resource with key {}, resource does not exist", key);
|
||||
std::unique_lock<std::shared_timed_mutex> resource_lock(found->second->resource_mutex);
|
||||
m_resources.erase(key);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
void release_by_pid(uint32_t pid)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
for (auto iter = m_resources.begin(); iter != m_resources.end(); ) {
|
||||
if (iter->second->pid == pid) {
|
||||
std::unique_lock<std::shared_timed_mutex> resource_lock(iter->second->resource_mutex);
|
||||
iter = m_resources.erase(iter);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ServiceResourceManager()
|
||||
: m_current_handle_index(0)
|
||||
{}
|
||||
|
||||
Expected<std::shared_ptr<Resource<T>>> resource_lookup(uint32_t key)
|
||||
{
|
||||
auto found = m_resources.find(key);
|
||||
CHECK_AS_EXPECTED(found != m_resources.end(), HAILO_NOT_FOUND, "Failed to find resource with key {}", key);
|
||||
|
||||
auto resource = found->second;
|
||||
return resource;
|
||||
}
|
||||
|
||||
std::mutex m_mutex;
|
||||
uint32_t m_current_handle_index;
|
||||
std::unordered_map<uint32_t, std::shared_ptr<Resource<T>>> m_resources;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* HAILO_SERVICE_RESOURCE_MANAGER_HPP_ */
|
||||
@@ -23,6 +23,7 @@ set(HAILORTCLI_CPP_FILES
|
||||
temp_measurement.cpp
|
||||
parse_hef_command.cpp
|
||||
graph_printer.cpp
|
||||
mon_command.cpp
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
@@ -52,8 +53,14 @@ add_executable(hailortcli
|
||||
target_compile_options(hailortcli PRIVATE ${HAILORT_COMPILE_OPTIONS})
|
||||
set_property(TARGET hailortcli PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET hailortcli PROPERTY INSTALL_RPATH "$ORIGIN" "../lib/") # Link with a relative libhailort
|
||||
target_link_libraries(hailortcli libhailort CLI11::CLI11 nlohmann_json spdlog::spdlog readerwriterqueue)
|
||||
target_link_libraries(hailortcli DotWriter)
|
||||
target_link_libraries(hailortcli
|
||||
libhailort
|
||||
CLI11::CLI11
|
||||
nlohmann_json
|
||||
spdlog::spdlog
|
||||
readerwriterqueue
|
||||
DotWriter
|
||||
scheduler_mon_proto)
|
||||
# TODO: Remove microprofile after removing pipeline.cpp from hailortcli sources
|
||||
target_link_libraries(hailortcli microprofile)
|
||||
|
||||
@@ -72,4 +79,6 @@ target_include_directories(hailortcli
|
||||
|
||||
install(TARGETS hailortcli
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
CONFIGURATIONS Release)
|
||||
CONFIGURATIONS Release
|
||||
)
|
||||
cli11_install_completion_file(hailortcli)
|
||||
@@ -18,8 +18,7 @@ BenchmarkCommand::BenchmarkCommand(CLI::App &parent_app) :
|
||||
Command(parent_app.add_subcommand("benchmark", "Measure basic performance on compiled network")),
|
||||
m_params({})
|
||||
{
|
||||
add_device_options(m_app, m_params.device_params);
|
||||
add_vdevice_options(m_app, m_params.device_params);
|
||||
add_vdevice_options(m_app, m_params.vdevice_params);
|
||||
m_params.measure_overall_latency = false;
|
||||
m_params.power_measurement.measure_current = false;
|
||||
m_params.show_progress = true;
|
||||
@@ -56,7 +55,7 @@ BenchmarkCommand::BenchmarkCommand(CLI::App &parent_app) :
|
||||
|
||||
// TODO HRT-5363 support multiple devices
|
||||
m_app->parse_complete_callback([this]() {
|
||||
PARSE_CHECK((this->m_params.device_params.vdevice_params.device_count == 1) || this->m_csv_file_path.empty() || this->m_not_measure_power,
|
||||
PARSE_CHECK((m_params.vdevice_params.device_count == 1) || m_csv_file_path.empty() || m_not_measure_power,
|
||||
"Writing power measurements in csv format is not supported for multiple devices");
|
||||
});
|
||||
}
|
||||
@@ -73,22 +72,37 @@ hailo_status BenchmarkCommand::execute()
|
||||
auto streaming_mode_info = fps_streaming_mode();
|
||||
CHECK_EXPECTED_AS_STATUS(streaming_mode_info, "FPS in streaming mode failed");
|
||||
|
||||
// TODO - HRT-6931 - measure latnecy only in the case of single device.
|
||||
// TODO - HRT-6931 - measure latency only in the case of single device.
|
||||
std::cout << "Measuring HW Latency" << std::endl;
|
||||
auto latency_info = latency();
|
||||
CHECK_EXPECTED_AS_STATUS(latency_info, "Latency measuring failed");
|
||||
|
||||
assert(hw_only_mode_info->network_group_results().size() == streaming_mode_info->network_group_results().size());
|
||||
assert(latency_info->network_group_results().size() == streaming_mode_info->network_group_results().size());
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << "=======" << std::endl;
|
||||
std::cout << "Summary" << std::endl;
|
||||
std::cout << "=======" << std::endl;
|
||||
std::cout << "FPS (hw_only) = " << hw_only_mode_info->fps().value() <<std::endl;
|
||||
std::cout << " (streaming) = " << streaming_mode_info->fps().value() <<std::endl;
|
||||
if (auto hw_latency = latency_info->hw_latency()) {
|
||||
std::cout << "Latency (hw) = " << InferResultsFormatUtils::latency_result_to_ms(hw_latency.value()) << " ms" << std::endl;
|
||||
}
|
||||
if (auto overall_latency = latency_info->overall_latency()) {
|
||||
std::cout << " (overall) = " << InferResultsFormatUtils::latency_result_to_ms(overall_latency.value()) << " ms" << std::endl;
|
||||
|
||||
for (auto &hw_only_res : hw_only_mode_info->network_group_results()) {
|
||||
auto network_group_name = hw_only_res.network_group_name();
|
||||
auto streaming_res = std::find_if(streaming_mode_info->network_group_results().begin(), streaming_mode_info->network_group_results().end(),
|
||||
[network_group_name] (NetworkGroupInferResult &infer_results) { return (infer_results.network_group_name() == network_group_name); });
|
||||
CHECK(streaming_mode_info->network_group_results().end() != streaming_res, HAILO_INTERNAL_FAILURE, "Failed to fun streaming results for network group {}", network_group_name);
|
||||
|
||||
auto latency_res = std::find_if(latency_info->network_group_results().begin(), latency_info->network_group_results().end(),
|
||||
[network_group_name] (NetworkGroupInferResult &infer_results) { return (infer_results.network_group_name() == network_group_name); });
|
||||
CHECK(latency_info->network_group_results().end() != latency_res, HAILO_INTERNAL_FAILURE, "Failed to fun latency results for network group {}", network_group_name);
|
||||
|
||||
std::cout << "FPS (hw_only) = " << hw_only_res.fps().value() <<std::endl;
|
||||
std::cout << " (streaming) = " << streaming_res->fps().value() <<std::endl;
|
||||
if (auto hw_latency = latency_res->hw_latency()) {
|
||||
std::cout << "Latency (hw) = " << InferResultsFormatUtils::latency_result_to_ms(hw_latency.value()) << " ms" << std::endl;
|
||||
}
|
||||
if (auto overall_latency = latency_res->overall_latency()) {
|
||||
std::cout << " (overall) = " << InferResultsFormatUtils::latency_result_to_ms(overall_latency.value()) << " ms" << std::endl;
|
||||
}
|
||||
}
|
||||
if (!m_not_measure_power) {
|
||||
for (const auto &pair : streaming_mode_info->m_power_measurements) {
|
||||
@@ -98,7 +112,6 @@ hailo_status BenchmarkCommand::execute()
|
||||
std::cout << " Power in streaming mode (average) = " << data.average_value << " " << power_units << std::endl;
|
||||
std::cout << " (max) = " << data.max_value << " " << power_units << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!m_csv_file_path.empty()){
|
||||
@@ -106,13 +119,13 @@ hailo_status BenchmarkCommand::execute()
|
||||
auto printer = InferStatsPrinter::create(m_params, false);
|
||||
CHECK_EXPECTED_AS_STATUS(printer, "Failed to initialize infer stats printer");
|
||||
printer->print_benchmark_csv_header();
|
||||
printer->print_benchmark_csv(m_params.hef_path, hw_only_mode_info.release(),
|
||||
streaming_mode_info.release(), latency_info.release());
|
||||
printer->print_benchmark_csv(hw_only_mode_info.value(),
|
||||
streaming_mode_info.value(), latency_info.value());
|
||||
}
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
Expected<NetworkGroupInferResult> BenchmarkCommand::hw_only_mode()
|
||||
Expected<InferResult> BenchmarkCommand::hw_only_mode()
|
||||
{
|
||||
m_params.transform.transform = (m_params.inputs_name_and_file_path.size() > 0);
|
||||
m_params.power_measurement.measure_power = false;
|
||||
@@ -121,7 +134,7 @@ Expected<NetworkGroupInferResult> BenchmarkCommand::hw_only_mode()
|
||||
return run_command_hef(m_params);
|
||||
}
|
||||
|
||||
Expected<NetworkGroupInferResult> BenchmarkCommand::fps_streaming_mode()
|
||||
Expected<InferResult> BenchmarkCommand::fps_streaming_mode()
|
||||
{
|
||||
m_params.power_measurement.measure_power = !m_not_measure_power;
|
||||
m_params.mode = InferMode::STREAMING;
|
||||
@@ -131,7 +144,7 @@ Expected<NetworkGroupInferResult> BenchmarkCommand::fps_streaming_mode()
|
||||
return run_command_hef(m_params);
|
||||
}
|
||||
|
||||
Expected<NetworkGroupInferResult> BenchmarkCommand::latency()
|
||||
Expected<InferResult> BenchmarkCommand::latency()
|
||||
{
|
||||
m_params.power_measurement.measure_power = false;
|
||||
m_params.measure_latency = true;
|
||||
|
||||
@@ -21,9 +21,9 @@ public:
|
||||
hailo_status execute() override;
|
||||
|
||||
private:
|
||||
Expected<NetworkGroupInferResult> hw_only_mode();
|
||||
Expected<NetworkGroupInferResult> fps_streaming_mode();
|
||||
Expected<NetworkGroupInferResult> latency();
|
||||
Expected<InferResult> hw_only_mode();
|
||||
Expected<InferResult> fps_streaming_mode();
|
||||
Expected<InferResult> latency();
|
||||
|
||||
inference_runner_params m_params;
|
||||
bool m_not_measure_power;
|
||||
|
||||
@@ -41,34 +41,21 @@ DeviceCommand::DeviceCommand(CLI::App *app) :
|
||||
|
||||
hailo_status DeviceCommand::execute()
|
||||
{
|
||||
if ((DeviceType::PCIE == m_device_params.device_type ) &&
|
||||
("*" == m_device_params.pcie_params.pcie_bdf)) {
|
||||
return execute_on_all_pcie_devices();
|
||||
auto devices = create_devices(m_device_params);
|
||||
if (!devices) {
|
||||
return devices.status();
|
||||
}
|
||||
auto device = create_device(m_device_params);
|
||||
if (!device) {
|
||||
return device.status();
|
||||
}
|
||||
|
||||
return execute_on_device(*device.value());
|
||||
return execute_on_devices(devices.value());
|
||||
}
|
||||
|
||||
hailo_status DeviceCommand::execute_on_all_pcie_devices()
|
||||
hailo_status DeviceCommand::execute_on_devices(std::vector<std::unique_ptr<Device>> &devices)
|
||||
{
|
||||
auto status = HAILO_SUCCESS; // Best effort
|
||||
auto all_devices_infos = Device::scan_pcie();
|
||||
if (!all_devices_infos) {
|
||||
return all_devices_infos.status();
|
||||
}
|
||||
for (auto &dev_info : all_devices_infos.value()) {
|
||||
auto device = Device::create_pcie(dev_info);
|
||||
if (!device) {
|
||||
return device.status();
|
||||
}
|
||||
|
||||
auto execute_status = execute_on_device(*device.value());
|
||||
for (auto &device : devices) {
|
||||
std::cout << "Executing on device: " << device->get_dev_id() << std::endl;
|
||||
auto execute_status = execute_on_device(*device);
|
||||
if (HAILO_SUCCESS != execute_status) {
|
||||
std::cerr << "Failed to execute on device: " << device.value()->get_dev_id() << ". status= " << execute_status << std::endl;
|
||||
std::cerr << "Failed to execute on device: " << device->get_dev_id() << ". status= " << execute_status << std::endl;
|
||||
status = execute_status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual hailo_status execute_on_device(Device &device) = 0;
|
||||
hailo_status execute_on_all_pcie_devices();
|
||||
hailo_status execute_on_devices(std::vector<std::unique_ptr<Device>> &devices);
|
||||
|
||||
private:
|
||||
hailo_device_params m_device_params;
|
||||
|
||||
@@ -50,4 +50,30 @@ struct FileSuffixValidator : public CLI::Validator {
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _HAILO_HAILORTCLI_COMMON_HPP_ */
|
||||
// Based on NLOHMANN_JSON_SERIALIZE_ENUM (json/include/nlohmann/json.hpp)
|
||||
// Accepts a static array instead of building one in the function
|
||||
#define NLOHMANN_JSON_SERIALIZE_ENUM2(ENUM_TYPE, _pair_arr)\
|
||||
template<typename BasicJsonType> \
|
||||
inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \
|
||||
{ \
|
||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||
auto it = std::find_if(std::begin(_pair_arr), std::end(_pair_arr), \
|
||||
[e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||
{ \
|
||||
return ej_pair.first == e; \
|
||||
}); \
|
||||
j = ((it != std::end(_pair_arr)) ? it : std::begin(_pair_arr))->second; \
|
||||
} \
|
||||
template<typename BasicJsonType> \
|
||||
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
|
||||
{ \
|
||||
static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!"); \
|
||||
auto it = std::find_if(std::begin(_pair_arr), std::end(_pair_arr), \
|
||||
[&j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
|
||||
{ \
|
||||
return ej_pair.second == j; \
|
||||
}); \
|
||||
e = ((it != std::end(_pair_arr)) ? it : std::begin(_pair_arr))->first; \
|
||||
}
|
||||
|
||||
#endif /* _HAILO_HAILORTCLI_COMMON_HPP_ */
|
||||
|
||||
@@ -10,12 +10,16 @@
|
||||
#include "download_action_list_command.hpp"
|
||||
#include "common.hpp"
|
||||
#include "common/file_utils.hpp"
|
||||
#include "md5.h"
|
||||
#include "common/string_utils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#define MHz (1000 * 1000)
|
||||
// div factor is valid only for Hailo8-B0 platform.
|
||||
// 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)
|
||||
|
||||
constexpr int DownloadActionListCommand::INVALID_NUMERIC_VALUE;
|
||||
|
||||
@@ -38,7 +42,7 @@ hailo_status DownloadActionListCommand::execute(Device &device, const std::strin
|
||||
|
||||
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 / MHz;
|
||||
const auto 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()},
|
||||
@@ -90,6 +94,7 @@ Expected<ordered_json> DownloadActionListCommand::parse_hef_metadata(const std::
|
||||
return hef_info_json;
|
||||
}
|
||||
|
||||
|
||||
bool DownloadActionListCommand::is_valid_hef(const std::string &hef_file_path)
|
||||
{
|
||||
// Open hef, to check that it's valid
|
||||
@@ -108,14 +113,8 @@ Expected<std::string> DownloadActionListCommand::calc_md5_hexdigest(const std::s
|
||||
MD5_Update(&md5_ctx, hef_bin->data(), hef_bin->size());
|
||||
MD5_Final(md5_sum, &md5_ctx);
|
||||
|
||||
std::stringstream hexdigest;
|
||||
for (uint32_t i = 0; i < ARRAY_ENTRIES(md5_sum); i++) {
|
||||
// cast to int needed for proper formatting
|
||||
static const int NUM_HEX_DIGITS_IN_UNIT8 = 2;
|
||||
hexdigest << std::hex << std::setfill('0') << std::setw(NUM_HEX_DIGITS_IN_UNIT8) << static_cast<int>(md5_sum[i]);
|
||||
}
|
||||
|
||||
return hexdigest.str();
|
||||
const bool LOWERCASE = false;
|
||||
return StringUtils::to_hex_string(md5_sum, ARRAY_ENTRIES(md5_sum), LOWERCASE);
|
||||
}
|
||||
|
||||
hailo_status DownloadActionListCommand::write_json(const ordered_json &json_obj, const std::string &output_file_path,
|
||||
@@ -131,6 +130,11 @@ hailo_status DownloadActionListCommand::write_json(const ordered_json &json_obj,
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
// We want to make sure that the switch-case bellow handles all of the action types in order to prevent parsing errors
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic error "-Wswitch-enum"
|
||||
#endif
|
||||
Expected<ordered_json> DownloadActionListCommand::parse_action_data(uint32_t base_address, uint8_t *action,
|
||||
uint32_t current_buffer_offset, uint32_t *action_length, CONTEXT_SWITCH_DEFS__ACTION_TYPE_t action_type,
|
||||
uint32_t timestamp, uint8_t sub_action_index, bool sub_action_index_set, bool *is_repeated, uint8_t *num_repeated,
|
||||
@@ -275,14 +279,24 @@ Expected<ordered_json> DownloadActionListCommand::parse_action_data(uint32_t bas
|
||||
data_json = *reinterpret_cast<CONTEXT_SWITCH_DEFS__deactivate_cfg_channel_t *>(action);
|
||||
action_length_local = sizeof(CONTEXT_SWITCH_DEFS__deactivate_cfg_channel_t);
|
||||
break;
|
||||
case CONTEXT_SWITCH_DEFS__ACTION_TYPE_DDR_BUFFERING_RESET:
|
||||
data_json = json({});
|
||||
action_length_local = 0;
|
||||
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
|
||||
default:
|
||||
std::cerr << "PARSING ERROR ! unknown action main type" << std::endl;
|
||||
std::cerr << "PARSING ERROR ! unknown action main type " << action_type << std::endl;
|
||||
return make_unexpected(HAILO_INTERNAL_FAILURE);
|
||||
}
|
||||
action_json["data"] = data_json;
|
||||
*action_length = static_cast<uint32_t>(action_length_local);
|
||||
return action_json;
|
||||
}
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
Expected<ordered_json> DownloadActionListCommand::parse_single_repeated_action(uint32_t base_address,
|
||||
uint8_t *action, uint32_t current_buffer_offset, uint32_t *action_length,
|
||||
@@ -410,12 +424,68 @@ Expected<ordered_json> DownloadActionListCommand::parse_network_groups(Device &d
|
||||
return network_group_list_json;
|
||||
}
|
||||
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__fetch_cfg_channel_descriptors_action_data_t& data) {
|
||||
j = json{{"descriptors_count", data.descriptors_count}, {"channel_index", data.cfg_channel_number}};
|
||||
template<typename ActionData>
|
||||
static json unpack_vdma_channel_id(const ActionData &data)
|
||||
{
|
||||
uint8_t engine_index = 0;
|
||||
uint8_t vdma_channel_index = 0;
|
||||
CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__READ(data.packed_vdma_channel_id, engine_index, vdma_channel_index);
|
||||
return json{{"vdma_channel_index", vdma_channel_index}, {"engine_index", engine_index}};
|
||||
}
|
||||
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t& data) {
|
||||
j = json{{"channel_index", data.cfg_channel_number}};
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__deactivate_vdma_channel_action_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__validate_vdma_channel_action_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_boundary_input_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_inter_context_input_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_ddr_buffer_input_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_boundary_output_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_inter_context_output_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_ddr_buffer_output_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
}
|
||||
|
||||
// Needs to be backwards compatible, so we use "channel_index" instead of "vdma_channel_index".
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__fetch_cfg_channel_descriptors_action_data_t& data) {
|
||||
uint8_t engine_index = 0;
|
||||
uint8_t vdma_channel_index = 0;
|
||||
CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__READ(data.packed_vdma_channel_id, engine_index, vdma_channel_index);
|
||||
j = json{{"descriptors_count", data.descriptors_count}, {"channel_index", vdma_channel_index},
|
||||
{"engine_index", engine_index}};
|
||||
}
|
||||
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__enable_lcu_action_non_default_data_t& data) {
|
||||
@@ -437,8 +507,26 @@ void to_json(json& j, const CONTEXT_SWITCH_DEFS__disable_lcu_action_data_t& data
|
||||
}
|
||||
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__change_vdma_to_stream_mapping_data_t& data) {
|
||||
j = json{{"vdma_channel_index", data.vdma_channel_index}, {"stream_index", data.stream_index},
|
||||
{"type", data.is_dummy_stream ? "dummy" : "active"}};
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
j["type"] = data.is_dummy_stream ? "dummy" : "active";
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__fetch_data_action_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__wait_dma_idle_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
j["stream_index"] = data.stream_index;
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__vdma_dataflow_interrupt_data_t &data)
|
||||
{
|
||||
j = unpack_vdma_channel_id(data);
|
||||
}
|
||||
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__lcu_interrupt_data_t& data) {
|
||||
@@ -446,3 +534,36 @@ void to_json(json& j, const CONTEXT_SWITCH_DEFS__lcu_interrupt_data_t& data) {
|
||||
const auto lcu_index = CONTEXT_SWITCH_DEFS__PACKED_LCU_ID_LCU_INDEX_READ(data.packed_lcu_id);
|
||||
j = json{{"cluster_index", cluster_index}, {"lcu_index", lcu_index}};
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_cfg_channel_t &data)
|
||||
{
|
||||
uint8_t engine_index = 0;
|
||||
uint8_t vdma_channel_index = 0;
|
||||
CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__READ(data.packed_vdma_channel_id, engine_index, vdma_channel_index);
|
||||
j = json{{"config_stream_index", data.config_stream_index}, {"channel_index", vdma_channel_index},
|
||||
{"engine_index", engine_index}};
|
||||
}
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__deactivate_cfg_channel_t &data)
|
||||
{
|
||||
uint8_t engine_index = 0;
|
||||
uint8_t vdma_channel_index = 0;
|
||||
CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__READ(data.packed_vdma_channel_id, engine_index, vdma_channel_index);
|
||||
j = json{{"config_stream_index", data.config_stream_index}, {"channel_index", vdma_channel_index},
|
||||
{"engine_index", engine_index}};
|
||||
}
|
||||
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__add_ddr_pair_info_action_data_t &data)
|
||||
{
|
||||
uint8_t h2d_engine_index = 0;
|
||||
uint8_t h2d_vdma_channel_index = 0;
|
||||
uint8_t d2h_engine_index = 0;
|
||||
uint8_t d2h_vdma_channel_index = 0;
|
||||
|
||||
CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__READ(data.h2d_packed_vdma_channel_id, h2d_engine_index,
|
||||
h2d_vdma_channel_index);
|
||||
CONTEXT_SWITCH_DEFS__PACKED_VDMA_CHANNEL_ID__READ(data.d2h_packed_vdma_channel_id, d2h_engine_index,
|
||||
d2h_vdma_channel_index);
|
||||
|
||||
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}};
|
||||
}
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
#define _HAILO_DOWNLOAD_ACTION_LIST_COMMAND_HPP_
|
||||
|
||||
#include "hailortcli.hpp"
|
||||
#include "common.hpp"
|
||||
#include "command.hpp"
|
||||
|
||||
#include "context_switch_defs.h"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -62,7 +64,7 @@ private:
|
||||
|
||||
// JSON serialization
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM(CONTEXT_SWITCH_DEFS__ACTION_TYPE_t, {
|
||||
static std::pair<CONTEXT_SWITCH_DEFS__ACTION_TYPE_t, std::string> mapping[] = {
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_FETCH_CFG_CHANNEL_DESCRIPTORS, "fetch_cfg_channel_descriptors"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_TRIGGER_SEQUENCER, "trigger_sequencer"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_FETCH_DATA_FROM_VDMA_CHANNEL, "fetch_data_from_vdma_channel"},
|
||||
@@ -93,38 +95,42 @@ NLOHMANN_JSON_SERIALIZE_ENUM(CONTEXT_SWITCH_DEFS__ACTION_TYPE_t, {
|
||||
{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_FETCH_CCW_BURSTS, "fetch_ccw_bursts"},
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_COUNT, nullptr},
|
||||
});
|
||||
{CONTEXT_SWITCH_DEFS__ACTION_TYPE_DDR_BUFFERING_RESET, "ddr_buffering_reset"}
|
||||
};
|
||||
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");
|
||||
|
||||
NLOHMANN_JSON_SERIALIZE_ENUM2(CONTEXT_SWITCH_DEFS__ACTION_TYPE_t, mapping);
|
||||
|
||||
// Default implementions
|
||||
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__deactivate_vdma_channel_action_data_t, vdma_channel_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__validate_vdma_channel_action_data_t, vdma_channel_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__fetch_data_action_data_t, vdma_channel_index, stream_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__add_ddr_pair_info_action_data_t, h2d_vdma_channel_index, d2h_vdma_channel_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__vdma_dataflow_interrupt_data_t, vdma_channel_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_dma_idle_data_t, vdma_channel_index, stream_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__activate_boundary_input_data_t, vdma_channel_index, stream_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__activate_inter_context_input_data_t, vdma_channel_index, stream_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__activate_ddr_buffer_input_data_t, vdma_channel_index, stream_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__activate_boundary_output_data_t, vdma_channel_index, stream_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__activate_inter_context_output_data_t, vdma_channel_index, stream_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__activate_ddr_buffer_output_data_t, vdma_channel_index, stream_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__activate_cfg_channel_t, channel_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__deactivate_cfg_channel_t, channel_index);
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t, config_stream_index);
|
||||
|
||||
// Non-default implementations
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__enable_lcu_action_default_data_t& data);
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__enable_lcu_action_non_default_data_t& data);
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__disable_lcu_action_data_t& data);
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__fetch_cfg_channel_descriptors_action_data_t& data);
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__fetch_ccw_bursts_action_data_t& data);
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__change_vdma_to_stream_mapping_data_t& data);
|
||||
void to_json(json& j, const CONTEXT_SWITCH_DEFS__lcu_interrupt_data_t& data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__deactivate_vdma_channel_action_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__validate_vdma_channel_action_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_boundary_input_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_inter_context_input_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_ddr_buffer_input_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_boundary_output_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_inter_context_output_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__activate_ddr_buffer_output_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__enable_lcu_action_default_data_t& data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__enable_lcu_action_non_default_data_t& data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__disable_lcu_action_data_t& data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__fetch_cfg_channel_descriptors_action_data_t& data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__change_vdma_to_stream_mapping_data_t& data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__fetch_data_action_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__wait_dma_idle_data_t &data);
|
||||
void to_json(json &j, const CONTEXT_SWITCH_DEFS__vdma_dataflow_interrupt_data_t &data);
|
||||
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);
|
||||
|
||||
#endif /* _HAILO_DOWNLOAD_ACTION_LIST_COMMAND_HPP_ */
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "hailo/hailort.h"
|
||||
#include "user_config_common.h"
|
||||
#include "common/file_utils.hpp"
|
||||
#include "common/string_utils.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
@@ -266,16 +267,8 @@ Expected<json> FwConfigJsonSerializer::deserialize_mac_address(uint8_t *entry_va
|
||||
CHECK_AS_EXPECTED((MAC_ADDRESS_LENGTH == size), HAILO_INTERNAL_FAILURE,
|
||||
"Mac address length is invalid. Length recieved is: {}, length expected: {}", size, MAC_ADDRESS_LENGTH);
|
||||
|
||||
std::stringstream ss;
|
||||
for (size_t i = 0; i < MAC_ADDRESS_LENGTH; i++) {
|
||||
if (i != 0) {
|
||||
ss << ':';
|
||||
}
|
||||
ss.width(2);
|
||||
ss.fill('0');
|
||||
ss << std::uppercase << std::hex << (int)(entry_value[i]);
|
||||
}
|
||||
return json(ss.str());
|
||||
const bool UPPERCASE = true;
|
||||
return json(StringUtils::to_hex_string(entry_value, size, UPPERCASE, ":"));
|
||||
}
|
||||
|
||||
Expected<json> FwConfigJsonSerializer::deserialize_supported_aspm_states(uint8_t *entry_value, uint32_t size)
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
|
||||
#include "fw_control_command.hpp"
|
||||
#include "firmware_header_utils.h"
|
||||
#include "common/string_utils.hpp"
|
||||
|
||||
|
||||
static const char *NOT_CONFIGURED_ATTR = "<Not Configured>";
|
||||
static const char *NOT_CONFIGURED_ATTR = "<N/A>";
|
||||
#define MHz (1000 * 1000)
|
||||
|
||||
|
||||
@@ -55,14 +56,8 @@ static std::string extended_device_information_supported_features(hailo_device_s
|
||||
|
||||
static void extended_device_information_print_array(uint8_t *array_for_print, size_t array_length, std::string splitter)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
for(i = 0; i < array_length; i++) {
|
||||
std::cout << std::setfill('0') << std::setw(2) << std::uppercase << std::hex << static_cast<int>(array_for_print[i]);
|
||||
if(array_length != (i+1)) {
|
||||
std::cout << splitter;
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
const bool UPPERCASE = true;
|
||||
std::cout << StringUtils::to_hex_string(array_for_print, array_length, UPPERCASE, splitter) << std::endl;
|
||||
}
|
||||
|
||||
static bool extended_device_information_is_array_not_empty(uint8_t *array_for_print, size_t array_length)
|
||||
@@ -135,8 +130,10 @@ static std::string fw_version_string(const hailo_device_identity_t &identity)
|
||||
static std::string identity_arch_string(const hailo_device_identity_t &identity)
|
||||
{
|
||||
switch (identity.device_architecture) {
|
||||
case HAILO_ARCH_HAILO8_B0:
|
||||
return "HAILO8_B0";
|
||||
case HAILO_ARCH_HAILO8:
|
||||
return "HAILO8";
|
||||
case HAILO_ARCH_HAILO8L:
|
||||
return "HAILO8L";
|
||||
case HAILO_ARCH_MERCURY_CA:
|
||||
return "MERCURY_CA";
|
||||
case HAILO_ARCH_MERCURY_VPU:
|
||||
|
||||
@@ -206,55 +206,60 @@ void PipelineGraphNode::set_visited()
|
||||
m_visited = true;
|
||||
}
|
||||
|
||||
hailo_status GraphPrinter::write_dot_file(const std::map<std::string, std::vector<InputVStream>> &input_vstreams_per_network,
|
||||
const std::map<std::string, std::vector<OutputVStream>> &output_vstreams_per_network, const std::string &graph_title,
|
||||
hailo_status GraphPrinter::write_dot_file(const std::vector<std::map<std::string, std::vector<std::reference_wrapper<InputVStream>>>> &input_vstreams_per_network_group,
|
||||
const std::vector<std::map<std::string, std::vector<std::reference_wrapper<OutputVStream>>>> &output_vstreams_per_network_group, const std::string &graph_title,
|
||||
const std::string &output_path, bool write_pipeline_stats)
|
||||
{
|
||||
PipelineGraph graph(input_vstreams_per_network, output_vstreams_per_network, graph_title, write_pipeline_stats);
|
||||
PipelineGraph graph(input_vstreams_per_network_group, output_vstreams_per_network_group, graph_title, write_pipeline_stats);
|
||||
return graph.write_dot_file(output_path);
|
||||
}
|
||||
|
||||
|
||||
GraphPrinter::PipelineGraph::PipelineGraph(const std::map<std::string, std::vector<InputVStream>> &input_vstreams_per_network,
|
||||
const std::map<std::string, std::vector<OutputVStream>> &output_vstreams_per_network,
|
||||
GraphPrinter::PipelineGraph::PipelineGraph(const std::vector<std::map<std::string, std::vector<std::reference_wrapper<InputVStream>>>> &input_vstreams_per_network_group,
|
||||
const std::vector<std::map<std::string, std::vector<std::reference_wrapper<OutputVStream>>>> &output_vstreams_per_network_group,
|
||||
const std::string &graph_title, bool write_pipeline_stats) :
|
||||
m_graph(true, create_graph_title_label(graph_title, DefaultNodeAttrs::MAIN_LABEL_FONT_SIZE)),
|
||||
m_elems_in_graph()
|
||||
{
|
||||
size_t total_inputs_count = 0;
|
||||
for (auto &input_vstreams_pair : input_vstreams_per_network) {
|
||||
total_inputs_count += input_vstreams_pair.second.size();
|
||||
}
|
||||
size_t total_outputs_count = 0;
|
||||
for (auto &output_vstreams_pair : output_vstreams_per_network) {
|
||||
total_outputs_count += output_vstreams_pair.second.size();
|
||||
}
|
||||
|
||||
// Set the graph "graph title" label to be on top
|
||||
m_graph.GetAttributes().SetLabelLoc(DotWriter::LabelLoc::T);
|
||||
// Set the graph direction from left to right
|
||||
m_graph.GetAttributes().SetRankDir(DotWriter::RankDir::LR);
|
||||
m_graph.GetAttributes().SetPackMode(format_pack_mode(total_outputs_count + total_inputs_count));
|
||||
|
||||
// Note: This order is important (input pipelines will be printed above output pipelines)
|
||||
for (const auto &output_vstreams_pair : output_vstreams_per_network) {
|
||||
for (const auto &vstream : output_vstreams_pair.second) {
|
||||
update_graph_nodes(vstream.get_pipeline(), write_pipeline_stats);
|
||||
assert(input_vstreams_per_network_group.size() == output_vstreams_per_network_group.size());
|
||||
|
||||
for (size_t network_group_index = 0; network_group_index < input_vstreams_per_network_group.size(); network_group_index++) {
|
||||
size_t total_inputs_count = 0;
|
||||
for (auto &input_vstreams_pair : input_vstreams_per_network_group[network_group_index]) {
|
||||
total_inputs_count += input_vstreams_pair.second.size();
|
||||
}
|
||||
}
|
||||
for (const auto &input_vstreams_pair : input_vstreams_per_network) {
|
||||
for (const auto &vstream : input_vstreams_pair.second) {
|
||||
update_graph_nodes(vstream.get_pipeline(), write_pipeline_stats);
|
||||
size_t total_outputs_count = 0;
|
||||
for (auto &output_vstreams_pair : output_vstreams_per_network_group[network_group_index]) {
|
||||
total_outputs_count += output_vstreams_pair.second.size();
|
||||
}
|
||||
}
|
||||
for (const auto &output_vstreams_pair : output_vstreams_per_network) {
|
||||
for (const auto &vstream : output_vstreams_pair.second) {
|
||||
update_edges_in_graph(vstream.get_pipeline(), "HW", "user_output");
|
||||
|
||||
m_graph.GetAttributes().SetPackMode(format_pack_mode(total_outputs_count + total_inputs_count));
|
||||
|
||||
// Note: This order is important (input pipelines will be printed above output pipelines)
|
||||
for (const auto &output_vstreams_pair : output_vstreams_per_network_group[network_group_index]) {
|
||||
for (const auto &vstream : output_vstreams_pair.second) {
|
||||
update_graph_nodes(vstream.get().get_pipeline(), write_pipeline_stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const auto &input_vstreams_pair : input_vstreams_per_network) {
|
||||
for (const auto &vstream : input_vstreams_pair.second) {
|
||||
update_edges_in_graph(vstream.get_pipeline(), "user_input", "HW");
|
||||
for (const auto &input_vstreams_pair : input_vstreams_per_network_group[network_group_index]) {
|
||||
for (const auto &vstream : input_vstreams_pair.second) {
|
||||
update_graph_nodes(vstream.get().get_pipeline(), write_pipeline_stats);
|
||||
}
|
||||
}
|
||||
for (const auto &output_vstreams_pair : output_vstreams_per_network_group[network_group_index]) {
|
||||
for (const auto &vstream : output_vstreams_pair.second) {
|
||||
update_edges_in_graph(vstream.get().get_pipeline(), "HW", "user_output");
|
||||
}
|
||||
}
|
||||
for (const auto &input_vstreams_pair : input_vstreams_per_network_group[network_group_index]) {
|
||||
for (const auto &vstream : input_vstreams_pair.second) {
|
||||
update_edges_in_graph(vstream.get().get_pipeline(), "user_input", "HW");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,16 +121,16 @@ class GraphPrinter
|
||||
{
|
||||
public:
|
||||
GraphPrinter() = delete;
|
||||
static hailo_status write_dot_file(const std::map<std::string, std::vector<InputVStream>> &input_vstreams_per_network,
|
||||
const std::map<std::string, std::vector<OutputVStream>> &output_vstreams_per_network,
|
||||
static hailo_status write_dot_file(const std::vector<std::map<std::string, std::vector<std::reference_wrapper<InputVStream>>>> &input_vstreams_per_network_group,
|
||||
const std::vector<std::map<std::string, std::vector<std::reference_wrapper<OutputVStream>>>> &output_vstreams_per_network_group,
|
||||
const std::string &graph_title, const std::string &output_path, bool write_pipeline_stats);
|
||||
|
||||
private:
|
||||
class PipelineGraph final
|
||||
{
|
||||
public:
|
||||
PipelineGraph(const std::map<std::string, std::vector<InputVStream>> &input_vstreams_per_network,
|
||||
const std::map<std::string, std::vector<OutputVStream>> &output_vstreams_per_network,
|
||||
PipelineGraph(const std::vector<std::map<std::string, std::vector<std::reference_wrapper<InputVStream>>>> &input_vstreams_per_network_group,
|
||||
const std::vector<std::map<std::string, std::vector<std::reference_wrapper<OutputVStream>>>> &output_vstreams_per_network_group,
|
||||
const std::string &graph_title, bool write_pipeline_stats);
|
||||
hailo_status write_dot_file(const std::string &output_path);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "fw_config_command.hpp"
|
||||
#include "fw_logger_command.hpp"
|
||||
#include "benchmark_command.hpp"
|
||||
#include "mon_command.hpp"
|
||||
#if defined(__GNUC__)
|
||||
#include "udp_rate_limiter_command.hpp"
|
||||
#endif
|
||||
@@ -42,148 +43,123 @@
|
||||
#include <thread>
|
||||
#include <map>
|
||||
|
||||
static Expected<hailo_pcie_device_info_t> get_pcie_device_info(const hailo_pcie_params &pcie_params)
|
||||
{
|
||||
if (pcie_params.pcie_bdf.empty()) {
|
||||
auto scan_result = Device::scan_pcie();
|
||||
if (!scan_result) {
|
||||
std::cerr << "Hailo PCIe scan failed (maybe pcie device not exists). status=" << scan_result.status() << std::endl;
|
||||
return make_unexpected(scan_result.status());
|
||||
}
|
||||
|
||||
if (scan_result->size() == 0) {
|
||||
std::cerr << "Hailo PCIe not found.." << std::endl;
|
||||
return make_unexpected(HAILO_INTERNAL_FAILURE);
|
||||
}
|
||||
return std::move(scan_result->at(0));
|
||||
} else {
|
||||
auto device_info_expected = Device::parse_pcie_device_info(pcie_params.pcie_bdf);
|
||||
if (!device_info_expected) {
|
||||
std::cerr << "Invalid pcie bdf format" << std::endl;
|
||||
return make_unexpected(device_info_expected.status());
|
||||
}
|
||||
return device_info_expected.release();
|
||||
Expected<std::vector<std::string>> get_device_ids(const hailo_device_params &device_params)
|
||||
{
|
||||
if (device_params.device_ids.empty() || contains(device_params.device_ids, std::string("*"))) {
|
||||
// No device id given, using all devices in the system.
|
||||
return Device::scan();
|
||||
}
|
||||
else {
|
||||
return std::vector<std::string>(device_params.device_ids);
|
||||
}
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<Device>> create_pcie_device(const hailo_pcie_params &pcie_params)
|
||||
Expected<std::vector<std::unique_ptr<Device>>> create_devices(const hailo_device_params &device_params)
|
||||
{
|
||||
auto device_info = get_pcie_device_info(pcie_params);
|
||||
if (!device_info) {
|
||||
return make_unexpected(device_info.status());
|
||||
std::vector<std::unique_ptr<Device>> res;
|
||||
|
||||
auto device_ids = get_device_ids(device_params);
|
||||
CHECK_EXPECTED(device_ids);
|
||||
|
||||
for (auto device_id : device_ids.value()) {
|
||||
auto device = Device::create(device_id);
|
||||
CHECK_EXPECTED(device);
|
||||
res.emplace_back(device.release());
|
||||
}
|
||||
|
||||
auto device = Device::create_pcie(device_info.value());
|
||||
if (!device) {
|
||||
std::cerr << "Failed create pcie device. status=" << device.status() << std::endl;
|
||||
return make_unexpected(device.status());
|
||||
}
|
||||
|
||||
return Expected<std::unique_ptr<Device>>(device.release());
|
||||
return res;
|
||||
}
|
||||
|
||||
static Expected<std::unique_ptr<Device>> create_eth_device(const hailo_eth_params ð_params)
|
||||
{
|
||||
auto device = Device::create_eth(eth_params.ip_addr);
|
||||
if (!device) {
|
||||
std::cerr << "Failed create ethernet device. status=" << device.status() << std::endl;
|
||||
return make_unexpected(device.status());
|
||||
}
|
||||
class BDFValidator : public CLI::Validator {
|
||||
public:
|
||||
BDFValidator(bool support_asterisk) : Validator("BDF") {
|
||||
func_ = [support_asterisk](std::string &bdf) {
|
||||
if (support_asterisk && (bdf == "*")) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return Expected<std::unique_ptr<Device>>(device.release());
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<Device>> create_device(const hailo_device_params &device_params)
|
||||
{
|
||||
switch (device_params.device_type) {
|
||||
case DeviceType::PCIE:
|
||||
return create_pcie_device(device_params.pcie_params);
|
||||
case DeviceType::ETH:
|
||||
return create_eth_device(device_params.eth_params);
|
||||
case DeviceType::DEFAULT:
|
||||
// If core driver is loaded (we are running on Mercury) then the default is core device; else, pcie device
|
||||
if (Device::is_core_driver_loaded()) {
|
||||
return Device::create_core_device();
|
||||
} else {
|
||||
return create_pcie_device(device_params.pcie_params);
|
||||
}
|
||||
default:
|
||||
std::cerr << "Invalid device type" << std::endl;
|
||||
return make_unexpected(HAILO_INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
void add_device_options(CLI::App *app, hailo_device_params &device_params)
|
||||
{
|
||||
// Initialize the device type to default
|
||||
device_params.device_type = DeviceType::DEFAULT;
|
||||
|
||||
auto group = app->add_option_group("Device Options");
|
||||
|
||||
const HailoCheckedTransformer<DeviceType> device_type_transformer({
|
||||
{ "pcie", DeviceType::PCIE },
|
||||
{ "eth", DeviceType::ETH },
|
||||
});
|
||||
auto *device_type_option = group->add_option("-d,--device-type,--target", device_params.device_type,
|
||||
"Device type to use\n"
|
||||
"Default is pcie.")
|
||||
->transform(device_type_transformer);
|
||||
|
||||
// PCIe options
|
||||
auto *pcie_bdf_option = group->add_option("-s,--bdf", device_params.pcie_params.pcie_bdf,
|
||||
"Device id ([<domain>]:<bus>:<device>.<func>, same as in lspci command).\n" \
|
||||
"In order to run on all PCIe devices connected to the machine one-by-one, use '*' (instead of device id).")
|
||||
->default_val("");
|
||||
|
||||
// Ethernet options
|
||||
auto *ip_option = group->add_option("--ip", device_params.eth_params.ip_addr, "IP address of the target")
|
||||
->default_val("")
|
||||
->check(CLI::ValidIPV4);
|
||||
|
||||
group->parse_complete_callback([&device_params, device_type_option, pcie_bdf_option, ip_option](){
|
||||
// The user didn't put target, we can figure it ourself
|
||||
if (device_type_option->empty()) {
|
||||
if (!ip_option->empty()) {
|
||||
// User gave IP, target is eth
|
||||
device_params.device_type = DeviceType::ETH;
|
||||
} else if (!pcie_bdf_option->empty()) {
|
||||
// User gave bdf, target is pcie
|
||||
device_params.device_type = DeviceType::PCIE;
|
||||
auto pcie_device_info = Device::parse_pcie_device_info(bdf);
|
||||
if (pcie_device_info.has_value()) {
|
||||
return std::string();
|
||||
}
|
||||
else {
|
||||
device_params.device_type = DeviceType::DEFAULT;
|
||||
return std::string("Invalid PCIe BDF " + bdf);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
if (ip_option->empty() && device_params.device_type == DeviceType::ETH) {
|
||||
throw CLI::ParseError("IP address is not set", CLI::ExitCodes::InvalidError);
|
||||
}
|
||||
void add_vdevice_options(CLI::App *app, hailo_vdevice_params &vdevice_params)
|
||||
{
|
||||
add_device_options(app, vdevice_params.device_params, false);
|
||||
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,
|
||||
"VDevice multi process service");
|
||||
group->add_option("--group-id", vdevice_params.group_id, "VDevice group id")->needs(multi_process_option);
|
||||
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
|
||||
PARSE_CHECK(device_count_option->empty(),
|
||||
"Passing " + device_count_option->get_name() + " in combination with device-ids is not allowed");
|
||||
|
||||
if (!ip_option->empty() && device_params.device_type != DeviceType::ETH) {
|
||||
throw CLI::ParseError("IP address is set on non eth device", CLI::ExitCodes::InvalidError);
|
||||
}
|
||||
|
||||
if (!pcie_bdf_option->empty() && device_params.device_type != DeviceType::PCIE) {
|
||||
throw CLI::ParseError("bdf (-s) is set on non pcie device", CLI::ExitCodes::InvalidError);
|
||||
// Fill device_count with real value
|
||||
vdevice_params.device_count = static_cast<uint32_t>(vdevice_params.device_params.device_ids.size());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void add_vdevice_options(CLI::App *app, hailo_device_params &device_params) {
|
||||
auto group = app->add_option_group("VDevice Options");
|
||||
void add_device_options(CLI::App *app, hailo_device_params &device_params, bool support_asterisk)
|
||||
{
|
||||
auto group = app->add_option_group("Device Options");
|
||||
|
||||
// VDevice options
|
||||
auto *device_count_option = group->add_option("--device-count", device_params.vdevice_params.device_count, "VDevice device count")
|
||||
->default_val(HAILO_DEFAULT_DEVICE_COUNT)
|
||||
->check(CLI::PositiveNumber);
|
||||
// General device id
|
||||
auto *device_id_option = group->add_option("-s,--device-id", device_params.device_ids,
|
||||
std::string("Device id, same as returned from `hailortcli scan` command. ") +
|
||||
std::string("For multiple devices, use space as separator.\n") +
|
||||
(support_asterisk ?
|
||||
std::string("In order to run on all devices connected to the machine one-by-one, use '*' (instead of device id).") :
|
||||
std::string("")));
|
||||
|
||||
group->parse_complete_callback([&device_params, device_count_option](){
|
||||
// The user gave device_count
|
||||
if (!device_count_option->empty()) {
|
||||
if ((device_params.vdevice_params.device_count > 1) &&
|
||||
((DeviceType::ETH == device_params.device_type) || (DeviceType::PCIE == device_params.device_type && !device_params.pcie_params.pcie_bdf.empty()))) {
|
||||
throw CLI::ParseError("Device type must not be specified when using multiple devices", CLI::ExitCodes::InvalidError);
|
||||
}
|
||||
// PCIe options
|
||||
auto *pcie_bdf_option = group->add_option("--bdf", device_params.device_ids,
|
||||
std::string("Device bdf ([<domain>]:<bus>:<device>.<func>, same as in lspci command).\n") +
|
||||
std::string("For multiple BDFs, use space as separator.\n") +
|
||||
(support_asterisk ?
|
||||
std::string("In order to run on all devices connected to the machine one-by-one, use '*' (instead of device id).") :
|
||||
std::string("")))
|
||||
->check(BDFValidator(support_asterisk));
|
||||
|
||||
// Ethernet options
|
||||
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
|
||||
const std::string device_id_options_names = device_id_option->get_name(true, true) + ", " +
|
||||
pcie_bdf_option->get_name(true, true) + ", " +
|
||||
ip_option->get_name(true, true);
|
||||
|
||||
const auto dev_id_options_parsed =
|
||||
static_cast<size_t>(!device_id_option->empty()) +
|
||||
static_cast<size_t>(!pcie_bdf_option->empty()) +
|
||||
static_cast<size_t>(!ip_option->empty());
|
||||
PARSE_CHECK(dev_id_options_parsed <= 1,
|
||||
"Only one of " + device_id_options_names + " Can bet set");
|
||||
|
||||
if (contains(device_params.device_ids, std::string("*"))) {
|
||||
PARSE_CHECK(support_asterisk, "Passing * is not allowed in this command");
|
||||
PARSE_CHECK(device_params.device_ids.size() == 1, "passing '*' in combination with other device ids is not allowed");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -235,6 +211,7 @@ public:
|
||||
add_subcommand<FwLoggerCommand>();
|
||||
add_subcommand<FwUpdateCommand>();
|
||||
add_subcommand<SSBUpdateCommand>();
|
||||
add_subcommand<MonCommand>();
|
||||
#if defined(__GNUC__)
|
||||
add_subcommand<UdpRateLimiterCommand>();
|
||||
#endif
|
||||
|
||||
@@ -27,35 +27,21 @@ using namespace hailort;
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct hailo_pcie_params {
|
||||
std::string pcie_bdf; // if empty use the first scanned. if '*', run on all devices on the machine one-by-one
|
||||
};
|
||||
|
||||
struct hailo_eth_params {
|
||||
std::string ip_addr;
|
||||
struct hailo_device_params {
|
||||
std::vector<std::string> device_ids;
|
||||
};
|
||||
|
||||
struct hailo_vdevice_params {
|
||||
uint32_t device_count;
|
||||
hailo_device_params device_params;
|
||||
uint32_t device_count = HAILO_DEFAULT_DEVICE_COUNT;
|
||||
std::string group_id;
|
||||
bool multi_process_service = false;
|
||||
};
|
||||
|
||||
enum class DeviceType {
|
||||
PCIE = 0,
|
||||
ETH,
|
||||
DEFAULT
|
||||
};
|
||||
|
||||
struct hailo_device_params {
|
||||
DeviceType device_type;
|
||||
hailo_pcie_params pcie_params;
|
||||
hailo_eth_params eth_params;
|
||||
hailo_vdevice_params vdevice_params;
|
||||
};
|
||||
|
||||
void add_device_options(CLI::App *app, hailo_device_params &device_params);
|
||||
void add_vdevice_options(CLI::App *app, hailo_device_params &device_params);
|
||||
Expected<std::unique_ptr<Device>> create_device(const hailo_device_params &device_params);
|
||||
Expected<std::unique_ptr<Device>> create_pcie_device(const hailo_pcie_params &pcie_params);
|
||||
void add_vdevice_options(CLI::App *app, hailo_vdevice_params &vdevice_params);
|
||||
void add_device_options(CLI::App *app, hailo_device_params &device_params, bool support_asterisk=true);
|
||||
Expected<std::vector<std::unique_ptr<Device>>> create_devices(const hailo_device_params &device_params);
|
||||
Expected<std::vector<std::string>> get_device_ids(const hailo_device_params &device_params);
|
||||
|
||||
/**
|
||||
* CLI11 transformer object, converting enum argument from string.
|
||||
@@ -101,7 +87,7 @@ using DeprecationActionPtr = std::shared_ptr<DeprecationAction>;
|
||||
class OptionDeprecation : public DeprecationAction
|
||||
{
|
||||
public:
|
||||
OptionDeprecation(CLI::Option *opt, const std::string &replacement) :
|
||||
OptionDeprecation(CLI::Option *opt, const std::string &replacement = std::string()) :
|
||||
DeprecationAction(),
|
||||
m_opt(opt),
|
||||
m_replacement(replacement)
|
||||
@@ -115,7 +101,12 @@ public:
|
||||
virtual std::string deprecate(bool message_inline) override
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "'" << m_opt->get_name() << "' is deprecated, please use '" << m_replacement << "' instead." << std::endl;
|
||||
message << "'" << m_opt->get_name() << "' is deprecated";
|
||||
if (!m_replacement.empty()) {
|
||||
std::cout << ", please use " << m_replacement << "' instead.";
|
||||
}
|
||||
message << std::endl;
|
||||
|
||||
CLI::Validator deprecate_warning(
|
||||
[message = message.str()](std::string &) {
|
||||
std::cout << message;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "infer_stats_printer.hpp"
|
||||
#include "run_command.hpp"
|
||||
#include "common.hpp"
|
||||
#include "pipeline.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -103,20 +104,22 @@ InferStatsPrinter::InferStatsPrinter(const inference_runner_params ¶ms, hail
|
||||
output_status = HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
void InferStatsPrinter::print(const std::string &network_group_name, Expected<NetworkGroupInferResult>& inference_result)
|
||||
void InferStatsPrinter::print(const std::vector<std::string> &network_groups_names, Expected<InferResult> &inference_result)
|
||||
{
|
||||
if (m_results_csv_file.is_open()) {
|
||||
std::cout << "> Writing inference results to '" << m_results_csv_path << "'... ";
|
||||
print_csv(network_group_name, inference_result);
|
||||
print_csv(network_groups_names, inference_result);
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
if (m_pipeline_stats_csv_file.is_open()) {
|
||||
if (m_pipeline_stats_csv_file.is_open() && (inference_result)) {
|
||||
std::cout << "> Writing pipeline statistics to '" << m_pipeline_stats_csv_path << "'... ";
|
||||
m_pipeline_stats_csv_file << "net_name,vstream_name,param_type,element,mean,min,max,var,sd,mean_sd,index" << std::endl;
|
||||
print_pipeline_elem_stats_csv(network_group_name, inference_result->m_fps_accumulators);
|
||||
print_pipeline_elem_stats_csv(network_group_name, inference_result->m_latency_accumulators);
|
||||
print_pipeline_elem_stats_csv(network_group_name, inference_result->m_queue_size_accumulators);
|
||||
print_entire_pipeline_stats_csv(network_group_name, inference_result->m_pipeline_latency_accumulators);
|
||||
for (auto &network_group_results : inference_result->network_group_results()) {
|
||||
print_pipeline_elem_stats_csv(network_group_results.network_group_name(), network_group_results.m_fps_accumulators);
|
||||
print_pipeline_elem_stats_csv(network_group_results.network_group_name(), network_group_results.m_latency_accumulators);
|
||||
print_pipeline_elem_stats_csv(network_group_results.network_group_name(), network_group_results.m_queue_size_accumulators);
|
||||
print_entire_pipeline_stats_csv(network_group_results.network_group_name(), network_group_results.m_pipeline_latency_accumulators);
|
||||
}
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
print_stdout(inference_result);
|
||||
@@ -132,100 +135,106 @@ void InferStatsPrinter::print_benchmark_csv_header()
|
||||
m_results_csv_file << "net_name,fps,hw_only_fps,num_of_frames,num_of_frames_hw_only,hw_latency,overall_latency,min_power,average_power,max_power" << std::endl;
|
||||
}
|
||||
|
||||
void InferStatsPrinter::print_csv(const std::string &network_group_name, Expected<NetworkGroupInferResult>& inference_result)
|
||||
void InferStatsPrinter::print_csv(const std::vector<std::string> &network_groups_names, Expected<InferResult> &inference_result)
|
||||
{
|
||||
auto status_description = hailo_get_status_message(inference_result.status());
|
||||
m_results_csv_file << network_group_name << "," << static_cast<uint32_t>(inference_result.status()) << "," << status_description;
|
||||
if (!inference_result) {
|
||||
m_results_csv_file << ",,,,,,,,,,,";
|
||||
}
|
||||
else {
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto fps = inference_result->fps()) {
|
||||
m_results_csv_file << fps.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto frames_count = inference_result->frames_count()) {
|
||||
m_results_csv_file << frames_count.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto send_data_rate = inference_result->send_data_rate_mbit_sec()) {
|
||||
m_results_csv_file << send_data_rate.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto recv_data_rate = inference_result->recv_data_rate_mbit_sec()) {
|
||||
m_results_csv_file << recv_data_rate.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto hw_latency = inference_result->hw_latency()) {
|
||||
m_results_csv_file << InferResultsFormatUtils::latency_result_to_ms(hw_latency.value());
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto overall_latency = inference_result->overall_latency()) {
|
||||
m_results_csv_file << InferResultsFormatUtils::latency_result_to_ms(overall_latency.value());
|
||||
}
|
||||
|
||||
// TODO HRT-5363 support multiple devices (Currently assumes 1 device in the map)
|
||||
if (1 == inference_result->m_power_measurements.size()) {
|
||||
for (const auto &pair : inference_result->m_power_measurements) {
|
||||
if (nullptr != pair.second) {
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().min_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().average_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().max_value;
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
if (HAILO_SUCCESS != inference_result.status()) {
|
||||
for (auto &network_group_name : network_groups_names) {
|
||||
m_results_csv_file << network_group_name << "," << static_cast<uint32_t>(inference_result.status()) << "," << status_description;
|
||||
if (!inference_result) {
|
||||
m_results_csv_file << ",,,,,,,,,,,";
|
||||
}
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
} else {
|
||||
for (auto &results : inference_result->network_group_results()) {
|
||||
m_results_csv_file << results.network_group_name() << "," << static_cast<uint32_t>(inference_result.status()) << "," << status_description;
|
||||
m_results_csv_file << ",";
|
||||
|
||||
// TODO HRT-5363 support multiple devices (Currently assumes 1 device in the map)
|
||||
if (1 == inference_result->m_current_measurements.size()) {
|
||||
for (const auto &pair : inference_result->m_current_measurements) {
|
||||
if (nullptr != pair.second) {
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().min_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().average_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().max_value;
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
if (auto fps = results.fps()) {
|
||||
m_results_csv_file << fps.value();
|
||||
}
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
// TODO HRT-5363 support multiple devices (Currently assumes 1 device in the map)
|
||||
if (1 == inference_result->m_temp_measurements.size()) {
|
||||
for (const auto &pair : inference_result->m_temp_measurements) {
|
||||
if (nullptr != pair.second) {
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->min_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->average_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->max_value;
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
if (auto frames_count = results.frames_count()) {
|
||||
m_results_csv_file << frames_count.value();
|
||||
}
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto send_data_rate = results.send_data_rate_mbit_sec()) {
|
||||
m_results_csv_file << send_data_rate.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto recv_data_rate = results.recv_data_rate_mbit_sec()) {
|
||||
m_results_csv_file << recv_data_rate.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto hw_latency = results.hw_latency()) {
|
||||
m_results_csv_file << InferResultsFormatUtils::latency_result_to_ms(hw_latency.value());
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto overall_latency = results.overall_latency()) {
|
||||
m_results_csv_file << InferResultsFormatUtils::latency_result_to_ms(overall_latency.value());
|
||||
}
|
||||
|
||||
// TODO HRT-5363 support multiple devices (Currently assumes 1 device in the map)
|
||||
if (1 == inference_result->m_power_measurements.size()) {
|
||||
for (const auto &pair : inference_result->m_power_measurements) {
|
||||
if (nullptr != pair.second) {
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().min_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().average_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().max_value;
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
|
||||
// TODO HRT-5363 support multiple devices (Currently assumes 1 device in the map)
|
||||
if (1 == inference_result->m_current_measurements.size()) {
|
||||
for (const auto &pair : inference_result->m_current_measurements) {
|
||||
if (nullptr != pair.second) {
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().min_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().average_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().max_value;
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
|
||||
// TODO HRT-5363 support multiple devices (Currently assumes 1 device in the map)
|
||||
if (1 == inference_result->m_temp_measurements.size()) {
|
||||
for (const auto &pair : inference_result->m_temp_measurements) {
|
||||
if (nullptr != pair.second) {
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->min_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->average_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->max_value;
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
m_results_csv_file << std::endl;
|
||||
}
|
||||
}
|
||||
m_results_csv_file << std::endl;
|
||||
}
|
||||
|
||||
void InferStatsPrinter::print_pipeline_elem_stats_csv(const std::string &network_group_name,
|
||||
@@ -273,59 +282,72 @@ void InferStatsPrinter::print_entire_pipeline_stats_csv(const std::string &netwo
|
||||
}
|
||||
}
|
||||
|
||||
void InferStatsPrinter::print_benchmark_csv(const std::string &network_group_name, const NetworkGroupInferResult &hw_inference_result,
|
||||
const NetworkGroupInferResult &streaming_inference_result, const NetworkGroupInferResult &hw_latency_result)
|
||||
void InferStatsPrinter::print_benchmark_csv(InferResult &hw_inference_result,
|
||||
InferResult &streaming_inference_result, InferResult &hw_latency_result)
|
||||
{
|
||||
m_results_csv_file << network_group_name << ",";
|
||||
assert(hw_inference_result.network_group_results().size() == streaming_inference_result.network_group_results().size());
|
||||
assert(hw_latency_result.network_group_results().size() == streaming_inference_result.network_group_results().size());
|
||||
|
||||
for (auto &hw_res : hw_inference_result.network_group_results()) {
|
||||
auto network_group_name = hw_res.network_group_name();
|
||||
|
||||
if (auto fps = streaming_inference_result.fps()) {
|
||||
m_results_csv_file << fps.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
auto streaming_res = std::find_if(streaming_inference_result.network_group_results().begin(), streaming_inference_result.network_group_results().end(),
|
||||
[network_group_name] (NetworkGroupInferResult &infer_results) { return (infer_results.network_group_name() == network_group_name); });
|
||||
|
||||
if (auto hw_only_fps = hw_inference_result.fps()) {
|
||||
m_results_csv_file << hw_only_fps.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
auto latency_res = std::find_if(hw_latency_result.network_group_results().begin(), hw_latency_result.network_group_results().end(),
|
||||
[network_group_name] (NetworkGroupInferResult &infer_results) { return (infer_results.network_group_name() == network_group_name); });
|
||||
|
||||
if (auto frames_count = streaming_inference_result.frames_count()) {
|
||||
m_results_csv_file << frames_count.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << network_group_name << ",";
|
||||
|
||||
if (auto frames_count = hw_inference_result.frames_count()) {
|
||||
m_results_csv_file << frames_count.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto hw_latency = hw_latency_result.hw_latency()) {
|
||||
m_results_csv_file << InferResultsFormatUtils::latency_result_to_ms(hw_latency.value());
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto overall_latency = hw_latency_result.overall_latency()) {
|
||||
m_results_csv_file << InferResultsFormatUtils::latency_result_to_ms(overall_latency.value());
|
||||
}
|
||||
|
||||
// TODO HRT-5363 support multiple devices (Currently assumes 1 device in the map)
|
||||
if (1 == streaming_inference_result.m_power_measurements.size()) {
|
||||
for (const auto &pair : streaming_inference_result.m_power_measurements) {
|
||||
if (nullptr != pair.second) {
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().min_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().average_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().max_value;
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
if (auto fps = streaming_res->fps()) {
|
||||
m_results_csv_file << fps.value();
|
||||
}
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
m_results_csv_file << std::endl;
|
||||
if (auto hw_only_fps = hw_res.fps()) {
|
||||
m_results_csv_file << hw_only_fps.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto frames_count = streaming_res->frames_count()) {
|
||||
m_results_csv_file << frames_count.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto frames_count = hw_res.frames_count()) {
|
||||
m_results_csv_file << frames_count.value();
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto hw_latency = latency_res->hw_latency()) {
|
||||
m_results_csv_file << InferResultsFormatUtils::latency_result_to_ms(hw_latency.value());
|
||||
}
|
||||
m_results_csv_file << ",";
|
||||
|
||||
if (auto overall_latency = latency_res->overall_latency()) {
|
||||
m_results_csv_file << InferResultsFormatUtils::latency_result_to_ms(overall_latency.value());
|
||||
}
|
||||
|
||||
// TODO HRT-5363 support multiple devices (Currently assumes 1 device in the map)
|
||||
if (1 == streaming_inference_result.m_power_measurements.size()) {
|
||||
for (const auto &pair : streaming_inference_result.m_power_measurements) {
|
||||
if (nullptr != pair.second) {
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().min_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().average_value;
|
||||
m_results_csv_file << ",";
|
||||
m_results_csv_file << pair.second->data().max_value;
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_results_csv_file << ",,,";
|
||||
}
|
||||
|
||||
m_results_csv_file << std::endl;
|
||||
}
|
||||
}
|
||||
template< typename T>
|
||||
void InferStatsPrinter::print_stdout_single_element(const T &results, size_t frames_count)
|
||||
@@ -351,13 +373,14 @@ void InferStatsPrinter::print_stdout_single_element(const T &results, size_t fra
|
||||
if (auto hw_latency = results.hw_latency()) {
|
||||
std::cout << " HW Latency: " << InferResultsFormatUtils::latency_result_to_ms(hw_latency.value()) << " ms" << std::endl;
|
||||
}
|
||||
|
||||
if (auto overall_latency = results.overall_latency()) {
|
||||
std::cout << " Overall Latency: " << InferResultsFormatUtils::latency_result_to_ms(overall_latency.value()) << " ms" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void InferStatsPrinter::print_stdout(Expected<NetworkGroupInferResult>& inference_result)
|
||||
void InferStatsPrinter::print_stdout(Expected<InferResult> &inference_result)
|
||||
{
|
||||
if (!inference_result) {
|
||||
return;
|
||||
@@ -369,31 +392,36 @@ void InferStatsPrinter::print_stdout(Expected<NetworkGroupInferResult>& inferenc
|
||||
std::cout << std::setprecision(2) << std::fixed;
|
||||
std::cout << FORMAT_CLEAR_LINE << "> Inference result:" << std::endl;
|
||||
|
||||
if (1 < inference_result->m_result_per_network.size()) {
|
||||
// If there is more than 1 network, we print results per network, and than sum of bandwith
|
||||
for (auto &network_result_pair : inference_result->m_result_per_network) {
|
||||
std::cout << " Network: " << network_result_pair.first << std::endl;
|
||||
auto frames_count = (m_print_frame_count) ? network_result_pair.second.m_frames_count : 0;
|
||||
print_stdout_single_element<NetworkInferResult>(network_result_pair.second, frames_count);
|
||||
}
|
||||
std::stringstream bandwidth_stream;
|
||||
bandwidth_stream << std::setprecision(2) << std::fixed;
|
||||
if (auto send_data_rate = inference_result->send_data_rate_mbit_sec()) {
|
||||
bandwidth_stream << " Send Rate: " << send_data_rate.value() << " Mbit/s" << std::endl;
|
||||
}
|
||||
for (auto &network_group_results : inference_result.value().network_group_results()) {
|
||||
std::cout << " Network group: " << network_group_results.network_group_name() << std::endl;
|
||||
if (1 < network_group_results.m_result_per_network.size()) {
|
||||
// If there is more than 1 network, we print results per network, and than sum of bandwith
|
||||
for (auto &network_result_pair : network_group_results.m_result_per_network) {
|
||||
std::cout << " Network: " << network_result_pair.first << std::endl;
|
||||
auto frames_count = (m_print_frame_count) ? network_result_pair.second.m_frames_count : 0;
|
||||
print_stdout_single_element<NetworkInferResult>(network_result_pair.second, frames_count);
|
||||
}
|
||||
std::stringstream bandwidth_stream;
|
||||
bandwidth_stream << std::setprecision(2) << std::fixed;
|
||||
if (auto send_data_rate = network_group_results.send_data_rate_mbit_sec()) {
|
||||
bandwidth_stream << " Send Rate: " << send_data_rate.value() << " Mbit/s" << std::endl;
|
||||
}
|
||||
|
||||
if (auto recv_data_rate = inference_result->recv_data_rate_mbit_sec()) {
|
||||
bandwidth_stream << " Recv Rate: " << recv_data_rate.value() << " Mbit/s" << std::endl;
|
||||
}
|
||||
if (auto recv_data_rate = network_group_results.recv_data_rate_mbit_sec()) {
|
||||
bandwidth_stream << " Recv Rate: " << recv_data_rate.value() << " Mbit/s" << std::endl;
|
||||
}
|
||||
|
||||
if (0 != bandwidth_stream.rdbuf()->in_avail()) {
|
||||
std::cout << " Total bandwidth: " << std::endl;
|
||||
std::cout << bandwidth_stream.rdbuf();
|
||||
if (0 != bandwidth_stream.rdbuf()->in_avail()) {
|
||||
std::cout << " Total bandwidth: " << std::endl;
|
||||
std::cout << bandwidth_stream.rdbuf();
|
||||
}
|
||||
std::cout << std::endl;
|
||||
} else {
|
||||
auto frames_count_exp = network_group_results.frames_count();
|
||||
auto frames_count = ((frames_count_exp) && (m_print_frame_count)) ? frames_count_exp.value() : 0;
|
||||
print_stdout_single_element<NetworkGroupInferResult>(network_group_results, frames_count);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
} else {
|
||||
auto frames_count_exp = inference_result->frames_count();
|
||||
auto frames_count = ((frames_count_exp) && (m_print_frame_count)) ? frames_count_exp.value() : 0;
|
||||
print_stdout_single_element<NetworkGroupInferResult>(inference_result.value(), frames_count);
|
||||
}
|
||||
|
||||
if ((inference_result->m_power_measurements.size() != inference_result->m_current_measurements.size()) ||
|
||||
@@ -419,9 +447,9 @@ void InferStatsPrinter::print_stdout(Expected<NetworkGroupInferResult>& inferenc
|
||||
}
|
||||
auto temp_measure_iter = inference_result->m_temp_measurements.find(pair.first);
|
||||
if ((temp_measure_iter != inference_result->m_temp_measurements.end()) && (nullptr != temp_measure_iter->second)) {
|
||||
measurement_stream << " Minimum chip temperature: " << temp_measure_iter->second->min_value << "°C" << std::endl;
|
||||
measurement_stream << " Average chip temperature: " << temp_measure_iter->second->average_value << "°C" << std::endl;
|
||||
measurement_stream << " Maximum chip temperature: " << temp_measure_iter->second->max_value << "°C" << std::endl;
|
||||
measurement_stream << " Minimum chip temperature: " << temp_measure_iter->second->min_value << "C" << std::endl;
|
||||
measurement_stream << " Average chip temperature: " << temp_measure_iter->second->average_value << "C" << std::endl;
|
||||
measurement_stream << " Maximum chip temperature: " << temp_measure_iter->second->max_value << "C" << std::endl;
|
||||
}
|
||||
if (0 != measurement_stream.rdbuf()->in_avail()) {
|
||||
std::cout << " Device: " << pair.first << std::endl;
|
||||
@@ -439,6 +467,8 @@ void InferStatsPrinter::write_accumulator_results(std::ofstream &output_stream,
|
||||
{
|
||||
const auto &accumulator_result = accumulator->get();
|
||||
if ((!accumulator_result.count()) || (accumulator_result.count().value() == 0)) {
|
||||
LOGGER__WARNING("No {} data has been collected for element '{}' (vstream '{}'). Collection begins after the element has processed {} frames...",
|
||||
accumulator->get_data_type(), elem_name, vstream_name, DEFAULT_NUM_FRAMES_BEFORE_COLLECTION_START);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ public:
|
||||
class InferStatsPrinter final {
|
||||
public:
|
||||
static Expected<InferStatsPrinter> create(const inference_runner_params ¶ms, bool print_running_info = true);
|
||||
void print(const std::string &network_name, Expected<NetworkGroupInferResult>& inference_result);
|
||||
void print_benchmark_csv(const std::string &network_name, const NetworkGroupInferResult &hw_inference_result,
|
||||
const NetworkGroupInferResult &streaming_inference_result, const NetworkGroupInferResult &hw_latency_result);
|
||||
void print(const std::vector<std::string> &network_groups_names, Expected<InferResult> &inference_result);
|
||||
void print_benchmark_csv(InferResult &hw_inference_result,
|
||||
InferResult &streaming_inference_result, InferResult &hw_latency_result);
|
||||
void print_csv_header();
|
||||
void print_benchmark_csv_header();
|
||||
|
||||
@@ -39,14 +39,14 @@ private:
|
||||
static constexpr uint32_t NO_INDEX = std::numeric_limits<uint32_t>::max();
|
||||
|
||||
InferStatsPrinter(const inference_runner_params ¶ms, hailo_status &output_status, bool print_running_info = true);
|
||||
void print_csv(const std::string &network_name, Expected<NetworkGroupInferResult>& inference_result);
|
||||
void print_csv(const std::vector<std::string> &network_groups_names, Expected<InferResult> &inference_result);
|
||||
void print_pipeline_elem_stats_csv(const std::string &network_name,
|
||||
const std::map<std::string, std::map<std::string, AccumulatorPtr>> &inference_result);
|
||||
void print_pipeline_elem_stats_csv(const std::string &network_name,
|
||||
const std::map<std::string, std::map<std::string, std::vector<AccumulatorPtr>>> &inference_result);
|
||||
void print_entire_pipeline_stats_csv(const std::string &network_name,
|
||||
const std::map<std::string, AccumulatorPtr> &inference_result);
|
||||
void print_stdout(Expected<NetworkGroupInferResult>& inference_result);
|
||||
void print_stdout(Expected<InferResult> &inference_result);
|
||||
template <typename T>
|
||||
void print_stdout_single_element(const T &results, size_t frames_count);
|
||||
|
||||
|
||||
@@ -13,33 +13,59 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
InferProgress::InferProgress(ConfiguredNetworkGroup &configured_network_group, const inference_runner_params ¶ms,
|
||||
std::chrono::duration<double> print_interval) :
|
||||
m_configured_network_group(configured_network_group), m_params(params),
|
||||
m_print_interval(print_interval), m_networks_progress(), m_stop(true) {}
|
||||
Expected<std::shared_ptr<InferProgress>> InferProgress::create(const inference_runner_params ¶ms,
|
||||
std::chrono::milliseconds print_interval)
|
||||
{
|
||||
auto status = HAILO_UNINITIALIZED;
|
||||
|
||||
auto progress_bar_ptr = std::shared_ptr<InferProgress>(new (std::nothrow) InferProgress(params, print_interval, status));
|
||||
CHECK_AS_EXPECTED((nullptr != progress_bar_ptr), HAILO_OUT_OF_HOST_MEMORY);
|
||||
|
||||
return progress_bar_ptr;
|
||||
}
|
||||
|
||||
InferProgress::InferProgress(const inference_runner_params ¶ms,
|
||||
std::chrono::milliseconds print_interval, hailo_status &status) :
|
||||
m_params(params), m_print_interval(print_interval), m_networks_progress(),
|
||||
m_stop_event(Event::create_shared(Event::State::not_signalled)), m_finished(false)
|
||||
{
|
||||
if (nullptr == m_stop_event) {
|
||||
LOGGER__ERROR("Failed to create event for progress bar");
|
||||
status = HAILO_OUT_OF_HOST_MEMORY;
|
||||
return;
|
||||
}
|
||||
status = HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
void InferProgress::start()
|
||||
{
|
||||
m_stop = false;
|
||||
m_print_thread = std::thread([this] () {
|
||||
while (!m_stop.load()) {
|
||||
while (true) {
|
||||
print_progress(true);
|
||||
std::this_thread::sleep_for(m_print_interval);
|
||||
auto status = m_stop_event->wait(m_print_interval);
|
||||
if (HAILO_TIMEOUT != status) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void InferProgress::finish(bool should_print_progress)
|
||||
{
|
||||
m_stop = true;
|
||||
m_print_thread.join();
|
||||
(void)m_stop_event->signal();
|
||||
if (m_print_thread.joinable()) {
|
||||
m_print_thread.join();
|
||||
}
|
||||
|
||||
if (should_print_progress) {
|
||||
print_progress(false);
|
||||
}
|
||||
m_finished = true;
|
||||
}
|
||||
|
||||
void InferProgress::print_progress(bool should_reset_cursor)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
for (auto &network_progress_bar : m_networks_progress) {
|
||||
std::cout << network_progress_bar->get_progress_text() << std::endl;
|
||||
}
|
||||
@@ -50,15 +76,15 @@ void InferProgress::print_progress(bool should_reset_cursor)
|
||||
|
||||
InferProgress::~InferProgress()
|
||||
{
|
||||
if (!m_stop.load()) {
|
||||
if (!m_finished) {
|
||||
finish(false);
|
||||
}
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<NetworkProgressBar>> InferProgress::create_network_progress_bar(const std::string &network_name)
|
||||
Expected<std::shared_ptr<NetworkProgressBar>> InferProgress::create_network_progress_bar(std::shared_ptr<ConfiguredNetworkGroup> network_group, const std::string &network_name)
|
||||
{
|
||||
std::shared_ptr<NetworkProgressBar> network_progress_ber =
|
||||
make_shared_nothrow<NetworkProgressBar>(m_configured_network_group, m_params, network_name);
|
||||
make_shared_nothrow<NetworkProgressBar>(network_group, m_params, network_name);
|
||||
CHECK_NOT_NULL_AS_EXPECTED(network_progress_ber, HAILO_OUT_OF_HOST_MEMORY);
|
||||
|
||||
{
|
||||
@@ -71,7 +97,7 @@ Expected<std::shared_ptr<NetworkProgressBar>> InferProgress::create_network_prog
|
||||
return prog_bar_cpy;
|
||||
}
|
||||
|
||||
NetworkProgressBar::NetworkProgressBar(ConfiguredNetworkGroup &configured_network_group,
|
||||
NetworkProgressBar::NetworkProgressBar(std::shared_ptr<ConfiguredNetworkGroup> configured_network_group,
|
||||
const inference_runner_params ¶ms, const std::string &network_name) :
|
||||
m_network_name(network_name), m_configured_network_group(configured_network_group), m_params(params),
|
||||
m_progress_count(0), m_start(std::chrono::steady_clock::now()) // NetworkProgressBar sets start time to its creation time
|
||||
@@ -110,7 +136,7 @@ std::string NetworkProgressBar::get_progress_text()
|
||||
res << " | FPS: " << fps;
|
||||
} else {
|
||||
double avg_hw_latency = 0;
|
||||
auto latency_expected = m_configured_network_group.get_latency_measurement(m_network_name);
|
||||
auto latency_expected = m_configured_network_group->get_latency_measurement(m_network_name);
|
||||
if (latency_expected) {
|
||||
avg_hw_latency = InferResultsFormatUtils::latency_result_to_ms(latency_expected.release().avg_hw_latency);
|
||||
}
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
|
||||
class NetworkProgressBar final {
|
||||
public:
|
||||
NetworkProgressBar(ConfiguredNetworkGroup &configured_network_group,
|
||||
NetworkProgressBar(std::shared_ptr<ConfiguredNetworkGroup> configured_network_group,
|
||||
const inference_runner_params ¶ms, const std::string &network_name);
|
||||
|
||||
void make_progress();
|
||||
std::string get_progress_text();
|
||||
private:
|
||||
const std::string m_network_name;
|
||||
ConfiguredNetworkGroup &m_configured_network_group;
|
||||
std::shared_ptr<ConfiguredNetworkGroup> m_configured_network_group;
|
||||
const inference_runner_params m_params;
|
||||
std::atomic<uint32_t> m_progress_count;
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_start;
|
||||
@@ -34,25 +34,29 @@ private:
|
||||
|
||||
class InferProgress final {
|
||||
public:
|
||||
InferProgress(ConfiguredNetworkGroup &configured_network_group,
|
||||
const inference_runner_params ¶ms, std::chrono::duration<double> print_interval);
|
||||
static Expected<std::shared_ptr<InferProgress>> create(const inference_runner_params ¶ms,
|
||||
std::chrono::milliseconds print_interval);
|
||||
|
||||
~InferProgress();
|
||||
|
||||
Expected<std::shared_ptr<NetworkProgressBar>> create_network_progress_bar(const std::string &network_name);
|
||||
Expected<std::shared_ptr<NetworkProgressBar>> create_network_progress_bar(std::shared_ptr<ConfiguredNetworkGroup> network_group,
|
||||
const std::string &network_name);
|
||||
void start();
|
||||
void finish(bool should_print_progress = true);
|
||||
|
||||
|
||||
InferProgress(const inference_runner_params ¶ms, std::chrono::milliseconds print_interval, hailo_status &status);
|
||||
private:
|
||||
void print_progress(bool should_reset_cursor);
|
||||
|
||||
ConfiguredNetworkGroup &m_configured_network_group;
|
||||
std::vector<std::shared_ptr<ConfiguredNetworkGroup>> m_configured_network_groups;
|
||||
const inference_runner_params m_params;
|
||||
std::chrono::duration<double> m_print_interval;
|
||||
std::chrono::milliseconds m_print_interval;
|
||||
std::vector<std::shared_ptr<NetworkProgressBar>> m_networks_progress;
|
||||
std::atomic_bool m_stop;
|
||||
EventPtr m_stop_event;
|
||||
std::thread m_print_thread;
|
||||
std::mutex m_mutex;
|
||||
std::atomic_bool m_finished;
|
||||
};
|
||||
|
||||
#endif /* _HAILO_INFERENCE_PROGRESS_HPP_ */
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
|
||||
Expected<double> send_data_rate_mbit_sec() const
|
||||
{
|
||||
if (!m_infer_duration) {
|
||||
if (!m_infer_duration || !m_total_send_frame_size) {
|
||||
return make_unexpected(HAILO_NOT_AVAILABLE);
|
||||
}
|
||||
return (static_cast<double>(m_frames_count * m_total_send_frame_size) / *m_infer_duration) * MBIT_PER_BYTE;
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
|
||||
Expected<double> recv_data_rate_mbit_sec() const
|
||||
{
|
||||
if (!m_infer_duration) {
|
||||
if (!m_infer_duration || !m_total_recv_frame_size) {
|
||||
return make_unexpected(HAILO_NOT_AVAILABLE);
|
||||
}
|
||||
return (static_cast<double>(m_frames_count * m_total_recv_frame_size) / *m_infer_duration) * MBIT_PER_BYTE;
|
||||
@@ -84,25 +84,28 @@ public:
|
||||
size_t m_total_recv_frame_size;
|
||||
|
||||
// TODO: change to optional
|
||||
std::unique_ptr<double> m_infer_duration;
|
||||
std::unique_ptr<std::chrono::nanoseconds> m_hw_latency;
|
||||
std::unique_ptr<std::chrono::nanoseconds> m_overall_latency;
|
||||
std::shared_ptr<double> m_infer_duration;
|
||||
std::shared_ptr<std::chrono::nanoseconds> m_hw_latency;
|
||||
std::shared_ptr<std::chrono::nanoseconds> m_overall_latency;
|
||||
};
|
||||
|
||||
struct NetworkGroupInferResult
|
||||
{
|
||||
public:
|
||||
NetworkGroupInferResult(std::map<std::string, NetworkInferResult> &&result_per_network = {}) :
|
||||
NetworkGroupInferResult(const std::string &network_group_name, std::map<std::string, NetworkInferResult> &&result_per_network = {}) :
|
||||
m_network_group_name(network_group_name),
|
||||
m_result_per_network(std::move(result_per_network)),
|
||||
m_power_measurements(),
|
||||
m_current_measurements(),
|
||||
m_temp_measurements(),
|
||||
m_fps_accumulators(),
|
||||
m_latency_accumulators(),
|
||||
m_queue_size_accumulators(),
|
||||
m_pipeline_latency_accumulators()
|
||||
{}
|
||||
|
||||
std::string network_group_name()
|
||||
{
|
||||
return m_network_group_name;
|
||||
}
|
||||
|
||||
Expected<double> infer_duration(const std::string &network_name = "") const
|
||||
{
|
||||
if (network_name.empty()) {
|
||||
@@ -228,15 +231,15 @@ public:
|
||||
return frames_count_cpy;
|
||||
}
|
||||
|
||||
const std::map<std::string, NetworkInferResult> &results_per_network() const
|
||||
{
|
||||
return m_result_per_network;
|
||||
}
|
||||
|
||||
std::string m_network_group_name;
|
||||
// <network_name, network_inference_results>
|
||||
std::map<std::string, NetworkInferResult> m_result_per_network;
|
||||
|
||||
// <device_id, measurement>
|
||||
// TODO: create a struct contianing all device measurements, and keep only one map
|
||||
std::map<std::string, std::unique_ptr<LongPowerMeasurement>> m_power_measurements;
|
||||
std::map<std::string, std::unique_ptr<LongPowerMeasurement>> m_current_measurements;
|
||||
std::map<std::string, std::unique_ptr<TempMeasurementData>> m_temp_measurements;
|
||||
|
||||
// <vstream_name, accumulator>
|
||||
std::map<std::string, std::map<std::string, AccumulatorPtr>> m_fps_accumulators;
|
||||
std::map<std::string, std::map<std::string, AccumulatorPtr>> m_latency_accumulators;
|
||||
@@ -274,40 +277,7 @@ public:
|
||||
void update_pipeline_stats(const std::map<std::string, std::vector<std::reference_wrapper<InputStream>>> &/*inputs_per_network*/,
|
||||
const std::map<std::string, std::vector<std::reference_wrapper<OutputStream>>> &/*outputs_per_network*/)
|
||||
{
|
||||
// Overloading fow hw_object inference - not using any pipelines so nothing to update
|
||||
}
|
||||
|
||||
void initialize_measurements(const std::vector<std::reference_wrapper<Device>> &devices)
|
||||
{
|
||||
for (const auto &device : devices) {
|
||||
m_power_measurements.emplace(device.get().get_dev_id(), std::unique_ptr<LongPowerMeasurement>{});
|
||||
m_current_measurements.emplace(device.get().get_dev_id(), std::unique_ptr<LongPowerMeasurement>{});
|
||||
m_temp_measurements.emplace(device.get().get_dev_id(), std::unique_ptr<TempMeasurementData>{});
|
||||
}
|
||||
}
|
||||
|
||||
hailo_status set_power_measurement(const std::string &device_id, std::unique_ptr<LongPowerMeasurement> &&power_measure)
|
||||
{
|
||||
auto iter = m_power_measurements.find(device_id);
|
||||
CHECK(m_power_measurements.end() != iter, HAILO_INVALID_ARGUMENT);
|
||||
iter->second = std::move(power_measure);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status set_current_measurement(const std::string &device_id, std::unique_ptr<LongPowerMeasurement> &¤t_measure)
|
||||
{
|
||||
auto iter = m_current_measurements.find(device_id);
|
||||
CHECK(m_current_measurements.end() != iter, HAILO_INVALID_ARGUMENT);
|
||||
iter->second = std::move(current_measure);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status set_temp_measurement(const std::string &device_id, std::unique_ptr<TempMeasurementData> &&temp_measure)
|
||||
{
|
||||
auto iter = m_temp_measurements.find(device_id);
|
||||
CHECK(m_temp_measurements.end() != iter, HAILO_INVALID_ARGUMENT);
|
||||
iter->second = std::move(temp_measure);
|
||||
return HAILO_SUCCESS;
|
||||
// Overloading fow hw_only inference - not using any pipelines so nothing to update
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -323,4 +293,58 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
struct InferResult
|
||||
{
|
||||
public:
|
||||
InferResult(std::vector<NetworkGroupInferResult> &&network_groups_results) : m_network_group_results(std::move(network_groups_results))
|
||||
{}
|
||||
|
||||
std::vector<NetworkGroupInferResult> &network_group_results()
|
||||
{
|
||||
return m_network_group_results;
|
||||
}
|
||||
|
||||
void initialize_measurements(const std::vector<std::reference_wrapper<Device>> &devices)
|
||||
{
|
||||
for (const auto &device : devices) {
|
||||
m_power_measurements.emplace(device.get().get_dev_id(), std::shared_ptr<LongPowerMeasurement>{});
|
||||
m_current_measurements.emplace(device.get().get_dev_id(), std::shared_ptr<LongPowerMeasurement>{});
|
||||
m_temp_measurements.emplace(device.get().get_dev_id(), std::shared_ptr<TempMeasurementData>{});
|
||||
}
|
||||
}
|
||||
|
||||
hailo_status set_power_measurement(const std::string &device_id, std::shared_ptr<LongPowerMeasurement> &&power_measure)
|
||||
{
|
||||
auto iter = m_power_measurements.find(device_id);
|
||||
CHECK(m_power_measurements.end() != iter, HAILO_INVALID_ARGUMENT);
|
||||
iter->second = std::move(power_measure);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status set_current_measurement(const std::string &device_id, std::shared_ptr<LongPowerMeasurement> &¤t_measure)
|
||||
{
|
||||
auto iter = m_current_measurements.find(device_id);
|
||||
CHECK(m_current_measurements.end() != iter, HAILO_INVALID_ARGUMENT);
|
||||
iter->second = std::move(current_measure);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status set_temp_measurement(const std::string &device_id, std::shared_ptr<TempMeasurementData> &&temp_measure)
|
||||
{
|
||||
auto iter = m_temp_measurements.find(device_id);
|
||||
CHECK(m_temp_measurements.end() != iter, HAILO_INVALID_ARGUMENT);
|
||||
iter->second = std::move(temp_measure);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
// <device_id, measurement>
|
||||
// TODO: create a struct containing all device measurements, and keep only one map
|
||||
std::map<std::string, std::shared_ptr<LongPowerMeasurement>> m_power_measurements;
|
||||
std::map<std::string, std::shared_ptr<LongPowerMeasurement>> m_current_measurements;
|
||||
std::map<std::string, std::shared_ptr<TempMeasurementData>> m_temp_measurements;
|
||||
|
||||
private:
|
||||
std::vector<NetworkGroupInferResult> m_network_group_results;
|
||||
};
|
||||
|
||||
#endif /* _HAILO_INFER_RESULT_ */
|
||||
165
hailort/hailortcli/mon_command.cpp
Normal file
165
hailort/hailortcli/mon_command.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file mon_command.cpp
|
||||
* @brief Monitor of networks - Presents information about the running networks
|
||||
**/
|
||||
|
||||
#include "mon_command.hpp"
|
||||
#include "common.hpp"
|
||||
#include "hailo/hailort.h"
|
||||
#include "common/filesystem.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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 NUMBER_WIDTH = 15;
|
||||
constexpr size_t LINE_LENGTH = 125;
|
||||
|
||||
MonCommand::MonCommand(CLI::App &parent_app) :
|
||||
Command(parent_app.add_subcommand("monitor", "Monitor of networks - Presents information about the running networks. " \
|
||||
"To enable monitor, set in the application process the environment variable '" + std::string(SCHEDULER_MON_ENV_VAR) + "' to 1."))
|
||||
{}
|
||||
|
||||
hailo_status MonCommand::execute()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LOGGER__ERROR("hailortcli `monitor` command is not supported on Windows");
|
||||
return HAILO_NOT_IMPLEMENTED;
|
||||
#else
|
||||
return print_table();
|
||||
#endif
|
||||
}
|
||||
|
||||
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(NUMBER_WIDTH) << std::left << "PID" <<
|
||||
"\n" << std::left << std::string(LINE_LENGTH, '-') << "\n";
|
||||
static const uint32_t header_lines_count = 2;
|
||||
|
||||
return header_lines_count;
|
||||
}
|
||||
|
||||
size_t MonCommand::print_networks_info_table(const ProtoMon &mon_message)
|
||||
{
|
||||
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();
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
return mon_message.networks_infos().size();
|
||||
}
|
||||
|
||||
size_t MonCommand::print_frames_header()
|
||||
{
|
||||
std::cout <<
|
||||
std::setw(NETWORK_NAME_WIDTH) << std::left << "Network" <<
|
||||
std::setw(STREAM_NAME_WIDTH) << std::left << "Stream" <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << "Direction" <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << "Frames" <<
|
||||
"\n" << std::left << std::string(LINE_LENGTH, '-') << "\n";
|
||||
static const size_t header_lines_count = 2;
|
||||
return header_lines_count;
|
||||
}
|
||||
|
||||
size_t MonCommand::print_frames_table(const ProtoMon &mon_message)
|
||||
{
|
||||
size_t table_lines_count = 0;
|
||||
for (auto &net_info : mon_message.net_frames_infos()) {
|
||||
auto &net_name = net_info.network_name();
|
||||
table_lines_count += net_info.streams_frames_infos().size();
|
||||
for (auto &streams_frames : net_info.streams_frames_infos()) {
|
||||
auto &stream_name = streams_frames.stream_name();
|
||||
auto stream_direction = (streams_frames.stream_direction() == PROTO__STREAM_DIRECTION__HOST_TO_DEVICE) ? "H2D" : "D2H";
|
||||
|
||||
std::string frames;
|
||||
if (SCHEDULER_MON_NAN_VAL == streams_frames.buffer_frames_size() || SCHEDULER_MON_NAN_VAL == streams_frames.pending_frames_count()) {
|
||||
frames = "NaN";
|
||||
} else {
|
||||
frames = std::to_string(streams_frames.pending_frames_count()) + "/" + std::to_string(streams_frames.buffer_frames_size());
|
||||
}
|
||||
|
||||
std::cout <<
|
||||
std::setw(NETWORK_NAME_WIDTH) << std::left << net_name <<
|
||||
std::setw(STREAM_NAME_WIDTH) << std::left << stream_name <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << stream_direction <<
|
||||
std::setw(NUMBER_WIDTH) << std::left << frames << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return table_lines_count;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
hailo_status MonCommand::print_table()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
std::vector<ProtoMon> mon_messages;
|
||||
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());
|
||||
continue;
|
||||
}
|
||||
|
||||
ProtoMon mon_message;
|
||||
if (!mon_message.ParseFromFileDescriptor(file->get_fd())) {
|
||||
LOGGER__WARNING("Failed to ParseFromFileDescriptor monitor file {} with errno {}", mon_file, errno);
|
||||
continue;
|
||||
}
|
||||
|
||||
mon_messages.emplace_back(std::move(mon_message));
|
||||
}
|
||||
|
||||
size_t 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";
|
||||
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);
|
||||
|
||||
std::this_thread::sleep_for(DEFAULT_SCHEDULER_MON_INTERVAL);
|
||||
}
|
||||
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
41
hailort/hailortcli/mon_command.hpp
Normal file
41
hailort/hailortcli/mon_command.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file mon_command.hpp
|
||||
* @brief Monitor of networks - Presents information about the running networks
|
||||
**/
|
||||
|
||||
#ifndef _HAILO_MON_COMMAND_HPP_
|
||||
#define _HAILO_MON_COMMAND_HPP_
|
||||
|
||||
#include "hailo/hailort.h"
|
||||
#include "hailortcli.hpp"
|
||||
#include "command.hpp"
|
||||
#include "scheduler_mon.hpp"
|
||||
|
||||
#include "CLI/CLI.hpp"
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
class MonCommand : public Command
|
||||
{
|
||||
public:
|
||||
explicit MonCommand(CLI::App &parent_app);
|
||||
|
||||
virtual hailo_status execute() override;
|
||||
|
||||
private:
|
||||
hailo_status print_table();
|
||||
size_t print_networks_info_header();
|
||||
size_t print_frames_header();
|
||||
size_t print_networks_info_table(const ProtoMon &mon_message);
|
||||
size_t print_frames_table(const ProtoMon &mon_message);
|
||||
};
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
#endif /* _HAILO_MON_COMMAND_HPP_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,6 +44,9 @@ 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;
|
||||
@@ -51,7 +54,7 @@ struct runtime_data_params {
|
||||
};
|
||||
|
||||
struct inference_runner_params {
|
||||
hailo_device_params device_params;
|
||||
hailo_vdevice_params vdevice_params;
|
||||
std::string hef_path;
|
||||
uint32_t frames_count;
|
||||
uint32_t time_to_run;
|
||||
@@ -75,7 +78,7 @@ struct inference_runner_params {
|
||||
bool should_measure_pipeline_stats(const inference_runner_params& params);
|
||||
CLI::App* create_run_command(CLI::App& parent, inference_runner_params& params);
|
||||
hailo_status run_command(const inference_runner_params ¶ms);
|
||||
Expected<NetworkGroupInferResult> run_command_hef(const inference_runner_params ¶ms);
|
||||
Expected<InferResult> run_command_hef(const inference_runner_params ¶ms);
|
||||
|
||||
std::string format_type_to_string(hailo_format_type_t format_type);
|
||||
|
||||
|
||||
@@ -14,17 +14,13 @@
|
||||
|
||||
|
||||
ScanSubcommand::ScanSubcommand(CLI::App &parent_app) :
|
||||
Command(parent_app.add_subcommand("scan", "Shows all available devices")),
|
||||
m_device_type(Device::Type::PCIE)
|
||||
Command(parent_app.add_subcommand("scan", "Shows all available devices"))
|
||||
{
|
||||
const HailoCheckedTransformer<Device::Type> device_type_transformer({
|
||||
{ "pcie", Device::Type::PCIE },
|
||||
{ "eth", Device::Type::ETH },
|
||||
});
|
||||
auto *device_type_option = m_app->add_option("-d,--device-type,--target", m_device_type,
|
||||
"Device type to use.")
|
||||
->transform(device_type_transformer)
|
||||
->default_val("pcie");
|
||||
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");
|
||||
@@ -33,63 +29,37 @@ ScanSubcommand::ScanSubcommand(CLI::App &parent_app) :
|
||||
->default_val("")
|
||||
->check(CLI::ValidIPV4);
|
||||
|
||||
auto *interface_name_option = eth_options_group->add_option("--interface", m_interface_name, "Interface name to scan")
|
||||
eth_options_group->add_option("--interface", m_interface_name, "Interface name to scan")
|
||||
->default_val("")
|
||||
->excludes(interface_ip_option);
|
||||
|
||||
m_app->parse_complete_callback([this, device_type_option, interface_ip_option, interface_name_option]() {
|
||||
bool eth_options_given = !interface_ip_option->empty() || !interface_name_option->empty();
|
||||
|
||||
// The user didn't put target, we can figure it ourself
|
||||
if (device_type_option->empty()) {
|
||||
if (eth_options_given) {
|
||||
// User gave IP, target is eth
|
||||
m_device_type = Device::Type::ETH;
|
||||
}
|
||||
else {
|
||||
// Default is pcie
|
||||
m_device_type = Device::Type::PCIE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!eth_options_given && (m_device_type == Device::Type::ETH)) {
|
||||
throw CLI::ParseError("Ethernet options not set", CLI::ExitCodes::InvalidError);
|
||||
}
|
||||
|
||||
if (eth_options_given && (m_device_type != Device::Type::ETH)) {
|
||||
throw CLI::ParseError("Ethernet options set on non eth device", CLI::ExitCodes::InvalidError);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
hailo_status ScanSubcommand::execute()
|
||||
{
|
||||
switch (m_device_type)
|
||||
{
|
||||
case Device::Type::PCIE:
|
||||
return scan_pcie();
|
||||
case Device::Type::ETH:
|
||||
return scan_ethernet(m_interface_ip_addr, m_interface_name).status();
|
||||
default:
|
||||
std::cerr << "Unkown target" << std::endl;
|
||||
return HAILO_INVALID_ARGUMENT;
|
||||
const bool request_for_eth_scan = !m_interface_name.empty() || !m_interface_ip_addr.empty();
|
||||
|
||||
if (!request_for_eth_scan) {
|
||||
return scan();
|
||||
}
|
||||
else {
|
||||
auto res = scan_ethernet(m_interface_ip_addr, m_interface_name);
|
||||
CHECK_EXPECTED_AS_STATUS(res);
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
hailo_status ScanSubcommand::scan_pcie()
|
||||
hailo_status ScanSubcommand::scan()
|
||||
{
|
||||
auto scan_result = Device::scan_pcie();
|
||||
CHECK_SUCCESS(scan_result.status(), "Error scan failed status = {}", scan_result.status());
|
||||
auto device_ids = Device::scan();
|
||||
CHECK_EXPECTED_AS_STATUS(device_ids);
|
||||
|
||||
if (scan_result->size() == 0) {
|
||||
std::cout << "Hailo PCIe devices not found" << std::endl;
|
||||
if (device_ids->size() == 0) {
|
||||
std::cout << "Hailo devices not found" << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout << "Hailo PCIe Devices:" << std::endl;
|
||||
for (const auto& device_info : scan_result.value()) {
|
||||
auto device_info_str = Device::pcie_device_info_to_string(device_info);
|
||||
CHECK_EXPECTED_AS_STATUS(device_info_str);
|
||||
std::cout << "[-] Device BDF: " << device_info_str.value() << std::endl;
|
||||
std::cout << "Hailo Devices:" << std::endl;
|
||||
for (const auto& device_id : device_ids.value()) {
|
||||
std::cout << "[-] Device: " << device_id << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,9 +26,8 @@ public:
|
||||
const std::string &interface_name);
|
||||
|
||||
private:
|
||||
hailo_status scan_pcie();
|
||||
|
||||
Device::Type m_device_type;
|
||||
// Scans any system device
|
||||
hailo_status scan();
|
||||
|
||||
// Ethernet scan options
|
||||
std::string m_interface_ip_addr;
|
||||
|
||||
@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0.0)
|
||||
# set(CMAKE_C_CLANG_TIDY "clang-tidy;-checks=*")
|
||||
|
||||
set(HAILORT_MAJOR_VERSION 4)
|
||||
set(HAILORT_MINOR_VERSION 8)
|
||||
set(HAILORT_REVISION_VERSION 1)
|
||||
set(HAILORT_MINOR_VERSION 10)
|
||||
set(HAILORT_REVISION_VERSION 0)
|
||||
|
||||
# Add the cmake folder so the modules there are found
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
@@ -12,7 +12,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
protobuf_generate_cpp(PROTO_HEF_SRC PROTO_HEF_HEADR hef.proto)
|
||||
|
||||
add_library(hef_proto ${PROTO_HEF_SRC} ${PROTO_HEF_HEADR})
|
||||
target_link_libraries(hef_proto libprotobuf)
|
||||
target_link_libraries(hef_proto libprotobuf-lite)
|
||||
set_target_properties(hef_proto PROPERTIES CXX_STANDARD 14 GENERATED TRUE POSITION_INDEPENDENT_CODE ON)
|
||||
if(CMAKE_HOST_WIN32)
|
||||
# https://github.com/protocolbuffers/protobuf/tree/master/cmake#notes-on-compiler-warnings
|
||||
@@ -25,11 +25,26 @@ target_include_directories(hef_proto
|
||||
$<BUILD_INTERFACE: ${Protobuf_INCLUDE_DIRS}>
|
||||
)
|
||||
|
||||
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)
|
||||
set_target_properties(scheduler_mon_proto PROPERTIES CXX_STANDARD 14 GENERATED TRUE POSITION_INDEPENDENT_CODE ON)
|
||||
if(CMAKE_HOST_WIN32)
|
||||
target_compile_options(scheduler_mon_proto PRIVATE /wd4244)
|
||||
endif()
|
||||
get_filename_component(PROTO_SCHEDULER_MON_HEADER_DIRECTORY ${PROTO_SCHEDULER_MON_HEADR} DIRECTORY)
|
||||
target_include_directories(scheduler_mon_proto
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE: ${PROTO_SCHEDULER_MON_HEADER_DIRECTORY}>
|
||||
$<BUILD_INTERFACE: ${Protobuf_INCLUDE_DIRS}>
|
||||
)
|
||||
|
||||
# Add readerwriterqueue as a header-only library
|
||||
add_library(readerwriterqueue INTERFACE)
|
||||
target_include_directories(readerwriterqueue INTERFACE ${HAILO_EXTERNAL_DIR}/readerwriterqueue)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
if(HAILO_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
@@ -8,7 +8,7 @@ if(NOT CMAKE_HOST_UNIX)
|
||||
message(FATAL_ERROR "Only unix hosts are supported, stopping build")
|
||||
endif()
|
||||
|
||||
find_package(HailoRT 4.8.1 EXACT REQUIRED)
|
||||
find_package(HailoRT 4.10.0 EXACT REQUIRED)
|
||||
|
||||
# GST_PLUGIN_DEFINE needs PACKAGE to be defined
|
||||
set(GST_HAILO_PACKAGE_NAME "hailo")
|
||||
|
||||
@@ -48,7 +48,7 @@ using namespace hailort;
|
||||
#define DEFAULT_VDEVICE_KEY (0)
|
||||
#define MIN_VALID_VDEVICE_KEY (1)
|
||||
|
||||
#define HAILO_SUPPORTED_FORMATS "{ RGB, YUY2 }"
|
||||
#define HAILO_SUPPORTED_FORMATS "{ RGB, RGBA, YUY2 }"
|
||||
#define HAILO_VIDEO_CAPS GST_VIDEO_CAPS_MAKE(HAILO_SUPPORTED_FORMATS)
|
||||
|
||||
#define HAILO_DEFAULT_SCHEDULER_TIMEOUT_MS (0)
|
||||
@@ -70,6 +70,14 @@ using namespace hailort;
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define GST_CHECK_SUCCESS_AS_EXPECTED(status, element, domain, ...) \
|
||||
do { \
|
||||
if (HAILO_SUCCESS != (status)) { \
|
||||
GST_ELEMENT_ERROR((element), domain, FAILED, (__VA_ARGS__), (NULL)); \
|
||||
return make_unexpected(status); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define GST_CHECK_EXPECTED(obj, element, domain, ...) \
|
||||
do { \
|
||||
if (!(obj)) { \
|
||||
|
||||
@@ -570,7 +570,7 @@ hailo_status HailoNetImpl::configure_network_group()
|
||||
GST_CHECK_EXPECTED_AS_STATUS(network_group_name, m_element, RESOURCE, "Could not get network group name from name %s, status = %d",
|
||||
m_props.m_network_name.get(), network_group_name.status());
|
||||
|
||||
hailo_status status = m_net_group_handle->configure_network_group(network_group_name->c_str(), m_props.m_batch_size.get());
|
||||
hailo_status status = m_net_group_handle->configure_network_group(network_group_name->c_str(), m_props.m_scheduling_algorithm.get(), m_props.m_batch_size.get());
|
||||
if (HAILO_SUCCESS != status) {
|
||||
return status;
|
||||
}
|
||||
@@ -585,7 +585,7 @@ hailo_status HailoNetImpl::configure_network_group()
|
||||
GST_CHECK_SUCCESS(status, m_element, RESOURCE, "Setting scheduler threshold failed, status = %d", status);
|
||||
}
|
||||
|
||||
auto vstreams = m_net_group_handle->create_vstreams(m_props.m_network_name.get(), m_output_formats);
|
||||
auto vstreams = m_net_group_handle->create_vstreams(m_props.m_network_name.get(), m_props.m_scheduling_algorithm.get(), m_output_formats);
|
||||
GST_CHECK_EXPECTED_AS_STATUS(vstreams, m_element, RESOURCE, "Creating vstreams failed, status = %d", status);
|
||||
|
||||
GST_HAILOSEND(m_hailosend)->impl->set_input_vstreams(std::move(vstreams->first));
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
GST_DEBUG_CATEGORY_STATIC(gst_hailosend_debug_category);
|
||||
#define GST_CAT_DEFAULT gst_hailosend_debug_category
|
||||
#define RGB_FEATURES_SIZE (3)
|
||||
#define RGBA_FEATURES_SIZE (4)
|
||||
#define YUY2_FEATURES_SIZE (2)
|
||||
#define NV12_FEATURES_SIZE (3)
|
||||
#define NV21_FEATURES_SIZE (3)
|
||||
|
||||
static void gst_hailosend_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
|
||||
static void gst_hailosend_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
|
||||
@@ -61,7 +64,7 @@ static void gst_hailosend_class_init(GstHailoSendClass *klass)
|
||||
gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS, gst_caps_from_string(HAILO_VIDEO_CAPS)));
|
||||
|
||||
gst_element_class_set_static_metadata(GST_ELEMENT_CLASS(klass),
|
||||
"hailosend element", "Hailo/Filter/Video", "Send RGB/YUY2 video to HailoRT", PLUGIN_AUTHOR);
|
||||
"hailosend element", "Hailo/Filter/Video", "Send RGB/RGBA/YUY2 video to HailoRT", PLUGIN_AUTHOR);
|
||||
|
||||
element_class->change_state = GST_DEBUG_FUNCPTR(gst_hailosend_change_state);
|
||||
|
||||
@@ -173,7 +176,7 @@ hailo_status HailoSendImpl::write_to_vstreams(void *buf, size_t size)
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
GstCaps *HailoSendImpl::get_caps(GstBaseTransform */*trans*/, GstPadDirection /*direction*/, GstCaps */*caps*/, GstCaps */*filter*/)
|
||||
GstCaps *HailoSendImpl::get_caps(GstBaseTransform */*trans*/, GstPadDirection /*direction*/, GstCaps *caps, GstCaps */*filter*/)
|
||||
{
|
||||
GST_DEBUG_OBJECT(m_element, "transform_caps");
|
||||
|
||||
@@ -190,6 +193,11 @@ GstCaps *HailoSendImpl::get_caps(GstBaseTransform */*trans*/, GstPadDirection /*
|
||||
const gchar *format = nullptr;
|
||||
switch (m_input_vstream_infos[0].format.order) {
|
||||
case HAILO_FORMAT_ORDER_NHWC:
|
||||
if (m_input_vstream_infos[0].shape.features == RGBA_FEATURES_SIZE) {
|
||||
format = "RGBA";
|
||||
break;
|
||||
}
|
||||
/* Fallthrough */
|
||||
case HAILO_FORMAT_ORDER_NHCW:
|
||||
case HAILO_FORMAT_ORDER_FCR:
|
||||
case HAILO_FORMAT_ORDER_F8CR:
|
||||
@@ -204,6 +212,18 @@ GstCaps *HailoSendImpl::get_caps(GstBaseTransform */*trans*/, GstPadDirection /*
|
||||
"Features of input vstream %s is not %d for YUY2 format! (features=%d)", m_input_vstream_infos[0].name, YUY2_FEATURES_SIZE,
|
||||
m_input_vstream_infos[0].shape.features);
|
||||
break;
|
||||
case HAILO_FORMAT_ORDER_NV12:
|
||||
format = "NV12";
|
||||
GST_CHECK(NV12_FEATURES_SIZE == m_input_vstream_infos[0].shape.features, NULL, m_element, STREAM,
|
||||
"Features of input vstream %s is not %d for NV12 format! (features=%d)", m_input_vstream_infos[0].name, NV12_FEATURES_SIZE,
|
||||
m_input_vstream_infos[0].shape.features);
|
||||
break;
|
||||
case HAILO_FORMAT_ORDER_NV21:
|
||||
format = "NV21";
|
||||
GST_CHECK(NV21_FEATURES_SIZE == m_input_vstream_infos[0].shape.features, NULL, m_element, STREAM,
|
||||
"Features of input vstream %s is not %d for NV21 format! (features=%d)", m_input_vstream_infos[0].name, NV21_FEATURES_SIZE,
|
||||
m_input_vstream_infos[0].shape.features);
|
||||
break;
|
||||
default:
|
||||
GST_ELEMENT_ERROR(m_element, RESOURCE, FAILED,
|
||||
("Input VStream %s has an unsupported format order! order = %d", m_input_vstream_infos[0].name, m_input_vstream_infos[0].format.order), (NULL));
|
||||
@@ -211,11 +231,12 @@ GstCaps *HailoSendImpl::get_caps(GstBaseTransform */*trans*/, GstPadDirection /*
|
||||
}
|
||||
|
||||
/* filter against set allowed caps on the pad */
|
||||
return gst_caps_new_simple("video/x-raw",
|
||||
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,
|
||||
NULL);
|
||||
return gst_caps_intersect(caps, new_caps);
|
||||
}
|
||||
|
||||
void HailoSendImpl::set_input_vstream_infos(std::vector<hailo_vstream_info_t> &&input_vstream_infos)
|
||||
|
||||
@@ -22,14 +22,96 @@
|
||||
#include <sstream>
|
||||
#include <chrono>
|
||||
|
||||
VDeviceManager NetworkGroupHandle::m_vdevice_manager;
|
||||
std::unordered_set<std::shared_ptr<VDevice>> NetworkGroupHandle::m_vdevices;
|
||||
NetworkGroupConfigManager NetworkGroupHandle::m_net_group_config_manager;
|
||||
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)
|
||||
{
|
||||
// If passing device_id, than device_count must be 1
|
||||
const auto device_count = 1;
|
||||
|
||||
auto device_id_expected = HailoRTCommon::to_device_id(device_id);
|
||||
GST_CHECK_EXPECTED(device_id_expected, element, RESOURCE, "Failed parsing device id, status = %d", device_id_expected.status());
|
||||
|
||||
hailo_vdevice_params_t params = {};
|
||||
auto status = hailo_init_vdevice_params(¶ms);
|
||||
GST_CHECK_SUCCESS_AS_EXPECTED(status, element, RESOURCE, "Failed hailo_init_vdevice_params, status = %d", status);
|
||||
|
||||
params.device_count = device_count;
|
||||
params.device_ids = &(device_id_expected.value());
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
if (vdevice_key == DEFAULT_VDEVICE_KEY) {
|
||||
params.group_id = HAILO_UNIQUE_VDEVICE_GROUP_ID;
|
||||
} else {
|
||||
auto key = std::to_string(vdevice_key);
|
||||
params.group_id = key.c_str();
|
||||
}
|
||||
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());
|
||||
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)
|
||||
{
|
||||
auto device_id = std::to_string(vdevice_key);
|
||||
hailo_vdevice_params_t params = {};
|
||||
auto status = hailo_init_vdevice_params(¶ms);
|
||||
GST_CHECK_SUCCESS_AS_EXPECTED(status, element, RESOURCE, "Failed hailo_init_vdevice_params, status = %d", status);
|
||||
params.device_count = device_count;
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
params.group_id = device_id.c_str();
|
||||
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());
|
||||
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_vdevice_params_t params = {};
|
||||
auto status = hailo_init_vdevice_params(¶ms);
|
||||
GST_CHECK_SUCCESS_AS_EXPECTED(status, element, RESOURCE, "Failed hailo_init_vdevice_params, status = %d", status);
|
||||
|
||||
params.device_count = device_count;
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
params.group_id = HAILO_UNIQUE_VDEVICE_GROUP_ID;
|
||||
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());
|
||||
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)
|
||||
{
|
||||
if (!device_id.empty()) {
|
||||
auto result = create_shared_vdevice(element, device_id, vdevice_key, scheduling_algorithm);
|
||||
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);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
auto expected_device = m_vdevice_manager.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);
|
||||
GST_CHECK_EXPECTED(expected_device, m_element, RESOURCE, "Failed creating vdevice, status = %d", expected_device.status());
|
||||
return expected_device;
|
||||
}
|
||||
@@ -65,12 +147,13 @@ hailo_status NetworkGroupHandle::set_hef(const char *device_id, uint16_t device_
|
||||
return HAILO_SUCCESS;
|
||||
}
|
||||
|
||||
hailo_status NetworkGroupHandle::configure_network_group(const char *net_group_name, uint16_t batch_size)
|
||||
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);
|
||||
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, net_group_name, batch_size, m_vdevice, m_hef, net_groups_params_map.value());
|
||||
auto expected_cng = m_net_group_config_manager.configure_network_group(m_element, m_shared_device_id, scheduling_algorithm,
|
||||
net_group_name, batch_size, m_vdevice, m_hef, net_groups_params_map.value());
|
||||
GST_CHECK_EXPECTED_AS_STATUS(expected_cng, m_element, RESOURCE, "Failed configuring network, status = %d", expected_cng.status());
|
||||
|
||||
m_cng = expected_cng.release();
|
||||
@@ -91,14 +174,16 @@ hailo_status NetworkGroupHandle::set_scheduler_threshold(const char *network_nam
|
||||
}
|
||||
|
||||
Expected<std::pair<std::vector<InputVStream>, std::vector<OutputVStream>>> NetworkGroupHandle::create_vstreams(const char *network_name,
|
||||
const std::vector<hailo_format_with_name_t> &output_formats)
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, const std::vector<hailo_format_with_name_t> &output_formats)
|
||||
{
|
||||
GST_CHECK(nullptr != network_name, make_unexpected(HAILO_INVALID_ARGUMENT), m_element, RESOURCE, "Got nullptr in network name!");
|
||||
|
||||
m_network_name = network_name;
|
||||
hailo_status status = m_net_group_config_manager.add_network_to_shared_network_group(m_shared_device_id, m_network_name, m_element);
|
||||
GST_CHECK(HAILO_SUCCESS == status, make_unexpected(status), m_element, RESOURCE,
|
||||
"Inserting network name to configured networks has failed, status = %d", status);
|
||||
if (scheduling_algorithm == HAILO_SCHEDULING_ALGORITHM_NONE) {
|
||||
hailo_status status = m_net_group_config_manager.add_network_to_shared_network_group(m_shared_device_id, m_network_name, m_element);
|
||||
GST_CHECK(HAILO_SUCCESS == status, make_unexpected(status), m_element, RESOURCE,
|
||||
"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,
|
||||
HAILO_DEFAULT_VSTREAM_QUEUE_SIZE, m_network_name);
|
||||
@@ -151,7 +236,8 @@ Expected<NetworkGroupsParamsMap> NetworkGroupHandle::get_configure_params(Hef &h
|
||||
|
||||
hailo_status NetworkGroupHandle::activate_network_group()
|
||||
{
|
||||
auto expected_ang = m_net_group_activation_manager.activate_network_group(m_element, m_shared_device_id, m_net_group_name.c_str(), m_batch_size, m_cng);
|
||||
auto expected_ang = m_net_group_activation_manager.activate_network_group(m_element, m_shared_device_id, m_hef->hash(),
|
||||
m_net_group_name.c_str(), m_batch_size, m_cng);
|
||||
GST_CHECK_EXPECTED_AS_STATUS(expected_ang, m_element, RESOURCE, "Failed activating network, status = %d", expected_ang.status());
|
||||
m_ang = expected_ang.release();
|
||||
return HAILO_SUCCESS;
|
||||
@@ -197,7 +283,8 @@ Expected<bool> NetworkGroupHandle::remove_network_group()
|
||||
// If use count is 2, it means the only references to the activated network group is in the manager and the one here, meaning that we can clear it
|
||||
// from the manager
|
||||
if (m_ang.use_count() == 2) {
|
||||
hailo_status status = m_net_group_activation_manager.remove_activated_network(m_shared_device_id, m_net_group_name.c_str(), m_batch_size);
|
||||
hailo_status status = m_net_group_activation_manager.remove_activated_network(m_shared_device_id, m_hef->hash(),
|
||||
m_net_group_name.c_str(), m_batch_size);
|
||||
GST_CHECK(HAILO_SUCCESS == status, make_unexpected(status), m_element, RESOURCE, "Cound not find activated network group! status = %d", status);
|
||||
|
||||
was_network_deactivated = true;
|
||||
@@ -209,129 +296,45 @@ Expected<bool> NetworkGroupHandle::remove_network_group()
|
||||
return was_network_deactivated;
|
||||
}
|
||||
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> VDeviceManager::create_vdevice(const void *element, const std::string &device_id, uint16_t device_count,
|
||||
uint32_t vdevice_key, hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
if (!device_id.empty()) {
|
||||
return create_shared_vdevice(element, device_id, scheduling_algorithm);
|
||||
}
|
||||
if (DEFAULT_VDEVICE_KEY != vdevice_key) {
|
||||
return create_shared_vdevice(element, device_count, vdevice_key, scheduling_algorithm);
|
||||
}
|
||||
return create_unique_vdevice(element, device_count, scheduling_algorithm);
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> VDeviceManager::create_shared_vdevice(const void *element, const std::string &device_id,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
{
|
||||
// If passing device_id, than device_count must be 1
|
||||
const auto device_count = 1;
|
||||
|
||||
// If vdevice already exist, use it
|
||||
auto found_vdevice = get_vdevice(device_id, scheduling_algorithm);
|
||||
if (found_vdevice.status() != HAILO_NOT_FOUND) {
|
||||
GST_CHECK_EXPECTED(found_vdevice, element, RESOURCE, "Failed using shared vdevice, status = %d", found_vdevice.status());
|
||||
return found_vdevice.release();
|
||||
}
|
||||
|
||||
auto device_info_expected = Device::parse_pcie_device_info(device_id);
|
||||
GST_CHECK_EXPECTED(device_info_expected, element, RESOURCE, "Failed parsing pcie device info, status = %d", device_info_expected.status());
|
||||
|
||||
hailo_vdevice_params_t params = {};
|
||||
params.device_count = device_count;
|
||||
params.device_infos = &(device_info_expected.value());
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
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());
|
||||
|
||||
m_shared_vdevices[device_id] = vdevice_ptr;
|
||||
m_shared_vdevices_scheduling_algorithm[device_id] = scheduling_algorithm;
|
||||
return vdevice_ptr;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> VDeviceManager::create_shared_vdevice(const void *element, uint16_t device_count, uint32_t vdevice_key,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
{
|
||||
auto device_id = std::to_string(device_count) + "-" + std::to_string(vdevice_key);
|
||||
|
||||
// If vdevice already exist, use it
|
||||
auto found_vdevice = get_vdevice(device_id, scheduling_algorithm);
|
||||
if (found_vdevice.status() != HAILO_NOT_FOUND) {
|
||||
GST_CHECK_EXPECTED(found_vdevice, element, RESOURCE, "Failed using shared vdevice, status = %d", found_vdevice.status());
|
||||
return found_vdevice.release();
|
||||
}
|
||||
|
||||
hailo_vdevice_params_t params = {};
|
||||
params.device_count = device_count;
|
||||
params.device_infos = nullptr;
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
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());
|
||||
|
||||
m_shared_vdevices[device_id] = vdevice_ptr;
|
||||
m_shared_vdevices_scheduling_algorithm[device_id] = scheduling_algorithm;
|
||||
return vdevice_ptr;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> VDeviceManager::create_unique_vdevice(const void *element, uint16_t device_count,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
{
|
||||
hailo_vdevice_params_t params = {};
|
||||
params.device_count = device_count;
|
||||
params.device_infos = nullptr;
|
||||
params.scheduling_algorithm = scheduling_algorithm;
|
||||
auto vdevice = VDevice::create(params);
|
||||
GST_CHECK_EXPECTED(vdevice, element, RESOURCE, "Failed creating vdevice, status = %d", vdevice.status());
|
||||
|
||||
// Unique vdevices are not saved in VDeviceManager, only in their hailonet
|
||||
std::shared_ptr<VDevice> vdevice_ptr = std::move(vdevice.release());
|
||||
m_unique_vdevices.push_back(vdevice_ptr);
|
||||
return vdevice_ptr;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<VDevice>> VDeviceManager::get_vdevice(const std::string &device_id,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm)
|
||||
{
|
||||
auto found = m_shared_vdevices.find(device_id);
|
||||
if (found == m_shared_vdevices.end()) {
|
||||
return make_unexpected(HAILO_NOT_FOUND);
|
||||
}
|
||||
|
||||
// shared_vdevice is found, verify the requested scheduling_algorithm
|
||||
assert(m_shared_vdevices_scheduling_algorithm.end() != m_shared_vdevices_scheduling_algorithm.find(device_id));
|
||||
if (scheduling_algorithm != m_shared_vdevices_scheduling_algorithm[device_id]) {
|
||||
auto status = HAILO_INVALID_OPERATION;
|
||||
g_warning("Shared vdevice with the same credentials is already exists (%s) but with a different scheduling-algorithm (requested: %d, exists: %d), status = %d",
|
||||
device_id.c_str(), scheduling_algorithm, m_shared_vdevices_scheduling_algorithm[device_id], status);
|
||||
return make_unexpected(HAILO_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
auto vdevice_cpy = found->second;
|
||||
return vdevice_cpy;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<ConfiguredNetworkGroup>> NetworkGroupConfigManager::configure_network_group(const void *element, const std::string &device_id,
|
||||
const char *network_group_name, uint16_t batch_size, std::shared_ptr<VDevice> &vdevice, std::shared_ptr<Hef> hef,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, const char *network_group_name, uint16_t batch_size, std::shared_ptr<VDevice> &vdevice, std::shared_ptr<Hef> hef,
|
||||
NetworkGroupsParamsMap &net_groups_params_map)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
std::shared_ptr<ConfiguredNetworkGroup> found_cng = get_configured_network_group(device_id, network_group_name, batch_size);
|
||||
std::shared_ptr<ConfiguredNetworkGroup> found_cng = get_configured_network_group(device_id, hef->hash(), network_group_name, batch_size);
|
||||
if (nullptr != found_cng) {
|
||||
return found_cng;
|
||||
// If cng was already configured
|
||||
auto infos = found_cng->get_network_infos();
|
||||
GST_CHECK_EXPECTED(infos, element, RESOURCE, "Failed getting network infos");
|
||||
if ((infos.release().size() > 1) || (scheduling_algorithm == HAILO_SCHEDULING_ALGORITHM_NONE)) {
|
||||
// But hailonet is not running all networks in the cng (or if not using scheduler) -
|
||||
// Do not use multiplexer!
|
||||
return found_cng;
|
||||
}
|
||||
}
|
||||
|
||||
auto network_group_list = vdevice->configure(*hef, net_groups_params_map);
|
||||
GST_CHECK_EXPECTED(network_group_list, element, RESOURCE, "Failed configure device from hef, status = %d",
|
||||
network_group_list.status());
|
||||
|
||||
m_configured_net_groups[get_configure_string(device_id, network_group_name, batch_size)] = network_group_list->at(0);
|
||||
std::shared_ptr<ConfiguredNetworkGroup> result = nullptr;
|
||||
for (auto &network_group : network_group_list.value()) {
|
||||
m_configured_net_groups[get_configure_string(device_id, hef->hash(), network_group->name().c_str(), batch_size)] = network_group;
|
||||
if (std::string(network_group_name) == network_group->name()) {
|
||||
result = network_group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(network_group_list->at(0));
|
||||
if (result) {
|
||||
return result;
|
||||
} else if (1 != network_group_list->size()) {
|
||||
g_error("Configuring HEF with multiple network_groups without providing valid network_group name. passed name = %s, status = %d", network_group_name, HAILO_NOT_FOUND);
|
||||
return make_unexpected(HAILO_NOT_FOUND);
|
||||
} else {
|
||||
return std::move(network_group_list->at(0));
|
||||
}
|
||||
}
|
||||
|
||||
hailo_status NetworkGroupConfigManager::add_network_to_shared_network_group(const std::string &shared_device_id, const std::string &network_name,
|
||||
@@ -356,9 +359,9 @@ hailo_status NetworkGroupConfigManager::add_network_to_shared_network_group(cons
|
||||
}
|
||||
|
||||
std::shared_ptr<ConfiguredNetworkGroup> NetworkGroupConfigManager::get_configured_network_group(const std::string &device_id,
|
||||
const char *network_group_name, uint16_t batch_size)
|
||||
const std::string &hef_hash, const char *network_group_name, uint16_t batch_size)
|
||||
{
|
||||
auto found = m_configured_net_groups.find(get_configure_string(device_id, network_group_name, batch_size));
|
||||
auto found = m_configured_net_groups.find(get_configure_string(device_id, hef_hash, network_group_name, batch_size));
|
||||
if (found == m_configured_net_groups.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -366,7 +369,8 @@ std::shared_ptr<ConfiguredNetworkGroup> NetworkGroupConfigManager::get_configure
|
||||
return found->second;
|
||||
}
|
||||
|
||||
std::string NetworkGroupConfigManager::get_configure_string(const std::string &device_id, const char *network_group_name, uint16_t batch_size)
|
||||
std::string NetworkGroupConfigManager::get_configure_string(const std::string &device_id, const std::string &hef_hash,
|
||||
const char *network_group_name, uint16_t batch_size)
|
||||
{
|
||||
const char *EMPTY_FIELD = "NULL,";
|
||||
std::ostringstream oss;
|
||||
@@ -377,6 +381,8 @@ std::string NetworkGroupConfigManager::get_configure_string(const std::string &d
|
||||
oss << device_id << ",";
|
||||
}
|
||||
|
||||
oss << hef_hash << ",";
|
||||
|
||||
if (nullptr == network_group_name) {
|
||||
oss << EMPTY_FIELD;
|
||||
} else {
|
||||
@@ -388,11 +394,11 @@ std::string NetworkGroupConfigManager::get_configure_string(const std::string &d
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<ActivatedNetworkGroup>> NetworkGroupActivationManager::activate_network_group(const void *element, const std::string &device_id,
|
||||
const char *net_group_name, uint16_t batch_size, std::shared_ptr<ConfiguredNetworkGroup> cng)
|
||||
const std::string &hef_hash, const char *net_group_name, uint16_t batch_size, std::shared_ptr<ConfiguredNetworkGroup> cng)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
std::shared_ptr<ActivatedNetworkGroup> found_ang = get_activated_network_group(device_id, net_group_name, batch_size);
|
||||
std::shared_ptr<ActivatedNetworkGroup> found_ang = get_activated_network_group(device_id, hef_hash, net_group_name, batch_size);
|
||||
if (nullptr != found_ang) {
|
||||
return found_ang;
|
||||
}
|
||||
@@ -402,15 +408,15 @@ Expected<std::shared_ptr<ActivatedNetworkGroup>> NetworkGroupActivationManager::
|
||||
activated_network_group.status());
|
||||
|
||||
std::shared_ptr<ActivatedNetworkGroup> ang = std::move(activated_network_group.release());
|
||||
m_activated_net_groups[NetworkGroupConfigManager::get_configure_string(device_id, net_group_name, batch_size)] = ang;
|
||||
m_activated_net_groups[NetworkGroupConfigManager::get_configure_string(device_id, hef_hash, net_group_name, batch_size)] = ang;
|
||||
|
||||
return ang;
|
||||
}
|
||||
|
||||
std::shared_ptr<ActivatedNetworkGroup> NetworkGroupActivationManager::get_activated_network_group(const std::string &device_id,
|
||||
const char *net_group_name, uint16_t batch_size)
|
||||
const std::string &hef_hef, const char *net_group_name, uint16_t batch_size)
|
||||
{
|
||||
auto found = m_activated_net_groups.find(NetworkGroupConfigManager::get_configure_string(device_id, net_group_name, batch_size));
|
||||
auto found = m_activated_net_groups.find(NetworkGroupConfigManager::get_configure_string(device_id, hef_hef, net_group_name, batch_size));
|
||||
if (found == m_activated_net_groups.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -418,12 +424,12 @@ std::shared_ptr<ActivatedNetworkGroup> NetworkGroupActivationManager::get_activa
|
||||
return found->second;
|
||||
}
|
||||
|
||||
hailo_status NetworkGroupActivationManager::remove_activated_network(const std::string &device_id, const char *net_group_name,
|
||||
uint16_t batch_size)
|
||||
hailo_status NetworkGroupActivationManager::remove_activated_network(const std::string &device_id, const std::string &hef_hash,
|
||||
const char *net_group_name, uint16_t batch_size)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
auto found = m_activated_net_groups.find(NetworkGroupConfigManager::get_configure_string(device_id, net_group_name, batch_size));
|
||||
auto found = m_activated_net_groups.find(NetworkGroupConfigManager::get_configure_string(device_id, hef_hash, net_group_name, batch_size));
|
||||
if (found == m_activated_net_groups.end()) {
|
||||
return HAILO_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -26,32 +26,7 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
class VDeviceManager final
|
||||
{
|
||||
public:
|
||||
VDeviceManager() : m_shared_vdevices(), m_shared_vdevices_scheduling_algorithm(), m_unique_vdevices() {}
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
Expected<std::shared_ptr<VDevice>> create_shared_vdevice(const void *element, const std::string &device_id,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm);
|
||||
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);
|
||||
Expected<std::shared_ptr<VDevice>> create_unique_vdevice(const void *element, uint16_t device_count,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm);
|
||||
Expected<std::shared_ptr<VDevice>> get_vdevice(const std::string &device_id, hailo_scheduling_algorithm_t scheduling_algorithm);
|
||||
|
||||
/* Contains only the shared vdevices (either created by bdf, or with device-count && vdevice-key)
|
||||
Keys are either "<BDF>" or "<device_count>-<vdevice_key>" */
|
||||
std::unordered_map<std::string, std::shared_ptr<VDevice>> m_shared_vdevices;
|
||||
std::unordered_map<std::string, hailo_scheduling_algorithm_t> m_shared_vdevices_scheduling_algorithm; // Used to check that 2 shared vdevices gets the same scheduling-algorithm
|
||||
std::vector<std::shared_ptr<VDevice>> m_unique_vdevices;
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
#include <unordered_set>
|
||||
|
||||
using device_id_t = std::string;
|
||||
using network_name_t = std::string;
|
||||
@@ -62,17 +37,18 @@ class NetworkGroupConfigManager final
|
||||
public:
|
||||
NetworkGroupConfigManager() : m_configured_net_groups() {}
|
||||
Expected<std::shared_ptr<ConfiguredNetworkGroup>> configure_network_group(const void *element, const std::string &device_id,
|
||||
const char *network_group_name, uint16_t batch_size, std::shared_ptr<VDevice> &vdevice, std::shared_ptr<Hef> hef,
|
||||
hailo_scheduling_algorithm_t scheduling_algorithm, const char *network_group_name, uint16_t batch_size, std::shared_ptr<VDevice> &vdevice, std::shared_ptr<Hef> hef,
|
||||
NetworkGroupsParamsMap &net_groups_params_map);
|
||||
hailo_status add_network_to_shared_network_group(const std::string &shared_device_id, const std::string &network_name,
|
||||
const GstElement *owner_element);
|
||||
|
||||
private:
|
||||
static std::string get_configure_string(const std::string &device_id, const char *network_group_name, uint16_t batch_size);
|
||||
static std::string get_configure_string(const std::string &device_id, const std::string &hef_hash,
|
||||
const char *network_group_name, uint16_t batch_size);
|
||||
friend class NetworkGroupActivationManager;
|
||||
|
||||
std::shared_ptr<ConfiguredNetworkGroup> get_configured_network_group(const std::string &device_id, const char *net_group_name,
|
||||
uint16_t batch_size);
|
||||
std::shared_ptr<ConfiguredNetworkGroup> get_configured_network_group(const std::string &device_id, const std::string &hef_hash,
|
||||
const char *net_group_name, uint16_t batch_size);
|
||||
|
||||
// TODO: change this map to store only the shared network_groups (used by multiple hailonets with the same vdevices)
|
||||
std::unordered_map<std::string, std::shared_ptr<ConfiguredNetworkGroup>> m_configured_net_groups;
|
||||
@@ -85,12 +61,12 @@ class NetworkGroupActivationManager final
|
||||
public:
|
||||
NetworkGroupActivationManager() : m_activated_net_groups() {}
|
||||
Expected<std::shared_ptr<ActivatedNetworkGroup>> activate_network_group(const void *element, const std::string &device_id,
|
||||
const char *net_group_name, uint16_t batch_size, std::shared_ptr<ConfiguredNetworkGroup> cng);
|
||||
hailo_status remove_activated_network(const std::string &device_id, const char *net_group_name, uint16_t batch_size);
|
||||
const std::string &hef_hash, const char *net_group_name, uint16_t batch_size, std::shared_ptr<ConfiguredNetworkGroup> cng);
|
||||
hailo_status remove_activated_network(const std::string &device_id, const std::string &hef_hash, const char *net_group_name, uint16_t batch_size);
|
||||
|
||||
private:
|
||||
std::shared_ptr<ActivatedNetworkGroup> get_activated_network_group(const std::string &device_id, const char *net_group_name,
|
||||
uint16_t batch_size);
|
||||
std::shared_ptr<ActivatedNetworkGroup> get_activated_network_group(const std::string &device_id, const std::string &hef_hash,
|
||||
const char *net_group_name, uint16_t batch_size);
|
||||
|
||||
// TODO: change this map to store only the shared network_groups (used by multiple hailonets with the same vdevices)
|
||||
std::unordered_map<std::string, std::shared_ptr<ActivatedNetworkGroup>> m_activated_net_groups;
|
||||
@@ -105,9 +81,9 @@ public:
|
||||
|
||||
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);
|
||||
hailo_status configure_network_group(const char *net_group_name, uint16_t batch_size);
|
||||
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,
|
||||
const std::vector<hailo_format_with_name_t> &output_formats);
|
||||
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();
|
||||
@@ -123,10 +99,12 @@ public:
|
||||
|
||||
private:
|
||||
Expected<NetworkGroupsParamsMap> get_configure_params(Hef &hef, 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);
|
||||
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);
|
||||
|
||||
static VDeviceManager m_vdevice_manager;
|
||||
static std::unordered_set<std::shared_ptr<VDevice>> m_vdevices;
|
||||
static NetworkGroupConfigManager m_net_group_config_manager;
|
||||
static NetworkGroupActivationManager m_net_group_activation_manager;
|
||||
const GstElement *m_element;
|
||||
|
||||
@@ -19,14 +19,16 @@ def main():
|
||||
network_group = network_groups[0]
|
||||
network_group_params = network_group.create_params()
|
||||
input_vstreams_params = InputVStreamParams.make(network_group, quantized=False, format_type=FormatType.FLOAT32)
|
||||
output_vstreams_params = OutputVStreamParams.make(network_group, quantized=True, format_type=FormatType.UINT8)
|
||||
output_vstreams_params = OutputVStreamParams.make(network_group, quantized=True, format_type=FormatType.AUTO)
|
||||
with InferVStreams(network_group, input_vstreams_params, output_vstreams_params) as infer_pipeline:
|
||||
input_names_to_shape = {vstream_info.name: vstream_info.shape for vstream_info in hef.get_input_vstream_infos()}
|
||||
input_data = {name : 1 + np.ndarray([args.num_frames] + list(shape), dtype=np.float32) for name, shape in input_names_to_shape.items()}
|
||||
with network_group.activate(network_group_params):
|
||||
_ = infer_pipeline.infer(input_data)
|
||||
fps = args.num_frames / infer_pipeline.get_hw_time()
|
||||
|
||||
print('Inference ran successfully')
|
||||
print(f'FPS: {fps}')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -24,8 +24,9 @@ from hailo_platform.pyhailort.pyhailort import (HEF, ConfigureParams,
|
||||
Endianness, HailoStreamInterface,
|
||||
InputVStreamParams, OutputVStreamParams,
|
||||
InputVStreams, OutputVStreams,
|
||||
InferVStreams, HailoStreamDirection, HailoFormatFlags, HailoCpuId, VDevice,
|
||||
DvmTypes, PowerMeasurementTypes, SamplingPeriod, AveragingFactor, MeasurementBufferIndex)
|
||||
InferVStreams, HailoStreamDirection, HailoFormatFlags, HailoCpuId, Device, VDevice,
|
||||
DvmTypes, PowerMeasurementTypes, SamplingPeriod, AveragingFactor, MeasurementBufferIndex,
|
||||
HailoRTException)
|
||||
|
||||
def _verify_pyhailort_lib_exists():
|
||||
python_version = "".join(str(i) for i in sys.version_info[:2])
|
||||
@@ -61,4 +62,4 @@ __all__ = ['EthernetDevice', 'DvmTypes', 'PowerMeasurementTypes',
|
||||
'MipiIspImageInOrder', 'MipiIspImageOutDataType', 'join_drivers_path', 'IspLightFrequency', 'HailoPowerMode',
|
||||
'Endianness', 'HailoStreamInterface', 'InputVStreamParams', 'OutputVStreamParams',
|
||||
'InputVStreams', 'OutputVStreams', 'InferVStreams', 'HailoStreamDirection', 'HailoFormatFlags', 'HailoCpuId',
|
||||
'VDevice']
|
||||
'Device', 'VDevice', 'HailoRTException']
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""Control operations for the Hailo hardware device."""
|
||||
import struct
|
||||
import sys
|
||||
import signal
|
||||
|
||||
from builtins import object
|
||||
from abc import ABCMeta, abstractmethod
|
||||
from future.utils import with_metaclass
|
||||
|
||||
from hailo_platform.common.logger.logger import default_logger
|
||||
|
||||
from hailo_platform.pyhailort.hailo_control_protocol import BoardInformation, CoreInformation, DeviceArchitectureTypes, ExtendedDeviceInformation, HealthInformation
|
||||
from hailo_platform.pyhailort.power_measurement import SamplingPeriod, AveragingFactor, DvmTypes, PowerMeasurementTypes, MeasurementBufferIndex, _get_buffer_index_enum_member
|
||||
from hailo_platform.pyhailort.pyhailort import InternalPcieDevice, ExceptionWrapper
|
||||
from hailo_platform.pyhailort.pyhailort import (Control, InternalPcieDevice, ExceptionWrapper, BoardInformation, # noqa F401
|
||||
CoreInformation, DeviceArchitectureTypes, ExtendedDeviceInformation, # noqa F401
|
||||
HealthInformation, SamplingPeriod, AveragingFactor, DvmTypes, # noqa F401
|
||||
PowerMeasurementTypes, MeasurementBufferIndex) # noqa F401
|
||||
|
||||
import hailo_platform.pyhailort._pyhailort as _pyhailort
|
||||
|
||||
@@ -27,655 +19,12 @@ class FirmwareUpdateException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class HailoControl(with_metaclass(ABCMeta, object)):
|
||||
class HailoControl(Control):
|
||||
"""Control object that sends control operations to a Hailo hardware device."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initializes a new HailoControl object."""
|
||||
self._logger = default_logger()
|
||||
self._device = None
|
||||
|
||||
if sys.platform != "win32":
|
||||
signal.pthread_sigmask(signal.SIG_BLOCK, [signal.SIGWINCH])
|
||||
|
||||
@abstractmethod
|
||||
def open(self):
|
||||
"""Initializes the resources needed for using a control device."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def close(self):
|
||||
"""Releases the resources that were allocated for the control device."""
|
||||
pass
|
||||
|
||||
def configure(self, hef, configure_params_by_name={}):
|
||||
"""
|
||||
Configures 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. In case of a mismatch with net_groups_names, default params will
|
||||
be used.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.configure(hef._hef, configure_params_by_name)
|
||||
|
||||
@abstractmethod
|
||||
def chip_reset(self):
|
||||
"""Resets the device (chip reset)."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def read_memory(self, address, data_length):
|
||||
"""Reads memory from the Hailo chip.
|
||||
Byte order isn't changed. The core uses little-endian byte order.
|
||||
|
||||
Args:
|
||||
address (int): Physical address to read from.
|
||||
data_length (int): Size to read in bytes.
|
||||
|
||||
Returns:
|
||||
list of str: Memory read from the chip, each index in the list is a byte.
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def write_memory(self, address, data_buffer):
|
||||
"""Write memory to Hailo chip.
|
||||
Byte order isn't changed. The core uses little-endian byte order.
|
||||
|
||||
Args:
|
||||
address (int): Physical address to write to.
|
||||
data_buffer (list of str): Data to write.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class HcpControl(HailoControl):
|
||||
"""Control object that uses the HCP protocol for controlling the device."""
|
||||
|
||||
WORD_SIZE = 4
|
||||
|
||||
|
||||
def __init__(self):
|
||||
super(HcpControl, self).__init__()
|
||||
|
||||
@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.
|
||||
"""
|
||||
return self._device_id
|
||||
|
||||
def open(self):
|
||||
"""Initializes the resources needed for using a control device."""
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
"""Releases the resources that were allocated for the control device."""
|
||||
pass
|
||||
|
||||
def chip_reset(self):
|
||||
"""Resets the device (chip reset)."""
|
||||
with ExceptionWrapper():
|
||||
return self._device.reset(_pyhailort.ResetDeviceMode.CHIP)
|
||||
|
||||
def nn_core_reset(self):
|
||||
"""Resets the nn_core."""
|
||||
with ExceptionWrapper():
|
||||
return self._device.reset(_pyhailort.ResetDeviceMode.NN_CORE)
|
||||
|
||||
def soft_reset(self):
|
||||
"""reloads the device firmware (soft reset)"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.reset(_pyhailort.ResetDeviceMode.SOFT)
|
||||
|
||||
def forced_soft_reset(self):
|
||||
"""reloads the device firmware (forced soft reset)"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.reset(_pyhailort.ResetDeviceMode.FORCED_SOFT)
|
||||
|
||||
def read_memory(self, address, data_length):
|
||||
"""Reads memory from the Hailo chip. Byte order isn't changed. The core uses little-endian
|
||||
byte order.
|
||||
|
||||
Args:
|
||||
address (int): Physical address to read from.
|
||||
data_length (int): Size to read in bytes.
|
||||
|
||||
Returns:
|
||||
list of str: Memory read from the chip, each index in the list is a byte
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.read_memory(address, data_length)
|
||||
|
||||
def write_memory(self, address, data_buffer):
|
||||
"""Write memory to Hailo chip. Byte order isn't changed. The core uses little-endian byte
|
||||
order.
|
||||
|
||||
Args:
|
||||
address (int): Physical address to write to.
|
||||
data_buffer (list of str): Data to write.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.write_memory(address, data_buffer, len(data_buffer))
|
||||
|
||||
def power_measurement(self, dvm=DvmTypes.AUTO, measurement_type=PowerMeasurementTypes.AUTO):
|
||||
"""Perform a single power measurement on an Hailo chip. It works with the default settings
|
||||
where the sensor returns a new value every 2.2 ms without averaging the values.
|
||||
|
||||
Args:
|
||||
dvm (:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes`):
|
||||
Which DVM will be measured. Default (:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.AUTO`) will be different according to the board: \n
|
||||
Default (:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.AUTO`) for EVB is an approximation to the total power consumption of the chip in PCIe setups.
|
||||
It sums :class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.VDD_CORE`,
|
||||
:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.MIPI_AVDD` and :class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.AVDD_H`.
|
||||
Only :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.POWER` can measured with this option. \n
|
||||
Default (:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.AUTO`) for platforms supporting current monitoring (such as M.2 and mPCIe): :class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.OVERCURRENT_PROTECTION`
|
||||
measurement_type
|
||||
(:class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes`):
|
||||
The type of the measurement.
|
||||
|
||||
Returns:
|
||||
float: The measured power. \n
|
||||
For :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes`: \n
|
||||
- :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.SHUNT_VOLTAGE`: Unit is mV. \n
|
||||
- :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.BUS_VOLTAGE`: Unit is mV. \n
|
||||
- :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.POWER`: Unit is W. \n
|
||||
- :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.CURRENT`: Unit is mA. \n
|
||||
|
||||
|
||||
Note:
|
||||
This function can perform measurements for more than just power. For all supported
|
||||
measurement types, please look at
|
||||
:class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes`.
|
||||
"""
|
||||
if self.device_id.device_architecture != DeviceArchitectureTypes.HAILO8_B0:
|
||||
raise ControlObjectException("Invalid device architecture: {}".format(self.device_id.device_architecture))
|
||||
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):
|
||||
"""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`):
|
||||
Related conversion time, sensor configuration value. The sensor samples the power
|
||||
every ``sampling_period`` [ms] and averages every ``averaging_factor`` samples. The
|
||||
sensor provides a new value every: 2 * sampling_period * averaging_factor [ms]. The
|
||||
firmware wakes up every ``delay`` [ms] and checks the sensor. If there is a new`
|
||||
value to read from the sensor, the firmware reads it. Note that the average
|
||||
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)
|
||||
|
||||
def stop_power_measurement(self):
|
||||
"""Stop performing a long power measurement. Deletes all saved results from the firmware.
|
||||
Calling the function eliminates the start function settings for the averaging the samples,
|
||||
and returns to the default values, so the sensor will return a new value every 2.2 ms
|
||||
without averaging values.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.stop_power_measurement()
|
||||
|
||||
def set_power_measurement(self, buffer_index=MeasurementBufferIndex.MEASUREMENT_BUFFER_INDEX_0, dvm=DvmTypes.AUTO, measurement_type=PowerMeasurementTypes.AUTO):
|
||||
"""Set parameters for long power measurement on an Hailo chip.
|
||||
|
||||
Args:
|
||||
buffer_index (:class:`~hailo_platform.pyhailort.pyhailort.MeasurementBufferIndex`): Index of the buffer on the firmware the data would be saved at.
|
||||
Default is :class:`~hailo_platform.pyhailort.pyhailort.MeasurementBufferIndex.MEASUREMENT_BUFFER_INDEX_0`
|
||||
dvm (:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes`):
|
||||
Which DVM will be measured. Default (:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.AUTO`) will be different according to the board: \n
|
||||
Default (:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.AUTO`) for EVB is an approximation to the total power consumption of the chip in PCIe setups.
|
||||
It sums :class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.VDD_CORE`,
|
||||
:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.MIPI_AVDD` and :class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.AVDD_H`.
|
||||
Only :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.POWER` can measured with this option. \n
|
||||
Default (:class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.AUTO`) for platforms supporting current monitoring (such as M.2 and mPCIe): :class:`~hailo_platform.pyhailort.pyhailort.DvmTypes.OVERCURRENT_PROTECTION`
|
||||
measurement_type
|
||||
(:class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes`):
|
||||
The type of the measurement.
|
||||
|
||||
Note:
|
||||
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)
|
||||
|
||||
def get_power_measurement(self, buffer_index=MeasurementBufferIndex.MEASUREMENT_BUFFER_INDEX_0, should_clear=True):
|
||||
"""Read measured power from a long power measurement
|
||||
|
||||
Args:
|
||||
buffer_index (:class:`~hailo_platform.pyhailort.pyhailort.MeasurementBufferIndex`): Index of the buffer on the firmware the data would be saved at.
|
||||
Default is :class:`~hailo_platform.pyhailort.pyhailort.MeasurementBufferIndex.MEASUREMENT_BUFFER_INDEX_0`
|
||||
should_clear (bool): Flag indicating if the results saved at the firmware will be deleted after reading.
|
||||
|
||||
Returns:
|
||||
:class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementData`:
|
||||
Object containing measurement data \n
|
||||
For :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes`: \n
|
||||
- :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.SHUNT_VOLTAGE`: Unit is mV. \n
|
||||
- :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.BUS_VOLTAGE`: Unit is mV. \n
|
||||
- :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.POWER`: Unit is W. \n
|
||||
- :class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes.CURRENT`: Unit is mA. \n
|
||||
|
||||
Note:
|
||||
This function can perform measurements for more than just power.
|
||||
For all supported measurement types view
|
||||
:class:`~hailo_platform.pyhailort.pyhailort.PowerMeasurementTypes`.
|
||||
"""
|
||||
if self.device_id.device_architecture != DeviceArchitectureTypes.HAILO8_B0:
|
||||
raise ControlObjectException("Invalid device architecture: {}".format(self.device_id.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)
|
||||
|
||||
def _examine_user_config(self):
|
||||
with ExceptionWrapper():
|
||||
return self._device.examine_user_config()
|
||||
|
||||
def read_user_config(self):
|
||||
"""Read the user configuration section as binary data.
|
||||
|
||||
Returns:
|
||||
str: User config as a binary buffer.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.read_user_config()
|
||||
|
||||
def write_user_config(self, configuration):
|
||||
"""Write the user configuration.
|
||||
|
||||
Args:
|
||||
configuration (str): A binary representation of a Hailo device configuration.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.write_user_config(configuration)
|
||||
|
||||
def _erase_user_config(self):
|
||||
with ExceptionWrapper():
|
||||
return self._device.erase_user_config()
|
||||
|
||||
def read_board_config(self):
|
||||
"""Read the board configuration section as binary data.
|
||||
|
||||
Returns:
|
||||
str: Board config as a binary buffer.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.read_board_config()
|
||||
|
||||
def write_board_config(self, configuration):
|
||||
"""Write the static confuration.
|
||||
|
||||
Args:
|
||||
configuration (str): A binary representation of a Hailo device configuration.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.write_board_config(configuration)
|
||||
|
||||
def identify(self):
|
||||
"""Gets the Hailo chip identification.
|
||||
|
||||
Returns:
|
||||
class HailoIdentifyResponse with Protocol version.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
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)
|
||||
return board_information
|
||||
|
||||
def core_identify(self):
|
||||
"""Gets the Core Hailo chip identification.
|
||||
|
||||
Returns:
|
||||
class HailoIdentifyResponse with Protocol version.
|
||||
"""
|
||||
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)
|
||||
return core_information
|
||||
|
||||
def set_fw_logger(self, level, interface_mask):
|
||||
"""Configure logger level and interface of sending.
|
||||
|
||||
Args:
|
||||
level (FwLoggerLevel): The minimum logger level.
|
||||
interface_mask (int): Output interfaces (mix of FwLoggerInterface).
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.set_fw_logger(level, interface_mask)
|
||||
|
||||
def set_throttling_state(self, should_activate):
|
||||
"""Change throttling state of temperature protection component.
|
||||
|
||||
Args:
|
||||
should_activate (bool): Should be true to enable or false to disable.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.set_throttling_state(should_activate)
|
||||
|
||||
def get_throttling_state(self):
|
||||
"""Get the current throttling state of temperature protection component.
|
||||
|
||||
Returns:
|
||||
bool: true if temperature throttling is enabled, false otherwise.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.get_throttling_state()
|
||||
|
||||
def _set_overcurrent_state(self, should_activate):
|
||||
"""Control whether the overcurrent protection is enabled or disabled.
|
||||
|
||||
Args:
|
||||
should_activate (bool): Should be true to enable or false to disable.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device._set_overcurrent_state(should_activate)
|
||||
|
||||
def _get_overcurrent_state(self):
|
||||
"""Get the overcurrent protection state.
|
||||
|
||||
Returns:
|
||||
bool: true if overcurrent protection is enabled, false otherwise.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device._get_overcurrent_state()
|
||||
|
||||
@staticmethod
|
||||
def _create_c_i2c_slave(pythonic_slave):
|
||||
c_slave = _pyhailort.I2CSlaveConfig()
|
||||
c_slave.endianness = pythonic_slave.endianness
|
||||
c_slave.slave_address = pythonic_slave.slave_address
|
||||
c_slave.register_address_size = pythonic_slave.register_address_size
|
||||
c_slave.bus_index = pythonic_slave.bus_index
|
||||
return c_slave
|
||||
|
||||
def i2c_write(self, slave, register_address, data):
|
||||
"""Write data to an I2C slave.
|
||||
|
||||
Args:
|
||||
slave (:class:`hailo_platform.pyhailort.i2c_slaves.I2CSlave`): I2C slave
|
||||
configuration.
|
||||
register_address (int): The address of the register to which the data will be written.
|
||||
data (str): The data that will be written.
|
||||
"""
|
||||
c_slave = HcpControl._create_c_i2c_slave(slave)
|
||||
with ExceptionWrapper():
|
||||
return self._device.i2c_write(c_slave, register_address, data, len(data))
|
||||
|
||||
def i2c_read(self, slave, register_address, data_length):
|
||||
"""Read data from an I2C slave.
|
||||
|
||||
Args:
|
||||
slave (:class:`hailo_platform.pyhailort.i2c_slaves.I2CSlave`): I2C slave
|
||||
configuration.
|
||||
register_address (int): The address of the register from which the data will be read.
|
||||
data_length (int): The number of bytes to read.
|
||||
|
||||
Returns:
|
||||
str: Data read from the I2C slave.
|
||||
"""
|
||||
c_slave = HcpControl._create_c_i2c_slave(slave)
|
||||
with ExceptionWrapper():
|
||||
return self._device.i2c_read(c_slave, register_address, data_length)
|
||||
|
||||
def read_register(self, address):
|
||||
"""Read the value of a register from a given address.
|
||||
|
||||
Args:
|
||||
address (int): Address to read register from.
|
||||
|
||||
Returns:
|
||||
int: Value of the register
|
||||
"""
|
||||
register_value, = struct.unpack('!I', self.read_memory(address, type(self).WORD_SIZE))
|
||||
return register_value
|
||||
|
||||
def set_bit(self, address, bit_index):
|
||||
"""Set (turn on) a specific bit at a register from a given address.
|
||||
|
||||
Args:
|
||||
address (int) : Address of the register to modify.
|
||||
bit_index (int) : Index of the bit that would be set.
|
||||
"""
|
||||
register_value = self.read_register(address)
|
||||
register_value |= 1 << bit_index
|
||||
self.write_memory(address, struct.pack('!I', register_value))
|
||||
|
||||
def reset_bit(self, address, bit_index):
|
||||
"""Reset (turn off) a specific bit at a register from a given address.
|
||||
|
||||
Args:
|
||||
address (int) : Address of the register to modify.
|
||||
bit_index (int) : Index of the bit that would be reset.
|
||||
"""
|
||||
register_value = self.read_register(address)
|
||||
register_value &= ~(1 << bit_index)
|
||||
self.write_memory(address, struct.pack('!I', register_value))
|
||||
|
||||
def firmware_update(self, firmware_binary, should_reset=True):
|
||||
"""Update firmware binary on the flash.
|
||||
|
||||
Args:
|
||||
firmware_binary (bytes): firmware binary stream.
|
||||
should_reset (bool): Should a reset be performed after the update (to load the new firmware)
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.firmware_update(firmware_binary, len(firmware_binary), should_reset)
|
||||
|
||||
def second_stage_update(self, second_stage_binary):
|
||||
"""Update second stage binary on the flash
|
||||
|
||||
Args:
|
||||
second_stage_binary (bytes): second stage binary stream.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.second_stage_update(second_stage_binary, len(second_stage_binary))
|
||||
|
||||
def store_sensor_config(self, section_index, reset_data_size, sensor_type, config_file_path,
|
||||
config_height=0, config_width=0, config_fps=0, config_name=None):
|
||||
|
||||
"""Store sensor configuration to Hailo chip flash memory.
|
||||
|
||||
Args:
|
||||
section_index (int): Flash section index to write to. [0-6]
|
||||
reset_data_size (int): Size of reset configuration.
|
||||
sensor_type (:class:`~hailo_platform.pyhailort.pyhailort.SensorConfigTypes`): Sensor type.
|
||||
config_file_path (str): Sensor configuration file path.
|
||||
config_height (int): Configuration resolution height.
|
||||
config_width (int): Configuration resolution width.
|
||||
config_fps (int): Configuration FPS.
|
||||
config_name (str): Sensor configuration name.
|
||||
"""
|
||||
if config_name is None:
|
||||
config_name = "UNINITIALIZED"
|
||||
|
||||
with ExceptionWrapper():
|
||||
return self._device.sensor_store_config(section_index, reset_data_size, sensor_type, config_file_path,
|
||||
config_height, config_width, config_fps, config_name)
|
||||
|
||||
def store_isp_config(self, reset_config_size, isp_static_config_file_path, isp_runtime_config_file_path,
|
||||
config_height=0, config_width=0, config_fps=0, config_name=None):
|
||||
"""Store sensor isp configuration to Hailo chip flash memory.
|
||||
|
||||
Args:
|
||||
reset_config_size (int): Size of reset configuration.
|
||||
isp_static_config_file_path (str): Sensor isp static configuration file path.
|
||||
isp_runtime_config_file_path (str): Sensor isp runtime configuration file path.
|
||||
config_height (int): Configuration resolution height.
|
||||
config_width (int): Configuration resolution width.
|
||||
config_fps (int): Configuration FPS.
|
||||
config_name (str): Sensor configuration name.
|
||||
"""
|
||||
if config_name is None:
|
||||
config_name = "UNINITIALIZED"
|
||||
|
||||
with ExceptionWrapper():
|
||||
return self._device.store_isp_config(reset_config_size, config_height, config_width,
|
||||
config_fps, isp_static_config_file_path, isp_runtime_config_file_path, config_name)
|
||||
|
||||
def get_sensor_sections_info(self):
|
||||
"""Get sensor sections info from Hailo chip flash memory.
|
||||
|
||||
Returns:
|
||||
Sensor sections info read from the chip flash memory.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.sensor_get_sections_info()
|
||||
|
||||
def sensor_set_generic_i2c_slave(self, slave_address, register_address_size, bus_index, should_hold_bus, endianness):
|
||||
"""Set a generic I2C slave for sensor usage.
|
||||
|
||||
Args:
|
||||
sequence (int): Request/response sequence.
|
||||
slave_address (int): The address of the I2C slave.
|
||||
register_address_size (int): The size of the offset (in bytes).
|
||||
bus_index (int): The number of the bus the I2C slave is behind.
|
||||
should_hold_bus (bool): Hold the bus during the read.
|
||||
endianness (:class:`~hailo_platform.pyhailort.pyhailort.Endianness`):
|
||||
Big or little endian.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.sensor_set_generic_i2c_slave(slave_address, register_address_size, bus_index, should_hold_bus, endianness)
|
||||
|
||||
def set_sensor_i2c_bus_index(self, sensor_type, i2c_bus_index):
|
||||
"""Set the I2C bus to which the sensor of the specified type is connected.
|
||||
|
||||
Args:
|
||||
sensor_type (:class:`~hailo_platform.pyhailort.pyhailort.SensorConfigTypes`): The sensor type.
|
||||
i2c_bus_index (int): The I2C bus index of the sensor.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.sensor_set_i2c_bus_index(sensor_type, i2c_bus_index)
|
||||
|
||||
def load_and_start_sensor(self, section_index):
|
||||
"""Load the configuration with I2C in the section index.
|
||||
|
||||
Args:
|
||||
section_index (int): Flash section index to load config from. [0-6]
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.sensor_load_and_start_config(section_index)
|
||||
|
||||
def reset_sensor(self, section_index):
|
||||
"""Reset the sensor that is related to the section index config.
|
||||
|
||||
Args:
|
||||
section_index (int): Flash section index to reset. [0-6]
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.sensor_reset(section_index)
|
||||
|
||||
def wd_enable(self, cpu_id):
|
||||
"""Enable firmware watchdog.
|
||||
|
||||
Args:
|
||||
cpu_id (:class:`~hailo_platform.pyhailort.pyhailort.HailoCpuId`): 0 for App CPU, 1 for Core CPU.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.wd_enable(cpu_id)
|
||||
|
||||
def wd_disable(self, cpu_id):
|
||||
"""Disable firmware watchdog.
|
||||
|
||||
Args:
|
||||
cpu_id (:class:`~hailo_platform.pyhailort.pyhailort.HailoCpuId`): 0 for App CPU, 1 for Core CPU.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.wd_disable(cpu_id)
|
||||
|
||||
def wd_config(self, cpu_id, wd_cycles, wd_mode):
|
||||
"""Configure a firmware watchdog.
|
||||
|
||||
Args:
|
||||
cpu_id (:class:`~hailo_platform.pyhailort.pyhailort.HailoCpuId`): 0 for App CPU, 1 for Core CPU.
|
||||
wd_cycles (int): number of cycles until watchdog is triggered.
|
||||
wd_mode (int): 0 - HW/SW mode, 1 - HW only mode
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.wd_config(cpu_id, wd_cycles, wd_mode)
|
||||
|
||||
def previous_system_state(self, cpu_id):
|
||||
"""Read the FW previous system state.
|
||||
|
||||
Args:
|
||||
cpu_id (:class:`~hailo_platform.pyhailort.pyhailort.HailoCpuId`): 0 for App CPU, 1 for Core CPU.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.previous_system_state(cpu_id)
|
||||
|
||||
def get_chip_temperature(self):
|
||||
"""Returns the latest temperature measurements from the 2 internal temperature sensors of the Hailo chip.
|
||||
|
||||
Returns:
|
||||
:class:`~hailo_platform.pyhailort.pyhailort.TemperatureInfo`:
|
||||
Temperature in celsius of the 2 internal temperature sensors (TS), and a sample
|
||||
count (a running 16-bit counter)
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.get_chip_temperature()
|
||||
|
||||
def get_extended_device_information(self):
|
||||
with ExceptionWrapper():
|
||||
response = self._device.get_extended_device_information()
|
||||
device_information = ExtendedDeviceInformation(response.neural_network_core_clock_rate,
|
||||
response.supported_features, response.boot_source, response.lcs, response.soc_id, response.eth_mac_address , response.unit_level_tracking_id, response.soc_pm_values)
|
||||
return device_information
|
||||
|
||||
def _get_health_information(self):
|
||||
with ExceptionWrapper():
|
||||
response = self._device._get_health_information()
|
||||
health_information = HealthInformation(response.overcurrent_protection_active, response.current_overcurrent_zone, response.red_overcurrent_threshold,
|
||||
response.orange_overcurrent_threshold, response.temperature_throttling_active, response.current_temperature_zone, response.current_temperature_throttling_level,
|
||||
response.temperature_throttling_levels, response.orange_temperature_threshold, response.orange_hysteresis_temperature_threshold,
|
||||
response.red_temperature_threshold, response.red_hysteresis_temperature_threshold)
|
||||
return health_information
|
||||
|
||||
def set_pause_frames(self, rx_pause_frames_enable):
|
||||
"""Enable/Disable Pause frames.
|
||||
|
||||
Args:
|
||||
rx_pause_frames_enable (bool): False for disable, True for enable.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.set_pause_frames(rx_pause_frames_enable)
|
||||
|
||||
def test_chip_memories(self):
|
||||
"""test all chip memories using smart BIST
|
||||
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.test_chip_memories()
|
||||
|
||||
def _get_device_handle(self):
|
||||
return self._device
|
||||
|
||||
class UdpHcpControl(HcpControl):
|
||||
"""Control object that uses a HCP over UDP controller interface."""
|
||||
|
||||
@@ -688,58 +37,32 @@ class UdpHcpControl(HcpControl):
|
||||
response_timeout_seconds (float, optional): Number of seconds to wait until a response is received.
|
||||
ignore_socket_errors (bool, optional): Ignore socket error (might be usefull for debugging).
|
||||
"""
|
||||
super(UdpHcpControl, self).__init__()
|
||||
|
||||
# In the C API we define the total amount of attempts, instead of the amount of retries.
|
||||
max_number_of_attempts = retries + 1
|
||||
response_timeout_milliseconds = int(response_timeout_seconds * 1000)
|
||||
if device is None:
|
||||
with ExceptionWrapper():
|
||||
self.device = _pyhailort.Device.create_eth(remote_ip, remote_control_port,
|
||||
device = _pyhailort.Device.create_eth(remote_ip, remote_control_port,
|
||||
response_timeout_milliseconds, max_number_of_attempts)
|
||||
else:
|
||||
self._device = device.device
|
||||
self._device_id = self.identify()
|
||||
# Needs to get the _pyhailort.Device object
|
||||
device = device.device
|
||||
|
||||
super().__init__(device)
|
||||
|
||||
class PcieHcpControl(HcpControl):
|
||||
"""Control object that uses a HCP over PCIe controller interface."""
|
||||
|
||||
def __init__(self, device=None, device_info=None):
|
||||
"""Initializes a new HailoPcieController object."""
|
||||
super(PcieHcpControl, self).__init__()
|
||||
|
||||
if device_info is None:
|
||||
device_info = InternalPcieDevice.scan_devices()[0]
|
||||
|
||||
if device is None:
|
||||
with ExceptionWrapper():
|
||||
self._device = _pyhailort.Device.create_pcie(device_info)
|
||||
device = _pyhailort.Device.create_pcie(device_info)
|
||||
else:
|
||||
self._device = device.device
|
||||
self._device_id = self.identify()
|
||||
|
||||
def set_notification_callback(self, callback_func, notification_id, opaque):
|
||||
"""Set a callback function to be called when a notification is received.
|
||||
# Needs to get the _pyhailort.Device object
|
||||
device = device.device
|
||||
|
||||
Args:
|
||||
callback_func (function): Callback function with the parameters (device, notification, opaque).
|
||||
Note that throwing exceptions is not supported and will cause the program to terminate with an error!
|
||||
notification_id (NotificationId): Notification ID to register the callback to.
|
||||
opauqe (object): User defined data.
|
||||
|
||||
Note:
|
||||
The notifications thread is started and closed in the use_device() context, so
|
||||
notifications can only be received there.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.set_notification_callback(callback_func, notification_id, opaque)
|
||||
|
||||
def remove_notification_callback(self, notification_id):
|
||||
"""Remove a notification callback which was already set.
|
||||
|
||||
Args:
|
||||
notification_id (NotificationId): Notification ID to remove the callback from.
|
||||
"""
|
||||
with ExceptionWrapper():
|
||||
return self._device.remove_notification_callback(notification_id)
|
||||
super().__init__(device)
|
||||
|
||||
@@ -4,320 +4,9 @@
|
||||
:synopsis: Implements a Hailo Control Protocol message.
|
||||
"""
|
||||
|
||||
from builtins import object
|
||||
from enum import Enum, IntEnum
|
||||
|
||||
import struct
|
||||
|
||||
# Supported protocol and Firmware version of current SDK.
|
||||
SUPPORTED_PROTOCOL_VERSION = 2
|
||||
SUPPORTED_FW_MAJOR = 4
|
||||
SUPPORTED_FW_MINOR = 8
|
||||
SUPPORTED_FW_REVISION = 1
|
||||
|
||||
MEGA_MULTIPLIER = 1000.0 * 1000.0
|
||||
|
||||
|
||||
class HailoControlProtocolException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class DeviceArchitectureTypes(IntEnum):
|
||||
HAILO8_A0 = 0
|
||||
HAILO8_B0 = 1
|
||||
MERCURY_CA = 2
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
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):
|
||||
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.logger_version = logger_version
|
||||
self.board_name = board_name
|
||||
self.is_release = is_release
|
||||
self.device_architecture = DeviceArchitectureTypes(device_architecture)
|
||||
self.serial_number = serial_number
|
||||
self.part_number = part_number
|
||||
self.product_name = product_name
|
||||
|
||||
def _string_field_str(self, string_field):
|
||||
# Return <Not Configured> if the string field is empty
|
||||
return string_field.rstrip('\x00') or "<Not Configured>"
|
||||
|
||||
def __str__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
return 'Control Protocol Version: {}\n' \
|
||||
'Firmware Version: {}\n' \
|
||||
'Logger Version: {}\n' \
|
||||
'Board Name: {}\n' \
|
||||
'Device Architecture: {}\n' \
|
||||
'Serial Number: {}\n' \
|
||||
'Part Number: {}\n' \
|
||||
'Product Name: {}\n'.format(
|
||||
self.protocol_version,
|
||||
self.firmware_version,
|
||||
self.logger_version,
|
||||
self.board_name.rstrip('\x00'),
|
||||
str(self.device_architecture),
|
||||
self._string_field_str(self.serial_number),
|
||||
self._string_field_str(self.part_number),
|
||||
self._string_field_str(self.product_name))
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
return self.__str__()
|
||||
|
||||
@staticmethod
|
||||
def get_hw_arch_str(device_arch):
|
||||
if device_arch == DeviceArchitectureTypes.HAILO8_B0:
|
||||
return 'hailo8'
|
||||
elif device_arch == DeviceArchitectureTypes.MERCURY_CA:
|
||||
return 'mercury'
|
||||
else:
|
||||
raise HailoControlProtocolException("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)
|
||||
self.is_release = is_release
|
||||
|
||||
def __str__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
return 'Core Firmware Version: {}'.format(
|
||||
self.firmware_version)
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
return self.__str__()
|
||||
|
||||
class TemperatureThrottlingLevel(object):
|
||||
def __init__(self, level_number, temperature_threshold, hysteresis_temperature_threshold, throttling_nn_clock_freq):
|
||||
self.level_number = level_number
|
||||
self.temperature_threshold = temperature_threshold
|
||||
self.hysteresis_temperature_threshold = hysteresis_temperature_threshold
|
||||
self.throttling_nn_clock_freq = throttling_nn_clock_freq
|
||||
|
||||
def __str__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
return 'Temperature Throttling Level {}: \n' \
|
||||
'Temperature Threshold: {}\n' \
|
||||
'Hysteresis Temperature Threshold: {}\n' \
|
||||
'Throttling NN Clock Frequency: {}\n' \
|
||||
.format(self.level_number, self.temperature_threshold, self.hysteresis_temperature_threshold, self.throttling_nn_clock_freq)
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
class HealthInformation(object):
|
||||
def __init__(self, overcurrent_protection_active, current_overcurrent_zone, red_overcurrent_threshold, orange_overcurrent_threshold,
|
||||
temperature_throttling_active, current_temperature_zone, current_temperature_throttling_level,
|
||||
temperature_throttling_levels, orange_temperature_threshold, orange_hysteresis_temperature_threshold,
|
||||
red_temperature_threshold, red_hysteresis_temperature_threshold):
|
||||
self.overcurrent_protection_active = overcurrent_protection_active
|
||||
self.current_overcurrent_zone = current_overcurrent_zone
|
||||
self.red_overcurrent_threshold = red_overcurrent_threshold
|
||||
self.orange_overcurrent_threshold = orange_overcurrent_threshold
|
||||
self.temperature_throttling_active = temperature_throttling_active
|
||||
self.current_temperature_zone = current_temperature_zone
|
||||
self.current_temperature_throttling_level = current_temperature_throttling_level
|
||||
self.orange_temperature_threshold = orange_temperature_threshold
|
||||
self.orange_hysteresis_temperature_threshold = orange_hysteresis_temperature_threshold
|
||||
self.red_temperature_threshold = red_temperature_threshold
|
||||
self.red_hysteresis_temperature_threshold = red_hysteresis_temperature_threshold
|
||||
|
||||
# Add TemperatureThrottlingLevel in case it has new throttling_nn_clock_freq. level_number can be used as only last
|
||||
# levels can be with the same freq
|
||||
self.temperature_throttling_levels = []
|
||||
if self.temperature_throttling_active:
|
||||
throttling_nn_clock_frequencies = []
|
||||
for level_number, temperature_throttling_level in enumerate(temperature_throttling_levels):
|
||||
if temperature_throttling_level.throttling_nn_clock_freq not in throttling_nn_clock_frequencies:
|
||||
throttling_nn_clock_frequencies.append(temperature_throttling_level.throttling_nn_clock_freq)
|
||||
self.temperature_throttling_levels.append(TemperatureThrottlingLevel(level_number,
|
||||
temperature_throttling_level.temperature_threshold,
|
||||
temperature_throttling_level.hysteresis_temperature_threshold,
|
||||
temperature_throttling_level.throttling_nn_clock_freq))
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __str__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
temperature_throttling_levels_str = "\n".join(["\n\n{}\n".format(str(temperature_throttling_level)) for temperature_throttling_level in self.temperature_throttling_levels]) \
|
||||
if self.temperature_throttling_active else "<Temperature throttling is disabled>"
|
||||
return 'Overcurrent Protection Active: {}\n' \
|
||||
'Overcurrent Protection Current Overcurrent Zone: {}\n' \
|
||||
'Overcurrent Protection Red Threshold: {}\n' \
|
||||
'Overcurrent Protection Orange Threshold: {}\n' \
|
||||
'Temperature Protection Red Threshold: {}\n' \
|
||||
'Temperature Protection Red Hysteresis Threshold: {}\n' \
|
||||
'Temperature Protection Orange Threshold: {}\n' \
|
||||
'Temperature Protection Orange Hysteresis Threshold: {}\n' \
|
||||
'Temperature Protection Throttling State: {}\n' \
|
||||
'Temperature Protection Current Zone: {}\n' \
|
||||
'Temperature Protection Current Throttling Level: {}\n' \
|
||||
'Temperature Protection Throttling Levels: {}' \
|
||||
.format(self.overcurrent_protection_active, self.current_overcurrent_zone, self.red_overcurrent_threshold,
|
||||
self.orange_overcurrent_threshold, self.red_temperature_threshold,
|
||||
self.red_hysteresis_temperature_threshold, self.orange_temperature_threshold,
|
||||
self.orange_hysteresis_temperature_threshold, self.temperature_throttling_active,
|
||||
self.current_temperature_zone, self.current_temperature_throttling_level, temperature_throttling_levels_str)
|
||||
|
||||
class ExtendedDeviceInformation(object):
|
||||
def __init__(self, neural_network_core_clock_rate, supported_features, boot_source, lcs, soc_id, eth_mac_address, unit_level_tracking_id, soc_pm_values):
|
||||
self.neural_network_core_clock_rate = neural_network_core_clock_rate
|
||||
self.supported_features = SupportedFeatures(supported_features)
|
||||
self.boot_source = boot_source
|
||||
self.lcs = lcs
|
||||
self.soc_id = soc_id
|
||||
self.eth_mac_address = eth_mac_address
|
||||
self.unit_level_tracking_id = unit_level_tracking_id
|
||||
self.soc_pm_values = soc_pm_values
|
||||
|
||||
def __str__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
string = 'Neural Network Core Clock Rate: {}MHz\n' \
|
||||
'{}' \
|
||||
'Boot source: {}\n' \
|
||||
'LCS: {}\n'.format(
|
||||
self.neural_network_core_clock_rate / MEGA_MULTIPLIER,
|
||||
str(self.supported_features),
|
||||
str(self.boot_source.name),
|
||||
str(self.lcs))
|
||||
if any(self.soc_id):
|
||||
string += 'SoC ID: ' + (self.soc_id.hex())
|
||||
|
||||
if any(self.eth_mac_address):
|
||||
string += '\nMAC Address: ' + (":".join("{:02X}".format(i) for i in self.eth_mac_address))
|
||||
|
||||
if any(self.unit_level_tracking_id):
|
||||
string += '\nULT ID: ' + (self.unit_level_tracking_id.hex())
|
||||
|
||||
if any(self.soc_pm_values):
|
||||
string += '\nPM Values: ' + (self.soc_pm_values.hex())
|
||||
|
||||
|
||||
return string
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
return self.__str__()
|
||||
|
||||
class HailoFirmwareMode(Enum):
|
||||
"""Indication that firmware version is stable and official """
|
||||
DEVELOP = 'develop'
|
||||
RELEASE = 'release'
|
||||
|
||||
|
||||
class HailoFirmwareType(Enum):
|
||||
"""Indication the firmware type """
|
||||
CORE = 'core'
|
||||
APP = 'app'
|
||||
|
||||
|
||||
class HailoFirmwareVersion(object):
|
||||
"""Represents a Hailo chip firmware version."""
|
||||
DEV_BIT = 0x80000000
|
||||
CORE_BIT = 0x08000000
|
||||
FW_VERSION_FORMAT = '<III'
|
||||
|
||||
def __init__(self, firmware_version_buffer, is_release, 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
|
||||
"""
|
||||
self.major, self.minor, self.revision = struct.unpack(
|
||||
self.FW_VERSION_FORMAT,
|
||||
firmware_version_buffer)
|
||||
|
||||
self.fw_type = fw_type
|
||||
self.mode = HailoFirmwareMode.RELEASE if is_release else HailoFirmwareMode.DEVELOP
|
||||
|
||||
self.revision &= ~(self.CORE_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)
|
||||
|
||||
@classmethod
|
||||
def construct_from_params(cls, major, minor, revision, is_release, 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)
|
||||
|
||||
@property
|
||||
def comparable_value(self):
|
||||
"""A value that could be compared to other firmware versions."""
|
||||
return (self.major << 64) + (self.minor << 32) + (self.revision)
|
||||
|
||||
def __hash__(self):
|
||||
return self.comparable_value
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.comparable_value == other.comparable_value
|
||||
|
||||
# TODO: Required for Python2 BW compatibility (SDK-10038)
|
||||
# This impl' comes by default in Python3
|
||||
def __ne__(self, other):
|
||||
return not (self == other)
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.comparable_value < other.comparable_value
|
||||
|
||||
def check_protocol_compatibility(self, other):
|
||||
return ((self.major == other.major) and (self.minor == other.minor))
|
||||
|
||||
class SupportedFeatures(object):
|
||||
def __init__(self, supported_features):
|
||||
self.ethernet = supported_features.ethernet
|
||||
self.mipi = supported_features.mipi
|
||||
self.pcie = supported_features.pcie
|
||||
self.current_monitoring = supported_features.current_monitoring
|
||||
self.mdio = supported_features.mdio
|
||||
|
||||
def _feature_str(self, feature_name, is_feature_enabled):
|
||||
return '{}: {}\n'.format(feature_name, 'Enabled' if is_feature_enabled else 'Disabled')
|
||||
|
||||
def __str__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
return 'Device supported features: \n' + \
|
||||
self._feature_str('Ethernet', self.ethernet) + \
|
||||
self._feature_str('MIPI', self.mipi) + \
|
||||
self._feature_str('PCIE', self.pcie) + \
|
||||
self._feature_str('Current Monitoring', self.current_monitoring) + \
|
||||
self._feature_str('MDIO', self.mdio)
|
||||
|
||||
def __repr__(self):
|
||||
"""Returns:
|
||||
str: Human readable string.
|
||||
"""
|
||||
return self.__str__()
|
||||
|
||||
def _is_feature_enabled(self, feature):
|
||||
return (self.supported_features & feature) != 0
|
||||
from hailo_platform.pyhailort.pyhailort import (SUPPORTED_PROTOCOL_VERSION, SUPPORTED_FW_MAJOR, SUPPORTED_FW_MINOR, # noqa F401
|
||||
SUPPORTED_FW_REVISION, DeviceArchitectureTypes, ExtendedDeviceInformation, BoardInformation, # noqa F401
|
||||
CoreInformation, TemperatureThrottlingLevel, HealthInformation, HailoFirmwareMode, HailoFirmwareType, # noqa F401
|
||||
HailoFirmwareVersion, SupportedFeatures) # noqa F401
|
||||
import warnings
|
||||
warnings.warn('Importing hailo_control_protocol directly is deprecated. One should use direct hailo_platform instead')
|
||||
|
||||
@@ -10,9 +10,9 @@ from contextlib import contextmanager
|
||||
|
||||
from hailo_platform.pyhailort.control_object import UdpHcpControl, PcieHcpControl
|
||||
from hailo_platform.common.logger.logger import default_logger
|
||||
from hailo_platform.pyhailort.hailo_control_protocol import BoardInformation
|
||||
|
||||
from hailo_platform.pyhailort.pyhailort import ConfiguredNetwork, InternalEthernetDevice, InternalPcieDevice, HailoRTTransformUtils, HailoUdpScan, HailoRTException
|
||||
from hailo_platform.pyhailort.pyhailort import (ConfiguredNetwork, InternalEthernetDevice, InternalPcieDevice,
|
||||
HailoRTTransformUtils, HailoUdpScan, HailoRTException, BoardInformation)
|
||||
|
||||
|
||||
class InferenceTargets(object):
|
||||
@@ -385,7 +385,7 @@ class EthernetDevice(HailoChipObject):
|
||||
self._open_device()
|
||||
|
||||
self._id = "{}".format(self._remote_ip)
|
||||
identity = self._control_object._device_id
|
||||
identity = self._control_object._identify_info
|
||||
self._hw_arch = BoardInformation.get_hw_arch_str(identity.device_architecture)
|
||||
|
||||
@staticmethod
|
||||
@@ -450,7 +450,7 @@ class PcieDevice(HailoChipObject):
|
||||
|
||||
# At this point self._device_info is already initialized
|
||||
self._id = "{}".format(self._device_info)
|
||||
identity = self._control_object._device_id
|
||||
identity = self._control_object._identify_info
|
||||
self._hw_arch = BoardInformation.get_hw_arch_str(identity.device_architecture)
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
from hailo_platform.pyhailort.pyhailort import (DvmTypes, PowerMeasurementTypes, # noqa F401
|
||||
SamplingPeriod, AveragingFactor,
|
||||
HailoPowerMeasurementUtils, MeasurementBufferIndex, HailoRTException)
|
||||
|
||||
# https://github.com/pybind/pybind11/issues/253
|
||||
import re
|
||||
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")
|
||||
SamplingPeriod, AveragingFactor,
|
||||
HailoPowerMeasurementUtils, MeasurementBufferIndex, HailoRTException)
|
||||
import warnings
|
||||
warnings.warn('Importing power_measurements directly is deprecated. One should use direct hailo_platform instead')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -45,7 +45,8 @@
|
||||
"temperature_orange_threshold": {"size": 1, "deserialize_as": "int"},
|
||||
"temperature_orange_hysteresis_threshold": {"size": 1, "deserialize_as": "int"},
|
||||
"temperature_throttling_enable": {"size": 1, "deserialize_as": "bool"},
|
||||
"overcurrent_monitoring_orange_threshold_enable": {"size": 1, "deserialize_as": "bool"}
|
||||
"deprecated__overcurrent_monitoring_orange_threshold_enable": {"size": 1, "deserialize_as": "bool"},
|
||||
"overcurrent_throttling_enable": {"size": 1, "deserialize_as": "bool"}
|
||||
}
|
||||
},
|
||||
"control":
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import os
|
||||
import subprocess
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
import hailo_platform
|
||||
from hailo_platform.tools.hailocli.base_utils import HailortCliUtil
|
||||
import pkg_resources
|
||||
|
||||
"""
|
||||
HailoRTCLI matching commands in Hailo-CLI tool.
|
||||
@@ -67,4 +73,63 @@ class SSBUpdaterCLI(HailortCliUtil):
|
||||
class UDPRateLimiterCLI(HailortCliUtil):
|
||||
"""CLI tool for UDP rate limitation."""
|
||||
def __init__(self, parser):
|
||||
super().__init__(parser, 'udp-rate-limiter')
|
||||
super().__init__(parser, 'udp-rate-limiter')
|
||||
|
||||
|
||||
class TutorialRequired(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TutorialRunnerCLI():
|
||||
|
||||
TUTORIALS_DIR = os.path.join(pathlib.Path(hailo_platform.__file__).parent.parent, 'hailo_tutorials/notebooks/')
|
||||
TUTORIALS_REQUIREMENTS = ["jupyter"]
|
||||
ERROR_MSG = """
|
||||
Jupyter or one of its dependencies are not installed in this Python environment. These packages
|
||||
are not mandatory for pyHailoRT itself, but they are required in order to run the Python API tutorial
|
||||
notebooks. Please run the following command to install the missing Python packages:
|
||||
"""
|
||||
|
||||
def __init__(self, parser):
|
||||
parser.add_argument('--ip', type=str, default=None, help='the ip parameter passed to jupyter-notebook.')
|
||||
parser.add_argument('--port', type=str, default=None, help='the port parameter passed to jupyter-notebook.')
|
||||
parser.set_defaults(func=self.run)
|
||||
|
||||
def _check_requirements(self):
|
||||
missing_pkgs = []
|
||||
working_set = pkg_resources.WorkingSet()
|
||||
for req in self.TUTORIALS_REQUIREMENTS:
|
||||
try:
|
||||
working_set.require(req)
|
||||
except pkg_resources.DistributionNotFound:
|
||||
missing_pkgs.append(req)
|
||||
|
||||
if missing_pkgs:
|
||||
sys.tracebacklimit = 0
|
||||
raise TutorialRequired(f"\n{self.ERROR_MSG}\n {'; '.join([f'pip install {pkg}' for pkg in missing_pkgs])}")
|
||||
|
||||
def run(self, args):
|
||||
self._check_requirements()
|
||||
exec_string = f'jupyter-notebook {self.TUTORIALS_DIR}'
|
||||
if args.ip is not None:
|
||||
exec_string += f" --ip={args.ip}"
|
||||
|
||||
if args.port is not None:
|
||||
exec_string += f" --port={args.port}"
|
||||
|
||||
return subprocess.run(
|
||||
exec_string,
|
||||
shell=True,
|
||||
check=True,
|
||||
env=os.environ.copy(),
|
||||
)
|
||||
|
||||
|
||||
class ParseHEFCommandCLI(HailortCliUtil):
|
||||
def __init__(self, parser):
|
||||
super().__init__(parser, 'parse-hef')
|
||||
|
||||
|
||||
class MonitorCommandCLI(HailortCliUtil):
|
||||
def __init__(self, parser):
|
||||
super().__init__(parser, 'monitor')
|
||||
|
||||
@@ -8,7 +8,8 @@ import hailo_platform
|
||||
from hailo_platform.tools.hailocli.base_utils import HailortCliUtil, Helper, HailortCliUtilError
|
||||
from hailo_platform.tools.hailocli.hailocli_commands import (FWUpdaterCLI, SSBUpdaterCLI, ControlCommandCLI, ScanCommandCLI,
|
||||
LoggerCommandCLI, MeasurePowerCommandCLI, RunCommandCLI, SensorConfigCommandCLI,
|
||||
FWConfigCommandCLI, BenchmarkCommandCLI, UDPRateLimiterCLI)
|
||||
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:
|
||||
@@ -18,19 +19,23 @@ class PlatformCommands:
|
||||
'fw-update': ('Firmware update tool', FWUpdaterCLI),
|
||||
'ssb-update': ('Second stage boot update tool', SSBUpdaterCLI),
|
||||
'fw-config': ('Firmware configuration tool', FWConfigCommandCLI),
|
||||
'udp-limiter': ('UDP rate limitation tool', UDPRateLimiterCLI),
|
||||
'udp': ('Alias to udp-limiter', UDPRateLimiterCLI),
|
||||
'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),
|
||||
'scan': ('Scans for devices (Ethernet or PCIE)', ScanCommandCLI),
|
||||
'sensor-config': ('Sensor configuration tool', SensorConfigCommandCLI),
|
||||
'run': ('Run a compiled network', RunCommandCLI),
|
||||
'benchmark': ('Measure basic performance on compiled network', BenchmarkCommandCLI),
|
||||
'monitor': ("Monitor of networks - Presents information about the running networks. To enable monitor, set in the application process the environment variable 'SCHEDULER_MONITOR' to 1.", MonitorCommandCLI),
|
||||
'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),
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.parser = argparse.ArgumentParser(description=self._get_description())
|
||||
self.parser = argparse.ArgumentParser(description=self._get_generic_description())
|
||||
self.subparsers = self.parser.add_subparsers(help='Hailo utilities aimed to help with everything you need')
|
||||
self.COMMANDS = {}
|
||||
self.COMMANDS.update(type(self).PLATFORM_COMMANDS)
|
||||
@@ -46,6 +51,10 @@ class PlatformCommands:
|
||||
def _get_description():
|
||||
return 'Hailo Platform SW v{} command line utilities'.format(hailo_platform.__version__)
|
||||
|
||||
@staticmethod
|
||||
def _get_generic_description():
|
||||
return 'Hailo Command Line Utility'
|
||||
|
||||
def run(self):
|
||||
argv = sys.argv[1:]
|
||||
return self._run(argv)
|
||||
@@ -70,6 +79,10 @@ 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 :
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"core HW, using HailoRT. This way we can use the Hailo hardware without Tensorflow, and\n",
|
||||
"even without the Hailo SDK (after the HEF is built).\n",
|
||||
"\n",
|
||||
"An HEF is Hailo’s binary format for neural networks. The HEF files contain:\n",
|
||||
"An HEF is Hailo's binary format for neural networks. The HEF files contain:\n",
|
||||
"\n",
|
||||
"* Target HW configuration\n",
|
||||
"* Weights\n",
|
||||
|
||||
@@ -68,6 +68,6 @@ if __name__ == "__main__":
|
||||
"linux_aarch64",
|
||||
],
|
||||
url="https://hailo.ai/",
|
||||
version="4.8.1",
|
||||
version="4.10.0",
|
||||
zip_safe=False,
|
||||
)
|
||||
|
||||
@@ -19,6 +19,7 @@ pybind11_add_module(_pyhailort
|
||||
device_api.cpp
|
||||
hef_api.cpp
|
||||
vstream_api.cpp
|
||||
quantization_api.cpp
|
||||
${HAILORT_COMMON_CPP_SOURCES}
|
||||
)
|
||||
|
||||
|
||||
@@ -14,6 +14,20 @@
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
std::vector<std::string> DeviceWrapper::scan()
|
||||
{
|
||||
auto device_ids = Device::scan();
|
||||
VALIDATE_EXPECTED(device_ids);
|
||||
return device_ids.release();
|
||||
}
|
||||
|
||||
DeviceWrapper DeviceWrapper::create(const std::string &device_id)
|
||||
{
|
||||
auto device = Device::create(device_id);
|
||||
VALIDATE_EXPECTED(device);
|
||||
return DeviceWrapper(device.release());
|
||||
}
|
||||
|
||||
DeviceWrapper DeviceWrapper::create_pcie(hailo_pcie_device_info_t &device_info)
|
||||
{
|
||||
auto device = Device::create_pcie(device_info);
|
||||
@@ -22,7 +36,7 @@ DeviceWrapper DeviceWrapper::create_pcie(hailo_pcie_device_info_t &device_info)
|
||||
return DeviceWrapper(device.release());
|
||||
}
|
||||
|
||||
DeviceWrapper DeviceWrapper::create_eth(std::string &device_address, uint16_t port,
|
||||
DeviceWrapper DeviceWrapper::create_eth(const std::string &device_address, uint16_t port,
|
||||
uint32_t timeout_milliseconds, uint8_t max_number_of_attempts)
|
||||
{
|
||||
hailo_eth_device_info_t device_info = {};
|
||||
@@ -52,14 +66,6 @@ DeviceWrapper DeviceWrapper::create_eth(std::string &device_address, uint16_t po
|
||||
return DeviceWrapper(device.release());
|
||||
}
|
||||
|
||||
DeviceWrapper DeviceWrapper::create_core()
|
||||
{
|
||||
auto device = Device::create_core_device();
|
||||
VALIDATE_EXPECTED(device);
|
||||
|
||||
return DeviceWrapper(device.release());
|
||||
}
|
||||
|
||||
void DeviceWrapper::release()
|
||||
{
|
||||
m_device.reset();
|
||||
@@ -458,13 +464,21 @@ py::bytes DeviceWrapper::direct_read_memory(uint32_t address, uint32_t size)
|
||||
return py::bytes(buffer_str);
|
||||
}
|
||||
|
||||
const char *DeviceWrapper::get_dev_id() const
|
||||
{
|
||||
return device().get_dev_id();
|
||||
}
|
||||
|
||||
void DeviceWrapper::add_to_python_module(py::module &m)
|
||||
{
|
||||
py::class_<DeviceWrapper>(m, "Device")
|
||||
// Scan
|
||||
.def("scan", &DeviceWrapper::scan)
|
||||
|
||||
// C'tors
|
||||
.def("create", &DeviceWrapper::create)
|
||||
.def("create_pcie", &DeviceWrapper::create_pcie)
|
||||
.def("create_eth", &DeviceWrapper::create_eth)
|
||||
.def("create_core", &DeviceWrapper::create_core)
|
||||
.def("release", &DeviceWrapper::release)
|
||||
|
||||
//HEF
|
||||
@@ -514,6 +528,7 @@ void DeviceWrapper::add_to_python_module(py::module &m)
|
||||
.def("_get_overcurrent_state", &DeviceWrapper::get_overcurrent_state)
|
||||
.def("direct_write_memory", &DeviceWrapper::direct_write_memory)
|
||||
.def("direct_read_memory", &DeviceWrapper::direct_read_memory)
|
||||
.def_property_readonly("device_id", &DeviceWrapper::get_dev_id)
|
||||
.def("read_log", &DeviceWrapper::read_log, py::return_value_policy::move)
|
||||
|
||||
.def("set_notification_callback", &DeviceWrapper::set_notification_callback)
|
||||
|
||||
@@ -44,10 +44,11 @@ class DeviceWrapper final
|
||||
{
|
||||
public:
|
||||
|
||||
static std::vector<std::string> scan();
|
||||
static DeviceWrapper create(const std::string &device_id);
|
||||
static DeviceWrapper create_pcie(hailo_pcie_device_info_t &device_info);
|
||||
static DeviceWrapper create_eth(std::string &device_address, uint16_t port,
|
||||
static DeviceWrapper create_eth(const std::string &device_address, uint16_t port,
|
||||
uint32_t timeout_milliseconds, uint8_t max_number_of_attempts);
|
||||
static DeviceWrapper create_core();
|
||||
void release();
|
||||
|
||||
Device& device()
|
||||
@@ -56,6 +57,12 @@ public:
|
||||
return *(m_device.get());
|
||||
}
|
||||
|
||||
const Device& device() const
|
||||
{
|
||||
VALIDATE_NOT_NULL(m_device);
|
||||
return *(m_device.get());
|
||||
}
|
||||
|
||||
Device& operator*() // Used for control_internals
|
||||
{
|
||||
return device();
|
||||
@@ -117,6 +124,7 @@ public:
|
||||
py::bytes read_log(size_t byte_count, hailo_cpu_id_t cpu_id);
|
||||
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;
|
||||
|
||||
static void add_to_python_module(py::module &m);
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ void HefWrapper::initialize_python_module(py::module &m)
|
||||
py::class_<ConfiguredNetworkGroup>(m, "ConfiguredNetworkGroup")
|
||||
.def("get_name", [](ConfiguredNetworkGroup& self)
|
||||
{
|
||||
return self.get_network_group_name();
|
||||
return self.name();
|
||||
})
|
||||
.def("get_default_streams_interface", [](ConfiguredNetworkGroup& self)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,17 @@ target_include_directories(_pyhailort_internal
|
||||
$<BUILD_INTERFACE:${DRIVER_INC_DIR}>
|
||||
)
|
||||
|
||||
target_link_libraries(_pyhailort_internal PRIVATE libhailort hef_proto spdlog::spdlog readerwriterqueue microprofile)
|
||||
target_link_libraries(_pyhailort_internal PRIVATE
|
||||
libhailort
|
||||
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)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(_pyhailort_internal PRIVATE Ws2_32 Iphlpapi Shlwapi)
|
||||
endif()
|
||||
|
||||
@@ -183,7 +183,7 @@ PYBIND11_MODULE(_pyhailort_internal, m) {
|
||||
return self.format.order;
|
||||
})
|
||||
.def_readonly("direction", &LayerInfo::direction)
|
||||
.def_readonly("sys_index", &LayerInfo::index)
|
||||
.def_readonly("sys_index", &LayerInfo::stream_index)
|
||||
.def_readonly("name", &LayerInfo::name)
|
||||
.def_readonly("quant_info", &LayerInfo::quant_info)
|
||||
// For backwards compatibility (accessing qp through layer_info directly)
|
||||
@@ -207,8 +207,14 @@ PYBIND11_MODULE(_pyhailort_internal, m) {
|
||||
.def_readonly("height_gcd", &LayerInfo::height_gcd)
|
||||
.def_readonly("height_ratios", &LayerInfo::height_ratios)
|
||||
.def_readonly("buffer_indices", &LayerInfo::buffer_indices)
|
||||
.def_readonly("core_bytes_per_buffer", &LayerInfo::core_bytes_per_buffer)
|
||||
.def_readonly("core_buffers_per_frame", &LayerInfo::core_buffers_per_frame)
|
||||
.def_property_readonly("core_bytes_per_buffer", [](LayerInfo& self)
|
||||
{
|
||||
return self.nn_stream_config.core_bytes_per_buffer;
|
||||
})
|
||||
.def_property_readonly("core_buffers_per_frame", [](LayerInfo& self)
|
||||
{
|
||||
return self.nn_stream_config.core_buffers_per_frame;
|
||||
})
|
||||
.def_readonly("network_name", &LayerInfo::network_name)
|
||||
;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ using namespace std;
|
||||
#include "vstream_api.hpp"
|
||||
#include "vdevice_api.hpp"
|
||||
#include "device_api.hpp"
|
||||
#include "quantization_api.hpp"
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "utils.h"
|
||||
@@ -73,7 +74,13 @@ std::list<std::string> UdpScan::scan_devices(char* interface_name, uint32_t time
|
||||
return device_addresses;
|
||||
}
|
||||
|
||||
std::vector<hailo_pcie_device_info_t> scan_pcie_devices(void)
|
||||
class PcieScan {
|
||||
public:
|
||||
PcieScan() = default;
|
||||
std::vector<hailo_pcie_device_info_t> scan_devices(void);
|
||||
};
|
||||
|
||||
std::vector<hailo_pcie_device_info_t> PcieScan::scan_devices(void)
|
||||
{
|
||||
auto scan_result = Device::scan_pcie();
|
||||
VALIDATE_EXPECTED(scan_result);
|
||||
@@ -81,242 +88,6 @@ std::vector<hailo_pcie_device_info_t> scan_pcie_devices(void)
|
||||
return scan_result.release();
|
||||
}
|
||||
|
||||
// Quantization
|
||||
void dequantize_output_buffer_from_uint8(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::dequantize_output_buffer<uint8_t, uint8_t>(static_cast<uint8_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::dequantize_output_buffer<uint16_t, uint8_t>(static_cast<uint8_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer<float32_t, uint8_t>(static_cast<uint8_t*>(src_buffer.mutable_data()),
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src format type uint8 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dequantize_output_buffer_from_uint16(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::dequantize_output_buffer<uint16_t, uint16_t>(static_cast<uint16_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer<float32_t, uint16_t>(static_cast<uint16_t*>(src_buffer.mutable_data()),
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src dormat type uint16 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dequantize_output_buffer_from_float32(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer<float32_t, float32_t>(static_cast<float32_t*>(src_buffer.mutable_data()),
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src format type float32 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dequantize_output_buffer_from_uint8_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::dequantize_output_buffer_in_place<uint8_t, uint8_t>(
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::dequantize_output_buffer_in_place<uint16_t, uint8_t>(
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer_in_place<float32_t, uint8_t>(
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src format type uint8 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dequantize_output_buffer_from_uint16_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::dequantize_output_buffer_in_place<uint16_t, uint16_t>(
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer_in_place<float32_t, uint16_t>(
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src dormat type uint16 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dequantize_output_buffer_from_float32_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer_in_place<float32_t, float32_t>(
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src format type float32 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dequantize_output_buffer_in_place(py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (src_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
dequantize_output_buffer_from_uint8_in_place(dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
dequantize_output_buffer_from_uint16_in_place(dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
dequantize_output_buffer_from_float32_in_place(dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Unsupported src format type = {}", HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dequantize_output_buffer(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (src_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
dequantize_output_buffer_from_uint8(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
dequantize_output_buffer_from_uint16(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
dequantize_output_buffer_from_float32(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Unsupported src format type = {}", HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void quantize_input_buffer_from_uint8(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::quantize_input_buffer<uint8_t, uint8_t>(static_cast<uint8_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Input quantization isn't supported from src format type uint8 to dst format type = {}", HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void quantize_input_buffer_from_uint16(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::quantize_input_buffer<uint16_t, uint8_t>(static_cast<uint16_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::quantize_input_buffer<uint16_t, uint16_t>(static_cast<uint16_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Input quantization isn't supported from src format type uint16 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void quantize_input_buffer_from_float32(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::quantize_input_buffer<float32_t, uint8_t>(static_cast<float32_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::quantize_input_buffer<float32_t, uint16_t>(static_cast<float32_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Input quantization isn't supported from src format type float32 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void quantize_input_buffer(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (src_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
quantize_input_buffer_from_uint8(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
quantize_input_buffer_from_uint16(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
quantize_input_buffer_from_float32(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Input quantization isn't supported for src format type = {}", HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_status_message(uint32_t status_in)
|
||||
{
|
||||
auto status_str = hailo_get_status_message((hailo_status)status_in);
|
||||
@@ -413,10 +184,9 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
validate_versions_match();
|
||||
|
||||
m.def("get_status_message", &get_status_message);
|
||||
m.def("scan_pcie_devices", &scan_pcie_devices);
|
||||
m.def("dequantize_output_buffer_in_place", &dequantize_output_buffer_in_place);
|
||||
m.def("dequantize_output_buffer", &dequantize_output_buffer);
|
||||
m.def("quantize_input_buffer", &quantize_input_buffer);
|
||||
m.def("dequantize_output_buffer_in_place", &QuantizationBindings::dequantize_output_buffer_in_place);
|
||||
m.def("dequantize_output_buffer", &QuantizationBindings::dequantize_output_buffer);
|
||||
m.def("quantize_input_buffer", &QuantizationBindings::quantize_input_buffer);
|
||||
|
||||
m.def("get_format_data_bytes", &HailoRTCommon::get_format_data_bytes);
|
||||
m.def("get_dtype", &HailoRTBindingsCommon::get_dtype);
|
||||
@@ -443,6 +213,10 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
.def(py::init<>())
|
||||
.def("scan_devices", &UdpScan::scan_devices)
|
||||
;
|
||||
py::class_<PcieScan>(m, "PcieScan")
|
||||
.def(py::init<>())
|
||||
.def("scan_devices", &PcieScan::scan_devices)
|
||||
;
|
||||
|
||||
py::class_<PowerMeasurementData>(m, "PowerMeasurementData")
|
||||
.def_readonly("average_value", &PowerMeasurementData::m_average_value, "float, The average value of the samples that were sampled")
|
||||
@@ -456,7 +230,8 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
|
||||
py::enum_<hailo_device_architecture_t>(m, "DeviceArchitecture")
|
||||
.value("HAILO8_A0", HAILO_ARCH_HAILO8_A0)
|
||||
.value("HAILO8_B0", HAILO_ARCH_HAILO8_B0)
|
||||
.value("HAILO8", HAILO_ARCH_HAILO8)
|
||||
.value("HAILO8L", HAILO_ARCH_HAILO8L)
|
||||
.value("MERCURY_CA", HAILO_ARCH_MERCURY_CA)
|
||||
;
|
||||
|
||||
@@ -530,8 +305,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
;
|
||||
|
||||
py::enum_<hailo_overcurrent_protection_overcurrent_zone_t>(m, "OvercurrentAlertState")
|
||||
.value("OVERCURRENT_ZONE_NONE", HAILO_OVERCURRENT_PROTECTION_OVERCURRENT_ZONE__NONE)
|
||||
.value("OVERCURRENT_ZONE_ORANGE", HAILO_OVERCURRENT_PROTECTION_OVERCURRENT_ZONE__ORANGE)
|
||||
.value("OVERCURRENT_ZONE_GREEN", HAILO_OVERCURRENT_PROTECTION_OVERCURRENT_ZONE__GREEN)
|
||||
.value("OVERCURRENT_ZONE_RED", HAILO_OVERCURRENT_PROTECTION_OVERCURRENT_ZONE__RED)
|
||||
;
|
||||
|
||||
@@ -572,7 +346,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
py::class_<hailo_health_monitor_overcurrent_alert_notification_message_t>(m, "HealthMonitorOvercurrentAlertNotificationMessage")
|
||||
.def_readonly("overcurrent_zone", &hailo_health_monitor_overcurrent_alert_notification_message_t::overcurrent_zone)
|
||||
.def_readonly("exceeded_alert_threshold", &hailo_health_monitor_overcurrent_alert_notification_message_t::exceeded_alert_threshold)
|
||||
.def_readonly("sampled_current_during_alert", &hailo_health_monitor_overcurrent_alert_notification_message_t::sampled_current_during_alert)
|
||||
.def_readonly("is_last_overcurrent_violation_reached", &hailo_health_monitor_overcurrent_alert_notification_message_t::is_last_overcurrent_violation_reached)
|
||||
;
|
||||
|
||||
py::class_<hailo_health_monitor_lcu_ecc_error_notification_message_t>(m, "HealthMonitorLcuEccErrorNotificationMessage")
|
||||
@@ -997,11 +771,29 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
});
|
||||
;
|
||||
|
||||
py::class_<hailo_vdevice_params_t>(m, "VDeviceParams")
|
||||
py::class_<VDeviceParamsWrapper>(m, "VDeviceParams")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("device_count", &hailo_vdevice_params_t::device_count)
|
||||
.def_property("device_count",
|
||||
[](const VDeviceParamsWrapper& params) -> uint32_t {
|
||||
return params.orig_params.device_count;
|
||||
},
|
||||
[](VDeviceParamsWrapper& params, const uint32_t& device_count) {
|
||||
params.orig_params.device_count = device_count;
|
||||
}
|
||||
)
|
||||
.def_property("group_id",
|
||||
[](const VDeviceParamsWrapper& params) -> py::str {
|
||||
return std::string(params.orig_params.group_id);
|
||||
},
|
||||
[](VDeviceParamsWrapper& params, const std::string& group_id) {
|
||||
params.group_id_str = group_id;
|
||||
params.orig_params.group_id = params.group_id_str.c_str();
|
||||
}
|
||||
)
|
||||
.def_static("default", []() {
|
||||
return HailoRTDefaults::get_vdevice_params();
|
||||
auto orig_params = HailoRTDefaults::get_vdevice_params();
|
||||
VDeviceParamsWrapper params_wrapper{orig_params, ""};
|
||||
return params_wrapper;
|
||||
});
|
||||
;
|
||||
|
||||
@@ -1070,7 +862,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
.def_readonly("overcurrent_protection_active", &hailo_health_info_t::overcurrent_protection_active)
|
||||
.def_readonly("current_overcurrent_zone", &hailo_health_info_t::current_overcurrent_zone)
|
||||
.def_readonly("red_overcurrent_threshold", &hailo_health_info_t::red_overcurrent_threshold)
|
||||
.def_readonly("orange_overcurrent_threshold", &hailo_health_info_t::orange_overcurrent_threshold)
|
||||
.def_readonly("overcurrent_throttling_active", &hailo_health_info_t::overcurrent_throttling_active)
|
||||
.def_readonly("temperature_throttling_active", &hailo_health_info_t::temperature_throttling_active)
|
||||
.def_readonly("current_temperature_zone", &hailo_health_info_t::current_temperature_zone)
|
||||
.def_readonly("current_temperature_throttling_level", &hailo_health_info_t::current_temperature_throttling_level)
|
||||
@@ -1086,6 +878,8 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
.def_readonly("orange_hysteresis_temperature_threshold", &hailo_health_info_t::orange_hysteresis_temperature_threshold)
|
||||
.def_readonly("red_temperature_threshold", &hailo_health_info_t::red_temperature_threshold)
|
||||
.def_readonly("red_hysteresis_temperature_threshold", &hailo_health_info_t::red_hysteresis_temperature_threshold)
|
||||
.def_readonly("requested_overcurrent_clock_freq", &hailo_health_info_t::requested_overcurrent_clock_freq)
|
||||
.def_readonly("requested_temperature_clock_freq", &hailo_health_info_t::requested_temperature_clock_freq)
|
||||
;
|
||||
|
||||
py::class_<hailo_extended_device_information_t>(m, "ExtendedDeviceInformation")
|
||||
@@ -1148,10 +942,6 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
.value("CPU1", HAILO_CPU_ID_1)
|
||||
;
|
||||
|
||||
py::enum_<hailo_bootloader_version_t>(m, "BootloaderVersion")
|
||||
.value("UNSIGNED", BOOTLOADER_VERSION_HAILO8_B0_UNSIGNED)
|
||||
.value("SIGNED", BOOTLOADER_VERSION_HAILO8_B0_SIGNED)
|
||||
;
|
||||
|
||||
py::class_<uint32_t>(m, "HailoRTDefaults")
|
||||
.def_static("HAILO_INFINITE", []() { return HAILO_INFINITE;} )
|
||||
@@ -1160,6 +950,7 @@ PYBIND11_MODULE(_pyhailort, m) {
|
||||
.def_static("DEVICE_BASE_INPUT_STREAM_PORT", []() { return HailoRTCommon::ETH_INPUT_BASE_PORT;} )
|
||||
.def_static("DEVICE_BASE_OUTPUT_STREAM_PORT", []() { return HailoRTCommon::ETH_OUTPUT_BASE_PORT;} )
|
||||
.def_static("PCIE_ANY_DOMAIN", []() { return HAILO_PCIE_ANY_DOMAIN;} )
|
||||
.def_static("HAILO_UNIQUE_VDEVICE_GROUP_ID", []() { return std::string(HAILO_UNIQUE_VDEVICE_GROUP_ID); } )
|
||||
;
|
||||
|
||||
py::class_<hailo_network_group_info_t>(m, "NetworkGroupInfo", py::module_local())
|
||||
|
||||
251
hailort/libhailort/bindings/python/src/quantization_api.cpp
Normal file
251
hailort/libhailort/bindings/python/src/quantization_api.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file quantization_api.cpp
|
||||
* @brief Quantization python bindings functions
|
||||
**/
|
||||
|
||||
#include "quantization_api.hpp"
|
||||
#include "bindings_common.hpp"
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
void QuantizationBindings::dequantize_output_buffer_from_uint8(py::array src_buffer, py::array dst_buffer,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::dequantize_output_buffer<uint8_t, uint8_t>(static_cast<uint8_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::dequantize_output_buffer<uint16_t, uint8_t>(static_cast<uint8_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer<float32_t, uint8_t>(static_cast<uint8_t*>(src_buffer.mutable_data()),
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src format type uint8 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::dequantize_output_buffer_from_uint16(py::array src_buffer, py::array dst_buffer,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::dequantize_output_buffer<uint16_t, uint16_t>(static_cast<uint16_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer<float32_t, uint16_t>(static_cast<uint16_t*>(src_buffer.mutable_data()),
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src dormat type uint16 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::dequantize_output_buffer_from_float32(py::array src_buffer, py::array dst_buffer,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer<float32_t, float32_t>(static_cast<float32_t*>(src_buffer.mutable_data()),
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src format type float32 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::dequantize_output_buffer_from_uint8_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::dequantize_output_buffer_in_place<uint8_t, uint8_t>(
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::dequantize_output_buffer_in_place<uint16_t, uint8_t>(
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer_in_place<float32_t, uint8_t>(
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src format type uint8 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::dequantize_output_buffer_from_uint16_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::dequantize_output_buffer_in_place<uint16_t, uint16_t>(
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer_in_place<float32_t, uint16_t>(
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src dormat type uint16 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::dequantize_output_buffer_from_float32_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
Quantization::dequantize_output_buffer_in_place<float32_t, float32_t>(
|
||||
static_cast<float32_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Output quantization isn't supported from src format type float32 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::dequantize_output_buffer_in_place(py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (src_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
QuantizationBindings::dequantize_output_buffer_from_uint8_in_place(dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
QuantizationBindings::dequantize_output_buffer_from_uint16_in_place(dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
QuantizationBindings::dequantize_output_buffer_from_float32_in_place(dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Unsupported src format type = {}", HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::dequantize_output_buffer(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (src_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
QuantizationBindings::dequantize_output_buffer_from_uint8(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
QuantizationBindings::dequantize_output_buffer_from_uint16(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
QuantizationBindings::dequantize_output_buffer_from_float32(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Unsupported src format type = {}", HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::quantize_input_buffer_from_uint8(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::quantize_input_buffer<uint8_t, uint8_t>(static_cast<uint8_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Input quantization isn't supported from src format type uint8 to dst format type = {}", HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::quantize_input_buffer_from_uint16(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::quantize_input_buffer<uint16_t, uint8_t>(static_cast<uint16_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::quantize_input_buffer<uint16_t, uint16_t>(static_cast<uint16_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Input quantization isn't supported from src format type uint16 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::quantize_input_buffer_from_float32(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (dst_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
Quantization::quantize_input_buffer<float32_t, uint8_t>(static_cast<float32_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint8_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
Quantization::quantize_input_buffer<float32_t, uint16_t>(static_cast<float32_t*>(src_buffer.mutable_data()),
|
||||
static_cast<uint16_t*>(dst_buffer.mutable_data()), shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Input quantization isn't supported from src format type float32 to dst format type = {}",
|
||||
HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QuantizationBindings::quantize_input_buffer(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info)
|
||||
{
|
||||
switch (src_dtype) {
|
||||
case HAILO_FORMAT_TYPE_UINT8:
|
||||
QuantizationBindings::quantize_input_buffer_from_uint8(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_UINT16:
|
||||
QuantizationBindings::quantize_input_buffer_from_uint16(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
case HAILO_FORMAT_TYPE_FLOAT32:
|
||||
QuantizationBindings::quantize_input_buffer_from_float32(src_buffer, dst_buffer, dst_dtype, shape_size, quant_info);
|
||||
break;
|
||||
default:
|
||||
LOGGER__ERROR("Input quantization isn't supported for src format type = {}", HailoRTBindingsCommon::convert_format_type_to_string(dst_dtype));
|
||||
THROW_STATUS_ERROR(HAILO_INVALID_ARGUMENT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace hailort */
|
||||
56
hailort/libhailort/bindings/python/src/quantization_api.hpp
Normal file
56
hailort/libhailort/bindings/python/src/quantization_api.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file quantization_api.hpp
|
||||
* @brief Quantization python bindings functions
|
||||
**/
|
||||
|
||||
#ifndef _HAILO_QUANTIZATION_API_HPP_
|
||||
#define _HAILO_QUANTIZATION_API_HPP_
|
||||
|
||||
#include "hailo/hailort.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/numpy.h>
|
||||
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
class QuantizationBindings
|
||||
{
|
||||
public:
|
||||
static void quantize_input_buffer(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
static void dequantize_output_buffer_in_place(py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
static void dequantize_output_buffer(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &src_dtype,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
private:
|
||||
static void dequantize_output_buffer_from_uint8(py::array src_buffer, py::array dst_buffer,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
static void dequantize_output_buffer_from_uint16(py::array src_buffer, py::array dst_buffer,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
static void dequantize_output_buffer_from_float32(py::array src_buffer, py::array dst_buffer,
|
||||
const hailo_format_type_t &dst_dtype, uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
|
||||
static void dequantize_output_buffer_from_uint8_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
static void dequantize_output_buffer_from_uint16_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
static void dequantize_output_buffer_from_float32_in_place(py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
|
||||
static void quantize_input_buffer_from_uint8(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
static void quantize_input_buffer_from_uint16(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
static void quantize_input_buffer_from_float32(py::array src_buffer, py::array dst_buffer, const hailo_format_type_t &dst_dtype,
|
||||
uint32_t shape_size, const hailo_quant_info_t &quant_info);
|
||||
};
|
||||
|
||||
} /* namespace hailort */
|
||||
|
||||
#endif /* _HAILO_QUANTIZATION_API_HPP_ */
|
||||
@@ -30,6 +30,11 @@
|
||||
namespace hailort
|
||||
{
|
||||
|
||||
struct VDeviceParamsWrapper {
|
||||
hailo_vdevice_params_t orig_params;
|
||||
std::string group_id_str;
|
||||
};
|
||||
|
||||
class VDeviceWrapper {
|
||||
public:
|
||||
static VDeviceWrapper create(const hailo_vdevice_params_t ¶ms)
|
||||
@@ -37,13 +42,15 @@ public:
|
||||
return VDeviceWrapper(params);
|
||||
};
|
||||
|
||||
static VDeviceWrapper create_from_infos(const std::vector<hailo_pcie_device_info_t> &device_infos)
|
||||
static VDeviceWrapper create(const VDeviceParamsWrapper ¶ms)
|
||||
{
|
||||
hailo_vdevice_params_t params = {};
|
||||
params.device_count = static_cast<uint32_t>(device_infos.size());
|
||||
params.device_infos = const_cast<hailo_pcie_device_info_t*>(device_infos.data());
|
||||
return VDeviceWrapper(params);
|
||||
};
|
||||
return VDeviceWrapper(params.orig_params);
|
||||
}
|
||||
|
||||
static VDeviceWrapper create_from_ids(const std::vector<std::string> &device_ids)
|
||||
{
|
||||
return VDeviceWrapper(device_ids);
|
||||
}
|
||||
|
||||
VDeviceWrapper(const hailo_vdevice_params_t ¶ms)
|
||||
{
|
||||
@@ -53,13 +60,21 @@ public:
|
||||
m_vdevice = vdevice_expected.release();
|
||||
};
|
||||
|
||||
py::list get_physical_devices_infos()
|
||||
VDeviceWrapper(const std::vector<std::string> &device_ids)
|
||||
{
|
||||
auto phys_devs_infos = m_vdevice->get_physical_devices_infos();
|
||||
VALIDATE_EXPECTED(phys_devs_infos);
|
||||
auto vdevice_expected = VDevice::create(device_ids);
|
||||
VALIDATE_EXPECTED(vdevice_expected);
|
||||
|
||||
return py::cast(phys_devs_infos.value());
|
||||
};
|
||||
m_vdevice = vdevice_expected.release();
|
||||
}
|
||||
|
||||
py::list get_physical_devices_ids() const
|
||||
{
|
||||
const auto phys_devs_ids = m_vdevice->get_physical_devices_ids();
|
||||
VALIDATE_EXPECTED(phys_devs_ids);
|
||||
|
||||
return py::cast(phys_devs_ids.value());
|
||||
}
|
||||
|
||||
py::list configure(const HefWrapper &hef,
|
||||
const NetworkGroupsParamsMap &configure_params={})
|
||||
@@ -88,9 +103,10 @@ private:
|
||||
void VDevice_api_initialize_python_module(py::module &m)
|
||||
{
|
||||
py::class_<VDeviceWrapper>(m, "VDevice")
|
||||
.def("create", &VDeviceWrapper::create)
|
||||
.def("create_from_infos", &VDeviceWrapper::create_from_infos)
|
||||
.def("get_physical_devices_infos", &VDeviceWrapper::get_physical_devices_infos)
|
||||
.def("create", py::overload_cast<const hailo_vdevice_params_t&>(&VDeviceWrapper::create))
|
||||
.def("create", py::overload_cast<const VDeviceParamsWrapper&>(&VDeviceWrapper::create))
|
||||
.def("create_from_ids", &VDeviceWrapper::create_from_ids)
|
||||
.def("get_physical_devices_ids", &VDeviceWrapper::get_physical_devices_ids)
|
||||
.def("configure", &VDeviceWrapper::configure)
|
||||
.def("release", &VDeviceWrapper::release)
|
||||
;
|
||||
|
||||
@@ -56,7 +56,8 @@ InputVStreamsWrapper InputVStreamsWrapper::create(ConfiguredNetworkGroup &net_gr
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<InputVStream>> input_vstreams;
|
||||
for (auto &input : input_vstreams_expected.value()) {
|
||||
input_vstreams.emplace(input.name(), make_shared_nothrow<InputVStream>(std::move(input)));
|
||||
auto input_name = input.name();
|
||||
input_vstreams.emplace(input_name, make_shared_nothrow<InputVStream>(std::move(input)));
|
||||
}
|
||||
return InputVStreamsWrapper(input_vstreams);
|
||||
}
|
||||
@@ -168,7 +169,8 @@ OutputVStreamsWrapper OutputVStreamsWrapper::create(ConfiguredNetworkGroup &net_
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<OutputVStream>> output_vstreams;
|
||||
for (auto &output : output_vstreams_expected.value()) {
|
||||
output_vstreams.emplace(output.name(), make_shared_nothrow<OutputVStream>(std::move(output)));
|
||||
auto output_name = output.name();
|
||||
output_vstreams.emplace(output_name, make_shared_nothrow<OutputVStream>(std::move(output)));
|
||||
}
|
||||
return OutputVStreamsWrapper(output_vstreams);
|
||||
}
|
||||
|
||||
@@ -9,4 +9,4 @@ set(CMAKE_LINKER arm-linux-gnueabi-ld)
|
||||
add_compile_options(-march=armv7-a)
|
||||
|
||||
# pybind is not supported in this platform
|
||||
set(HAILO_BUILD_PYBIND 0)
|
||||
set(HAILO_BUILD_PYBIND "OFF" CACHE STRING "hailo_build_pybind" FORCE)
|
||||
|
||||
@@ -9,4 +9,4 @@ set(CMAKE_LINKER arm-linux-gnueabihf-ld)
|
||||
add_compile_options(-march=armv7-a)
|
||||
|
||||
# pybind is not supported in this platform
|
||||
set(HAILO_BUILD_PYBIND 0)
|
||||
set(HAILO_BUILD_PYBIND "OFF" CACHE STRING "hailo_build_pybind" FORCE)
|
||||
|
||||
@@ -47,6 +47,10 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=md5 -lang-c
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--build-id=md5 -lang-c++ -lsocket ${EXTRA_CMAKE_LINKER_FLAGS}" CACHE STRING "so_linker_flags")
|
||||
|
||||
# pybind is not supported in this platform
|
||||
set(HAILO_BUILD_PYBIND 0)
|
||||
set(HAILO_BUILD_PYBIND "OFF" CACHE STRING "hailo_build_pybind" FORCE)
|
||||
# GStreamer does not work on QNX currently
|
||||
set(HAILO_BUILD_GSTREAMER 0)
|
||||
set(HAILO_BUILD_GSTREAMER "OFF" CACHE STRING "hailo_build_gstreamer" FORCE)
|
||||
# Hailort service does not work on QNX currently
|
||||
set(HAILO_BUILD_SERVICE "OFF" CACHE STRING "hailo_build_service" FORCE)
|
||||
# Set little endian flag for protobuf to work correctly on QNX
|
||||
add_definitions("-D__LITTLE_ENDIAN__")
|
||||
@@ -47,6 +47,10 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=md5 -lang-c
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--build-id=md5 -lang-c++ -lsocket ${EXTRA_CMAKE_LINKER_FLAGS}" CACHE STRING "so_linker_flags")
|
||||
|
||||
# pybind is not supported in this platform
|
||||
set(HAILO_BUILD_PYBIND 0)
|
||||
set(HAILO_BUILD_PYBIND "OFF" CACHE STRING "hailo_build_pybind" FORCE)
|
||||
# GStreamer does not work on QNX currently
|
||||
set(HAILO_BUILD_GSTREAMER 0)
|
||||
set(HAILO_BUILD_GSTREAMER "OFF" CACHE STRING "hailo_build_gstreamer" FORCE)
|
||||
# Hailort service does not work on QNX currently
|
||||
set(HAILO_BUILD_SERVICE "OFF" CACHE STRING "hailo_build_service" FORCE)
|
||||
# Set little endian flag for protobuf to work correctly on QNX
|
||||
add_definitions("-D__LITTLE_ENDIAN__")
|
||||
@@ -5,7 +5,7 @@ project(hailort-examples)
|
||||
find_package(Threads REQUIRED)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
|
||||
find_package(HailoRT 4.8.1 EXACT REQUIRED)
|
||||
find_package(HailoRT 4.10.0 EXACT REQUIRED)
|
||||
|
||||
add_library(example_base INTERFACE)
|
||||
target_link_libraries(example_base INTERFACE HailoRT::libhailort Threads::Threads)
|
||||
|
||||
@@ -37,12 +37,14 @@ The following examples are provided, demonstrating the HailoRT 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.
|
||||
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
|
||||
Examples are configured and compiled using the following commands:
|
||||
```sh
|
||||
cmake -H. -Bbuild
|
||||
cmake --build build
|
||||
cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release
|
||||
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.
|
||||
|
||||
@@ -44,7 +44,7 @@ hailo_status infer(hailo_configured_network_group configured_network_group,
|
||||
src_data = malloc(input_buffer.raw_buffer.size);
|
||||
REQUIRE_ACTION(src_data != NULL, status = HAILO_OUT_OF_HOST_MEMORY, l_free_buffers, "Failed to allocate input buffer");
|
||||
// Prepare src data here
|
||||
for (size_t j = 0; j < frame_size; j++) {
|
||||
for (size_t j = 0; j < input_buffer.raw_buffer.size; j++) {
|
||||
src_data[j] = (uint8_t)(rand() % 256);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
/**
|
||||
* Copyright 2020 (C) Hailo Technologies Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Hailo Technologies Ltd. ("Hailo") disclaims any warranties, including, but not limited to,
|
||||
* the implied warranties of merchantability and fitness for a particular purpose.
|
||||
* This software is provided on an "AS IS" basis, and Hailo has no obligation to provide maintenance,
|
||||
* support, updates, enhancements, or modifications.
|
||||
*
|
||||
* You may use this software in the development of any project.
|
||||
* You shall not reproduce, modify or distribute this software without prior written permission.
|
||||
* Copyright (c) 2020-2022 Hailo Technologies Ltd. All rights reserved.
|
||||
* Distributed under the MIT license (https://opensource.org/licenses/MIT)
|
||||
**/
|
||||
/**
|
||||
* @file multi_device_example.c
|
||||
@@ -23,7 +15,7 @@
|
||||
|
||||
#define INFER_FRAME_COUNT (100)
|
||||
#define MAX_EDGE_LAYERS (16)
|
||||
#define MAX_PCIE_DEVICES (16)
|
||||
#define MAX_DEVICES (16)
|
||||
#define HEF_FILE ("hefs/shortcut_net.hef")
|
||||
|
||||
|
||||
@@ -136,8 +128,8 @@ int main()
|
||||
{
|
||||
hailo_status status = HAILO_UNINITIALIZED;
|
||||
hailo_vdevice vdevice = NULL;
|
||||
hailo_pcie_device_info_t device_infos[MAX_PCIE_DEVICES];
|
||||
size_t actual_count = 0;
|
||||
hailo_device_id_t device_ids[MAX_DEVICES];
|
||||
size_t actual_count = MAX_DEVICES;
|
||||
hailo_vdevice_params_t params = {0};
|
||||
hailo_hef hef = NULL;
|
||||
hailo_configure_params_t config_params = {0};
|
||||
@@ -151,8 +143,8 @@ int main()
|
||||
hailo_input_vstream input_vstreams[MAX_EDGE_LAYERS] = {NULL};
|
||||
hailo_output_vstream output_vstreams[MAX_EDGE_LAYERS] = {NULL};
|
||||
|
||||
status = hailo_scan_pcie_devices(device_infos, MAX_PCIE_DEVICES, &actual_count);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to scan pcie_device");
|
||||
status = hailo_scan_devices(NULL, device_ids, &actual_count);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to scan devices");
|
||||
|
||||
status = hailo_init_vdevice_params(¶ms);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed init vdevice_params");
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#define MEASUREMENT_BUFFER_INDEX (HAILO_MEASUREMENT_BUFFER_INDEX_0)
|
||||
|
||||
#define MEASUREMENTS_DURATION_SECS (5)
|
||||
#define MAX_PCIE_DEVICES (16)
|
||||
#define MAX_DEVICES (16)
|
||||
|
||||
#define MEASUREMENT_UNITS(__type) \
|
||||
((HAILO_POWER_MEASUREMENT_TYPES__POWER == __type) ? ("W") : ("mA"))
|
||||
@@ -80,17 +80,17 @@ int main(int argc, char **argv)
|
||||
{
|
||||
hailo_status status = HAILO_UNINITIALIZED;
|
||||
hailo_vdevice vdevice = NULL;
|
||||
hailo_pcie_device_info_t device_infos[MAX_PCIE_DEVICES];
|
||||
size_t actual_device_count = 0;
|
||||
hailo_device_id_t device_ids[MAX_DEVICES];
|
||||
size_t actual_device_count = MAX_DEVICES;
|
||||
hailo_vdevice_params_t params = {0};
|
||||
hailo_device physical_devices[MAX_PCIE_DEVICES];
|
||||
hailo_power_measurement_data_t measurement_result[MAX_PCIE_DEVICES] = {0};
|
||||
hailo_device physical_devices[MAX_DEVICES];
|
||||
hailo_power_measurement_data_t measurement_result[MAX_DEVICES] = {0};
|
||||
hailo_power_measurement_types_t measurement_type = {0};
|
||||
|
||||
parse_arguments(argc, argv, &measurement_type);
|
||||
|
||||
status = hailo_scan_pcie_devices(device_infos, MAX_PCIE_DEVICES, &actual_device_count);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to scan pcie_device");
|
||||
status = hailo_scan_devices(NULL, device_ids, &actual_device_count);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to scan devices");
|
||||
|
||||
status = hailo_init_vdevice_params(¶ms);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to init vdevice_params");
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/**
|
||||
* @file raw_streams_example.c
|
||||
* This example demonstrates basic usage of HailoRT streaming api.
|
||||
* It loads an HEF network with multiple inputs and multiple outputs into a Hailo PCIe device and performs a
|
||||
* It loads an HEF network with multiple inputs and multiple outputs into a Hailo device and performs a
|
||||
* short inference.
|
||||
**/
|
||||
|
||||
@@ -170,6 +170,8 @@ l_cleanup:
|
||||
int main()
|
||||
{
|
||||
hailo_status status = HAILO_UNINITIALIZED;
|
||||
hailo_device_id_t device_id = {0};
|
||||
size_t actual_devices_count = 1;
|
||||
hailo_device device = NULL;
|
||||
hailo_hef hef = NULL;
|
||||
hailo_configure_params_t configure_params = {0};
|
||||
@@ -184,13 +186,13 @@ int main()
|
||||
size_t number_output_streams = 0;
|
||||
size_t index = 0;
|
||||
|
||||
status = hailo_create_pcie_device(NULL, &device);
|
||||
/*
|
||||
For simplicity, passing NULL as `device_info` - This function will fail in case more than one PCIe device is present.
|
||||
See `hailo_scan_pcie_devices` and `hailo_create_pcie_device` functions documentation.
|
||||
*/
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to create pcie_device");
|
||||
status = hailo_scan_devices(NULL, &device_id, &actual_devices_count);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to scan devices");
|
||||
REQUIRE_ACTION(1 == actual_devices_count, status = HAILO_INVALID_OPERATION, l_exit,
|
||||
"Only 1 device on the system is supported on the example");
|
||||
|
||||
status = hailo_create_device_by_id(&device_id, &device);
|
||||
REQUIRE_SUCCESS(status, l_exit, "Failed to create device");
|
||||
|
||||
status = hailo_create_hef_file(&hef, HEF_FILE);
|
||||
REQUIRE_SUCCESS(status, l_release_device, "Failed creating hef file %s", HEF_FILE);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user