From 569e7bd38fa932923ca50e46e671d0392be2adf8 Mon Sep 17 00:00:00 2001 From: Zibai Wang Date: Mon, 30 Oct 2023 11:26:00 -0700 Subject: [PATCH] Adding support for Hostpipe sideband signals --- include/acl.h | 20 +++ include/acl_hal.h | 36 ++++++ include/acl_hal_mmd.h | 10 ++ include/acl_types.h | 14 ++- src/acl_auto_configure.cpp | 87 +++++++++++++ src/acl_hal_mmd.cpp | 180 +++++++++++++++++++++++++++ src/acl_hostch.cpp | 206 ++++++++++++++++++++++++++----- src/acl_program.cpp | 35 ++++++ test/acl_auto_configure_test.cpp | 104 +++++++++++++++- 9 files changed, 652 insertions(+), 40 deletions(-) diff --git a/include/acl.h b/include/acl.h index 5464e092..25cf4e44 100644 --- a/include/acl.h +++ b/include/acl.h @@ -544,6 +544,25 @@ struct acl_hostpipe_mapping { // avalon_mm = 2, avalon_mm_uses_ready = 3 }; +// Mapping of sideband signals to logical pipe + +struct acl_sideband_signal_mapping { + std::string logical_name; + unsigned port_identifier; + unsigned port_offset; // bit + unsigned sideband_size; // bit +}; + +// Must match the definition in the compiler +// Analysis/FPGAAnalysis/Utils/StreamParameters.h +enum signal_type { + SignalUnknown = -1, + AvalonData = 0, + AvalonSop = 1, + AvalonEop = 2, + AvalonEmpty = 3 +}; + // Part of acl_device_def_t where members are populated from the information // in the autodiscovery string. This will get updated every time the device // is programmed with a new device binary as the new binary would contain a @@ -570,6 +589,7 @@ typedef struct acl_device_def_autodiscovery_t { true; // Set the default value to true for backwards compatibility flows. std::vector hostpipe_mappings; + std::vector sideband_signal_mappings; } acl_device_def_autodiscovery_t; typedef struct acl_device_def_t { diff --git a/include/acl_hal.h b/include/acl_hal.h index 658c65e6..835b2f83 100644 --- a/include/acl_hal.h +++ b/include/acl_hal.h @@ -265,6 +265,42 @@ typedef struct { unsigned int physical_device_id, const char *interface_name, const void *host_addr, size_t dev_addr, size_t size); + /// Simulation only mmd call as of 2024.1 + /// Return the sideband signal buffer corresponding to the side band signal + /// port identifier + void *(*hostchannel_get_sideband_buffer)(unsigned int physical_device_id, + unsigned int port_name, + int channel_handle, + size_t *buffer_size, int *status); + + /// Pull read_size of sideband data from the device into host_buffer, WITHOUT + /// acknowledge + size_t (*hostchannel_sideband_pull_no_ack)(unsigned int physical_device_id, + unsigned int port_name, + int channel_handle, + void *host_buffer, + size_t read_size, int *status); + + /// Push write_size of sideband data to the device from host_buffer, WITHOUT + /// acknowledge + size_t (*hostchannel_sideband_push_no_ack)(unsigned int physical_device_id, + unsigned int port_name, + int channel_handle, + const void *host_buffer, + size_t write_size, int *status); + + /// Pull read_size of data from the device into host_buffer, WITHOUT + /// acknowledge + size_t (*hostchannel_pull_no_ack)(unsigned int physical_device_id, + int channel_handle, void *host_buffer, + size_t read_size, int *status); + + /// Push write_size of data to the device from host_buffer, WITHOUT + /// acknowledge + size_t (*hostchannel_push_no_ack)(unsigned int physical_device_id, + int channel_handle, const void *host_buffer, + size_t write_size, int *status); + } acl_hal_t; /// Linked list of MMD library names to load. diff --git a/include/acl_hal_mmd.h b/include/acl_hal_mmd.h index 44c5622b..4660f32d 100644 --- a/include/acl_hal_mmd.h +++ b/include/acl_hal_mmd.h @@ -269,6 +269,16 @@ typedef struct { int (*aocl_mmd_simulation_device_global_interface_write)( int handle, const char *interface_name, const void *host_addr, size_t dev_addr, size_t size); + + // Return the side band signal buffer corresponding to the side band signal + // port identifier Get a pointer to the mmd buffer for the host channel + // Simulation only mmd call as of 2024.1. HW MMD developer needs to implement + // this function in the future To support hostpipe sideband signals. + void *(*aocl_mmd_hostchannel_get_sideband_buffer)(int handle, int channel, + int port_id, + size_t *buffer_size, + int *status); + } acl_mmd_dispatch_t; typedef struct { diff --git a/include/acl_types.h b/include/acl_types.h index d018d7e0..c3892350 100644 --- a/include/acl_types.h +++ b/include/acl_types.h @@ -295,6 +295,12 @@ typedef struct host_op_struct { size_t m_size_sent; } host_op_t; +struct sideband_signal_t { + unsigned port_identifier; // matches enum signal_type in acl.h + unsigned port_offset; // in bit + unsigned side_band_size; // in bit +}; + typedef struct host_pipe_struct { // The handle to the device needed for mmd call unsigned int m_physical_device_id; @@ -337,6 +343,12 @@ typedef struct host_pipe_struct { int protocol = -1; // avalon_streaming = 0, avalon_streaming_uses_ready = 1 // avalon_mm = 2, avalon_mm_uses_ready = 3 + // Number of sideband signals. Exclude data port. + unsigned num_side_band_signals = 0; + + // Sideband signals vector + std::vector side_band_signals_vector; + } host_pipe_t; // The device-specific information about a program. @@ -617,7 +629,7 @@ typedef struct { const char *logical_name; // Use char* instead string here due to a // compilation error from acl_command_info_t // constructor malloc related - } host_pipe_info; + } host_pipe_dynamic_info; struct { // Used for device global ops diff --git a/src/acl_auto_configure.cpp b/src/acl_auto_configure.cpp index d665c839..6032a81e 100644 --- a/src/acl_auto_configure.cpp +++ b/src/acl_auto_configure.cpp @@ -681,6 +681,82 @@ static bool read_hostpipe_mappings( return result; } +/* +New section added in 2024.1 +- Number of group of sideband signals -> each group map to each hostpipe + For each sideband signal group + - pipe logical name + - number of sideband signals (including data field) + - number of fields for each sideband signal + - port identifier, like 0 for data, 1,2,3 for different sideband signals + - port offset (in bits) + - sideband size (in bits) + +If a hostpipe has no sideband signal (e.g, a pipe only has data field), it won't +have a sideband signal group. If none of the hostpipe has any sideband signals, +the whole section will just be 0, which represents the number of sideband signal +group is 0. + +*/ + +static bool read_sideband_mappings( + const std::string &config_str, std::string::size_type &curr_pos, + std::vector &sideband_signal_mappings, + std::vector &counters, std::string &err_str) noexcept { + + // Get how many hostpipes have sideband signals + unsigned int num_of_sideband_groups = 0; + bool result = read_uint_counters(config_str, curr_pos, num_of_sideband_groups, + counters); + + // If none of the hostpipes have sideband signals, this section ends here. + if (num_of_sideband_groups == 0) { + return result; + } + + // Reaching here means we need to parse sideband signals. + + for (unsigned int i = 0; result && (i < num_of_sideband_groups); i++) { + + std::string logical_name; + unsigned num_sideband_signals = 0; + result = + read_string_counters(config_str, curr_pos, logical_name, counters) && + read_uint_counters(config_str, curr_pos, num_sideband_signals, + counters); + assert(num_sideband_signals >= + 2); // If it has an entry, it must have 1 data signal + at least 1 + // sideband signals + + unsigned num_fields_per_sideband = 0; + if (result) { + result = read_uint_counters(config_str, curr_pos, num_fields_per_sideband, + counters); + } + + for (unsigned int j = 0; result && (j < num_sideband_signals); j++) { + counters.emplace_back(num_fields_per_sideband); + acl_sideband_signal_mapping mapping{}; + mapping.logical_name = logical_name; + result = read_uint_counters(config_str, curr_pos, mapping.port_identifier, + counters) && + read_uint_counters(config_str, curr_pos, mapping.port_offset, + counters) && + read_uint_counters(config_str, curr_pos, mapping.sideband_size, + counters); + sideband_signal_mappings.emplace_back(mapping); + + while (result && counters.back() > 0) { + std::string tmp; + result = read_string_counters(config_str, curr_pos, tmp, counters); + } + check_section_counters(counters); + counters.pop_back(); + } + } + return result; +} + static bool read_kernel_args(const std::string &config_str, const bool kernel_arg_info_available, std::string::size_type &curr_pos, @@ -1221,6 +1297,17 @@ bool acl_load_device_def_from_str(const std::string &config_str, config_str, curr_pos, devdef.hostpipe_mappings, counters, err_str); } + // Starting from 2024.1, there is a new section that adds sideband signal + // information. + + // Read program scoped hostpipes sideband signals mapping + + if (result && counters.back() > 0) { + result = read_sideband_mappings(config_str, curr_pos, + devdef.sideband_signal_mappings, counters, + err_str); + } + // forward compatibility: bypassing remaining fields at the end of device // description section while (result && counters.size() > 0 && diff --git a/src/acl_hal_mmd.cpp b/src/acl_hal_mmd.cpp index 704fa5ab..1c04870f 100644 --- a/src/acl_hal_mmd.cpp +++ b/src/acl_hal_mmd.cpp @@ -128,6 +128,14 @@ size_t acl_hal_mmd_hostchannel_pull(unsigned int physical_device_id, size_t acl_hal_mmd_hostchannel_push(unsigned int physical_device_id, int channel_handle, const void *host_buffer, size_t write_size, int *status); +size_t acl_hal_mmd_hostchannel_pull_no_ack(unsigned int physical_device_id, + int channel_handle, + void *host_buffer, size_t read_size, + int *status); +size_t acl_hal_mmd_hostchannel_push_no_ack(unsigned int physical_device_id, + int channel_handle, + const void *host_buffer, + size_t write_size, int *status); void *acl_hal_mmd_hostchannel_get_buffer(unsigned int physical_device_id, int channel_handle, size_t *buffer_size, int *status); @@ -178,6 +186,18 @@ int acl_hal_mmd_simulation_device_global_interface_write( unsigned int physical_device_id, const char *interface_name, const void *host_addr, size_t dev_addr, size_t size); +void *acl_hal_mmd_hostchannel_get_sideband_buffer( + unsigned int physical_device_id, unsigned int port_name, int channel_handle, + size_t *buffer_size, int *status); + +size_t acl_hal_mmd_hostchannel_sideband_pull_no_ack( + unsigned int physical_device_id, unsigned int port_name, int channel_handle, + void *host_buffer, size_t read_size, int *status); + +size_t acl_hal_mmd_hostchannel_sideband_push_no_ack( + unsigned int physical_device_id, unsigned int port_name, int channel_handle, + const void *host_buffer, size_t write_size, int *status); + static size_t acl_kernel_if_read(acl_bsp_io *io, dev_addr_t src, char *dest, size_t size); static size_t acl_kernel_if_write(acl_bsp_io *io, dev_addr_t dest, @@ -376,6 +396,11 @@ static acl_hal_t acl_hal_mmd = { acl_hal_mmd_write_csr, // write_csr acl_hal_mmd_simulation_device_global_interface_read, // simulation_device_global_interface_read acl_hal_mmd_simulation_device_global_interface_write, // simulation_device_global_interface_write + acl_hal_mmd_hostchannel_get_sideband_buffer, // hostchannel_get_sideband_buffer + acl_hal_mmd_hostchannel_sideband_pull_no_ack, // hostchannel_sideband_push + acl_hal_mmd_hostchannel_sideband_push_no_ack, // hostchannel_sideband_push + acl_hal_mmd_hostchannel_pull_no_ack, // hostchannel_pull_no_ack + acl_hal_mmd_hostchannel_push_no_ack, // hostchannel_push_no_ack }; // This will contain the device physical id to tell us which device across all @@ -2303,6 +2328,74 @@ size_t acl_hal_mmd_hostchannel_push(unsigned int physical_device_id, return pushed; } +size_t acl_hal_mmd_hostchannel_pull_no_ack(unsigned int physical_device_id, + int channel_handle, + void *host_buffer, size_t read_size, + int *status) { + size_t buffer_size = 0; + size_t pulled; + int pcie_dev_handle; + void *pull_buffer; + + *status = 0; + pcie_dev_handle = device_info[physical_device_id].handle; + + assert(device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_buffer); + pull_buffer = device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_buffer( + pcie_dev_handle, channel_handle, &buffer_size, status); + + if ((NULL == pull_buffer) || (0 == buffer_size)) { + return 0; + } + + // How much can be pulled to user buffer + buffer_size = (read_size > buffer_size) ? buffer_size : read_size; + + // Copy the data into the user buffer + safe_memcpy(host_buffer, pull_buffer, buffer_size, buffer_size, buffer_size); + + pulled = buffer_size; + + return pulled; +} + +size_t acl_hal_mmd_hostchannel_push_no_ack(unsigned int physical_device_id, + int channel_handle, + const void *host_buffer, + size_t write_size, int *status) { + size_t buffer_size = 0; + size_t pushed; + int pcie_dev_handle; + void *push_buffer; + + *status = 0; + pcie_dev_handle = device_info[physical_device_id].handle; + + // get the pointer to host channel push buffer + assert(device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_buffer); + + push_buffer = device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_buffer( + pcie_dev_handle, channel_handle, &buffer_size, status); + + if ((NULL == push_buffer) || (0 == buffer_size)) { + return 0; + } + + // How much can be pushed to push buffer + buffer_size = (write_size > buffer_size) ? buffer_size : write_size; + + // Copy the data into the push buffer + + safe_memcpy(push_buffer, host_buffer, buffer_size, buffer_size, buffer_size); + + pushed = buffer_size; + return pushed; +} + void *acl_hal_mmd_hostchannel_get_buffer(unsigned int physical_device_id, int channel_handle, size_t *buffer_size, int *status) { @@ -2929,4 +3022,91 @@ int acl_hal_mmd_simulation_device_global_interface_write( .mmd_dispatch->aocl_mmd_simulation_device_global_interface_write( device_info[physical_device_id].handle, interface_name, host_addr, dev_addr, size); +} + +void *acl_hal_mmd_hostchannel_get_sideband_buffer( + unsigned int physical_device_id, unsigned int port_name, int channel_handle, + size_t *buffer_size, int *status) { + + int pcie_dev_handle; + + pcie_dev_handle = device_info[physical_device_id].handle; + *status = 0; + + // get the pointer to host channel mmd buffer + assert(device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_sideband_buffer); + return device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_sideband_buffer( + pcie_dev_handle, channel_handle, port_name, buffer_size, status); +} + +size_t acl_hal_mmd_hostchannel_sideband_pull_no_ack( + unsigned int physical_device_id, unsigned int port_name, int channel_handle, + void *host_buffer, size_t read_size, int *status) { + + size_t buffer_size = 0; + size_t pulled; + int pcie_dev_handle; + void *pull_buffer; + + *status = 0; + pcie_dev_handle = device_info[physical_device_id].handle; + + assert(device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_sideband_buffer); + pull_buffer = + device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_sideband_buffer( + pcie_dev_handle, channel_handle, port_name, &buffer_size, status); + + if ((NULL == pull_buffer) || (0 == buffer_size)) { + return 0; + } + + // How much can be pulled to user buffer + buffer_size = (read_size > buffer_size) ? buffer_size : read_size; + + // Copy the data into the user buffer + safe_memcpy(host_buffer, pull_buffer, buffer_size, buffer_size, buffer_size); + + pulled = buffer_size; + + return pulled; +} + +size_t acl_hal_mmd_hostchannel_sideband_push_no_ack( + unsigned int physical_device_id, unsigned int port_name, int channel_handle, + const void *host_buffer, size_t write_size, int *status) { + + size_t buffer_size = 0; + size_t pushed; + int pcie_dev_handle; + void *push_buffer; + + *status = 0; + pcie_dev_handle = device_info[physical_device_id].handle; + + // get the pointer to host channel push buffer + assert(device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_sideband_buffer); + + push_buffer = + device_info[physical_device_id] + .mmd_dispatch->aocl_mmd_hostchannel_get_sideband_buffer( + pcie_dev_handle, channel_handle, port_name, &buffer_size, status); + + if ((NULL == push_buffer) || (0 == buffer_size)) { + return 0; + } + + // How much can be pushed to push buffer + buffer_size = (write_size > buffer_size) ? buffer_size : write_size; + + // Copy the data into the push buffer + + safe_memcpy(push_buffer, host_buffer, buffer_size, buffer_size, buffer_size); + + pushed = buffer_size; + return pushed; } \ No newline at end of file diff --git a/src/acl_hostch.cpp b/src/acl_hostch.cpp index 4e852114..19213efb 100644 --- a/src/acl_hostch.cpp +++ b/src/acl_hostch.cpp @@ -59,6 +59,97 @@ static cl_int l_push_packet(unsigned int physical_device_id, int channel_handle, } } +static cl_int l_push_sideband_packet(unsigned int physical_device_id, + int channel_handle, + const void *host_buffer, size_t write_size, + host_pipe_t &host_pipe_info) { + // This pipe has sideband signals, need to break into data section and + // sideband signal sections + int status = 0; + bool final_status = true; + size_t total_pushed = 0; + for (auto const &sideband_signal_entry : + host_pipe_info.side_band_signals_vector) { + size_t pushed_data; + if (sideband_signal_entry.port_identifier == AvalonData) { + pushed_data = acl_get_hal()->hostchannel_push_no_ack( + host_pipe_info.m_physical_device_id, host_pipe_info.m_channel_handle, + (const void *)((char *)host_buffer + + sideband_signal_entry.port_offset / 8), + sideband_signal_entry.side_band_size / 8, &status); + } else { + // this is sideband signal + pushed_data = acl_get_hal()->hostchannel_sideband_push_no_ack( + host_pipe_info.m_physical_device_id, + sideband_signal_entry.port_identifier, + host_pipe_info.m_channel_handle, + (const void *)((char *)host_buffer + + sideband_signal_entry.port_offset / 8), + sideband_signal_entry.side_band_size / 8, &status); + } + final_status = final_status && status; + if (pushed_data == 0) { + return CL_PIPE_FULL; + } + total_pushed += pushed_data; + } + // Now need to acknowledge + size_t acked_size; + + acked_size = acl_get_hal()->hostchannel_ack_buffer( + host_pipe_info.m_physical_device_id, host_pipe_info.m_channel_handle, + total_pushed, &status); + + if (acked_size == 0) { + return CL_PIPE_FULL; + } + + status = final_status && status; + return status; +} + +static size_t l_pull_sideband_packet(unsigned int physical_device_id, + int channel_handle, + const void *host_buffer, size_t write_size, + host_pipe_t &host_pipe_info, int &status) { + bool final_status = true; + size_t total_pulled_data = 0; + for (auto const &sideband_signal_entry : + host_pipe_info.side_band_signals_vector) { + size_t pulled_data; + if (sideband_signal_entry.port_identifier == AvalonData) { + pulled_data = acl_get_hal()->hostchannel_pull_no_ack( + host_pipe_info.m_physical_device_id, host_pipe_info.m_channel_handle, + (void *)((char *)host_buffer + sideband_signal_entry.port_offset / 8), + sideband_signal_entry.side_band_size / 8, &status); + } else { + // this is sideband signal + pulled_data = acl_get_hal()->hostchannel_sideband_pull_no_ack( + host_pipe_info.m_physical_device_id, + sideband_signal_entry.port_identifier, + host_pipe_info.m_channel_handle, + (void *)((char *)host_buffer + sideband_signal_entry.port_offset / 8), + sideband_signal_entry.side_band_size / 8, &status); + } + final_status = final_status && status; + if (pulled_data == 0) { + return 0; + } + total_pulled_data += pulled_data; + } + // Now need to acknowledge + size_t acked_size; + + acked_size = acl_get_hal()->hostchannel_ack_buffer( + host_pipe_info.m_physical_device_id, host_pipe_info.m_channel_handle, + total_pulled_data, &status); + if (acked_size == 0) { + return 0; + } + status = final_status && status; + return total_pulled_data; +} + static void l_clean_up_pending_pipe_ops(cl_mem pipe) { size_t acked_size = 0; int status = 0; @@ -708,7 +799,7 @@ void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op) { cl_event event = op->info.event; cl_int status = 0; size_t pulled_data = 0; - bool blocking = event->cmd.info.host_pipe_info.blocking; + bool blocking = event->cmd.info.host_pipe_dynamic_info.blocking; acl_assert_locked(); if (!acl_event_is_valid(event) || @@ -717,10 +808,16 @@ void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op) { return; } + // Difference between event->cmd.info.host_pipe_dynamic_info + // And host_pipe_info. + // Event member contains dynamic information like data and size + // The host_pipe_info stored in the dev_prog->program_hostpipe_map + // Contains the static information of the pipe, like protocol + acl_device_program_info_t *dev_prog = event->command_queue->device->loaded_bin->get_dev_prog(); auto host_pipe_info = dev_prog->program_hostpipe_map.at( - std::string(event->cmd.info.host_pipe_info.logical_name)); + std::string(event->cmd.info.host_pipe_dynamic_info.logical_name)); acl_mutex_lock(&(host_pipe_info.m_lock)); acl_set_device_op_execution_status(op, CL_SUBMITTED); acl_set_device_op_execution_status(op, CL_RUNNING); @@ -771,8 +868,8 @@ void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op) { // start the CSR read auto status = acl_get_hal()->read_csr(host_pipe_info.m_physical_device_id, data_reg, - event->cmd.info.host_pipe_info.ptr, - event->cmd.info.host_pipe_info.size); + event->cmd.info.host_pipe_dynamic_info.ptr, + event->cmd.info.host_pipe_dynamic_info.size); if (status != 0) { acl_mutex_unlock(&(host_pipe_info.m_lock)); acl_set_device_op_execution_status(op, -1); @@ -786,10 +883,19 @@ void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op) { } } else { // Non CSR Case - pulled_data = acl_get_hal()->hostchannel_pull( - host_pipe_info.m_physical_device_id, host_pipe_info.m_channel_handle, - event->cmd.info.host_pipe_info.ptr, event->cmd.info.host_pipe_info.size, - &status); + if (host_pipe_info.num_side_band_signals == 0) { + pulled_data = acl_get_hal()->hostchannel_pull( + host_pipe_info.m_physical_device_id, host_pipe_info.m_channel_handle, + event->cmd.info.host_pipe_dynamic_info.ptr, + event->cmd.info.host_pipe_dynamic_info.size, &status); + } else { + // This pipe has sideband signals, need to break into data section and + // sideband signal sections + pulled_data = l_pull_sideband_packet( + host_pipe_info.m_physical_device_id, host_pipe_info.m_channel_handle, + event->cmd.info.host_pipe_dynamic_info.ptr, + event->cmd.info.host_pipe_dynamic_info.size, host_pipe_info, status); + } if (!blocking) { // If it is non-blocking read, we return with the success code right away @@ -808,10 +914,20 @@ void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op) { // are fully implemented. Right now we consider the result is good as long // as pulled_data > 0. while (status != 0 || pulled_data == 0) { - pulled_data = acl_get_hal()->hostchannel_pull( - host_pipe_info.m_physical_device_id, - host_pipe_info.m_channel_handle, event->cmd.info.host_pipe_info.ptr, - event->cmd.info.host_pipe_info.size, &status); + if (host_pipe_info.num_side_band_signals == 0) { + pulled_data = acl_get_hal()->hostchannel_pull( + host_pipe_info.m_physical_device_id, + host_pipe_info.m_channel_handle, + event->cmd.info.host_pipe_dynamic_info.ptr, + event->cmd.info.host_pipe_dynamic_info.size, &status); + } else { + pulled_data = l_pull_sideband_packet( + host_pipe_info.m_physical_device_id, + host_pipe_info.m_channel_handle, + event->cmd.info.host_pipe_dynamic_info.ptr, + event->cmd.info.host_pipe_dynamic_info.size, host_pipe_info, + status); + } acl_update_device_op_queue(&(acl_platform.device_op_queue)); } } @@ -825,7 +941,7 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) { cl_int status; cl_event event = op->info.event; - bool blocking = event->cmd.info.host_pipe_info.blocking; + bool blocking = event->cmd.info.host_pipe_dynamic_info.blocking; acl_assert_locked(); if (!acl_event_is_valid(event) || @@ -834,10 +950,16 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) { return; } + // Difference between event->cmd.info.host_pipe_dynamic_info + // And host_pipe_info. + // Event member contains dynamic information like data and size + // The host_pipe_info stored in the dev_prog->program_hostpipe_map + // Contains the static information of the pipe, like protocol + acl_device_program_info_t *dev_prog = event->command_queue->device->loaded_bin->get_dev_prog(); auto host_pipe_info = dev_prog->program_hostpipe_map.at( - std::string(event->cmd.info.host_pipe_info.logical_name)); + std::string(event->cmd.info.host_pipe_dynamic_info.logical_name)); acl_mutex_lock(&(host_pipe_info.m_lock)); acl_set_device_op_execution_status(op, CL_SUBMITTED); acl_set_device_op_execution_status(op, CL_RUNNING); @@ -859,10 +981,10 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) { // this to the autodiscovery string maybe unsigned int valid = 1; // start the write - auto status = - acl_get_hal()->write_csr(host_pipe_info.m_physical_device_id, data_reg, - event->cmd.info.host_pipe_info.write_ptr, - event->cmd.info.host_pipe_info.size); + auto status = acl_get_hal()->write_csr( + host_pipe_info.m_physical_device_id, data_reg, + event->cmd.info.host_pipe_dynamic_info.write_ptr, + event->cmd.info.host_pipe_dynamic_info.size); if (status != 0) { acl_mutex_unlock(&(host_pipe_info.m_lock)); acl_set_device_op_execution_status(op, -1); @@ -890,10 +1012,17 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) { } else { // Regular hostpipe // Attempt to write once - status = l_push_packet(host_pipe_info.m_physical_device_id, - host_pipe_info.m_channel_handle, - event->cmd.info.host_pipe_info.write_ptr, - event->cmd.info.host_pipe_info.size); + if (host_pipe_info.num_side_band_signals == 0) { + status = l_push_packet(host_pipe_info.m_physical_device_id, + host_pipe_info.m_channel_handle, + event->cmd.info.host_pipe_dynamic_info.write_ptr, + event->cmd.info.host_pipe_dynamic_info.size); + } else { + status = l_push_sideband_packet( + host_pipe_info.m_physical_device_id, host_pipe_info.m_channel_handle, + event->cmd.info.host_pipe_dynamic_info.write_ptr, + event->cmd.info.host_pipe_dynamic_info.size, host_pipe_info); + } if (!blocking) { // If it is non-blocking write, we return with the success/failure code // right away @@ -906,10 +1035,19 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) { // If it's a blocking write, this function won't return until the write // success. while (status != CL_SUCCESS) { - status = l_push_packet(host_pipe_info.m_physical_device_id, - host_pipe_info.m_channel_handle, - event->cmd.info.host_pipe_info.write_ptr, - event->cmd.info.host_pipe_info.size); + if (host_pipe_info.num_side_band_signals == 0) { + status = + l_push_packet(host_pipe_info.m_physical_device_id, + host_pipe_info.m_channel_handle, + event->cmd.info.host_pipe_dynamic_info.write_ptr, + event->cmd.info.host_pipe_dynamic_info.size); + } else { + status = l_push_sideband_packet( + host_pipe_info.m_physical_device_id, + host_pipe_info.m_channel_handle, + event->cmd.info.host_pipe_dynamic_info.write_ptr, + event->cmd.info.host_pipe_dynamic_info.size, host_pipe_info); + } acl_update_device_op_queue(&(acl_platform.device_op_queue)); } } @@ -1047,10 +1185,10 @@ CL_API_ENTRY cl_int CL_API_CALL clEnqueueReadHostPipeINTEL( if (status != CL_SUCCESS) return status; - local_event->cmd.info.host_pipe_info.size = size; - local_event->cmd.info.host_pipe_info.ptr = ptr; - local_event->cmd.info.host_pipe_info.blocking = blocking_read; - local_event->cmd.info.host_pipe_info.logical_name = pipe_symbol; + local_event->cmd.info.host_pipe_dynamic_info.size = size; + local_event->cmd.info.host_pipe_dynamic_info.ptr = ptr; + local_event->cmd.info.host_pipe_dynamic_info.blocking = blocking_read; + local_event->cmd.info.host_pipe_dynamic_info.logical_name = pipe_symbol; acl_idle_update( command_queue @@ -1114,10 +1252,10 @@ CL_API_ENTRY cl_int CL_API_CALL clEnqueueWriteHostPipeINTEL( if (status != CL_SUCCESS) return status; - local_event->cmd.info.host_pipe_info.size = size; - local_event->cmd.info.host_pipe_info.write_ptr = ptr; - local_event->cmd.info.host_pipe_info.blocking = blocking_write; - local_event->cmd.info.host_pipe_info.logical_name = pipe_symbol; + local_event->cmd.info.host_pipe_dynamic_info.size = size; + local_event->cmd.info.host_pipe_dynamic_info.write_ptr = ptr; + local_event->cmd.info.host_pipe_dynamic_info.blocking = blocking_write; + local_event->cmd.info.host_pipe_dynamic_info.logical_name = pipe_symbol; acl_idle_update( command_queue diff --git a/src/acl_program.cpp b/src/acl_program.cpp index f4dc2054..e4698650 100644 --- a/src/acl_program.cpp +++ b/src/acl_program.cpp @@ -1374,6 +1374,41 @@ l_register_hostpipes_to_program(acl_device_program_info_t *dev_prog, dev_prog->program_hostpipe_map[hostpipe.logical_name] = host_pipe_info; } + // Start from 2024.1, Runtime receives sideband signals information + for (const auto &sideband_signal_mapping : + dev_prog->device_binary.get_devdef() + .autodiscovery_def.sideband_signal_mappings) { + + // Skip if the sideband_signal doesn't have a logical name. + // It's not the program scoped hostpipe. + if (sideband_signal_mapping.logical_name == "-") { + continue; + } + + // The hostpipe hostpipe logical name must be found in the program + auto search = dev_prog->program_hostpipe_map.find( + sideband_signal_mapping.logical_name); + if (search == dev_prog->program_hostpipe_map.end()) { + ERR_RET(CL_INVALID_VALUE, context, + "Sideband signal is binded to non-exist hostpipe"); + } + + auto &host_pipe_info = + dev_prog->program_hostpipe_map.at(sideband_signal_mapping.logical_name); + if (sideband_signal_mapping.port_identifier != AvalonData) { + host_pipe_info.num_side_band_signals++; + } + + // Store the sideband info into the hostpipe info. + sideband_signal_t sideband_signal_info; + sideband_signal_info.port_identifier = + sideband_signal_mapping.port_identifier; + sideband_signal_info.port_offset = sideband_signal_mapping.port_offset; + sideband_signal_info.side_band_size = sideband_signal_mapping.sideband_size; + + host_pipe_info.side_band_signals_vector.emplace_back(sideband_signal_info); + } + return CL_SUCCESS; } diff --git a/test/acl_auto_configure_test.cpp b/test/acl_auto_configure_test.cpp index 28200da5..fb3adfd1 100644 --- a/test/acl_auto_configure_test.cpp +++ b/test/acl_auto_configure_test.cpp @@ -493,15 +493,21 @@ TEST(auto_configure, many_ok_forward_compatibility) { // sections and subsections to check forward compatibility std::string str(VERSIONIDTOSTR( - ACL_AUTO_CONFIGURE_VERSIONID) " 51 " + ACL_AUTO_CONFIGURE_VERSIONID) " 52 " "sample40byterandomhash000000000000000000 " "a10gx 0 1 17 DDR 2 1 6 0 2147483648 100 " "100 100 100 0 - 0 200 200 200 200 0 0 0 " - "2 10 ms_dev_global1 0x800 1024 3 0 0 0 " + "2 10 " // Two device global below each has + // 10 fields + "ms_dev_global1 0x800 1024 3 0 0 0 300 300 " "300 " - "300 300 ms_dev_global2 0x1000 1024 1 1 1 " - "0 " - "300 300 300 0 0 400 400 47 " + "ms_dev_global2 0x1000 1024 1 1 1 0 300 " + "300 300 " + "0 " // cra_ring_root_exist + "0 " // num of hostpipe mappings + "0 " // num of hostpipe mapping field + "0 " // Number of groups of sideband signals + "400 47 " // future fields "40 external_sort_stage_0 0 128 1 0 0 1 0 " "1 0 1 10 0 0 4 1 0 0 0 500 500 500 0 0 " "0 0 1 1 1 3 1 1 1 3 1 0 0 800 800 800 " @@ -1573,3 +1579,91 @@ TEST(auto_configure, hostpipe_mappings) { CHECK(devdef.hostpipe_mappings[4].pipe_depth == 10); CHECK(devdef.hostpipe_mappings[4].protocol == 3); } + +TEST(auto_configure, sideband_mappings) { + const std::string config_str{ + "23 102 " RANDOM_HASH + " pac_a10 0 1 13 DDR 2 2 24 1 2 0 4294967296 4294967296 8589934592 0 - 0 " + "0 0 0 0 0 1 5 9 " // 5 Hostpipes, 9 in each mapping + "pipe_logical_name1 pipe_physical_name1 1 12345 0 1 4 10 0 " + "pipe_logical_name2 pipe_physical_name2 0 12323 1 0 8 20 1 " + "pipe_logical_name3 pipe_physical_name1 1 12313 0 1 4 10 2 " + "pipe_logical_name5 pipe_physical_name1 0 12316 1 0 8 20 3 " + "pipe_logical_name4 pipe_physical_name3 0 12342 0 1 4 10 3 " + "2 " // 2 Sideband groups + "pipe_logical_name1 4 3 0 0 320 1 320 8 2 328 8 3 352 32 " + "pipe_logical_name2 4 3 0 0 320 1 320 8 2 328 8 3 352 32 " + // Kernel section starts below + "3 90 " + "_ZTS3CRCILi0EE 512 256 1 0 0 1 0 1 0 9 6 0 0 8 1 0 0 6 2 1 8 1024 0 3 6 " + "0 0 8 1 0 0 6 0 0 8 1 0 0 6 0 0 8 1 0 0 6 2 1 8 1024 0 2 6 0 0 8 1 0 0 " + "6 0 0 8 1 0 0 6 0 0 8 1 0 0 0 0 1 2 64 4096 1 1 1 3 1 1 1 3 1 0 64 " + "_ZTS11LZReductionILi0EE 0 256 1 0 0 0 0 1 0 5 6 0 0 8 1 0 0 6 2 1 8 " + "1024 0 3 6 0 0 8 1 0 0 6 0 0 8 1 0 0 6 0 0 8 1 0 0 0 0 2 2 64 131072 65 " + "32768 1 1 1 3 1 1 1 3 1 0 125 _ZTS13StaticHuffmanILi0EE 256 256 1 0 0 1 " + "0 1 0 10 6 0 0 8 1 0 0 6 0 0 4 1 0 0 6 2 1 8 1024 0 2 6 0 0 8 1 0 0 6 0 " + "0 8 1 0 0 6 0 0 8 1 0 0 6 2 1 8 1024 0 2 6 0 0 8 1 0 0 6 0 0 8 1 0 0 6 " + "0 0 8 1 0 0 0 0 15 2 64 116 65 116 66 1152 67 512 68 256 69 120 70 120 " + "71 1152 72 116 73 1152 74 512 75 256 76 120 77 120 78 1152 1 1 1 3 1 1 " + "1 3 1 0"}; + + acl_device_def_autodiscovery_t devdef; + { + bool result; + std::string err_str; + ACL_LOCKED(result = + acl_load_device_def_from_str(config_str, devdef, err_str)); + std::cerr << err_str; + CHECK(result); + } + + CHECK_EQUAL(8, devdef.sideband_signal_mappings.size()); + + CHECK(devdef.sideband_signal_mappings[0].logical_name == + "pipe_logical_name1"); + CHECK(devdef.sideband_signal_mappings[0].port_identifier == 0); + CHECK(devdef.sideband_signal_mappings[0].port_offset == 0); + CHECK(devdef.sideband_signal_mappings[0].sideband_size == 320); + + CHECK(devdef.sideband_signal_mappings[1].logical_name == + "pipe_logical_name1"); + CHECK(devdef.sideband_signal_mappings[1].port_identifier == 1); + CHECK(devdef.sideband_signal_mappings[1].port_offset == 320); + CHECK(devdef.sideband_signal_mappings[1].sideband_size == 8); + + CHECK(devdef.sideband_signal_mappings[2].logical_name == + "pipe_logical_name1"); + CHECK(devdef.sideband_signal_mappings[2].port_identifier == 2); + CHECK(devdef.sideband_signal_mappings[2].port_offset == 328); + CHECK(devdef.sideband_signal_mappings[2].sideband_size == 8); + + CHECK(devdef.sideband_signal_mappings[3].logical_name == + "pipe_logical_name1"); + CHECK(devdef.sideband_signal_mappings[3].port_identifier == 3); + CHECK(devdef.sideband_signal_mappings[3].port_offset == 352); + CHECK(devdef.sideband_signal_mappings[3].sideband_size == 32); + + CHECK(devdef.sideband_signal_mappings[4].logical_name == + "pipe_logical_name2"); + CHECK(devdef.sideband_signal_mappings[4].port_identifier == 0); + CHECK(devdef.sideband_signal_mappings[4].port_offset == 0); + CHECK(devdef.sideband_signal_mappings[4].sideband_size == 320); + + CHECK(devdef.sideband_signal_mappings[5].logical_name == + "pipe_logical_name2"); + CHECK(devdef.sideband_signal_mappings[5].port_identifier == 1); + CHECK(devdef.sideband_signal_mappings[5].port_offset == 320); + CHECK(devdef.sideband_signal_mappings[5].sideband_size == 8); + + CHECK(devdef.sideband_signal_mappings[6].logical_name == + "pipe_logical_name2"); + CHECK(devdef.sideband_signal_mappings[6].port_identifier == 2); + CHECK(devdef.sideband_signal_mappings[6].port_offset == 328); + CHECK(devdef.sideband_signal_mappings[6].sideband_size == 8); + + CHECK(devdef.sideband_signal_mappings[7].logical_name == + "pipe_logical_name2"); + CHECK(devdef.sideband_signal_mappings[7].port_identifier == 3); + CHECK(devdef.sideband_signal_mappings[7].port_offset == 352); + CHECK(devdef.sideband_signal_mappings[7].sideband_size == 32); +}