diff --git a/include/acl.h b/include/acl.h index b3e6d6f2..d91f4a6d 100644 --- a/include/acl.h +++ b/include/acl.h @@ -381,6 +381,8 @@ typedef struct { return result; } + + std::string id = "-"; } acl_system_global_mem_def_t; // Our allocator is optimized for simplicity, and for the case where there diff --git a/src/acl_auto_configure.cpp b/src/acl_auto_configure.cpp index 219d0bb1..ec9da39d 100644 --- a/src/acl_auto_configure.cpp +++ b/src/acl_auto_configure.cpp @@ -278,6 +278,8 @@ read_global_mem_defs(const std::string &config_str, for (auto i = 0U; result && (i < num_global_mem_systems); i++) { std::string gmem_name; + std::string gmem_id = "-"; // This should be the default value even if the + // auto-discovery string doesn't have this field. // read total number of fields in global_memories int total_fields_global_memories = 0; result = read_int_counters(config_str, curr_pos, @@ -403,6 +405,12 @@ read_global_mem_defs(const std::string &config_str, can_access.push_back(temp); } } + + // read global memory id field. If it doesn't exist, then the value is "-" + // It's a new field introduced from 2024.2 + if (result && counters.back() > 0) { + result = read_string_counters(config_str, curr_pos, gmem_id, counters); + } } if (result) { @@ -428,6 +436,7 @@ read_global_mem_defs(const std::string &config_str, global_mem_defs[i].allocation_type = allocation_type; global_mem_defs[i].primary_interface = primary_interface; global_mem_defs[i].can_access_list = can_access; + global_mem_defs[i].id = gmem_id; } // forward compatibility: bypassing remaining fields at the end of global diff --git a/src/acl_mem.cpp b/src/acl_mem.cpp index f724a7fd..9cf72ee4 100644 --- a/src/acl_mem.cpp +++ b/src/acl_mem.cpp @@ -437,6 +437,64 @@ CL_API_ENTRY cl_mem clCreateBufferWithPropertiesINTEL( } break; case CL_MEM_ALLOC_BUFFER_LOCATION_INTEL: { tmp_mem_id = (cl_uint) * (properties + 1); + + // In FullSystem flow, buffer location is always the index of the global + // memories. Therefore, there is no additional handling needed for FS. + + // However, in SYCL_HLS(IPA) flow, the user passed buffer_location + // maps to the global memory with the same id. Runtime needs to find the + // correct index of the global memory with that id. The id filed is + // introduced in 2024.2 in auto-discovery string. This change is for + // accessor only and the USM buffer location change is done in the + // simulator. + + // Runtime needs to determine whether it's FS or SYCL_HLS first by + // checking if the global memory id exist or not. If exists, then it's + // SYCL_HLS flow. + bool is_SYCL_HLS = false; + + // We document the limitation here: + // https://www.intel.com/content/www/us/en/docs/oneapi-fpga-add-on/ + // developer-guide/2024-0/targeting-multiple-homogeneous-fpga-devices.html + // All FPGA devices used must be of the same FPGA card (same -Xstarget + // target). There might be some workaround supporting multi-device with + // different boards but they are for FS, not for SYCL_HLS. + + // Therefore, we can safely assume all devices have the same + // global_mem_defs in SYCL_HLS flow as of 2024.2. So we can just check + // acl_platform.device[0]. + + auto global_mem_defs = + acl_platform.device[0].def.autodiscovery_def.global_mem_defs; + + for (const auto &global_mem_def : global_mem_defs) { + if (global_mem_def.id != "-") { + is_SYCL_HLS = true; + break; + } + } + + if (is_SYCL_HLS) { + // find the correct index in the global memory + long index = -1; + for (auto it = begin(global_mem_defs); it != end(global_mem_defs); + ++it) { + if (stoul(it->id) == tmp_mem_id) { + index = it - global_mem_defs.begin(); + break; + } + } + + if (index == -1) { + BAIL_INFO(CL_INVALID_VALUE, context, + "Invalid Buffer Location id provided"); + } + + // Update the tmp_mem_id to the corect index in the global memories + // vector. + tmp_mem_id = static_cast(index); + } + } break; default: { BAIL_INFO(CL_INVALID_DEVICE, context, "Invalid properties"); diff --git a/src/acl_program.cpp b/src/acl_program.cpp index 86929df2..cf01c8e0 100644 --- a/src/acl_program.cpp +++ b/src/acl_program.cpp @@ -2125,6 +2125,7 @@ l_device_memory_definition_copy(acl_device_def_autodiscovery_t *dest_dev, src_dev->global_mem_defs[idef].primary_interface; dest_dev->global_mem_defs[idef].can_access_list = src_dev->global_mem_defs[idef].can_access_list; + dest_dev->global_mem_defs[idef].id = src_dev->global_mem_defs[idef].id; } } diff --git a/test/acl_auto_configure_test.cpp b/test/acl_auto_configure_test.cpp index e763ffae..ed826981 100644 --- a/test/acl_auto_configure_test.cpp +++ b/test/acl_auto_configure_test.cpp @@ -1672,3 +1672,39 @@ TEST(auto_configure, sideband_mappings) { CHECK(devdef.sideband_signal_mappings[7].port_offset == 352); CHECK(devdef.sideband_signal_mappings[7].sideband_size == 32); } + +TEST(auto_configure, global_mem_id) { + const std::string config_str{ + "23 46 " RANDOM_HASH " custom_ipa 0 3 " + " 10 1 2 1 2 2199023255552 2233382993920 4 - 0 1" // Global memory 1 + " 10 3 2 1 2 6597069766656 6631429505024 4 - 0 3" // Global memory 2 + " 10 5 2 1 2 10995116277760 11029476016128 4 - 0 5" // Global memory 3 + " 0 0 0 0 0 1 0 0" + " 0 2 133 _ZTS10SimpleVAddIiE 0 256 1 0 0 1 0 1 0 13 8 2 1 8" + " 1 1 5 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 8" + " 2 1 8 1 1 3 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0" + " 0 0 8 2 1 8 1 1 1 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 7 0 0" + " 8 1 0 0 0 7 0 0 4 1 0 0 0 0 0 0 0 1 1 1 3 1 1 1 0 1 1 0 133 " + " _ZTS10SimpleVAddIfE 256 256 1 0 0 1 0 1 0 13 8 2 1 8 1 1 5 0" + " 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 8 2 1 8 1 1" + " 3 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 8 2 1 8" + " 1 1 1 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 7 0 0 8 1 0 0 0 7 0" + " 0 4 1 0 0 0 0 0 0 0 1 1 1 3 1 1 1 0 1 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("1" == devdef.global_mem_defs[0].name); + CHECK("1" == devdef.global_mem_defs[0].id); + CHECK("3" == devdef.global_mem_defs[1].name); + CHECK("3" == devdef.global_mem_defs[1].id); + CHECK("5" == devdef.global_mem_defs[2].name); + CHECK("5" == devdef.global_mem_defs[2].id); +}