Vengineerの妄想

人生を妄想しています。

Hot Chips 2024 での Tenstorrent Blackhole の発表内容から復習する

はじめに

Hot Chips 2024 にて、TenstorrentのBlackholeの詳細が公開されました。下記の記事をベースに気になったとこを復習したいと思います。

www.servethehome.com

下記の図は、上記の記事から説明のために引用します。

Blackhole のレイアウト

下図からBlackholeのレイアウトが分かります。

この情報は、github にある tt-umd の中を探るとある程度分かっていました。tt-umd からの情報をマッピングしてみました。

縦方向に 0 - 11, 横方向に 0 -17 の 2D-Mesh に配置されています。

  • DRAM : 0 と 9 の縦一列
  • Ethernet : 1 の横一列
  • PCIe I/F : [2, 0] と [11, 0] (元の図では、[2, 0] だけですが、tt-umd には、[11, 0] もあります。昨日のブログにも書きました)
  • Tile : その他
  • Router Only : 0 の横一列と 8 の縦一列

  • 右上のAが ARC CPU (たぶん、4コア)です。

これ以外に、big な RISC-V コアが16個

NoC

tt-umd でも NoC は 2 という情報があるんですが、下記の図でそれがどのようになっているのかがわかります。

NoCが2というのは、

  • 上から下、左から右のNoC
  • 下から上、右から左のNoC

の2つがあるという意味のようです。

Blackholeだけでなく、Grayskull, Wormhole も NoC は2になっているので、おなじような構成なんですね。

NoCは、64Byte (512bit) で 83GB/s の転送レートです。83GB/s / 64B = 1.3GHzぐらいで動いているようです。

Ethernet

下記の図から、Wohmhole は 16 x 100 Gbps, Blackhole は 10 x 400Gbps の Ethernet が付いています。

Wormholeの 16 x 100Gbps は、2D-Mesh で接続すると、4 x 100Gbps x 4 になりますが、Blackholeでは 10 x 400Gbps なので、2 x 400Gbps x 4 だと、2つ余ります。これ、どうなっているのかが分からなかったのですが、今回、そのスライドが公開されました。

Z方向にも接続できるようになっています。

Blackholle 版の Galaxy

Galaxy については、2021年5月31日に初めて取り上げました。この時は、Wohmhole を 4 x 8 = 32 個搭載というものでした。

vengineer.hatenablog.com

2023年11月2日のブログでは、どんな感じになるかも取り上げました。

vengineer.hatenablog.com

下図は上記のブログで取り上げたもので、説明のために引用します。右上にWohmholeベースのGalaxy(2段構成版)があります。

そして、今回、Blackhole版のGalaxyが下記のようなものです。ぱっと見、Wohmhole 版の Galaxy と同じです。

(4 x 8) = 32 個のBlackholeで構成されます。上下の4辺で各チップから 2 x 400Gbps (100GB/s) でチップ間の接続を行っています。

Z方向では、どのように接続するのでしょうか?

Wohmhole と Blackhole は、PCIe ではなく、Ethernetを使う

WohmholeのGalaxyの時にも疑問だったのですが、2次元に配列して、ホストとの接続をどうするの? PCIe でやるの?と思っていました。

その疑問は、tt-umd を調べ直したらわかりました。broadcasttensix_risc_reset_to_cluster というメソッドのソースコードを見たら、Grayskullの時は、broadcast_pcie_tensix_risc_reset で PCIe 経由(GrayskullはEthernetを持っていない)経由で各 Tensix に対して、リセットをBroadcastしていますが、Wohmhole と Blackhole に関しては、broadcast_write_to_clusterメソッドにて、リセットをBroadcastしています。

