From a1792227271da0819dbf3f3e8bf3269784aa666e Mon Sep 17 00:00:00 2001 From: Pavle Janevski Date: Fri, 1 Nov 2024 11:42:17 +0000 Subject: [PATCH] Implement CoreCoord struct and translation --- device/CMakeLists.txt | 1 + .../blackhole_coordinate_manager.cpp | 97 +++- .../blackhole/blackhole_coordinate_manager.h | 41 +- device/blackhole/blackhole_implementation.h | 54 ++- device/cluster.cpp | 3 + device/cluster.h | 17 +- device/coordinate_manager.cpp | 441 +++++++++++++----- device/coordinate_manager.h | 138 ++++-- .../grayskull_coordinate_manager.cpp | 32 ++ .../grayskull/grayskull_coordinate_manager.h | 29 +- device/grayskull/grayskull_implementation.h | 45 +- device/tt_core_coordinates.h | 52 +++ device/tt_soc_descriptor.cpp | 63 +-- device/tt_soc_descriptor.h | 50 +- device/tt_xy_pair.h | 56 --- .../wormhole/wormhole_coordinate_manager.cpp | 37 +- device/wormhole/wormhole_coordinate_manager.h | 40 +- device/wormhole/wormhole_implementation.h | 64 ++- tests/CMakeLists.txt | 6 +- tests/api/CMakeLists.txt | 7 +- tests/api/test_core_coord_translation_bh.cpp | 412 ++++++++++++++++ tests/api/test_core_coord_translation_gs.cpp | 183 ++++++++ tests/api/test_core_coord_translation_wh.cpp | 266 +++++++++++ tests/api/test_core_coordinates.cpp | 119 +++++ 24 files changed, 1868 insertions(+), 385 deletions(-) create mode 100644 device/grayskull/grayskull_coordinate_manager.cpp create mode 100644 device/tt_core_coordinates.h create mode 100644 tests/api/test_core_coord_translation_bh.cpp create mode 100644 tests/api/test_core_coord_translation_gs.cpp create mode 100644 tests/api/test_core_coord_translation_wh.cpp create mode 100644 tests/api/test_core_coordinates.cpp diff --git a/device/CMakeLists.txt b/device/CMakeLists.txt index a21d7d81..4df34de5 100644 --- a/device/CMakeLists.txt +++ b/device/CMakeLists.txt @@ -19,6 +19,7 @@ set(UMD_DEVICE_SRCS coordinate_manager.cpp blackhole/blackhole_coordinate_manager.cpp wormhole/wormhole_coordinate_manager.cpp + grayskull/grayskull_coordinate_manager.cpp pcie/pci_device.cpp hugepage.cpp ) diff --git a/device/blackhole/blackhole_coordinate_manager.cpp b/device/blackhole/blackhole_coordinate_manager.cpp index 32775ece..e121774d 100644 --- a/device/blackhole/blackhole_coordinate_manager.cpp +++ b/device/blackhole/blackhole_coordinate_manager.cpp @@ -1,29 +1,96 @@ /* - * SPDX-FileCopyrightText: (c) 2023 Tenstorrent Inc. + * SPDX-FileCopyrightText: (c) 2024 Tenstorrent Inc. * * SPDX-License-Identifier: Apache-2.0 */ #include "blackhole_coordinate_manager.h" +#include +void BlackholeCoordinateManager::tensix_harvesting(const std::size_t tensix_harvesting_mask) { + CoordinateManager::tensix_harvesting_mask = tensix_harvesting_mask; + CoordinateManager::clear_tensix_harvesting_structures(); + + std::size_t num_harvested_x = __builtin_popcount(tensix_harvesting_mask); + std::size_t grid_size_x = CoordinateManager::tensix_grid_size.x; + std::size_t grid_size_y = CoordinateManager::tensix_grid_size.y; -std::set BlackholeCoordinateManager::get_x_coordinates_to_harvest(std::size_t harvesting_mask) { - std::set x_to_harvest; std::size_t logical_x = 0; - while (harvesting_mask > 0) { - if (harvesting_mask & 1) { - x_to_harvest.insert(logical_x); + for (std::size_t x = 0; x < grid_size_x; x++) { + if (!(tensix_harvesting_mask & (1 << x))) { + for (std::size_t y = 0; y < grid_size_y; y++) { + const tt_xy_pair& tensix_core = CoordinateManager::tensix_cores[x + y * grid_size_x]; + tensix_logical_to_physical[{logical_x, y}] = CoreCoord(tensix_core.x, tensix_core.y, CoreType::TENSIX, CoordSystem::PHYSICAL); + tensix_physical_to_logical[tensix_core] = CoreCoord(logical_x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + } + logical_x++; + } + } + + for (std::size_t x = 0; x < grid_size_x - num_harvested_x; x++) { + for (std::size_t y = 0; y < grid_size_y; y++) { + const tt_xy_pair& tensix_core = CoordinateManager::tensix_cores[x + y * grid_size_x]; + tensix_logical_to_virtual[{x, y}] = CoreCoord(tensix_core.x, tensix_core.y, CoreType::TENSIX, CoordSystem::VIRTUAL); + tensix_virtual_to_logical[tensix_core] = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); } - logical_x++; - harvesting_mask >>= 1; } - return x_to_harvest; + + BlackholeCoordinateManager::fill_tensix_logical_to_translated(); } -tt_translated_coords BlackholeCoordinateManager::to_translated_coords(tt_logical_coords logical_coords) { - tt_virtual_coords virtual_coords = to_virtual_coords(logical_coords); - return tt_translated_coords(virtual_coords.x, virtual_coords.y); +void BlackholeCoordinateManager::fill_tensix_logical_to_translated() { + const std::size_t num_harvested_x = __builtin_popcount(CoordinateManager::tensix_harvesting_mask); + const std::size_t grid_size_x = CoordinateManager::tensix_grid_size.x; + const std::size_t grid_size_y = CoordinateManager::tensix_grid_size.y; + + for (std::size_t x = 0; x < grid_size_x - num_harvested_x; x++) { + for (std::size_t y = 0; y < grid_size_y; y++) { + const CoreCoord virtual_coord = CoordinateManager::tensix_logical_to_virtual[{x, y}]; + const std::size_t translated_x = virtual_coord.x; + const std::size_t translated_y = virtual_coord.y; + CoordinateManager::tensix_logical_to_translated[{x, y}] = CoreCoord(translated_x, translated_y, CoreType::TENSIX, CoordSystem::TRANSLATED); + CoordinateManager::tensix_translated_to_logical[{translated_x, translated_y}] = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + } + } +} + +void BlackholeCoordinateManager::dram_harvesting(const std::size_t dram_harvesting_mask) { + CoordinateManager::dram_harvesting_mask = dram_harvesting_mask; + CoordinateManager::clear_dram_harvesting_structures(); + + std::size_t num_harvested_banks = __builtin_popcount(dram_harvesting_mask); + + for (std::size_t x = 0; x < dram_grid_size.x - num_harvested_banks; x++) { + for (std::size_t y = 0; y < dram_grid_size.y; y++) { + const tt_xy_pair& dram_core = CoordinateManager::dram_cores[x * dram_grid_size.y + y]; + CoordinateManager::dram_logical_to_virtual[{x, y}] = CoreCoord(dram_core.x, dram_core.y, CoreType::DRAM, CoordSystem::VIRTUAL); + CoordinateManager::dram_virtual_to_logical[dram_core] = CoreCoord(x, y, CoreType::DRAM, CoordSystem::LOGICAL); + } + } + + std::size_t logical_x = 0; + for (std::size_t x = 0; x < dram_grid_size.x; x++) { + if (!(dram_harvesting_mask & (1 << x))) { + for (std::size_t y = 0; y < dram_grid_size.y; y++) { + const tt_xy_pair& dram_core = CoordinateManager::dram_cores[x * dram_grid_size.y + y]; + CoordinateManager::dram_logical_to_physical[{logical_x, y}] = CoreCoord(dram_core.x, dram_core.y, CoreType::DRAM, CoordSystem::PHYSICAL); + CoordinateManager::dram_physical_to_logical[dram_core] = CoreCoord(logical_x, y, CoreType::DRAM, CoordSystem::LOGICAL); + } + logical_x++; + } + } +} + +void BlackholeCoordinateManager::fill_eth_logical_to_translated() { + for (size_t x = 0; x < CoordinateManager::eth_grid_size.x; x++) { + for (size_t y = 0; y < CoordinateManager::eth_grid_size.y; y++) { + const size_t translated_x = x + eth_translated_coordinate_start_x; + const size_t translated_y = y + eth_translated_coordinate_start_y; + CoordinateManager::eth_logical_to_translated[{x, y}] = CoreCoord(translated_x, translated_y, CoreType::ETH, CoordSystem::TRANSLATED); + CoordinateManager::eth_translated_to_logical[{translated_x, translated_y}] = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); + } + } } -tt_logical_coords BlackholeCoordinateManager::to_logical_coords(tt_translated_coords translated_coords) { - tt_virtual_coords virtual_coords = tt_virtual_coords(translated_coords.x, translated_coords.y); - return CoordinateManager::to_logical_coords(virtual_coords); +void BlackholeCoordinateManager::fill_pcie_logical_to_translated() { + CoordinateManager::pcie_logical_to_translated[{0, 0}] = CoreCoord(pcie_translated_coordinate_start_x, pcie_translated_coordinate_start_y, CoreType::PCIE, CoordSystem::TRANSLATED); + CoordinateManager::pcie_translated_to_logical[{pcie_translated_coordinate_start_x, pcie_translated_coordinate_start_y}] = CoreCoord(0, 0, CoreType::PCIE, CoordSystem::LOGICAL); } diff --git a/device/blackhole/blackhole_coordinate_manager.h b/device/blackhole/blackhole_coordinate_manager.h index 5a316f8c..8df1864c 100644 --- a/device/blackhole/blackhole_coordinate_manager.h +++ b/device/blackhole/blackhole_coordinate_manager.h @@ -1,23 +1,52 @@ /* - * SPDX-FileCopyrightText: (c) 2023 Tenstorrent Inc. + * SPDX-FileCopyrightText: (c) 2024 Tenstorrent Inc. * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include "blackhole_implementation.h" #include "device/coordinate_manager.h" +#include "device/blackhole/blackhole_implementation.h" class BlackholeCoordinateManager : public CoordinateManager { public: BlackholeCoordinateManager( - const tt_xy_pair& worker_grid_size, const std::vector& workers, std::size_t harvesting_mask) : - CoordinateManager(worker_grid_size, workers, harvesting_mask) {} + const tt_xy_pair& tensix_grid_size, const std::vector& tensix_cores, const std::size_t tensix_harvesting_mask, + const tt_xy_pair& dram_grid_size, const std::vector& dram_cores, const std::size_t dram_harvesting_mask, + const tt_xy_pair& eth_grid_size, const std::vector& eth_cores, + const tt_xy_pair& arc_grid_size, const std::vector& arc_cores, + const tt_xy_pair& pcie_grid_size, const std::vector& pcie_cores) + : CoordinateManager( + tensix_grid_size, tensix_cores, tensix_harvesting_mask, + dram_grid_size, dram_cores, dram_harvesting_mask, + eth_grid_size, eth_cores, + arc_grid_size, arc_cores, + pcie_grid_size, pcie_cores) + { + this->tensix_harvesting(tensix_harvesting_mask); + this->dram_harvesting(dram_harvesting_mask); + this->translate_eth_coords(); + this->translate_arc_coords(); + this->translate_pcie_coords(); + } - tt_translated_coords to_translated_coords(tt_logical_coords logical_coords) override; + void dram_harvesting(const std::size_t dram_harvesting_mask) override; - tt_logical_coords to_logical_coords(tt_translated_coords translated_coords) override; + void tensix_harvesting(const std::size_t tensix_harvesting_mask) override; protected: - std::set get_x_coordinates_to_harvest(std::size_t harvesting_mask) override; + void fill_tensix_logical_to_translated() override; + + void fill_eth_logical_to_translated() override; + + void fill_pcie_logical_to_translated() override; + +private: + static const std::size_t eth_translated_coordinate_start_x = 20; + static const std::size_t eth_translated_coordinate_start_y = 25; + + static const size_t pcie_translated_coordinate_start_x = 19; + static const size_t pcie_translated_coordinate_start_y = 24; }; diff --git a/device/blackhole/blackhole_implementation.h b/device/blackhole/blackhole_implementation.h index 74789233..f201a575 100644 --- a/device/blackhole/blackhole_implementation.h +++ b/device/blackhole/blackhole_implementation.h @@ -11,6 +11,8 @@ #include "device/architecture_implementation.h" #include "device/tlb.h" +#include "device/tt_xy_pair.h" +#include namespace tt::umd { @@ -58,13 +60,50 @@ enum class arc_message_type { }; // DEVICE_DATA -static constexpr std::array DRAM_LOCATIONS = { - {{0, 0}, {0, 1}, {0, 11}, {0, 2}, {0, 10}, {0, 3}, {0, 9}, {0, 4}, {0, 8}, {0, 5}, {0, 7}, {0, 6}, - {9, 0}, {9, 1}, {9, 11}, {9, 2}, {9, 10}, {9, 3}, {9, 9}, {9, 4}, {9, 8}, {9, 5}, {9, 7}, {9, 6}}}; - -static constexpr std::array ARC_LOCATIONS = {{{8, 0}}}; -static constexpr std::array PCI_LOCATIONS = {{{11, 0}}}; -static constexpr std::array ETH_LOCATIONS = { +const static tt_xy_pair TENSIX_GRID_SIZE = {14, 10}; +const static std::vector TENSIX_CORES = {{ + {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}, {6, 2}, {7, 2}, {10, 2}, {11, 2}, {12, 2}, {13, 2}, {14, 2}, {15, 2}, {16, 2}, + {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {10, 3}, {11, 3}, {12, 3}, {13, 3}, {14, 3}, {15, 3}, {16, 3}, + {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}, {7, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15, 4}, {16, 4}, + {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {10, 5}, {11, 5}, {12, 5}, {13, 5}, {14, 5}, {15, 5}, {16, 5}, + {1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}, {6, 6}, {7, 6}, {10, 6}, {11, 6}, {12, 6}, {13, 6}, {14, 6}, {15, 6}, {16, 6}, + {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7}, {7, 7}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {15, 7}, {16, 7}, + {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {10, 8}, {11, 8}, {12, 8}, {13, 8}, {14, 8}, {15, 8}, {16, 8}, + {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {10, 9}, {11, 9}, {12, 9}, {13, 9}, {14, 9}, {15, 9}, {16, 9}, + {1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}, {6, 10}, {7, 10}, {10, 10}, {11, 10}, {12, 10}, {13, 10}, {14, 10}, {15, 10}, {16, 10}, + {1, 11}, {2, 11}, {3, 11}, {4, 11}, {5, 11}, {6, 11}, {7, 11}, {10, 11}, {11, 11}, {12, 11}, {13, 11}, {14, 11}, {15, 11}, {16, 11}, +}}; + + +const std::size_t NUM_DRAM_BANKS = 8; +const std::size_t NUM_NOC_PORTS_PER_DRAM_BANK = 3; +static const tt_xy_pair DRAM_GRID_SIZE = {NUM_DRAM_BANKS, NUM_NOC_PORTS_PER_DRAM_BANK}; +static const std::vector DRAM_CORES = { + { + {0, 0}, {0, 1}, {0, 11}, + {0, 2}, {0, 10}, {0, 3}, + {0, 9}, {0, 4}, {0, 8}, + {0, 5}, {0, 7}, {0, 6}, + {9, 0}, {9, 1}, {9, 11}, + {9, 2}, {9, 10}, {9, 3}, + {9, 9}, {9, 4}, {9, 8}, + {9, 5}, {9, 7}, {9, 6} +}}; + +// TODO: DRAM locations should be deleted. We keep it for compatibility with +// the existing code in clients which rely on DRAM_LOCATIONS. +static const std::vector DRAM_LOCATIONS = DRAM_CORES; + +static const tt_xy_pair ARC_GRID_SIZE = {1, 1}; +static const std::vector ARC_CORES = {{8, 0}}; +static const std::vector ARC_LOCATIONS = ARC_CORES; + +static const tt_xy_pair PCIE_GRID_SIZE = {1, 1}; +static const std::vector PCIE_CORES = {{{11, 0}}}; +static const std::vector PCI_LOCATIONS = PCIE_CORES; + +static const tt_xy_pair ETH_GRID_SIZE = {14, 1}; +static const std::vector ETH_CORES = { {{1, 1}, {2, 1}, {3, 1}, @@ -79,6 +118,7 @@ static constexpr std::array ETH_LOCATIONS = { {14, 1}, {15, 1}, {16, 1}}}; +static const std::vector ETH_LOCATIONS = ETH_CORES; // Return to std::array instead of std::vector once we get std::span support in C++20 static const std::vector T6_X_LOCATIONS = {1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16}; static const std::vector T6_Y_LOCATIONS = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; diff --git a/device/cluster.cpp b/device/cluster.cpp index 33c89668..38883f54 100644 --- a/device/cluster.cpp +++ b/device/cluster.cpp @@ -36,6 +36,9 @@ #include #include +#include "tt_core_coordinates.h" +#include "tt_soc_descriptor.h" +#include "yaml-cpp/yaml.h" #include "common/logger.hpp" #include "device/architecture_implementation.h" #include "device/driver_atomics.h" diff --git a/device/cluster.h b/device/cluster.h index 8fde9f78..939d1238 100644 --- a/device/cluster.h +++ b/device/cluster.h @@ -13,9 +13,17 @@ #include #include +#include "tt_core_coordinates.h" +#include "tt_soc_descriptor.h" +#include "tt_xy_pair.h" +#include "tt_silicon_driver_common.hpp" +#include "device/tt_cluster_descriptor_types.h" #include "device/tlb.h" #include "device/tt_cluster_descriptor_types.h" #include "device/tt_io.hpp" +#include "device/tt_core_coordinates.h" + +#include "pcie/pci_device.hpp" #include "fmt/core.h" #include "pcie/pci_device.hpp" #include "tt_silicon_driver_common.hpp" @@ -651,8 +659,9 @@ namespace tt::umd { /** * Silicon Driver Class, derived from the tt_device class * Implements APIs to communicate with a physical Tenstorrent Device. - */ -class Cluster : public tt_device { +*/ +class Cluster: public tt_device +{ public: // Constructor /** @@ -828,6 +837,10 @@ class Cluster : public tt_device { // TODO: This should be accessible through public API, probably to be moved to tt_device. PCIDevice* get_pci_device(int device_id) const; + // Core coordinates functions + // virtual void write_to_device(const void *mem_ptr, uint32_t size_in_bytes, chip_id_t chip, CoreCoord core_coord, uint64_t addr); + // virtual void read_from_device(void* mem_ptr, uint32_t size_in_bytes, chip_id_t chip, CoreCoord core_coord, uint64_t addr); + // Destructor virtual ~Cluster(); diff --git a/device/coordinate_manager.cpp b/device/coordinate_manager.cpp index b2eac485..a76191c1 100644 --- a/device/coordinate_manager.cpp +++ b/device/coordinate_manager.cpp @@ -6,184 +6,393 @@ #include "device/coordinate_manager.h" #include - +#include #include "coordinate_manager.h" #include "grayskull/grayskull_coordinate_manager.h" - -tt_physical_coords CoordinateManager::to_physical_coords(tt_logical_coords logical_coords) { - return tt_physical_coords(logical_x_to_physical_x[logical_coords.x], logical_y_to_physical_y[logical_coords.y]); +#include "grayskull/grayskull_implementation.h" +#include "tt_core_coordinates.h" +#include "device/tt_xy_pair.h" + +std::map& CoordinateManager::get_logical_to_translated(CoreType core_type) { + switch (core_type) { + case CoreType::TENSIX: + return tensix_logical_to_translated; + case CoreType::DRAM: + return dram_logical_to_translated; + case CoreType::ACTIVE_ETH: + case CoreType::IDLE_ETH: + case CoreType::ETH: + return eth_logical_to_translated; + case CoreType::ARC: + return arc_logical_to_translated; + case CoreType::PCIE: + return pcie_logical_to_translated; + default: + throw std::runtime_error("Core type is not supported for getting logical to translated mapping"); + } } -// TODO(pjanevski): this is different for Wormhole and Blackhole. -// investigate and implement -tt_translated_coords CoordinateManager::to_translated_coords(tt_logical_coords logical_coords) { - tt_physical_coords physical_coords = to_physical_coords(logical_coords); - return tt_translated_coords(physical_coords.x, physical_coords.y); +std::map& CoordinateManager::get_logical_to_virtual(CoreType core_type) { + switch (core_type) { + case CoreType::TENSIX: + return tensix_logical_to_virtual; + case CoreType::DRAM: + return dram_logical_to_virtual; + case CoreType::ACTIVE_ETH: + case CoreType::IDLE_ETH: + case CoreType::ETH: + return eth_logical_to_virtual; + case CoreType::ARC: + return arc_logical_to_translated; + case CoreType::PCIE: + return pcie_logical_to_translated; + default: + throw std::runtime_error("Core type is not supported for getting logical to virtual mapping"); + } } -tt_virtual_coords CoordinateManager::to_virtual_coords(tt_logical_coords logical_coords) { - return tt_virtual_coords(logical_x_to_virtual_x[logical_coords.x], logical_y_to_virtual_y[logical_coords.y]); +std::map& CoordinateManager::get_logical_to_physical(CoreType core_type) { + switch (core_type) { + case CoreType::TENSIX: + return tensix_logical_to_physical; + case CoreType::DRAM: + return dram_logical_to_physical; + case CoreType::ACTIVE_ETH: + case CoreType::IDLE_ETH: + case CoreType::ETH: + return eth_logical_to_physical; + case CoreType::ARC: + return arc_logical_to_physical; + case CoreType::PCIE: + return pcie_logical_to_physical; + default: + throw std::runtime_error("Core type is not supported for getting logical to physical mapping"); + } } -tt_logical_coords CoordinateManager::to_logical_coords(tt_physical_coords physical_coords) { - return tt_logical_coords(physical_x_to_logical_x[physical_coords.x], physical_y_to_logical_y[physical_coords.y]); +std::map& CoordinateManager::get_physical_to_logical(CoreType core_type) { + switch (core_type) { + case CoreType::TENSIX: + return tensix_physical_to_logical; + case CoreType::DRAM: + return dram_physical_to_logical; + case CoreType::ACTIVE_ETH: + case CoreType::IDLE_ETH: + case CoreType::ETH: + return eth_physical_to_logical; + case CoreType::ARC: + return arc_physical_to_logical; + case CoreType::PCIE: + return pcie_physical_to_logical; + default: + throw std::runtime_error("Core type is not supported for getting physical to logical mapping"); + } } -tt_virtual_coords CoordinateManager::to_virtual_coords(tt_physical_coords physical_coords) { - return to_virtual_coords(to_logical_coords(physical_coords)); +std::map& CoordinateManager::get_virtual_to_logical(CoreType core_type) { + switch (core_type) { + case CoreType::TENSIX: + return tensix_virtual_to_logical; + case CoreType::DRAM: + return dram_virtual_to_logical; + case CoreType::ACTIVE_ETH: + case CoreType::IDLE_ETH: + case CoreType::ETH: + return eth_virtual_to_logical; + case CoreType::ARC: + return arc_virtual_to_logical; + case CoreType::PCIE: + return pcie_virtual_to_logical; + default: + throw std::runtime_error("Core type is not supported for getting virtual to logical mapping"); + } } -tt_translated_coords CoordinateManager::to_translated_coords(tt_physical_coords physical_coords) { - return to_translated_coords(to_logical_coords(physical_coords)); +std::map& CoordinateManager::get_translated_to_logical(CoreType core_type) { + switch (core_type) { + case CoreType::TENSIX: + return tensix_translated_to_logical; + case CoreType::DRAM: + return dram_translated_to_logical; + case CoreType::ACTIVE_ETH: + case CoreType::IDLE_ETH: + case CoreType::ETH: + return eth_translated_to_logical; + case CoreType::ARC: + return arc_translated_to_logical; + case CoreType::PCIE: + return pcie_translated_to_logical; + default: + throw std::runtime_error("Core type is not supported for getting translated to logical mapping"); + } } -tt_logical_coords CoordinateManager::to_logical_coords(tt_virtual_coords virtual_coords) { - return tt_logical_coords(virtual_x_to_logical_x[virtual_coords.x], virtual_y_to_logical_y[virtual_coords.y]); +CoreCoord CoordinateManager::to_physical(const CoreCoord core_coord) { + switch (core_coord.coord_system) { + case CoordSystem::PHYSICAL: + return core_coord; + case CoordSystem::VIRTUAL: + case CoordSystem::TRANSLATED: + return to_physical(to_logical(core_coord)); + } + + // Coord system is surely logical. + auto& logical_mapping = get_logical_to_physical(core_coord.core_type); + return logical_mapping[{core_coord.x, core_coord.y}]; } -tt_physical_coords CoordinateManager::to_physical_coords(tt_virtual_coords virtual_coords) { - return to_physical_coords(to_logical_coords(virtual_coords)); -} +CoreCoord CoordinateManager::to_virtual(const CoreCoord core_coord) { + switch (core_coord.coord_system) { + case CoordSystem::TRANSLATED: + case CoordSystem::PHYSICAL: + return to_virtual(to_logical(core_coord)); + case CoordSystem::VIRTUAL: + return core_coord; + } -tt_translated_coords CoordinateManager::to_translated_coords(tt_virtual_coords virtual_coords) { - return to_translated_coords(to_logical_coords(virtual_coords)); + // Coord system is surely logical. + auto& logical_mapping = get_logical_to_virtual(core_coord.core_type); + return logical_mapping[{core_coord.x,core_coord.y}]; } -tt_logical_coords CoordinateManager::to_logical_coords(tt_translated_coords translated_coords) { - tt_physical_coords physical_coords = tt_physical_coords(translated_coords.x, translated_coords.y); - return to_logical_coords(physical_coords); +CoreCoord CoordinateManager::to_logical(const CoreCoord core_coord) { + switch (core_coord.coord_system) { + case CoordSystem::LOGICAL: + return core_coord; + case CoordSystem::PHYSICAL: { + auto& physical_mapping = get_physical_to_logical(core_coord.core_type); + return physical_mapping[{core_coord.x, core_coord.y}]; + } + case CoordSystem::VIRTUAL: { + auto& virtual_mapping = get_virtual_to_logical(core_coord.core_type); + return virtual_mapping[{core_coord.x, core_coord.y}]; + } + case CoordSystem::TRANSLATED: { + auto& translated_mapping = get_translated_to_logical(core_coord.core_type); + return translated_mapping[{core_coord.x, core_coord.y}]; + } + } } -tt_physical_coords CoordinateManager::to_physical_coords(tt_translated_coords translated_coords) { - return to_physical_coords(to_logical_coords(translated_coords)); +CoreCoord CoordinateManager::to_translated(const CoreCoord core_coord) { + switch (core_coord.coord_system) { + case CoordSystem::PHYSICAL: + case CoordSystem::VIRTUAL: + return to_translated(to_logical(core_coord)); + case CoordSystem::TRANSLATED: + return core_coord; + } + + // Coord system is surely logical. + auto& logical_mapping = get_logical_to_translated(core_coord.core_type); + return logical_mapping[{core_coord.x, core_coord.y}]; } -tt_virtual_coords CoordinateManager::to_virtual_coords(tt_translated_coords translated_coords) { - return to_virtual_coords(to_logical_coords(translated_coords)); +void CoordinateManager::clear_tensix_harvesting_structures() { + tensix_logical_to_physical.clear(); + tensix_logical_to_virtual.clear(); + tensix_physical_to_logical.clear(); + tensix_virtual_to_logical.clear(); + tensix_logical_to_translated.clear(); + tensix_translated_to_logical.clear(); } -void CoordinateManager::clear_harvesting_structures() { - logical_x_to_physical_x.clear(); - logical_y_to_physical_y.clear(); - logical_x_to_virtual_x.clear(); - logical_y_to_virtual_y.clear(); - physical_x_to_logical_x.clear(); - physical_y_to_logical_y.clear(); - virtual_x_to_logical_x.clear(); - virtual_y_to_logical_y.clear(); +void CoordinateManager::clear_dram_harvesting_structures() { + dram_logical_to_virtual.clear(); + dram_logical_to_physical.clear(); + dram_virtual_to_logical.clear(); + dram_physical_to_logical.clear(); + dram_logical_to_translated.clear(); + dram_translated_to_logical.clear(); } -std::set CoordinateManager::get_x_coordinates_to_harvest(std::size_t harvesting_mask) { return {}; } +void CoordinateManager::tensix_harvesting(const std::size_t harvesting_mask) { + this->tensix_harvesting_mask = harvesting_mask; + clear_tensix_harvesting_structures(); -std::set CoordinateManager::get_y_coordinates_to_harvest(std::size_t harvesting_mask) { return {}; } + std::size_t num_harvested_y = __builtin_popcount(harvesting_mask); + std::size_t grid_size_x = tensix_grid_size.x; + std::size_t grid_size_y = tensix_grid_size.y; -void CoordinateManager::perform_harvesting(std::size_t harvesting_mask) { - clear_harvesting_structures(); + std::size_t logical_y = 0; + for (std::size_t y = 0; y < grid_size_y; y++) { + if (!(harvesting_mask & (1 << y))) { + for (std::size_t x = 0; x < grid_size_x; x++) { + const tt_xy_pair& tensix_core = tensix_cores[y * grid_size_x + x]; + tensix_logical_to_physical[{x, logical_y}] = CoreCoord(tensix_core.x, tensix_core.y, CoreType::TENSIX, CoordSystem::PHYSICAL); + tensix_physical_to_logical[tensix_core] = CoreCoord(x, logical_y, CoreType::TENSIX, CoordSystem::LOGICAL); + } + logical_y++; + } + } - std::set physical_x_unharvested; - std::set physical_y_unharvested; - for (auto core : workers) { - physical_x_unharvested.insert(core.x); - physical_y_unharvested.insert(core.y); + for (std::size_t y = 0; y < grid_size_y - num_harvested_y; y++) { + for (std::size_t x = 0; x < grid_size_x; x++) { + const tt_xy_pair& tensix_core = tensix_cores[y * grid_size_x + x]; + tensix_logical_to_virtual[{x, y}] = CoreCoord(tensix_core.x, tensix_core.y, CoreType::TENSIX, CoordSystem::VIRTUAL); + tensix_virtual_to_logical[tensix_core] = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + } } - std::set x_coordinates_to_harvest = get_x_coordinates_to_harvest(harvesting_mask); - std::set y_coordinates_to_harvest = get_y_coordinates_to_harvest(harvesting_mask); + fill_tensix_logical_to_translated(); +} + +void CoordinateManager::fill_tensix_logical_to_translated() {} + +void CoordinateManager::dram_harvesting(const std::size_t dram_harvesting_mask) { + this->dram_harvesting_mask = dram_harvesting_mask; + clear_dram_harvesting_structures(); - std::size_t num_harvested_y = y_coordinates_to_harvest.size(); - std::size_t num_harvested_x = x_coordinates_to_harvest.size(); + for (std::size_t x = 0; x < dram_grid_size.x; x++) { + for (std::size_t y = 0; y < dram_grid_size.y; y++) { + const tt_xy_pair dram_core = dram_cores[x * dram_grid_size.y + y]; + dram_logical_to_virtual[{x, y}] = CoreCoord(dram_core.x, dram_core.y, CoreType::DRAM, CoordSystem::VIRTUAL); + dram_virtual_to_logical[dram_core] = CoreCoord(x, y, CoreType::DRAM, CoordSystem::LOGICAL); - std::size_t grid_size_x = worker_grid_size.x; - std::size_t grid_size_y = worker_grid_size.y; + dram_logical_to_physical[{x, y}] = CoreCoord(dram_core.x, dram_core.y, CoreType::DRAM, CoordSystem::PHYSICAL); + dram_physical_to_logical[dram_core] = CoreCoord(x, y, CoreType::DRAM, CoordSystem::LOGICAL); + } + } +} - logical_x_to_physical_x.resize(grid_size_x - num_harvested_x); - logical_y_to_physical_y.resize(grid_size_y - num_harvested_y); +void CoordinateManager::translate_eth_coords() { + for (std::size_t x = 0; x < eth_grid_size.x; x++) { + for (std::size_t y = 0; y < eth_grid_size.y; y++) { + const tt_xy_pair eth_core = eth_cores[x * eth_grid_size.y + y]; + eth_logical_to_virtual[{x, y}] = CoreCoord(eth_core.x, eth_core.y, CoreType::ETH, CoordSystem::VIRTUAL); + eth_virtual_to_logical[eth_core] = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); - logical_x_to_virtual_x.resize(grid_size_x - num_harvested_x); - logical_y_to_virtual_y.resize(grid_size_y - num_harvested_y); + eth_logical_to_physical[{x, y}] = CoreCoord(eth_core.x, eth_core.y, CoreType::ETH, CoordSystem::PHYSICAL); + eth_physical_to_logical[eth_core] = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); + } + } - fill_logical_to_physical_mapping( - x_coordinates_to_harvest, y_coordinates_to_harvest, physical_x_unharvested, physical_y_unharvested); - fill_logical_to_virtual_mapping(physical_x_unharvested, physical_y_unharvested); + fill_eth_logical_to_translated(); } -void CoordinateManager::fill_logical_to_physical_mapping( - const std::set& x_to_harvest, - const std::set& y_to_harvest, - const std::set& physical_x_unharvested, - const std::set& physical_y_unharvested) { - auto physical_y_it = physical_y_unharvested.begin(); - std::size_t logical_y = 0; - for (size_t y = 0; y < worker_grid_size.y; y++) { - if (y_to_harvest.find(y) == y_to_harvest.end()) { - logical_y_to_physical_y[logical_y] = *physical_y_it; - if (physical_y_to_logical_y.find(*physical_y_it) != physical_y_to_logical_y.end()) { - throw std::runtime_error("Duplicate physical y coordinate found in the worker cores"); - } - physical_y_to_logical_y[*physical_y_it] = logical_y; - logical_y++; - physical_y_it++; - } else { - physical_y_it++; +void CoordinateManager::translate_arc_coords() { + for (std::size_t x = 0; x < arc_grid_size.x; x++) { + for (std::size_t y = 0; y < arc_grid_size.y; y++) { + const tt_xy_pair arc_core = arc_cores[x * arc_grid_size.y + y]; + arc_logical_to_virtual[{x, y}] = CoreCoord(arc_core.x, arc_core.y, CoreType::ARC, CoordSystem::VIRTUAL); + arc_virtual_to_logical[arc_core] = CoreCoord(x, y, CoreType::ARC, CoordSystem::LOGICAL); + + arc_logical_to_physical[{x, y}] = CoreCoord(arc_core.x, arc_core.y, CoreType::ARC, CoordSystem::PHYSICAL); + arc_physical_to_logical[arc_core] = CoreCoord(x, y, CoreType::ARC, CoordSystem::LOGICAL); + + arc_logical_to_translated[{x, y}] = CoreCoord(arc_core.x, arc_core.y, CoreType::ARC, CoordSystem::TRANSLATED); + arc_translated_to_logical[arc_core] = CoreCoord(x, y, CoreType::ARC, CoordSystem::LOGICAL); } } +} - auto physical_x_it = physical_x_unharvested.begin(); - std::size_t logical_x = 0; - for (std::size_t x = 0; x < worker_grid_size.x; x++) { - if (x_to_harvest.find(x) == x_to_harvest.end()) { - logical_x_to_physical_x[logical_x] = *physical_x_it; - if (physical_x_to_logical_x.find(*physical_x_it) != physical_x_to_logical_x.end()) { - throw std::runtime_error("Duplicate physical x coordinate found in the worker cores"); - } - physical_x_to_logical_x[*physical_x_it] = logical_x; - logical_x++; - physical_x_it++; - } else { - physical_x_it++; +void CoordinateManager::translate_pcie_coords() { + for (std::size_t x = 0; x < pcie_grid_size.x; x++) { + for (std::size_t y = 0; y < pcie_grid_size.y; y++) { + const tt_xy_pair pcie_core = pcie_cores[x * pcie_grid_size.y + y]; + pcie_logical_to_virtual[{x, y}] = CoreCoord(pcie_core.x, pcie_core.y, CoreType::PCIE, CoordSystem::VIRTUAL); + pcie_virtual_to_logical[pcie_core] = CoreCoord(x, y, CoreType::PCIE, CoordSystem::LOGICAL); + + pcie_logical_to_physical[{x, y}] = CoreCoord(pcie_core.x, pcie_core.y, CoreType::PCIE, CoordSystem::PHYSICAL); + pcie_physical_to_logical[pcie_core] = CoreCoord(x, y, CoreType::PCIE, CoordSystem::LOGICAL); + + pcie_logical_to_translated[{x, y}] = CoreCoord(pcie_core.x, pcie_core.y, CoreType::PCIE, CoordSystem::TRANSLATED); + pcie_translated_to_logical[pcie_core] = CoreCoord(x, y, CoreType::PCIE, CoordSystem::LOGICAL); } } } -void CoordinateManager::fill_logical_to_virtual_mapping( - const std::set& physical_x_unharvested, const std::set& physical_y_unharvested) { - auto physical_y_it = physical_y_unharvested.begin(); - for (std::size_t y = 0; y < logical_y_to_virtual_y.size(); y++) { - logical_y_to_virtual_y[y] = *physical_y_it; - if (virtual_y_to_logical_y.find(*physical_y_it) != virtual_y_to_logical_y.end()) { - throw std::runtime_error("Duplicate virtual y coordinate found in the worker cores"); +void CoordinateManager::fill_eth_logical_to_translated() { + for (size_t x = 0; x < eth_grid_size.x; x++) { + for (size_t y = 0; y < eth_grid_size.y; y++) { + const CoreCoord physical_coord = eth_logical_to_physical[{x, y}]; + const size_t translated_x = physical_coord.x; + const size_t translated_y = physical_coord.y; + eth_logical_to_translated[{x, y}] = CoreCoord(translated_x, translated_y, CoreType::ETH, CoordSystem::TRANSLATED); + eth_translated_to_logical[{translated_x, translated_y}] = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); } - virtual_y_to_logical_y[*physical_y_it] = y; - physical_y_it++; } +} - auto physical_x_it = physical_x_unharvested.begin(); - for (std::size_t x = 0; x < logical_x_to_virtual_x.size(); x++) { - logical_x_to_virtual_x[x] = *physical_x_it; - if (virtual_x_to_logical_x.find(*physical_x_it) != virtual_x_to_logical_x.end()) { - throw std::runtime_error("Duplicate virtual x coordinate found in the worker cores"); +void CoordinateManager::fill_pcie_logical_to_translated() { + for (size_t x = 0; x < eth_grid_size.x; x++) { + for (size_t y = 0; y < eth_grid_size.y; y++) { + const CoreCoord physical_coord = pcie_logical_to_physical[{x, y}]; + const size_t translated_x = physical_coord.x; + const size_t translated_y = physical_coord.y; + pcie_logical_to_translated[{x, y}] = CoreCoord(translated_x, translated_y, CoreType::PCIE, CoordSystem::TRANSLATED); + pcie_translated_to_logical[{translated_x, translated_y}] = CoreCoord(x, y, CoreType::PCIE, CoordSystem::LOGICAL); } - virtual_x_to_logical_x[*physical_x_it] = x; - physical_x_it++; } } -#include "device/blackhole/blackhole_coordinate_manager.h" #include "device/grayskull/grayskull_coordinate_manager.h" #include "device/wormhole/wormhole_coordinate_manager.h" +#include "device/blackhole/blackhole_coordinate_manager.h" std::unique_ptr CoordinateManager::get_coordinate_manager( tt::ARCH arch, - const tt_xy_pair& worker_grid_size, - const std::vector& workers, - std::size_t harvesting_mask) { + const std::size_t tensix_harvesting_mask, + const std::size_t dram_harvesting_mask) { + + switch (arch) { + case tt::ARCH::GRAYSKULL: + return get_coordinate_manager( + arch, + tt::umd::grayskull::TENSIX_GRID_SIZE, tt::umd::grayskull::TENSIX_CORES, tensix_harvesting_mask, + tt::umd::grayskull::DRAM_GRID_SIZE, tt::umd::grayskull::DRAM_CORES, dram_harvesting_mask, + tt::umd::grayskull::ETH_GRID_SIZE, tt::umd::grayskull::ETH_CORES, + tt::umd::grayskull::ARC_GRID_SIZE, tt::umd::grayskull::ARC_CORES, + tt::umd::grayskull::PCIE_GRID_SIZE, tt::umd::grayskull::PCIE_CORES); + case tt::ARCH::WORMHOLE_B0: + return get_coordinate_manager( + arch, + tt::umd::wormhole::TENSIX_GRID_SIZE, tt::umd::wormhole::TENSIX_CORES, tensix_harvesting_mask, + tt::umd::wormhole::DRAM_GRID_SIZE, tt::umd::wormhole::DRAM_CORES, dram_harvesting_mask, + tt::umd::wormhole::ETH_GRID_SIZE, tt::umd::wormhole::ETH_CORES, + tt::umd::wormhole::ARC_GRID_SIZE, tt::umd::wormhole::ARC_CORES, + tt::umd::wormhole::PCIE_GRID_SIZE, tt::umd::wormhole::PCIE_CORES); + case tt::ARCH::BLACKHOLE: + return get_coordinate_manager( + arch, + tt::umd::blackhole::TENSIX_GRID_SIZE, tt::umd::blackhole::TENSIX_CORES, tensix_harvesting_mask, + tt::umd::blackhole::DRAM_GRID_SIZE, tt::umd::blackhole::DRAM_CORES, dram_harvesting_mask, + tt::umd::blackhole::ETH_GRID_SIZE, tt::umd::blackhole::ETH_CORES, + tt::umd::blackhole::ARC_GRID_SIZE, tt::umd::blackhole::ARC_CORES, + tt::umd::blackhole::PCIE_GRID_SIZE, tt::umd::blackhole::PCIE_CORES); + } +} + +std::unique_ptr CoordinateManager::get_coordinate_manager( + tt::ARCH arch, + const tt_xy_pair& tensix_grid_size, const std::vector& tensix_cores, const std::size_t tensix_harvesting_mask, + const tt_xy_pair& dram_grid_size, const std::vector& dram_cores, const std::size_t dram_harvesting_mask, + const tt_xy_pair& eth_grid_size, const std::vector& eth_cores, + const tt_xy_pair& arc_grid_size, const std::vector& arc_cores, + const tt_xy_pair& pcie_grid_size, const std::vector& pcie_cores) { + switch (arch) { case tt::ARCH::GRAYSKULL: - return std::make_unique(worker_grid_size, workers, harvesting_mask); + return std::make_unique( + tensix_grid_size, tensix_cores, tensix_harvesting_mask, + dram_grid_size, dram_cores, dram_harvesting_mask, + eth_grid_size, eth_cores, + arc_grid_size, arc_cores, + pcie_grid_size, pcie_cores); case tt::ARCH::WORMHOLE_B0: - return std::make_unique(worker_grid_size, workers, harvesting_mask); + return std::make_unique( + tensix_grid_size, tensix_cores, tensix_harvesting_mask, + dram_grid_size, dram_cores, dram_harvesting_mask, + eth_grid_size, eth_cores, + arc_grid_size, arc_cores, + pcie_grid_size, pcie_cores); case tt::ARCH::BLACKHOLE: - return std::make_unique(worker_grid_size, workers, harvesting_mask); + return std::make_unique( + tensix_grid_size, tensix_cores, tensix_harvesting_mask, + dram_grid_size, dram_cores, dram_harvesting_mask, + eth_grid_size, eth_cores, + arc_grid_size, arc_cores, + pcie_grid_size, pcie_cores); case tt::ARCH::Invalid: throw std::runtime_error("Invalid architecture for creating coordinate manager"); } diff --git a/device/coordinate_manager.h b/device/coordinate_manager.h index 53ad266f..8ea7bd7a 100644 --- a/device/coordinate_manager.h +++ b/device/coordinate_manager.h @@ -11,55 +11,64 @@ #include #include "device/tt_arch_types.h" -#include "device/tt_xy_pair.h" +#include "tt_core_coordinates.h" + +#include class CoordinateManager { public: CoordinateManager( - const tt_xy_pair& worker_grid_size, const std::vector& workers, std::size_t harvesting_mask) : - worker_grid_size(worker_grid_size), workers(workers), harvesting_mask(harvesting_mask) {} + const tt_xy_pair& tensix_grid_size, const std::vector& tensix_cores, const std::size_t tensix_harvesting_mask, + const tt_xy_pair& dram_grid_size, const std::vector& dram_cores, const std::size_t dram_harvesting_mask, + const tt_xy_pair& eth_grid_size, const std::vector& eth_cores, + const tt_xy_pair& arc_grid_size, const std::vector& arc_cores, + const tt_xy_pair& pcie_grid_size, const std::vector& pcie_cores) + : tensix_grid_size(tensix_grid_size), tensix_cores(tensix_cores), tensix_harvesting_mask(tensix_harvesting_mask), + dram_grid_size(dram_grid_size), dram_cores(dram_cores), dram_harvesting_mask(dram_harvesting_mask), + eth_grid_size(eth_grid_size), eth_cores(eth_cores), + arc_grid_size(arc_grid_size), arc_cores(arc_cores), + pcie_grid_size(pcie_grid_size), pcie_cores(pcie_cores) + {} + + virtual void tensix_harvesting(const std::size_t harvesting_mask); - virtual void perform_harvesting(std::size_t harvesting_mask); + virtual void dram_harvesting(const std::size_t dram_harvesting_mask); - virtual tt_physical_coords to_physical_coords(tt_logical_coords logical_coords); - virtual tt_translated_coords to_translated_coords(tt_logical_coords logical_coords); - virtual tt_virtual_coords to_virtual_coords(tt_logical_coords logical_coords); + virtual void translate_eth_coords(); - virtual tt_logical_coords to_logical_coords(tt_physical_coords physical_coords); - virtual tt_virtual_coords to_virtual_coords(tt_physical_coords physical_coords); - virtual tt_translated_coords to_translated_coords(tt_physical_coords physical_coords); + virtual void translate_arc_coords(); - virtual tt_logical_coords to_logical_coords(tt_virtual_coords virtual_coords); - virtual tt_physical_coords to_physical_coords(tt_virtual_coords virtual_coords); - virtual tt_translated_coords to_translated_coords(tt_virtual_coords virtual_coords); + virtual void translate_pcie_coords(); - virtual tt_logical_coords to_logical_coords(tt_translated_coords translated_coords); - virtual tt_physical_coords to_physical_coords(tt_translated_coords translated_coords); - virtual tt_virtual_coords to_virtual_coords(tt_translated_coords translated_coords); + static std::unique_ptr get_coordinate_manager( + tt::ARCH arch, + const tt_xy_pair& tensix_grid_size, const std::vector& tensix_cores, const std::size_t tensix_harvesting_mask, + const tt_xy_pair& dram_grid_size, const std::vector& dram_cores, const std::size_t dram_harvesting_mask, + const tt_xy_pair& eth_grid_size, const std::vector& eth_cores, + const tt_xy_pair& arc_grid_size, const std::vector& arc_cores, + const tt_xy_pair& pcie_grid_size, const std::vector& pcie_cores); static std::unique_ptr get_coordinate_manager( tt::ARCH arch, - const tt_xy_pair& worker_grid_size, - const std::vector& workers, - std::size_t harvesting_mask); + const std::size_t tensix_harvesting_mask = 0, + const std::size_t dram_harvesting_mask = 0); CoordinateManager(CoordinateManager& other) = default; - virtual ~CoordinateManager() {} + CoreCoord to_physical(const CoreCoord core_coord); + CoreCoord to_logical(const CoreCoord core_coord); + CoreCoord to_virtual(const CoreCoord core_coord); + CoreCoord to_translated(const CoreCoord core_coord); -protected: - virtual void clear_harvesting_structures(); + virtual ~CoordinateManager() = default; - virtual std::set get_x_coordinates_to_harvest(std::size_t harvesting_mask); - virtual std::set get_y_coordinates_to_harvest(std::size_t harvesting_mask); +protected: + void clear_tensix_harvesting_structures(); + void clear_dram_harvesting_structures(); - virtual void fill_logical_to_physical_mapping( - const std::set& x_to_harvest, - const std::set& y_to_harvest, - const std::set& physical_x_unharvested, - const std::set& physical_y_unharvested); - virtual void fill_logical_to_virtual_mapping( - const std::set& physical_x_unharvested, const std::set& physical_y_unharvested); + virtual void fill_tensix_logical_to_translated(); + virtual void fill_eth_logical_to_translated(); + virtual void fill_pcie_logical_to_translated(); std::map physical_y_to_logical_y; std::map physical_x_to_logical_x; @@ -73,7 +82,68 @@ class CoordinateManager { std::map virtual_y_to_logical_y; std::map virtual_x_to_logical_x; - const tt_xy_pair worker_grid_size; - const std::vector& workers; - const std::size_t harvesting_mask; + std::map tensix_logical_to_translated; + std::map tensix_logical_to_virtual; + std::map tensix_logical_to_physical; + + std::map tensix_physical_to_logical; + std::map tensix_virtual_to_logical; + std::map tensix_translated_to_logical; + + std::map dram_logical_to_translated; + std::map dram_logical_to_virtual; + std::map dram_logical_to_physical; + + std::map dram_physical_to_logical; + std::map dram_virtual_to_logical; + std::map dram_translated_to_logical; + + std::map eth_logical_to_translated; + std::map eth_logical_to_virtual; + std::map eth_logical_to_physical; + + std::map eth_physical_to_logical; + std::map eth_virtual_to_logical; + std::map eth_translated_to_logical; + + std::map arc_logical_to_translated; + std::map arc_logical_to_virtual; + std::map arc_logical_to_physical; + + std::map arc_physical_to_logical; + std::map arc_virtual_to_logical; + std::map arc_translated_to_logical; + + std::map pcie_logical_to_translated; + std::map pcie_logical_to_virtual; + std::map pcie_logical_to_physical; + + std::map pcie_physical_to_logical; + std::map pcie_virtual_to_logical; + std::map pcie_translated_to_logical; + + std::map& get_logical_to_translated(CoreType core_type); + std::map& get_logical_to_virtual(CoreType core_type); + std::map& get_logical_to_physical(CoreType core_type); + + std::map& get_physical_to_logical(CoreType core_type); + std::map& get_virtual_to_logical(CoreType core_type); + std::map& get_translated_to_logical(CoreType core_type); + + const tt_xy_pair tensix_grid_size; + const std::vector& tensix_cores; + std::size_t tensix_harvesting_mask; + + const tt_xy_pair dram_grid_size; + const std::vector& dram_cores; + std::size_t dram_harvesting_mask; + + const tt_xy_pair eth_grid_size; + const std::vector& eth_cores; + + const tt_xy_pair arc_grid_size; + const std::vector& arc_cores; + + const tt_xy_pair pcie_grid_size; + const std::vector& pcie_cores; }; diff --git a/device/grayskull/grayskull_coordinate_manager.cpp b/device/grayskull/grayskull_coordinate_manager.cpp new file mode 100644 index 00000000..e3e5e5c9 --- /dev/null +++ b/device/grayskull/grayskull_coordinate_manager.cpp @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: (c) 2024 Tenstorrent Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "grayskull_coordinate_manager.h" + +void GrayskullCoordinateManager::fill_tensix_logical_to_translated() { + std::size_t num_harvested_y = __builtin_popcount(CoordinateManager::tensix_harvesting_mask); + + for (std::size_t x = 0; x < CoordinateManager::tensix_grid_size.x; x++) { + for (std::size_t y = 0; y < CoordinateManager::tensix_grid_size.y - num_harvested_y; y++) { + const CoreCoord physical_coord = CoordinateManager::tensix_logical_to_physical[{x, y}]; + const std::size_t translated_x = physical_coord.x; + const std::size_t translated_y = physical_coord.y; + CoordinateManager::tensix_logical_to_translated[{x, y}] = CoreCoord(translated_x, translated_y, CoreType::TENSIX, CoordSystem::TRANSLATED); + CoordinateManager::tensix_translated_to_logical[tt_xy_pair(translated_x, translated_y)] = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + } + } +} + +void GrayskullCoordinateManager::fill_eth_logical_to_translated() { + for (std::size_t x = 0; x < CoordinateManager::eth_grid_size.x; x++) { + for (std::size_t y = 0; y < CoordinateManager::eth_grid_size.y; y++) { + const CoreCoord physical_coord = CoordinateManager::eth_logical_to_physical[{x, y}]; + const std::size_t translated_x = physical_coord.x; + const std::size_t translated_y = physical_coord.y; + CoordinateManager::eth_logical_to_translated[{x, y}] = CoreCoord(translated_x, translated_y, CoreType::ETH, CoordSystem::TRANSLATED); + CoordinateManager::eth_translated_to_logical[{translated_x, translated_y}] = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); + } + } +} diff --git a/device/grayskull/grayskull_coordinate_manager.h b/device/grayskull/grayskull_coordinate_manager.h index ba7eebe2..46c47892 100644 --- a/device/grayskull/grayskull_coordinate_manager.h +++ b/device/grayskull/grayskull_coordinate_manager.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: (c) 2023 Tenstorrent Inc. + * SPDX-FileCopyrightText: (c) 2024 Tenstorrent Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,10 +7,33 @@ #pragma once #include "device/coordinate_manager.h" +#include "device/grayskull/grayskull_implementation.h" +#include "grayskull_implementation.h" class GrayskullCoordinateManager : public CoordinateManager { public: GrayskullCoordinateManager( - const tt_xy_pair& worker_grid_size, const std::vector& workers, std::size_t harvesting_mask) : - CoordinateManager(worker_grid_size, workers, harvesting_mask) {} + const tt_xy_pair& tensix_grid_size, const std::vector& tensix_cores, const std::size_t tensix_harvesting_mask, + const tt_xy_pair& dram_grid_size, const std::vector& dram_cores, const std::size_t dram_harvesting_mask, + const tt_xy_pair& eth_grid_size, const std::vector& eth_cores, + const tt_xy_pair& arc_grid_size, const std::vector& arc_cores, + const tt_xy_pair& pcie_grid_size, const std::vector& pcie_cores) + : CoordinateManager( + tensix_grid_size, tensix_cores, tensix_harvesting_mask, + dram_grid_size, dram_cores, dram_harvesting_mask, + eth_grid_size, eth_cores, + arc_grid_size, arc_cores, + pcie_grid_size, pcie_cores) + { + this->tensix_harvesting(tensix_harvesting_mask); + this->dram_harvesting(dram_harvesting_mask); + this->translate_eth_coords(); + this->translate_arc_coords(); + this->translate_pcie_coords(); + } + +protected: + void fill_tensix_logical_to_translated() override; + + void fill_eth_logical_to_translated() override; }; diff --git a/device/grayskull/grayskull_implementation.h b/device/grayskull/grayskull_implementation.h index 5984710c..a066c340 100644 --- a/device/grayskull/grayskull_implementation.h +++ b/device/grayskull/grayskull_implementation.h @@ -10,6 +10,7 @@ #include "device/architecture_implementation.h" #include "device/tlb.h" +#include "device/tt_xy_pair.h" namespace tt::umd { @@ -104,10 +105,46 @@ enum class arc_message_type { }; // DEVICE_DATA -static const std::array DRAM_LOCATIONS = { - {{1, 6}, {4, 6}, {7, 6}, {10, 6}, {1, 0}, {4, 0}, {7, 0}, {10, 0}}}; -static const std::array ARC_LOCATIONS = {{{0, 2}}}; -static const std::array PCI_LOCATIONS = {{{0, 4}}}; +static const tt_xy_pair TENSIX_GRID_SIZE = {12, 10}; +static const std::vector TENSIX_CORES = {{ + {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1}, {12, 1}, + {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}, {6, 2}, {7, 2}, {8, 2}, {9, 2}, {10, 2}, {11, 2}, {12, 2}, + {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {8, 3}, {9, 3}, {10, 3}, {11, 3}, {12, 3}, + {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}, {7, 4}, {8, 4}, {9, 4}, {10, 4}, {11, 4}, {12, 4}, + {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {8, 5}, {9, 5}, {10, 5}, {11, 5}, {12, 5}, + {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7}, {7, 7}, {8, 7}, {9, 7}, {10, 7}, {11, 7}, {12, 7}, + {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, {12, 8}, + {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}, {12, 9}, + {1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}, {6, 10}, {7, 10}, {8, 10}, {9, 10}, {10, 10}, {11, 10}, {12, 10}, + {1, 11}, {2, 11}, {3, 11}, {4, 11}, {5, 11}, {6, 11}, {7, 11}, {8, 11}, {9, 11}, {10, 11}, {11, 11}, {12, 11}, +}}; + +const std::size_t NUM_DRAM_BANKS = 8; +const std::size_t NUM_NOC_PORTS_PER_DRAM_BANK = 1; +static const tt_xy_pair DRAM_GRID_SIZE = {NUM_DRAM_BANKS, NUM_NOC_PORTS_PER_DRAM_BANK}; +static const std::vector DRAM_CORES = {{ + {1, 0}, + {1, 6}, + {4, 0}, + {4, 6}, + {7, 0}, + {7, 6}, + {10, 0}, + {10, 6} +}}; + +static const tt_xy_pair ETH_GRID_SIZE = {0, 0}; +static const std::vector ETH_CORES = {}; +// TODO: DRAM locations should be deleted. We keep it for compatibility with +// the existing code in clients which rely on DRAM_LOCATIONS. +static const std::vector DRAM_LOCATIONS = DRAM_CORES; +static const tt_xy_pair ARC_GRID_SIZE = {1, 1}; +static const std::vector ARC_CORES = {{{0, 2}}}; +static const std::vector ARC_LOCATIONS = ARC_CORES; + +static const tt_xy_pair PCIE_GRID_SIZE = {1, 1}; +static const std::vector PCIE_CORES = {{{0, 4}}}; +static const std::vector PCI_LOCATIONS = PCIE_CORES; static const std::array ETH_LOCATIONS = {}; // Return to std::array instead of std::vector once we get std::span support in C++20 static const std::vector T6_X_LOCATIONS = {12, 1, 11, 2, 10, 3, 9, 4, 8, 5, 7, 6}; diff --git a/device/tt_core_coordinates.h b/device/tt_core_coordinates.h new file mode 100644 index 00000000..e9287ef1 --- /dev/null +++ b/device/tt_core_coordinates.h @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: (c) 2024 Tenstorrent Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + + #include "device/tt_xy_pair.h" + +/* + * CoordSystem is an enum class that represents all types of coordinate + * systems that can be used to represent a core's location. + */ +enum class CoordSystem : std::uint8_t { + LOGICAL, + PHYSICAL, + VIRTUAL, + TRANSLATED, +}; + +/* + * CoreType is an enum class that represents all types of cores + * present on the Tenstorrent chip. + */ +enum class CoreType : std::uint8_t { + ARC, + DRAM, + ACTIVE_ETH, + IDLE_ETH, + PCIE, + TENSIX, + ROUTER_ONLY, + // TODO: this keeps compatibility with existing code in SocDescriptor + // but it won't be needed later on + HARVESTED, + ETH, +}; + + struct CoreCoord : public tt_xy_pair { + CoreCoord() {} + CoreCoord(const size_t x, const size_t y, const CoreType type, const CoordSystem coord_system) + : tt_xy_pair(x, y), core_type(type), coord_system(coord_system) {} + + CoreType core_type; + CoordSystem coord_system; + + bool operator==(const CoreCoord& other) const + { + return this->x == other.x && this->y == other.y && this->core_type == other.core_type && this->coord_system == other.coord_system; + } + }; diff --git a/device/tt_soc_descriptor.cpp b/device/tt_soc_descriptor.cpp index ac9b31ad..761c5e81 100644 --- a/device/tt_soc_descriptor.cpp +++ b/device/tt_soc_descriptor.cpp @@ -128,7 +128,7 @@ void tt_SocDescriptor::load_core_descriptors_from_device_descriptor(YAML::Node & for (const auto &core_string : worker_cores) { CoreDescriptor core_descriptor; core_descriptor.coord = format_node(core_string); - core_descriptor.type = CoreType::WORKER; + core_descriptor.type = CoreType::TENSIX; core_descriptor.l1_size = worker_l1_size; cores.insert({core_descriptor.coord, core_descriptor}); workers.push_back(core_descriptor.coord); @@ -168,63 +168,35 @@ void tt_SocDescriptor::load_core_descriptors_from_device_descriptor(YAML::Node & } } -void tt_SocDescriptor::create_coordinate_manager(std::size_t harvesting_mask) { - coordinate_manager = CoordinateManager::get_coordinate_manager(arch, worker_grid_size, workers, harvesting_mask); +void tt_SocDescriptor::create_coordinate_manager(const std::size_t tensix_harvesting_mask, const std::size_t dram_harvesting_mask) { + coordinate_manager = CoordinateManager::get_coordinate_manager(arch, tensix_harvesting_mask, dram_harvesting_mask); } -void tt_SocDescriptor::perform_harvesting(std::size_t harvesting_mask) { - coordinate_manager->perform_harvesting(harvesting_mask); +void tt_SocDescriptor::tensix_harvesting(std::size_t harvesting_mask) { + coordinate_manager->tensix_harvesting(harvesting_mask); } -tt_physical_coords tt_SocDescriptor::to_physical_coords(tt_logical_coords logical_coords) { - return coordinate_manager->to_physical_coords(logical_coords); +void tt_SocDescriptor::dram_harvesting(const std::size_t dram_harvesting_mask) { + coordinate_manager->dram_harvesting(dram_harvesting_mask); } -tt_virtual_coords tt_SocDescriptor::to_virtual_coords(tt_logical_coords logical_coords) { - return coordinate_manager->to_virtual_coords(logical_coords); +CoreCoord tt_SocDescriptor::to_physical(const CoreCoord core_coord) { + return coordinate_manager->to_physical(core_coord); } -tt_translated_coords tt_SocDescriptor::to_translated_coords(tt_logical_coords logical_coords) { - return coordinate_manager->to_translated_coords(logical_coords); +CoreCoord tt_SocDescriptor::to_logical(const CoreCoord core_coord) { + return coordinate_manager->to_logical(core_coord); } -tt_logical_coords tt_SocDescriptor::to_logical_coords(tt_physical_coords physical_coords) { - return coordinate_manager->to_logical_coords(physical_coords); +CoreCoord tt_SocDescriptor::to_virtual(const CoreCoord core_coord) { + return coordinate_manager->to_virtual(core_coord); } -tt_virtual_coords tt_SocDescriptor::to_virtual_coords(tt_physical_coords physical_coords) { - return coordinate_manager->to_virtual_coords(physical_coords); +CoreCoord tt_SocDescriptor::to_translated(const CoreCoord core_coord) { + return coordinate_manager->to_translated(core_coord); } -tt_translated_coords tt_SocDescriptor::to_translated_coords(tt_physical_coords physical_coords) { - return coordinate_manager->to_translated_coords(physical_coords); -} - -tt_logical_coords tt_SocDescriptor::to_logical_coords(tt_virtual_coords virtual_coords) { - return coordinate_manager->to_logical_coords(virtual_coords); -} - -tt_physical_coords tt_SocDescriptor::to_physical_coords(tt_virtual_coords virtual_coords) { - return coordinate_manager->to_physical_coords(virtual_coords); -} - -tt_translated_coords tt_SocDescriptor::to_translated_coords(tt_virtual_coords virtual_coords) { - return coordinate_manager->to_translated_coords(virtual_coords); -} - -tt_logical_coords tt_SocDescriptor::to_logical_coords(tt_translated_coords translated_coords) { - return coordinate_manager->to_logical_coords(translated_coords); -} - -tt_physical_coords tt_SocDescriptor::to_physical_coords(tt_translated_coords translated_coords) { - return coordinate_manager->to_physical_coords(translated_coords); -} - -tt_virtual_coords tt_SocDescriptor::to_virtual_coords(tt_translated_coords translated_coords) { - return coordinate_manager->to_virtual_coords(translated_coords); -} - -tt_SocDescriptor::tt_SocDescriptor(std::string device_descriptor_path, std::size_t harvesting_mask) { +tt_SocDescriptor::tt_SocDescriptor(std::string device_descriptor_path, const std::size_t tensix_harvesting_mask, const std::size_t dram_harvesting_mask) { std::ifstream fdesc(device_descriptor_path); if (fdesc.fail()) { throw std::runtime_error( @@ -250,8 +222,7 @@ tt_SocDescriptor::tt_SocDescriptor(std::string device_descriptor_path, std::size arch_name_value = trim(arch_name_value); arch = get_arch_name(arch_name_value); load_soc_features_from_device_descriptor(device_descriptor_yaml); - create_coordinate_manager(harvesting_mask); - perform_harvesting(harvesting_mask); + create_coordinate_manager(tensix_harvesting_mask, dram_harvesting_mask); } int tt_SocDescriptor::get_num_dram_channels() const { diff --git a/device/tt_soc_descriptor.h b/device/tt_soc_descriptor.h index 4d3c2ad5..65a04a76 100644 --- a/device/tt_soc_descriptor.h +++ b/device/tt_soc_descriptor.h @@ -15,7 +15,8 @@ #include #include "device/coordinate_manager.h" -#include "device/tt_arch_types.h" +#include "device/tt_core_coordinates.h" + #include "fmt/core.h" #include "tt_xy_pair.h" @@ -64,19 +65,6 @@ std::string format_node(tt_xy_pair xy); tt_xy_pair format_node(std::string str); -//! SocCore type enumerations -/*! Superset for all chip generations */ -enum class CoreType { - ARC, - DRAM, - ETH, - PCIE, - WORKER, - HARVESTED, - ROUTER_ONLY, - -}; - //! SocNodeDescriptor contains information regarding the Node/Core /*! Should only contain relevant configuration for SOC @@ -132,8 +120,8 @@ class tt_SocDescriptor { // Default constructor. Creates uninitialized object with public access to all of its attributes. tt_SocDescriptor() = default; - // Constructor used to build object from device descriptor file. - tt_SocDescriptor(std::string device_descriptor_path, std::size_t harvesting_mask = 0); + // Constructor used to build object from device descriptor file. + tt_SocDescriptor(std::string device_descriptor_path, const std::size_t tensix_harvesting_mask = 0, const std::size_t dram_harvesting_mask = 0); // Copy constructor tt_SocDescriptor(const tt_SocDescriptor &other) : @@ -166,32 +154,20 @@ class tt_SocDescriptor { dram_bank_size(other.dram_bank_size) { coordinate_manager.reset(new CoordinateManager(*other.coordinate_manager)); } + + // CoreCoord conversions. + CoreCoord to_physical(const CoreCoord core_coord); + CoreCoord to_logical(const CoreCoord core_coord); + CoreCoord to_virtual(const CoreCoord core_coord); + CoreCoord to_translated(const CoreCoord core_coord); - // Coordinate conversions. - - // Conversions from logical coordinates should be used just for worker cores. - tt_physical_coords to_physical_coords(tt_logical_coords logical_coords); - tt_virtual_coords to_virtual_coords(tt_logical_coords logical_coords); - tt_translated_coords to_translated_coords(tt_logical_coords logical_coords); - - tt_logical_coords to_logical_coords(tt_physical_coords physical_coords); - tt_virtual_coords to_virtual_coords(tt_physical_coords physical_coords); - tt_translated_coords to_translated_coords(tt_physical_coords physical_coords); - - tt_logical_coords to_logical_coords(tt_virtual_coords virtual_coords); - tt_physical_coords to_physical_coords(tt_virtual_coords virtual_coords); - tt_translated_coords to_translated_coords(tt_virtual_coords virtual_coords); - - tt_logical_coords to_logical_coords(tt_translated_coords translated_coords); - tt_physical_coords to_physical_coords(tt_translated_coords translated_coords); - tt_virtual_coords to_virtual_coords(tt_translated_coords translated_coords); - - void perform_harvesting(std::size_t harvesting_mask); + void tensix_harvesting(std::size_t harvesting_mask); + void dram_harvesting(const std::size_t dram_harvesting_mask); static std::string get_soc_descriptor_path(tt::ARCH arch); private: - void create_coordinate_manager(std::size_t harvesting_mask); + void create_coordinate_manager(const std::size_t tensix_harvesting_mask, const std::size_t dram_harvesting_mask); void load_core_descriptors_from_device_descriptor(YAML::Node &device_descriptor_yaml); void load_soc_features_from_device_descriptor(YAML::Node &device_descriptor_yaml); diff --git a/device/tt_xy_pair.h b/device/tt_xy_pair.h index 3d982ac9..f75d9033 100644 --- a/device/tt_xy_pair.h +++ b/device/tt_xy_pair.h @@ -12,59 +12,3 @@ using tt_xy_pair = tt::umd::xy_pair; using tt_cxy_pair = tt::umd::cxy_pair; - -struct tt_physical_coords : public tt_xy_pair { - tt_physical_coords() : tt_xy_pair() {} - - tt_physical_coords(std::size_t x, std::size_t y) : tt_xy_pair(x, y) {} -}; - -struct tt_chip_physical_coords : public tt_cxy_pair { - tt_chip_physical_coords() : tt_cxy_pair() {} - - tt_chip_physical_coords(std::size_t ichip, xy_pair pair) : tt_cxy_pair(ichip, pair) {} - - tt_chip_physical_coords(std::size_t ichip, std::size_t x, std::size_t y) : tt_cxy_pair(ichip, x, y) {} -}; - -struct tt_logical_coords : public tt_xy_pair { - tt_logical_coords() : tt_xy_pair() {} - - tt_logical_coords(std::size_t x, std::size_t y) : tt_xy_pair(x, y) {} -}; - -struct tt_chip_logical_coords : public tt_cxy_pair { - tt_chip_logical_coords() : tt_cxy_pair() {} - - tt_chip_logical_coords(std::size_t ichip, xy_pair pair) : tt_cxy_pair(ichip, pair) {} - - tt_chip_logical_coords(std::size_t ichip, std::size_t x, std::size_t y) : tt_cxy_pair(ichip, x, y) {} -}; - -struct tt_virtual_coords : public tt_xy_pair { - tt_virtual_coords() : tt_xy_pair() {} - - tt_virtual_coords(std::size_t x, std::size_t y) : tt_xy_pair(x, y) {} -}; - -struct tt_chip_virtual_coords : public tt_cxy_pair { - tt_chip_virtual_coords() : tt_cxy_pair() {} - - tt_chip_virtual_coords(std::size_t ichip, xy_pair pair) : tt_cxy_pair(ichip, pair) {} - - tt_chip_virtual_coords(std::size_t ichip, std::size_t x, std::size_t y) : tt_cxy_pair(ichip, x, y) {} -}; - -struct tt_translated_coords : public tt_xy_pair { - tt_translated_coords() : tt_xy_pair() {} - - tt_translated_coords(std::size_t x, std::size_t y) : tt_xy_pair(x, y) {} -}; - -struct tt_chip_translated_coords : public tt_cxy_pair { - tt_chip_translated_coords() : tt_cxy_pair() {} - - tt_chip_translated_coords(std::size_t ichip, xy_pair pair) : tt_cxy_pair(ichip, pair) {} - - tt_chip_translated_coords(std::size_t ichip, std::size_t x, std::size_t y) : tt_cxy_pair(ichip, x, y) {} -}; diff --git a/device/wormhole/wormhole_coordinate_manager.cpp b/device/wormhole/wormhole_coordinate_manager.cpp index e9766d16..14fed000 100644 --- a/device/wormhole/wormhole_coordinate_manager.cpp +++ b/device/wormhole/wormhole_coordinate_manager.cpp @@ -1,29 +1,30 @@ /* - * SPDX-FileCopyrightText: (c) 2023 Tenstorrent Inc. + * SPDX-FileCopyrightText: (c) 2024 Tenstorrent Inc. * * SPDX-License-Identifier: Apache-2.0 */ #include "wormhole_coordinate_manager.h" -std::set WormholeCoordinateManager::get_y_coordinates_to_harvest(std::size_t harvesting_mask) { - std::set y_to_harvest; - std::size_t logical_y = 0; - while (harvesting_mask > 0) { - if (harvesting_mask & 1) { - y_to_harvest.insert(logical_y); +void WormholeCoordinateManager::fill_tensix_logical_to_translated() { + std::size_t num_harvested_y = __builtin_popcount(CoordinateManager::tensix_harvesting_mask); + + for (std::size_t y = 0; y < CoordinateManager::tensix_grid_size.y - num_harvested_y; y++) { + for (std::size_t x = 0; x < CoordinateManager::tensix_grid_size.x; x++) { + const std::size_t translated_x = x + tensix_translated_coordinate_start_x; + const std::size_t translated_y = y + tensix_translated_coordinate_start_y; + CoordinateManager::tensix_logical_to_translated[{x, y}] = CoreCoord(translated_x, translated_y, CoreType::TENSIX, CoordSystem::TRANSLATED); + CoordinateManager::tensix_translated_to_logical[tt_xy_pair(translated_x, translated_y)] = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); } - logical_y++; - harvesting_mask >>= 1; } - return y_to_harvest; -} - -tt_translated_coords WormholeCoordinateManager::to_translated_coords(tt_logical_coords logical_coords) { - return tt_translated_coords( - logical_coords.x + translated_coordinate_start_x, logical_coords.y + translated_coordinate_start_y); } -tt_logical_coords WormholeCoordinateManager::to_logical_coords(tt_translated_coords translated_coords) { - return tt_logical_coords( - translated_coords.x - translated_coordinate_start_x, translated_coords.y - translated_coordinate_start_y); +void WormholeCoordinateManager::fill_eth_logical_to_translated() { + for (std::size_t x = 0; x < CoordinateManager::eth_grid_size.x; x++) { + for (std::size_t y = 0; y < CoordinateManager::eth_grid_size.y; y++) { + const std::size_t translated_x = x + eth_translated_coordinate_start_x; + const std::size_t translated_y = y + eth_translated_coordinate_start_y; + CoordinateManager::eth_logical_to_translated[{x, y}] = CoreCoord(translated_x, translated_y, CoreType::ETH, CoordSystem::TRANSLATED); + CoordinateManager::eth_translated_to_logical[{translated_x, translated_y}] = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); + } + } } diff --git a/device/wormhole/wormhole_coordinate_manager.h b/device/wormhole/wormhole_coordinate_manager.h index e3e35886..09872974 100644 --- a/device/wormhole/wormhole_coordinate_manager.h +++ b/device/wormhole/wormhole_coordinate_manager.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: (c) 2023 Tenstorrent Inc. + * SPDX-FileCopyrightText: (c) 2024 Tenstorrent Inc. * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,21 +7,39 @@ #pragma once #include "device/coordinate_manager.h" +#include "device/wormhole/wormhole_implementation.h" +#include "wormhole_implementation.h" class WormholeCoordinateManager : public CoordinateManager { public: WormholeCoordinateManager( - const tt_xy_pair& worker_grid_size, const std::vector& workers, std::size_t harvesting_mask) : - CoordinateManager(worker_grid_size, workers, harvesting_mask) {} - - tt_translated_coords to_translated_coords(tt_logical_coords logical_coords) override; - - tt_logical_coords to_logical_coords(tt_translated_coords translated_coords) override; - + const tt_xy_pair& tensix_grid_size, const std::vector& tensix_cores, const std::size_t tensix_harvesting_mask, + const tt_xy_pair& dram_grid_size, const std::vector& dram_cores, const std::size_t dram_harvesting_mask, + const tt_xy_pair& eth_grid_size, const std::vector& eth_cores, + const tt_xy_pair& arc_grid_size, const std::vector& arc_cores, + const tt_xy_pair& pcie_grid_size, const std::vector& pcie_cores) + : CoordinateManager( + tensix_grid_size, tensix_cores, tensix_harvesting_mask, + dram_grid_size, dram_cores, dram_harvesting_mask, + eth_grid_size, eth_cores, + arc_grid_size, arc_cores, + pcie_grid_size, pcie_cores) + { + this->tensix_harvesting(tensix_harvesting_mask); + this->dram_harvesting(dram_harvesting_mask); + this->translate_eth_coords(); + this->translate_arc_coords(); + this->translate_pcie_coords(); + } protected: - std::set get_y_coordinates_to_harvest(std::size_t harvesting_mask) override; + void fill_tensix_logical_to_translated() override; + + void fill_eth_logical_to_translated() override; private: - static const std::size_t translated_coordinate_start_x = 18; - static const std::size_t translated_coordinate_start_y = 18; + static const std::size_t tensix_translated_coordinate_start_x = 18; + static const std::size_t tensix_translated_coordinate_start_y = 18; + + static const std::size_t eth_translated_coordinate_start_x = 18; + static const std::size_t eth_translated_coordinate_start_y = 16; }; diff --git a/device/wormhole/wormhole_implementation.h b/device/wormhole/wormhole_implementation.h index f8bf6f14..823acdc5 100644 --- a/device/wormhole/wormhole_implementation.h +++ b/device/wormhole/wormhole_implementation.h @@ -10,6 +10,7 @@ #include "device/architecture_implementation.h" #include "device/tlb.h" +#include "device/tt_xy_pair.h" namespace tt::umd { @@ -102,28 +103,46 @@ enum class arc_message_type { }; // DEVICE_DATA -static constexpr std::array DRAM_LOCATIONS = { - {{0, 0}, - {5, 0}, - {0, 1}, - {5, 1}, - {5, 2}, - {5, 3}, - {5, 4}, - {0, 5}, - {5, 5}, - {0, 6}, - {5, 6}, - {0, 7}, - {5, 7}, - {5, 8}, - {5, 9}, - {5, 10}, - {0, 11}, - {5, 11}}}; -static constexpr std::array ARC_LOCATIONS = {{{0, 2}}}; -static constexpr std::array PCI_LOCATIONS = {{{0, 4}}}; -static constexpr std::array ETH_LOCATIONS = { +static const tt_xy_pair TENSIX_GRID_SIZE = {8, 10}; +static const std::vector TENSIX_CORES = { + {{1, 1}, {2, 1}, {3, 1}, {4, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, + {1, 2}, {2, 2}, {3, 2}, {4, 2}, {6, 2}, {7, 2}, {8, 2}, {9, 2}, + {1, 3}, {2, 3}, {3, 3}, {4, 3}, {6, 3}, {7, 3}, {8, 3}, {9, 3}, + {1, 4}, {2, 4}, {3, 4}, {4, 4}, {6, 4}, {7, 4}, {8, 4}, {9, 4}, + {1, 5}, {2, 5}, {3, 5}, {4, 5}, {6, 5}, {7, 5}, {8, 5}, {9, 5}, + {1, 7}, {2, 7}, {3, 7}, {4, 7}, {6, 7}, {7, 7}, {8, 7}, {9, 7}, + {1, 8}, {2, 8}, {3, 8}, {4, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, + {1, 9}, {2, 9}, {3, 9}, {4, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, + {1, 10}, {2, 10}, {3, 10}, {4, 10}, {6, 10}, {7, 10}, {8, 10}, {9, 10}, + {1, 11}, {2, 11}, {3, 11}, {4, 11}, {6, 11}, {7, 11}, {8, 11}, {9, 11}, +}}; + +static const std::size_t NUM_DRAM_BANKS = 6; +static const std::size_t NUM_NOC_PORTS_PER_DRAM_BANK = 3; +static const tt_xy_pair DRAM_GRID_SIZE = {NUM_DRAM_BANKS, NUM_NOC_PORTS_PER_DRAM_BANK}; +static const std::vector DRAM_CORES = { + {{0, 0}, {5, 0}, {0, 1}, + {5, 1}, {5, 2}, {5, 3}, + {5, 4}, {0, 5}, {5, 5}, + {0, 6}, {5, 6}, {0, 7}, + {5, 7}, {5, 8}, {5, 9}, + {5, 10},{0, 11},{5, 11} +}}; + +// TODO: DRAM locations should be deleted. We keep it for compatibility with +// the existing code in clients which rely on DRAM_LOCATIONS. +static const std::vector DRAM_LOCATIONS = DRAM_CORES; + +static const tt_xy_pair ARC_GRID_SIZE = {1, 1}; +static const std::vector ARC_CORES = {{0, 2}}; +static const std::vector ARC_LOCATIONS = ARC_CORES; + +static const tt_xy_pair PCIE_GRID_SIZE = {1, 1}; +static const std::vector PCIE_CORES = {{{0, 4}}}; +static const std::vector PCI_LOCATIONS = PCIE_CORES; + +static const tt_xy_pair ETH_GRID_SIZE = {8, 2}; +static const std::vector ETH_CORES = { {{1, 0}, {2, 0}, {3, 0}, @@ -140,6 +159,7 @@ static constexpr std::array ETH_LOCATIONS = { {7, 6}, {8, 6}, {9, 6}}}; +static const std::vector ETH_LOCATIONS = ETH_CORES; // Return to std::array instead of std::vector once we get std::span support in C++20 static const std::vector T6_X_LOCATIONS = {1, 2, 3, 4, 6, 7, 8, 9}; static const std::vector T6_Y_LOCATIONS = {1, 2, 3, 4, 5, 7, 8, 9, 10, 11}; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bbc47fcd..a8640910 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -51,12 +51,8 @@ foreach(ARCH IN LISTS ARCHS) message(FATAL_ERROR "Failed to download ${HW_NOC_PARAMETERS_URL}") endif() endif() + include_directories("${CMAKE_CURRENT_BINARY_DIR}/${ARCH}") endforeach() -if($ENV{ARCH_NAME} STREQUAL "wormhole_b0") - include_directories("${CMAKE_CURRENT_BINARY_DIR}/wormhole") -else() - include_directories("${CMAKE_CURRENT_BINARY_DIR}/$ENV{ARCH_NAME}") -endif() if(MASTER_PROJECT) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/microbenchmark) diff --git a/tests/api/CMakeLists.txt b/tests/api/CMakeLists.txt index eb50a772..bf6c14cd 100644 --- a/tests/api/CMakeLists.txt +++ b/tests/api/CMakeLists.txt @@ -2,10 +2,11 @@ set(API_TESTS_SRCS test_chip.cpp test_cluster_descriptor.cpp test_cluster.cpp - test_soc_descriptor_gs.cpp - test_soc_descriptor_wh.cpp - test_soc_descriptor_bh.cpp + test_core_coord_translation_gs.cpp + test_core_coord_translation_wh.cpp + test_core_coord_translation_bh.cpp test_mockup_device.cpp + test_core_coordinates.cpp ) add_executable(api_tests ${API_TESTS_SRCS}) diff --git a/tests/api/test_core_coord_translation_bh.cpp b/tests/api/test_core_coord_translation_bh.cpp new file mode 100644 index 00000000..a3e40715 --- /dev/null +++ b/tests/api/test_core_coord_translation_bh.cpp @@ -0,0 +1,412 @@ +/* + * SPDX-FileCopyrightText: (c) 2023 Tenstorrent Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "gtest/gtest.h" + +#include "device/tt_soc_descriptor.h" +#include "tests/test_utils/generate_cluster_desc.hpp" +#include "tests/test_utils/soc_desc_test_utils.hpp" +#include "device/blackhole/blackhole_implementation.h" + +// Tests that all physical coordinates are same as all virtual coordinates +// when there is no harvesting. +TEST(CoordinateManager, CoordinateManagerBlackholeNoHarvesting) { + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + + // We expect full grid size since there is no harvesting. + tt_xy_pair tensix_grid_size = tt::umd::blackhole::TENSIX_GRID_SIZE; + for (size_t x = 0; x < tensix_grid_size.x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + + // Virtual and physical coordinates should be the same. + EXPECT_EQ(physical_coords.x, virtual_coords.x); + EXPECT_EQ(physical_coords.y, virtual_coords.y); + } + } +} + +// Test basic translation to virtual and physical noc coordinates. +// We expect that the top left core will have virtual and physical coordinates (1, 2) and (2, 2) for +// the logical coordinates if the first row is harvested. +TEST(CoordinateManager, CoordinateManagerBlackholeTopLeftCore) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE, 1); + tt_xy_pair tensix_grid_size = tt::umd::blackhole::TENSIX_GRID_SIZE; + + CoreCoord logical_coords = CoreCoord(0, 0, CoreType::TENSIX, CoordSystem::LOGICAL); + + // Always expect same virtual coordinate for (0, 0) logical coordinate. + CoreCoord virtual_cords = coordinate_manager->to_virtual(logical_coords); + EXPECT_EQ(virtual_cords, CoreCoord(1, 2, CoreType::TENSIX, CoordSystem::VIRTUAL)); + + // This depends on harvesting mask. So expected physical coord is specific to this test and Blackhole arch. + CoreCoord physical_cords = coordinate_manager->to_physical(logical_coords); + EXPECT_EQ(physical_cords, CoreCoord(2, 2, CoreType::TENSIX, CoordSystem::PHYSICAL)); +} + +// Test logical to physical coordinate translation. +// For the full grid of logical coordinates we expect that there are no duplicates of physical coordinates. +// For the reverse mapping back of physical to logical coordinates we expect that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerBlackholeLogicalPhysicalMapping) { + + const std::size_t max_num_harvested_x = 14; + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_harvested_x); harvesting_mask++) { + coordinate_manager->tensix_harvesting(harvesting_mask); + + std::map logical_to_physical; + std::set physical_coords_set; + tt_xy_pair tensix_grid_size = tt::umd::blackhole::TENSIX_GRID_SIZE; + + std::size_t num_harvested_x = test_utils::get_num_harvested(harvesting_mask); + + for (size_t x = 0; x < tensix_grid_size.x - num_harvested_x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + logical_to_physical[logical_coords] = physical_coords; + + // Expect that logical to physical translation is 1-1 mapping. No duplicates for physical coordinates. + EXPECT_EQ(physical_coords_set.count(physical_coords), 0); + physical_coords_set.insert(physical_coords); + } + } + + EXPECT_EQ(physical_coords_set.size(), tensix_grid_size.y * (tensix_grid_size.x - num_harvested_x)); + + for (auto it : logical_to_physical) { + CoreCoord physical_coords = it.second; + CoreCoord logical_coords = coordinate_manager->to_logical(physical_coords); + + // Expect that reverse mapping of physical coordinates gives the same logical coordinates + // using which we got the physical coordinates. + EXPECT_EQ(it.first, logical_coords); + } + } +} + +// Test logical to virtual coordinate translation. +// For the full grid of logical coordinates we expect that there are no duplicates of virtual coordinates. +// For the reverse mapping back of virtual to logical coordinates we expect that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerBlackholeLogicalVirtualMapping) { + + const std::size_t max_num_harvested_x = 14; + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_harvested_x); harvesting_mask++) { + + coordinate_manager->tensix_harvesting(harvesting_mask); + + std::map logical_to_virtual; + std::set virtual_coords_set; + tt_xy_pair tensix_grid_size = tt::umd::blackhole::TENSIX_GRID_SIZE; + + std::size_t num_harvested_x = test_utils::get_num_harvested(harvesting_mask); + + for (size_t x = 0; x < tensix_grid_size.x - num_harvested_x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + logical_to_virtual[logical_coords] = virtual_coords; + + // Expect that logical to virtual translation is 1-1 mapping. No duplicates for virtual coordinates. + EXPECT_EQ(virtual_coords_set.count(virtual_coords), 0); + virtual_coords_set.insert(virtual_coords); + } + } + + EXPECT_EQ(virtual_coords_set.size(), tensix_grid_size.y * (tensix_grid_size.x - num_harvested_x)); + + for (auto it : logical_to_virtual) { + CoreCoord virtual_coords = it.second; + CoreCoord logical_coords = coordinate_manager->to_logical(virtual_coords); + + // Expect that reverse mapping of virtual coordinates gives the same logical coordinates + // using which we got the virtual coordinates. + EXPECT_EQ(it.first, logical_coords); + } + } +} + +// Test logical to translated coordinate translation. +// For the full grid of logical coordinates we expect that there are no duplicates of translated coordinates. +// For the reverse mapping back of translated to logical coordinates we expect that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerBlackholeLogicalTranslatedMapping) { + + const std::size_t max_num_harvested_x = 14; + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_harvested_x); harvesting_mask++) { + + coordinate_manager->tensix_harvesting(harvesting_mask); + + std::map logical_to_translated; + std::set translated_coords_set; + tt_xy_pair tensix_grid_size = tt::umd::blackhole::TENSIX_GRID_SIZE; + + std::size_t num_harvested_x = test_utils::get_num_harvested(harvesting_mask); + + for (size_t x = 0; x < tensix_grid_size.x - num_harvested_x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord translated_coords = coordinate_manager->to_translated(logical_coords); + logical_to_translated[logical_coords] = translated_coords; + + // Expect that logical to translated translation is 1-1 mapping. No duplicates for translated coordinates. + EXPECT_EQ(translated_coords_set.count(translated_coords), 0); + translated_coords_set.insert(translated_coords); + } + } + + EXPECT_EQ(translated_coords_set.size(), tensix_grid_size.y * (tensix_grid_size.x - num_harvested_x)); + + for (auto it : logical_to_translated) { + CoreCoord translated_coords = it.second; + CoreCoord logical_coords = coordinate_manager->to_logical(translated_coords); + + // Expect that reverse mapping of translated coordinates gives the same logical coordinates + // using which we got the translated coordinates. + EXPECT_EQ(it.first, logical_coords); + } + } +} + +// Test that virtual and translated coordinates are same for all logical coordinates. +// This is expected for Blackhole way of harvesting. +TEST(CoordinateManager, CoordinateManagerBlackholeVirtualEqualTranslated) { + const std::size_t max_num_harvested_x = 14; + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_harvested_x); harvesting_mask++) { + coordinate_manager->tensix_harvesting(harvesting_mask); + + std::size_t num_harvested_x = test_utils::get_num_harvested(harvesting_mask); + + for (std::size_t x = 0; x < tt::umd::blackhole::TENSIX_GRID_SIZE.x - num_harvested_x; x++) { + for (std::size_t y = 0; y < tt::umd::blackhole::TENSIX_GRID_SIZE.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord translated_coords = coordinate_manager->to_translated(logical_coords); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + + // Expect that translated coordinates are same as virtual coordinates. + EXPECT_EQ(translated_coords.x, virtual_coords.x); + EXPECT_EQ(translated_coords.y, virtual_coords.y); + } + } + } +} + +// Test mapping of DRAM coordinates from logical to physical. When there is no DRAM harvesting, logical +// coordinates should cover all physical coordinates. +TEST(CoordinateManager, CoordinateManagerBlackholeDRAMNoHarvesting) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + + const std::size_t num_dram_banks = tt::umd::blackhole::NUM_DRAM_BANKS; + const std::size_t num_noc_ports_per_bank = tt::umd::blackhole::NUM_NOC_PORTS_PER_DRAM_BANK; + const std::vector& dram_cores = tt::umd::blackhole::DRAM_CORES; + + for (std::size_t dram_bank = 0; dram_bank < num_dram_banks; dram_bank++) { + for (std::size_t noc_port = 0; noc_port < num_noc_ports_per_bank; noc_port++) { + const CoreCoord dram_logical(dram_bank, noc_port, CoreType::DRAM, CoordSystem::LOGICAL); + const std::size_t physical_core_index = dram_bank * num_noc_ports_per_bank + noc_port; + const CoreCoord expected_physical = CoreCoord(dram_cores[physical_core_index].x, dram_cores[physical_core_index].y, CoreType::DRAM, CoordSystem::PHYSICAL); + + const CoreCoord dram_physical = coordinate_manager->to_physical(dram_logical); + + EXPECT_EQ(dram_physical, expected_physical); + } + } +} + +// Test top left corner translation from logical to physical coordinates. +TEST(CoordinateManager, CoordinateManagerBlackholeDRAMTopLeft) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE, 0, 1); + + const CoreCoord top_left_dram_logical = CoreCoord(0, 0, CoreType::DRAM, CoordSystem::LOGICAL); + const CoreCoord expected_top_left_physical = CoreCoord(0, 2, CoreType::DRAM, CoordSystem::PHYSICAL); + + const CoreCoord top_left_physical = coordinate_manager->to_physical(top_left_dram_logical); + + EXPECT_EQ(top_left_physical, expected_top_left_physical); +} + +// Test logical to physical DRAM coordinate translation. +// For the full grid of logical coordinates we expect that there are no duplicates of physical coordinates. +// For the reverse mapping back of physical to logical coordinates we expect that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerBlackholeDRAMLogicalPhysicalMapping) { + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + + const std::size_t max_num_banks_harvested = tt::umd::blackhole::NUM_DRAM_BANKS; + const std::size_t num_dram_banks = tt::umd::blackhole::NUM_DRAM_BANKS; + const std::size_t num_noc_ports_per_bank = tt::umd::blackhole::NUM_NOC_PORTS_PER_DRAM_BANK; + const std::vector& dram_cores = tt::umd::blackhole::DRAM_CORES; + + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_banks_harvested); harvesting_mask++) { + + coordinate_manager->dram_harvesting(harvesting_mask); + + std::map logical_to_physical; + std::set physical_coords_set; + + std::size_t num_banks_harvested = test_utils::get_num_harvested(harvesting_mask); + + for (size_t x = 0; x < num_dram_banks - num_banks_harvested; x++) { + for (size_t y = 0; y < num_noc_ports_per_bank; y++) { + const CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + const CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + logical_to_physical[logical_coords] = physical_coords; + + // Expect that logical to physical translation is 1-1 mapping. No duplicates for physical coordinates. + EXPECT_EQ(physical_coords_set.count(physical_coords), 0); + physical_coords_set.insert(physical_coords); + } + } + + EXPECT_EQ(physical_coords_set.size(), num_noc_ports_per_bank * (num_dram_banks - num_banks_harvested)); + + for (auto it : logical_to_physical) { + const CoreCoord physical_coords = it.second; + const CoreCoord logical_coords = coordinate_manager->to_logical(physical_coords); + + // Expect that reverse mapping of physical coordinates gives the same logical coordinates + // using which we got the physical coordinates. + EXPECT_EQ(it.first, logical_coords); + } + } +} + +// Test logical to virtual DRAM coordinate translation. +// For the full grid of logical coordinates it is expected that there are no duplicates of virtual coordinates. +// For the reverse mapping back of virtual to logical coordinates it is expected that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerBlackholeDRAMLogicalVirtualMapping) { + + const std::size_t max_num_banks_harvested = tt::umd::blackhole::NUM_DRAM_BANKS; + const std::size_t num_dram_banks = tt::umd::blackhole::NUM_DRAM_BANKS; + const std::size_t num_noc_ports_per_bank = tt::umd::blackhole::NUM_NOC_PORTS_PER_DRAM_BANK; + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_banks_harvested); harvesting_mask++) { + + coordinate_manager->dram_harvesting(harvesting_mask); + + std::map logical_to_virtual; + std::set virtual_coords_set; + + std::size_t num_harvested_banks = test_utils::get_num_harvested(harvesting_mask); + + for (size_t x = 0; x < num_dram_banks - num_harvested_banks; x++) { + for (size_t y = 0; y < num_noc_ports_per_bank; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + logical_to_virtual[logical_coords] = virtual_coords; + + // Expect that logical to virtual translation is 1-1 mapping. No duplicates for virtual coordinates. + EXPECT_EQ(virtual_coords_set.count(virtual_coords), 0); + virtual_coords_set.insert(virtual_coords); + } + } + + for (auto it : logical_to_virtual) { + CoreCoord virtual_coords = it.second; + CoreCoord logical_coords = coordinate_manager->to_logical(virtual_coords); + + // Expect that reverse mapping of virtual coordinates gives the same logical coordinates + // using which we got the virtual coordinates. + EXPECT_EQ(it.first, logical_coords); + } + } +} + +// Test equality of physical and translated coordinates for all logical coordinates for any harvesting mask. +TEST(CoordinateManager, CoordinateManagerBlackholeDRAMPhysicalTranslatedEquality) { + const std::size_t max_num_banks_harvested = tt::umd::blackhole::NUM_DRAM_BANKS; + const std::size_t num_dram_banks = tt::umd::blackhole::NUM_DRAM_BANKS; + const std::size_t num_noc_ports_per_bank = tt::umd::blackhole::NUM_NOC_PORTS_PER_DRAM_BANK; + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_banks_harvested); harvesting_mask++) { + + coordinate_manager->dram_harvesting(harvesting_mask); + + const std::size_t num_harvested_banks = test_utils::get_num_harvested(harvesting_mask); + + for (size_t x = 0; x < num_dram_banks - num_harvested_banks; x++) { + for (size_t y = 0; y < num_noc_ports_per_bank; y++) { + const CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + + const CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + const CoreCoord translated_coords = coordinate_manager->to_translated(logical_coords); + + EXPECT_EQ(physical_coords.x, translated_coords.x); + EXPECT_EQ(physical_coords.y, translated_coords.y); + } + } + } +} + +// Test that virtual, physical and translated coordinates are the same for all logical PCIE coordinates. +TEST(CoordinateManager, CoordinateManagerBlackholePCIETranslation) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + const tt_xy_pair pcie_grid_size = tt::umd::blackhole::PCIE_GRID_SIZE; + + for (std::size_t x = 0; x < pcie_grid_size.x; x++) { + for (std::size_t y = 0; y < pcie_grid_size.y; y++) { + const CoreCoord arc_logical = CoreCoord(x, y, CoreType::PCIE, CoordSystem::LOGICAL); + const CoreCoord arc_virtual = coordinate_manager->to_virtual(arc_logical); + const CoreCoord arc_physical = coordinate_manager->to_physical(arc_logical); + + EXPECT_EQ(arc_virtual.x, arc_physical.x); + EXPECT_EQ(arc_virtual.y, arc_physical.y); + } + } +} + +// Test that virtual, physical and translated coordinates are the same for all logical ARC coordinates. +TEST(CoordinateManager, CoordinateManagerBlackholeARCTranslation) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + const tt_xy_pair arc_grid_size = tt::umd::blackhole::ARC_GRID_SIZE; + + for (std::size_t x = 0; x < arc_grid_size.x; x++) { + for (std::size_t y = 0; y < arc_grid_size.y; y++) { + const CoreCoord arc_logical = CoreCoord(x, y, CoreType::ARC, CoordSystem::LOGICAL); + const CoreCoord arc_virtual = coordinate_manager->to_virtual(arc_logical); + const CoreCoord arc_physical = coordinate_manager->to_physical(arc_logical); + const CoreCoord arc_translated = coordinate_manager->to_translated(arc_logical); + + EXPECT_EQ(arc_virtual.x, arc_physical.x); + EXPECT_EQ(arc_virtual.y, arc_physical.y); + + EXPECT_EQ(arc_virtual.x, arc_translated.x); + EXPECT_EQ(arc_virtual.y, arc_translated.y); + } + } +} + +// Test ethernet coordinate translation. +TEST(CoordinateManager, CoordinateManagerBlackholeETHTranslation) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::BLACKHOLE); + const tt_xy_pair eth_grid_size = tt::umd::blackhole::ETH_GRID_SIZE; + + const std::size_t eth_translated_coordinate_start_x = 20; + const std::size_t eth_translated_coordinate_start_y = 25; + + for (std::size_t x = 0; x < eth_grid_size.x; x++) { + for (std::size_t y = 0; y < eth_grid_size.y; y++) { + const CoreCoord eth_logical = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); + const CoreCoord eth_virtual = coordinate_manager->to_virtual(eth_logical); + const CoreCoord eth_physical = coordinate_manager->to_physical(eth_logical); + const CoreCoord eth_translated = coordinate_manager->to_translated(eth_logical); + + EXPECT_EQ(eth_virtual.x, eth_physical.x); + EXPECT_EQ(eth_virtual.y, eth_physical.y); + + EXPECT_EQ(eth_translated.x, x + eth_translated_coordinate_start_x); + EXPECT_EQ(eth_translated.y, eth_translated_coordinate_start_y); + } + } +} diff --git a/tests/api/test_core_coord_translation_gs.cpp b/tests/api/test_core_coord_translation_gs.cpp new file mode 100644 index 00000000..6af9e658 --- /dev/null +++ b/tests/api/test_core_coord_translation_gs.cpp @@ -0,0 +1,183 @@ +/* + * SPDX-FileCopyrightText: (c) 2023 Tenstorrent Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "gtest/gtest.h" + +#include "device/tt_soc_descriptor.h" +#include "tests/test_utils/generate_cluster_desc.hpp" +#include "tests/test_utils/soc_desc_test_utils.hpp" +#include "device/grayskull/grayskull_implementation.h" + +// Tests that all physical coordinates are same as all virtual coordinates +// when there is no harvesting. +TEST(CoordinateManager, CoordinateManagerGrayskullNoHarvesting) { + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::GRAYSKULL); + + // We expect full grid size since there is no harvesting. + tt_xy_pair tensix_grid_size = tt::umd::grayskull::TENSIX_GRID_SIZE; + for (size_t x = 0; x < tensix_grid_size.x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + + // Virtual and physical coordinates should be the same. + EXPECT_EQ(physical_coords.x, virtual_coords.x); + EXPECT_EQ(physical_coords.y, virtual_coords.y); + } + } +} + +// Test basic translation to virtual and physical noc coordinates. +// We expect that the top left core will have virtual and physical coordinates (1, 1) and (1, 2) for +// the logical coordinates if the first row is harvested. +TEST(CoordinateManager, CoordinateManagerGrayskullTopLeftCore) { + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::GRAYSKULL); + tt_xy_pair tensix_grid_size = tt::umd::grayskull::TENSIX_GRID_SIZE; + + CoreCoord logical_coords = CoreCoord(0, 0, CoreType::TENSIX, CoordSystem::LOGICAL); + + // Always expect same virtual coordinate for (0, 0) logical coordinate. + CoreCoord virtual_cords = coordinate_manager->to_virtual(logical_coords); + EXPECT_EQ(virtual_cords, CoreCoord(1, 1, CoreType::TENSIX, CoordSystem::VIRTUAL)); + + // This depends on harvesting mask. So expected physical coord is specific to this test and Wormhole arch. + CoreCoord physical_cords = coordinate_manager->to_physical(logical_coords); + EXPECT_EQ(physical_cords, CoreCoord(1, 1, CoreType::TENSIX, CoordSystem::PHYSICAL)); +} + +// Test logical to physical, virtual and translated coordinates. +// We always expect that physical, virtual and translated coordinates are the same. +TEST(CoordinateManager, CoordinateManagerGrayskullTranslatingCoords) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::GRAYSKULL); + tt_xy_pair tensix_grid_size = tt::umd::grayskull::TENSIX_GRID_SIZE; + + for (size_t x = 0; x < tensix_grid_size.x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + CoreCoord translated_coords = coordinate_manager->to_translated(logical_coords); + + // Virtual, physical and translated coordinates should be the same. + EXPECT_EQ(physical_coords.x, virtual_coords.x); + EXPECT_EQ(physical_coords.y, virtual_coords.y); + + EXPECT_EQ(physical_coords.x, translated_coords.x); + EXPECT_EQ(physical_coords.y, translated_coords.y); + } + } +} + +// Test logical to physical coordinate translation. +// For the full grid of logical coordinates we expect that there are no duplicates of physical coordinates. +// For the reverse mapping back of physical to logical coordinates we expect that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerGrayskullLogicalPhysicalMapping) { + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::GRAYSKULL); + + std::map logical_to_physical; + std::set physical_coords_set; + tt_xy_pair tensix_grid_size = tt::umd::grayskull::TENSIX_GRID_SIZE; + + for (size_t x = 0; x < tensix_grid_size.x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + logical_to_physical[logical_coords] = physical_coords; + + // Expect that logical to physical translation is 1-1 mapping. No duplicates for physical coordinates. + EXPECT_EQ(physical_coords_set.count(physical_coords), 0); + physical_coords_set.insert(physical_coords); + } + } + + EXPECT_EQ(physical_coords_set.size(), tensix_grid_size.y * tensix_grid_size.x); + + for (auto it : logical_to_physical) { + CoreCoord physical_coords = it.second; + CoreCoord logical_coords = coordinate_manager->to_logical(physical_coords); + + // Expect that reverse mapping of physical coordinates gives the same logical coordinates + // using which we got the physical coordinates. + EXPECT_EQ(it.first, logical_coords); + } +} + +// Test logical to virtual coordinate translation. +// For the full grid of logical coordinates we expect that there are no duplicates of virtual coordinates. +// For the reverse mapping back of virtual to logical coordinates we expect that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerGrayskullLogicalVirtualMapping) { + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::GRAYSKULL); + + std::map logical_to_virtual; + std::set virtual_coords_set; + tt_xy_pair tensix_grid_size = tt::umd::grayskull::TENSIX_GRID_SIZE; + + for (size_t x = 0; x < tensix_grid_size.x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + logical_to_virtual[logical_coords] = virtual_coords; + + // Expect that logical to virtual translation is 1-1 mapping. No duplicates for virtual coordinates. + EXPECT_EQ(virtual_coords_set.count(virtual_coords), 0); + virtual_coords_set.insert(virtual_coords); + } + } + + EXPECT_EQ(virtual_coords_set.size(), tensix_grid_size.y * tensix_grid_size.x); + + for (auto it : logical_to_virtual) { + CoreCoord virtual_coords = it.second; + CoreCoord logical_coords = coordinate_manager->to_logical(virtual_coords); + + // Expect that reverse mapping of virtual coordinates gives the same logical coordinates + // using which we got the virtual coordinates. + EXPECT_EQ(it.first, logical_coords); + } +} + +// Test mapping of DRAM coordinates from logical to physical. We have no DRAM harvesting on Grayskull, +// so logical coordinates should cover all physical coordinates. +TEST(CoordinateManager, CoordinateManagerGrayskullDRAMNoHarvesting) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::GRAYSKULL); + + const std::size_t num_dram_banks = tt::umd::grayskull::NUM_DRAM_BANKS; + const std::vector& dram_cores = tt::umd::grayskull::DRAM_CORES; + + for (std::size_t dram_bank = 0; dram_bank < num_dram_banks; dram_bank++) { + const CoreCoord dram_logical(dram_bank, 0, CoreType::DRAM, CoordSystem::LOGICAL); + const CoreCoord expected_physical = CoreCoord(dram_cores[dram_bank].x, dram_cores[dram_bank].y, CoreType::DRAM, CoordSystem::PHYSICAL); + + const CoreCoord dram_physical = coordinate_manager->to_physical(dram_logical); + + EXPECT_EQ(dram_physical, expected_physical); + } +} + +// Test that virtual, physical and translated coordinates are the same for all logical PCIE coordinates. +TEST(CoordinateManager, CoordinateManagerGrayskullPCIETranslation) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::GRAYSKULL); + const tt_xy_pair pcie_grid_size = tt::umd::grayskull::PCIE_GRID_SIZE; + + for (std::size_t x = 0; x < pcie_grid_size.x; x++) { + for (std::size_t y = 0; y < pcie_grid_size.y; y++) { + const CoreCoord arc_logical = CoreCoord(x, y, CoreType::PCIE, CoordSystem::LOGICAL); + const CoreCoord arc_virtual = coordinate_manager->to_virtual(arc_logical); + const CoreCoord arc_physical = coordinate_manager->to_physical(arc_logical); + const CoreCoord arc_translated = coordinate_manager->to_translated(arc_logical); + + EXPECT_EQ(arc_virtual.x, arc_physical.x); + EXPECT_EQ(arc_virtual.y, arc_physical.y); + + EXPECT_EQ(arc_physical.x, arc_translated.x); + EXPECT_EQ(arc_physical.y, arc_translated.y); + } + } +} diff --git a/tests/api/test_core_coord_translation_wh.cpp b/tests/api/test_core_coord_translation_wh.cpp new file mode 100644 index 00000000..782f1a91 --- /dev/null +++ b/tests/api/test_core_coord_translation_wh.cpp @@ -0,0 +1,266 @@ +/* + * SPDX-FileCopyrightText: (c) 2023 Tenstorrent Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "gtest/gtest.h" + +#include "device/tt_soc_descriptor.h" +#include "tests/test_utils/generate_cluster_desc.hpp" +#include "tests/test_utils/soc_desc_test_utils.hpp" +#include "device/wormhole/wormhole_implementation.h" + +// Tests that all physical coordinates are same as all virtual coordinates +// when there is no harvesting. +TEST(CoordinateManager, CoordinateManagerWormholeNoHarvesting) { + + const std::size_t harvesting_mask = 0; + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0, 0, 0); + + // We expect full grid size since there is no harvesting. + tt_xy_pair tensix_grid_size = tt::umd::wormhole::TENSIX_GRID_SIZE; + for (size_t x = 0; x < tensix_grid_size.x; x++) { + for (size_t y = 0; y < tensix_grid_size.y; y++) { + const CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + const CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + const CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + + // Virtual and physical coordinates should be the same. + EXPECT_EQ(physical_coords.x, virtual_coords.x); + EXPECT_EQ(physical_coords.y, virtual_coords.y); + } + } +} + +// Test basic translation to virtual and physical noc coordinates. +// We expect that the top left core will have virtual and physical coordinates (1, 1) and (1, 2) for +// the logical coordinates if the first row is harvested. +TEST(CoordinateManager, CoordinateManagerWormholeTopLeftCore) { + + const std::size_t harvesting_mask = 1; + + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0, harvesting_mask); + tt_xy_pair tensix_grid_size = tt::umd::wormhole::TENSIX_GRID_SIZE; + + CoreCoord logical_coords = CoreCoord(0, 0, CoreType::TENSIX, CoordSystem::LOGICAL); + + // Always expect same virtual coordinate for (0, 0) logical coordinate. + CoreCoord virtual_cords = coordinate_manager->to_virtual(logical_coords); + EXPECT_EQ(virtual_cords, CoreCoord(1, 1, CoreType::TENSIX, CoordSystem::VIRTUAL)); + + // This depends on harvesting mask. So expected physical coord is specific to this test and Wormhole arch. + CoreCoord physical_cords = coordinate_manager->to_physical(logical_coords); + EXPECT_EQ(physical_cords, CoreCoord(1, 2, CoreType::TENSIX, CoordSystem::PHYSICAL)); +} + +// Test logical to physical coordinate translation. +// For the full grid of logical coordinates we expect that there are no duplicates of physical coordinates. +// For the reverse mapping back of physical to logical coordinates we expect that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerWormholeLogicalPhysicalMapping) { + + const std::size_t max_num_harvested_y = 10; + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0); + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_harvested_y); harvesting_mask++) { + + coordinate_manager->tensix_harvesting(harvesting_mask); + + std::map logical_to_physical; + std::set physical_coords_set; + tt_xy_pair tensix_grid_size = tt::umd::wormhole::TENSIX_GRID_SIZE; + + std::size_t num_harvested_y = test_utils::get_num_harvested(harvesting_mask); + + for (size_t x = 0; x < tensix_grid_size.x; x++) { + for (size_t y = 0; y < tensix_grid_size.y - num_harvested_y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + logical_to_physical[logical_coords] = physical_coords; + + // Expect that logical to physical translation is 1-1 mapping. No duplicates for physical coordinates. + EXPECT_EQ(physical_coords_set.count(physical_coords), 0); + physical_coords_set.insert(physical_coords); + } + } + + // Expect that the number of physical coordinates is equal to the number of workers minus the number of harvested rows. + EXPECT_EQ(physical_coords_set.size(), tensix_grid_size.x * (tensix_grid_size.y - num_harvested_y)); + + for (auto it : logical_to_physical) { + CoreCoord physical_coords = it.second; + CoreCoord logical_coords = coordinate_manager->to_logical(physical_coords); + + // Expect that reverse mapping of physical coordinates gives the same logical coordinates + // using which we got the physical coordinates. + EXPECT_EQ(it.first, logical_coords); + } + } +} + +// Test logical to virtual coordinate translation. +// For the full grid of logical coordinates we expect that there are no duplicates of virtual coordinates. +// For the reverse mapping back of virtual to logical coordinates we expect that same logical coordinates are returned as from original mapping. +TEST(CoordinateManager, CoordinateManagerWormholeLogicalVirtualMapping) { + + const std::size_t max_num_harvested_y = 10; + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0); + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_harvested_y); harvesting_mask++) { + + coordinate_manager->tensix_harvesting(harvesting_mask); + + std::map logical_to_virtual; + std::set virtual_coords_set; + tt_xy_pair tensix_grid_size = tt::umd::wormhole::TENSIX_GRID_SIZE; + + std::size_t num_harvested_y = test_utils::get_num_harvested(harvesting_mask); + + for (size_t x = 0; x < tensix_grid_size.x; x++) { + for (size_t y = 0; y < tensix_grid_size.y - num_harvested_y; y++) { + CoreCoord logical_coords = CoreCoord(x, y, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + logical_to_virtual[logical_coords] = virtual_coords; + + // Expect that logical to virtual translation is 1-1 mapping. No duplicates for virtual coordinates. + EXPECT_EQ(virtual_coords_set.count(virtual_coords), 0); + virtual_coords_set.insert(virtual_coords); + } + } + + for (auto it : logical_to_virtual) { + CoreCoord virtual_coords = it.second; + CoreCoord logical_coords = coordinate_manager->to_logical(virtual_coords); + + // Expect that reverse mapping of virtual coordinates gives the same logical coordinates + // using which we got the virtual coordinates. + EXPECT_EQ(it.first, logical_coords); + } + } +} + +// Test top left corner translation from logical to translated coordinates. +TEST(CoordinateManager, CoordinateManagerWormholeLogicalTranslatedTopLeft) { + + const std::size_t translated_x_start = 18; + const std::size_t translated_y_start = 18; + const CoreCoord expected_translated_coords = CoreCoord(translated_x_start, translated_y_start, CoreType::TENSIX, CoordSystem::TRANSLATED); + + const std::size_t max_num_harvested_y = 10; + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0); + // We go up to numbers less than 2^10 - 1 to test all possible harvesting masks, we don't want to try to convert if everything is harvested. + for (std::size_t harvesting_mask = 0; harvesting_mask < (1 << max_num_harvested_y) - 1; harvesting_mask++) { + coordinate_manager->tensix_harvesting(harvesting_mask); + + tt_xy_pair tensix_grid_size = tt::umd::wormhole::TENSIX_GRID_SIZE; + + std::size_t num_harvested_y = test_utils::get_num_harvested(harvesting_mask); + + CoreCoord logical_coords = CoreCoord(0, 0, CoreType::TENSIX, CoordSystem::LOGICAL); + CoreCoord physical_coords = coordinate_manager->to_physical(logical_coords); + CoreCoord virtual_coords = coordinate_manager->to_virtual(logical_coords); + + CoreCoord translated_from_logical = coordinate_manager->to_translated(logical_coords); + CoreCoord translated_from_physical = coordinate_manager->to_translated(physical_coords); + CoreCoord translated_from_virtual = coordinate_manager->to_translated(virtual_coords); + + EXPECT_EQ(translated_from_logical, expected_translated_coords); + EXPECT_EQ(translated_from_physical, expected_translated_coords); + EXPECT_EQ(translated_from_virtual, expected_translated_coords); + } +} + +// Test translation of DRAM core coordinates. There is no DRAM harvesting on Wormhole, +// so logical coordinates should cover all physical coordinates. +TEST(CoordinateManager, CoordinateManagerWormholeDRAMNoHarvesting) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0); + + const std::size_t num_dram_banks = tt::umd::wormhole::NUM_DRAM_BANKS; + const std::size_t num_noc_ports_per_bank = tt::umd::wormhole::NUM_NOC_PORTS_PER_DRAM_BANK; + const std::vector& dram_cores = tt::umd::wormhole::DRAM_CORES; + + for (std::size_t dram_bank = 0; dram_bank < num_dram_banks; dram_bank++) { + for (std::size_t noc_port = 0; noc_port < num_noc_ports_per_bank; noc_port++) { + const CoreCoord dram_logical(dram_bank, noc_port, CoreType::DRAM, CoordSystem::LOGICAL); + const std::size_t physical_core_index = dram_bank * num_noc_ports_per_bank + noc_port; + const CoreCoord expected_physical = CoreCoord(dram_cores[physical_core_index].x, dram_cores[physical_core_index].y, CoreType::DRAM, CoordSystem::PHYSICAL); + + const CoreCoord dram_physical = coordinate_manager->to_physical(dram_logical); + + EXPECT_EQ(dram_physical, expected_physical); + } + } +} + +// Test that physical and virtual coordinates are the same for all logical coordinates, since there is no DRAM harvesting. +TEST(CoordinateManager, CoordinateManagerWormholeETHPhysicalEqualVirtual) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0); + const tt_xy_pair eth_grid_size = tt::umd::wormhole::ETH_GRID_SIZE; + + for (std::size_t x = 0; x < eth_grid_size.x; x++) { + for (std::size_t y = 0; y < eth_grid_size.y; y++) { + const CoreCoord eth_logical = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); + const CoreCoord eth_virtual = coordinate_manager->to_virtual(eth_logical); + const CoreCoord eth_physical = coordinate_manager->to_physical(eth_logical); + + EXPECT_EQ(eth_virtual.x, eth_physical.x); + EXPECT_EQ(eth_virtual.y, eth_physical.y); + } + } +} + +// Test translation of logical to translated ethernet coordinates. +TEST(CoordinateManager, CoordinateManagerWormholeETHLogicalToTranslated) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0); + const tt_xy_pair eth_grid_size = tt::umd::wormhole::ETH_GRID_SIZE; + + for (std::size_t x = 0; x < eth_grid_size.x; x++) { + for (std::size_t y = 0; y < eth_grid_size.y; y++) { + const CoreCoord eth_logical = CoreCoord(x, y, CoreType::ETH, CoordSystem::LOGICAL); + const CoreCoord eth_translated = coordinate_manager->to_translated(eth_logical); + + EXPECT_EQ(eth_translated.x, x + 18); + EXPECT_EQ(eth_translated.y, y + 16); + } + } +} + +// Test that virtual, physical and translated coordinates are the same for all logical coordinates. +TEST(CoordinateManager, CoordinateManagerWormholeARCTranslation) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0); + const tt_xy_pair arc_grid_size = tt::umd::wormhole::ARC_GRID_SIZE; + + for (std::size_t x = 0; x < arc_grid_size.x; x++) { + for (std::size_t y = 0; y < arc_grid_size.y; y++) { + const CoreCoord arc_logical = CoreCoord(x, y, CoreType::ARC, CoordSystem::LOGICAL); + const CoreCoord arc_virtual = coordinate_manager->to_virtual(arc_logical); + const CoreCoord arc_physical = coordinate_manager->to_physical(arc_logical); + const CoreCoord arc_translated = coordinate_manager->to_translated(arc_logical); + + EXPECT_EQ(arc_virtual.x, arc_physical.x); + EXPECT_EQ(arc_virtual.y, arc_physical.y); + + EXPECT_EQ(arc_physical.x, arc_translated.x); + EXPECT_EQ(arc_physical.y, arc_translated.y); + } + } +} + +// Test that virtual, physical and translated coordinates are the same for all logical PCIE coordinates. +TEST(CoordinateManager, CoordinateManagerWormholePCIETranslation) { + std::unique_ptr coordinate_manager = CoordinateManager::get_coordinate_manager(tt::ARCH::WORMHOLE_B0); + const tt_xy_pair pcie_grid_size = tt::umd::wormhole::PCIE_GRID_SIZE; + + for (std::size_t x = 0; x < pcie_grid_size.x; x++) { + for (std::size_t y = 0; y < pcie_grid_size.y; y++) { + const CoreCoord arc_logical = CoreCoord(x, y, CoreType::PCIE, CoordSystem::LOGICAL); + const CoreCoord arc_virtual = coordinate_manager->to_virtual(arc_logical); + const CoreCoord arc_physical = coordinate_manager->to_physical(arc_logical); + const CoreCoord arc_translated = coordinate_manager->to_translated(arc_logical); + + EXPECT_EQ(arc_virtual.x, arc_physical.x); + EXPECT_EQ(arc_virtual.y, arc_physical.y); + + EXPECT_EQ(arc_physical.x, arc_translated.x); + EXPECT_EQ(arc_physical.y, arc_translated.y); + } + } +} diff --git a/tests/api/test_core_coordinates.cpp b/tests/api/test_core_coordinates.cpp new file mode 100644 index 00000000..0916ceb3 --- /dev/null +++ b/tests/api/test_core_coordinates.cpp @@ -0,0 +1,119 @@ +// SPDX-FileCopyrightText: (c) 2024 Tenstorrent Inc. +// +// SPDX-License-Identifier: Apache-2.0 +#include +#include +#include + +// #include "device/tt_device.h" + +// TEST(CoreCoordinates, CoreCoordinatesReadWriteV1) { + +// Cluster device = Cluster(); + +// device.start_device(); + +// std::vector vector_to_write = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +// std::vector readback_vec = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +// const uint32_t address = 0; +// const uint32_t chip = 0; + +// tt_xy_pair worker_grid_size = device.get_worker_grid_size(); + +// // Write to tensix cores. +// for (size_t x = 0; x < worker_grid_size.x; x++) { +// for (size_t y = 0; y < worker_grid_size.y; y++) { + +// // Construct the core coordinates. +// CoreCoord_V1 tensix_core_coords; +// tensix_core_coords.x = x; +// tensix_core_coords.y = y; +// tensix_core_coords.coord_system = CoordSystem::LOGICAL; +// // This step is not needed for V2 coordinates. +// tensix_core_coords.core_type = CoreType::TENSIX; + +// device.write_to_device(vector_to_write.data(), vector_to_write.size() * sizeof(std::uint32_t), chip, tensix_core_coords, address); + +// device_read_from_device(readback_vec.data(), readback_vec.size() * sizeof(std::uint32_t), chip, tensix_core_coords, address); + +// EXPECT_EQ(vector_to_write, readback_vec); +// } +// } + +// // Write to DRAM cores. +// const uint32_t num_channels = 6; +// const uint32_t num_subchannels = 2; + +// for (std::uint32_t channel = 0; channel < num_channels; channel++) { +// for (std::uint32_t subchannel = 0; subchannel < num_subchannels; subchannel++) { +// CoreCoord_V1 dram_core_coords; +// dram_core_coords.x = channel; +// dram_core_coords.y = subchannel; +// dram_core_coords.coord_system = CoordSystem::LOGICAL; +// // This step is not needed for V2 coordinates. +// dram_core_coords.core_type = CoreType::DRAM; + +// device.write_to_device(vector_to_write.data(), vector_to_write.size() * sizeof(std::uint32_t), chip, dram_core_coords, address); + +// device_read_from_device(readback_vec.data(), readback_vec.size() * sizeof(std::uint32_t), chip, dram_core_coords, address); + +// EXPECT_EQ(vector_to_write, readback_vec); +// } +// } + +// device.close_device(); +// } + +// TEST(CoreCoordinates, CoreCoordinatesReadWriteV1) { + +// Cluster device = Cluster(); + +// device.start_device(); + +// std::vector vector_to_write = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +// std::vector readback_vec = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +// const uint32_t address = 0; +// const uint32_t chip = 0; + +// tt_xy_pair worker_grid_size = device.get_worker_grid_size(); + +// // Write to tensix cores. +// for (size_t x = 0; x < worker_grid_size.x; x++) { +// for (size_t y = 0; y < worker_grid_size.y; y++) { + +// TensixCoreCoord_V2 tensix_core_coords; +// tensix_core_coords.x = x; +// tensix_core_coords.y = y; +// tensix_core_coords.coord_system = CoordSystem::LOGICAL; + +// device.write_to_device(vector_to_write.data(), vector_to_write.size() * sizeof(std::uint32_t), chip, tensix_core_coords, address); + +// device_read_from_device(readback_vec.data(), readback_vec.size() * sizeof(std::uint32_t), chip, tensix_core_coords, address); + +// EXPECT_EQ(vector_to_write, readback_vec); +// } +// } + +// // Write to DRAM cores. +// const uint32_t num_channels = 6; +// const uint32_t num_subchannels = 2; + +// for (std::uint32_t channel = 0; channel < num_channels; channel++) { +// for (std::uint32_t subchannel = 0; subchannel < num_subchannels; subchannel++) { +// DramCoreCoord_V2 dram_core_coords; +// dram_core_coords.x = channel; +// dram_core_coords.y = subchannel; +// dram_core_coords.coord_system = CoordSystem::LOGICAL; + +// device.write_to_device(vector_to_write.data(), vector_to_write.size() * sizeof(std::uint32_t), chip, dram_core_coords, address); + +// device_read_from_device(readback_vec.data(), readback_vec.size() * sizeof(std::uint32_t), chip, dram_core_coords, address); + +// EXPECT_EQ(vector_to_write, readback_vec); +// } +// } + +// device.close_device(); +// }