diff --git a/tt_metal/hw/toolchain/main.ld b/tt_metal/hw/toolchain/main.ld index 8cee67693d8..03732862192 100644 --- a/tt_metal/hw/toolchain/main.ld +++ b/tt_metal/hw/toolchain/main.ld @@ -306,7 +306,8 @@ SECTIONS LONG(TEXT_SIZE #if defined(TYPE_KERNEL) && !(defined(COMPILE_FOR_NCRISC) && defined(ARCH_WORMHOLE)) \ && !defined(COMPILE_FOR_AERISC) && !defined(COMPILE_FOR_SUBORDINATE_AERISC) \ - && !defined(COMPILE_FOR_MAIN_AERISC) + && !defined(COMPILE_FOR_MAIN_AERISC) \ + && !(defined(ARCH_BLACKHOLE) && (defined(COMPILE_FOR_IERISC) || defined(COMPILE_FOR_SUBORDINATE_IERISC))) - (__fw_export_text_end - TEXT_START) #endif ) diff --git a/tt_metal/impl/dispatch/dispatch_query_manager.cpp b/tt_metal/impl/dispatch/dispatch_query_manager.cpp index 38c31376178..fef7bafe6cd 100644 --- a/tt_metal/impl/dispatch/dispatch_query_manager.cpp +++ b/tt_metal/impl/dispatch/dispatch_query_manager.cpp @@ -148,6 +148,15 @@ void DispatchQueryManager::reset(DispatchCoreConfig& dispatch_core_config, uint8 (num_hw_cqs == 1 or dispatch_core_config_.get_dispatch_core_type() == DispatchCoreType::WORKER); distributed_dispatcher_ = (num_hw_cqs == 1 and dispatch_core_config_.get_dispatch_core_type() == DispatchCoreType::ETH); + // Blackhole ETH dispatch with 1 CQ needs 3 idle ETH cores (prefetch, dispatch, dispatch_s). + // Galaxy BH chips only have 2 idle ETH cores (the rest are trained links), so fall back to + // running without dispatch_s (dispatch_d sends go signals), which needs only 2 cores. + if (arch == tt::ARCH::BLACKHOLE and num_hw_cqs == 1 and + dispatch_core_config_.get_dispatch_core_type() == DispatchCoreType::ETH and + populate_all_logical_dispatch_cores(env_, num_hw_cqs_, dispatch_core_config_).size() < 3) { + dispatch_s_enabled_ = false; + distributed_dispatcher_ = false; + } } go_signal_noc_ = (dispatch_s_enabled_ and arch != tt::ARCH::QUASAR) ? NOC::NOC_1 : NOC::NOC_0; diff --git a/tt_metal/impl/dispatch/topology.cpp b/tt_metal/impl/dispatch/topology.cpp index 3dc6377b652..813787a2bf5 100644 --- a/tt_metal/impl/dispatch/topology.cpp +++ b/tt_metal/impl/dispatch/topology.cpp @@ -130,6 +130,12 @@ static const std::vector single_chip_arch_1cq = { {2, 0, 0, 0, DISPATCH_S, {0, x, x, x}, {1, x, x, x}, k_dispatcher_s_noc}, }; +// 1 CQ without dispatch_s (used for Blackhole ETH dispatch when only 2 idle ETH cores exist) +static const std::vector single_chip_arch_1cq_no_dispatch_s = { + {0, 0, 0, 0, PREFETCH_HD, {x, x, x, x}, {1, x, x, x}, k_prefetcher_noc}, + {1, 0, 0, 0, DISPATCH_HD, {0, x, x, x}, {x, x, x, x}, k_dispatcher_noc}, +}; + static const std::vector single_chip_arch_2cq = { {0, 0, 0, 0, PREFETCH_HD, {x, x, x, x}, {2, x, x, x}, k_prefetcher_noc}, {1, 0, 0, 1, PREFETCH_HD, {x, x, x, x}, {3, x, x, x}, k_prefetcher_noc}, @@ -464,7 +470,13 @@ std::vector DispatchTopology::generate_nodes( auto populate_single_device = [&]() { const bool is_quasar = this->descriptor_.cluster().arch() == tt::ARCH::QUASAR; if (num_hw_cqs == 1) { - return is_quasar ? quasar_single_chip_1cq : single_chip_arch_1cq; + if (is_quasar) { + return quasar_single_chip_1cq; + } + if (!this->get_dispatch_query_manager_().dispatch_s_enabled()) { + return single_chip_arch_1cq_no_dispatch_s; + } + return single_chip_arch_1cq; } if (is_quasar) { return quasar_single_chip_2cq; diff --git a/tt_metal/llrt/core_descriptor.cpp b/tt_metal/llrt/core_descriptor.cpp index 0ada4eff2f0..1a2358d6cf7 100644 --- a/tt_metal/llrt/core_descriptor.cpp +++ b/tt_metal/llrt/core_descriptor.cpp @@ -290,6 +290,13 @@ const tt::core_descriptor_t& MetalEnvImpl::get_core_descriptor_config( coord = RelativeCoreCoord({.x = core_node[0].as(), .y = core_node[1].as()}); if (get_core_type_from_config(dispatch_core_config) == CoreType::ETH) { auto logical_coord = get_core_coord_from_relative(coord, grid_size); + // Skip ETH dispatch entries that do not exist on this chip (harvested ETH cores, e.g. + // Blackhole Galaxy chips expose fewer than the 14 ETH cores listed in the YAML). + const size_t num_logical_eth_cores = + get_cluster().get_soc_desc(device_id).get_cores(CoreType::ETH, CoordSystem::LOGICAL).size(); + if (logical_coord.y >= num_logical_eth_cores) { + continue; + } if (logical_active_eth_cores.contains(logical_coord)) { continue; }