void tt_SiliconDevice::broadcast_tensix_risc_reset_to_cluster(const TensixSoftResetOptions &soft_resets) {
    if(arch_name == tt::ARCH::GRAYSKULL) {
        for (auto &device_it : m_pci_device_map) {
            broadcast_pcie_tensix_risc_reset(device_it.second, soft_resets);
        }
    }
    else {
        auto valid = soft_resets & ALL_TENSIX_SOFT_RESET;
        uint32_t valid_val = (std::underlying_type<TensixSoftResetOptions>::type) valid;
        std::set<chip_id_t> chips_to_exclude = {};
        std::set<uint32_t> rows_to_exclude;
        std::set<uint32_t> columns_to_exclude;
        if (arch_name == tt::ARCH::BLACKHOLE) {
            rows_to_exclude = {0, 1};
            columns_to_exclude = {0, 8, 9};
        } else {
            rows_to_exclude = {0, 6};
            columns_to_exclude = {0, 5};
        }
        std::string fallback_tlb = "LARGE_WRITE_TLB";
        broadcast_write_to_cluster(&valid_val, sizeof(uint32_t), 0xFFB121B0, chips_to_exclude, rows_to_exclude, columns_to_exclude, fallback_tlb);
        // Ensure that reset signal is globally visible
        wait_for_non_mmio_flush();
    }
}

broadcast_write_to_clusterメソッド内では、ethernet_broadcast_writeメソッドを使っています。

   else if (arch_name == tt::ARCH::BLACKHOLE) {
        auto architecture_implementation = tt::umd::architecture_implementation::create(static_cast<tt::umd::architecture>(arch_name));
        if(cols_to_exclude.find(0) == cols_to_exclude.end() or cols_to_exclude.find(9) == cols_to_exclude.end()) {
            log_assert(!tensix_or_eth_in_broadcast(cols_to_exclude, architecture_implementation.get()), "Cannot broadcast to tensix/ethernet and DRAM simultaneously on Blackhole.");
            if(cols_to_exclude.find(0) == cols_to_exclude.end()) {
                // When broadcast includes column zero do not exclude anything
                std::set<uint32_t> unsafe_rows = {};
                std::set<uint32_t> cols_to_exclude_for_col_0_bcast = cols_to_exclude;
                std::set<uint32_t> rows_to_exclude_for_col_0_bcast = rows_to_exclude;
                cols_to_exclude_for_col_0_bcast.insert(9);
                rows_to_exclude_for_col_0_bcast.insert(unsafe_rows.begin(), unsafe_rows.end());
                ethernet_broadcast_write(mem_ptr, size_in_bytes, address, chips_to_exclude,
                                        rows_to_exclude_for_col_0_bcast, cols_to_exclude_for_col_0_bcast, fallback_tlb, false);
            }
            if(cols_to_exclude.find(9) == cols_to_exclude.end()) {
                std::set<uint32_t> cols_to_exclude_for_col_9_bcast = cols_to_exclude;
                cols_to_exclude_for_col_9_bcast.insert(0);
                ethernet_broadcast_write(mem_ptr, size_in_bytes, address, chips_to_exclude,
                                        rows_to_exclude, cols_to_exclude_for_col_9_bcast, fallback_tlb, false);
            }
        }
        else {
            log_assert(use_virtual_coords_for_eth_broadcast or valid_tensix_broadcast_grid(rows_to_exclude, cols_to_exclude, architecture_implementation.get()), 
                        "Must broadcast to all tensix rows when ERISC FW is < 6.8.0.");
            ethernet_broadcast_write(mem_ptr, size_in_bytes, address, chips_to_exclude,
                                    rows_to_exclude, cols_to_exclude, fallback_tlb, use_virtual_coords_for_eth_broadcast);
        }
    }

おわりに

Tenstorrent

  • Grayskull : Gen 1
  • Wohmhole : Gen 1 + Ethernet
  • Wohmhole Galaxy : 4 x 8 構成
  • Blackhole : Gen 2 (big RISC-V x 16) + Ethernet
  • Blackhole Galaxy : 4 x 8 構成

となっていて、アーキテクチャとしては、Gen 2 ですが、チップとしては、第3世代となり、あたし的には、勝負どころになるのではないでしょうか?

  • NVIDIA Blackwell : N3, NVLink v5 (1,800GB/s, 双方向)、片方向だと、900GB/s
  • NVIDIA Hopper : N4, NVLINK v4 (900GB/s, 双方向)、片方向だと、450GB/s
  • NVIDIA Ampere : N7, NVLINK v3 (600GB/s, 双方向)、片方向だと、300GB/s

Tenstorrent Blackhole : N6, 10 x 400Gbps (4000Gbps = 500GB/s、片方向)

なので、N4なHopperよりもチップ間接続の帯域は大きいですね。。。