Vengineerの戯言

人生は短いけど、長いです。人生を楽しみましょう!

Intel Habana Gaudi2 の linuxデバイスドライバを眺めて

はじめて

Intel Habana Gaudi/Gaudi2 の linux デバイスドライバは公開されています。Gaudiについては、下記のブログにちょっとだけ書きました。

追記)、2024.04.10 : v6.2 までしか存在しません。ので、master から v6.2 にURLを修正しました。

vengineer.hatenablog.com

今回は、Intel Habana Gaudi2 のlinuxデバイスドライバを眺めてみました。

github.com

Gaudi2 の Gaudi と内部の構成が違う

下図は、Gadui2(左側)とGaudi(右側)です。説明のために引用します。

上記の図だけを見ると、Media Engineが追加されて、各要素が増えた感じです。

しかしながら、デバイスドライバソースコードを眺めたら、かなり違うことがわかりました。

ここを見ると、TPC_ID_DCOREX_TPCY という感じになっています。

enum gaudi2_tpc_id {
    TPC_ID_DCORE0_TPC0,
    TPC_ID_DCORE0_TPC1,
    TPC_ID_DCORE0_TPC2,
    TPC_ID_DCORE0_TPC3,
    TPC_ID_DCORE0_TPC4,
    TPC_ID_DCORE0_TPC5,
    TPC_ID_DCORE1_TPC0,
    TPC_ID_DCORE1_TPC1,
    TPC_ID_DCORE1_TPC2,
    TPC_ID_DCORE1_TPC3,
    TPC_ID_DCORE1_TPC4,
    TPC_ID_DCORE1_TPC5,
    TPC_ID_DCORE2_TPC0,
    TPC_ID_DCORE2_TPC1,
    TPC_ID_DCORE2_TPC2,
    TPC_ID_DCORE2_TPC3,
    TPC_ID_DCORE2_TPC4,
    TPC_ID_DCORE2_TPC5,
    TPC_ID_DCORE3_TPC0,
    TPC_ID_DCORE3_TPC1,
    TPC_ID_DCORE3_TPC2,
    TPC_ID_DCORE3_TPC3,
    TPC_ID_DCORE3_TPC4,
    TPC_ID_DCORE3_TPC5,
    /* the PCI TPC is placed last (mapped liked HW) */
    TPC_ID_DCORE0_TPC6,
    TPC_ID_SIZE,
};

DCOREは0-3で、各DCOREには6個のTPC(TPC0-TPC5) があります。Gaudi2にはTPCが24個入っているので、DCORE(4) x TPC(6) = 24 であっています。

各DCOREには、TPC以外に以下のものが入っているようです。

  • EDMA(各DCOREに2個)
  • KDMA(DCORE0のみ1個)
  • PDMA (DCORE0のみ2個)
  • Decoder (MediaEngine)
  • MME (Matrix Engine)

この他にも

  • PCIE には、VDECに2個
  • ROTATORが2個

MESHタイプのNoCがあるみたい

PLLの情報を得る関数では、MESH なるものがあります。

static int gaudi2_map_pll_idx_to_fw_idx(u32 pll_idx)
{
    switch (pll_idx) {
    case HL_GAUDI2_CPU_PLL: return CPU_PLL;
    case HL_GAUDI2_PCI_PLL: return PCI_PLL;
    case HL_GAUDI2_NIC_PLL: return NIC_PLL;
    case HL_GAUDI2_DMA_PLL: return DMA_PLL;
    case HL_GAUDI2_MESH_PLL: return MESH_PLL;
    case HL_GAUDI2_MME_PLL: return MME_PLL;
    case HL_GAUDI2_TPC_PLL: return TPC_PLL;
    case HL_GAUDI2_IF_PLL: return IF_PLL;
    case HL_GAUDI2_SRAM_PLL: return SRAM_PLL;
    case HL_GAUDI2_HBM_PLL: return HBM_PLL;
    case HL_GAUDI2_VID_PLL: return VID_PLL;
    case HL_GAUDI2_MSS_PLL: return MSS_PLL;
    default: return -EINVAL;
    }
}

ここには、RAZWIなるものがあります。X方向に5ビット(最大32個)、Y方向に4ビット(最大16個)が接続するようになっています。RTR_ID_X_YというマクロでMESHの位置を決められるようです。実際には、X方向は0-17、Y方向は0-11になっているようです。

/* RAZWI initiator coordinates- X- 5 bits, Y- 4 bits */
#define RAZWI_INITIATOR_X_SHIFT     0
#define RAZWI_INITIATOR_X_MASK      0x1F
#define RAZWI_INITIATOR_Y_SHIFT     5
#define RAZWI_INITIATOR_Y_MASK      0xF

#define RTR_ID_X_Y(x, y) \
    ((((y) & RAZWI_INITIATOR_Y_MASK) << RAZWI_INITIATOR_Y_SHIFT) | \
        (((x) & RAZWI_INITIATOR_X_MASK) << RAZWI_INITIATOR_X_SHIFT))

MESHの中は、この部分で分かりそう。

static const u32 rtr_coordinates_to_rtr_id[NUM_OF_RTR_PER_DCORE * NUM_OF_DCORES] = {
    RTR_ID_X_Y(2, 4),
    RTR_ID_X_Y(3, 4),
    RTR_ID_X_Y(4, 4),
    RTR_ID_X_Y(5, 4),
    RTR_ID_X_Y(6, 4),
    RTR_ID_X_Y(7, 4),
    RTR_ID_X_Y(8, 4),
    RTR_ID_X_Y(9, 4),
    RTR_ID_X_Y(10, 4),
    RTR_ID_X_Y(11, 4),
    RTR_ID_X_Y(12, 4),
    RTR_ID_X_Y(13, 4),
    RTR_ID_X_Y(14, 4),
    RTR_ID_X_Y(15, 4),
    RTR_ID_X_Y(16, 4),
    RTR_ID_X_Y(17, 4),
    RTR_ID_X_Y(2, 11),
    RTR_ID_X_Y(3, 11),
    RTR_ID_X_Y(4, 11),
    RTR_ID_X_Y(5, 11),
    RTR_ID_X_Y(6, 11),
    RTR_ID_X_Y(7, 11),
    RTR_ID_X_Y(8, 11),
    RTR_ID_X_Y(9, 11),
    RTR_ID_X_Y(0, 0),/* 24 no id */
    RTR_ID_X_Y(0, 0),/* 25 no id */
    RTR_ID_X_Y(0, 0),/* 26 no id */
    RTR_ID_X_Y(0, 0),/* 27 no id */
    RTR_ID_X_Y(14, 11),
    RTR_ID_X_Y(15, 11),
    RTR_ID_X_Y(16, 11),
    RTR_ID_X_Y(17, 11)
};

32個あります。

この部分で DCOREX_RTRY に何が居るのがわかります。

static const char *gaudi2_get_initiators_name(u32 rtr_id)
{
    switch (rtr_id) {
    case DCORE0_RTR0:
        return "DEC0/1/8/9, TPC24, PDMA0/1, PMMU, PCIE_IF, EDMA0/2, HMMU0/2/4/6, CPU";
    case DCORE0_RTR1:
        return "TPC0/1";
    case DCORE0_RTR2:
        return "TPC2/3";
    case DCORE0_RTR3:
        return "TPC4/5";
    case DCORE0_RTR4:
        return "MME0_SBTE0/1";
    case DCORE0_RTR5:
        return "MME0_WAP0/SBTE2";
    case DCORE0_RTR6:
        return "MME0_CTRL_WR/SBTE3";
    case DCORE0_RTR7:
        return "MME0_WAP1/CTRL_RD/SBTE4";
    case DCORE1_RTR0:
        return "MME1_WAP1/CTRL_RD/SBTE4";
    case DCORE1_RTR1:
        return "MME1_CTRL_WR/SBTE3";
    case DCORE1_RTR2:
        return "MME1_WAP0/SBTE2";
    case DCORE1_RTR3:
        return "MME1_SBTE0/1";
    case DCORE1_RTR4:
        return "TPC10/11";
    case DCORE1_RTR5:
        return "TPC8/9";
    case DCORE1_RTR6:
        return "TPC6/7";
    case DCORE1_RTR7:
        return "DEC2/3, NIC0/1/2/3/4, ARC_FARM, KDMA, EDMA1/3, HMMU1/3/5/7";
    case DCORE2_RTR0:
        return "DEC4/5, NIC5/6/7/8, EDMA4/6, HMMU8/10/12/14, ROT0";
    case DCORE2_RTR1:
        return "TPC16/17";
    case DCORE2_RTR2:
        return "TPC14/15";
    case DCORE2_RTR3:
        return "TPC12/13";
    case DCORE2_RTR4:
        return "MME2_SBTE0/1";
    case DCORE2_RTR5:
        return "MME2_WAP0/SBTE2";
    case DCORE2_RTR6:
        return "MME2_CTRL_WR/SBTE3";
    case DCORE2_RTR7:
        return "MME2_WAP1/CTRL_RD/SBTE4";
    case DCORE3_RTR0:
        return "MME3_WAP1/CTRL_RD/SBTE4";
    case DCORE3_RTR1:
        return "MME3_CTRL_WR/SBTE3";
    case DCORE3_RTR2:
        return "MME3_WAP0/SBTE2";
    case DCORE3_RTR3:
        return "MME3_SBTE0/1";
    case DCORE3_RTR4:
        return "TPC18/19";
    case DCORE3_RTR5:
        return "TPC20/21";
    case DCORE3_RTR6:
        return "TPC22/23";
    case DCORE3_RTR7:
        return "DEC6/7, NIC9/10/11, EDMA5/7, HMMU9/11/13/15, ROT1, PSOC";
    default:
    return "N/A";
    }
}

歩留まり対策

ここTPC内で最大2個まで置き換えできるようです。

/*
 * Gaudi2 subtitute TPCs Numbering
 * At most- two faulty TPCs are allowed
 * First replacement to a faulty TPC will be TPC24, second- TPC23
 */
enum substitude_tpc {
    FAULTY_TPC_SUBTS_1_TPC_24,
    FAULTY_TPC_SUBTS_2_TPC_23,
    MAX_FAULTY_TPCS
};

ARC CPU がたくさん?

このヘッダーを見ると、ARC CPUがいっぱい入っているようです。

/*
 * CPU IDs for each ARC CPUs
 */

#define CPU_ID_SCHED_ARC0      0  /* FARM_ARC0 */
#define CPU_ID_SCHED_ARC1      1  /* FARM_ARC1 */
#define CPU_ID_SCHED_ARC2      2  /* FARM_ARC2 */
#define CPU_ID_SCHED_ARC3      3  /* FARM_ARC3 */
/* Dcore1 MME Engine ARC instance used as scheduler */
#define CPU_ID_SCHED_ARC4      4  /* DCORE1_MME0 */
/* Dcore3 MME Engine ARC instance used as scheduler */
#define CPU_ID_SCHED_ARC5      5  /* DCORE3_MME0 */

#define CPU_ID_TPC_QMAN_ARC0       6  /* DCORE0_TPC0 */
#define CPU_ID_TPC_QMAN_ARC1       7  /* DCORE0_TPC1 */
#define CPU_ID_TPC_QMAN_ARC2       8  /* DCORE0_TPC2 */
#define CPU_ID_TPC_QMAN_ARC3       9  /* DCORE0_TPC3 */
#define CPU_ID_TPC_QMAN_ARC4       10 /* DCORE0_TPC4 */
#define CPU_ID_TPC_QMAN_ARC5       11 /* DCORE0_TPC5 */
#define CPU_ID_TPC_QMAN_ARC6       12 /* DCORE1_TPC0 */
#define CPU_ID_TPC_QMAN_ARC7       13 /* DCORE1_TPC1 */
#define CPU_ID_TPC_QMAN_ARC8       14 /* DCORE1_TPC2 */
#define CPU_ID_TPC_QMAN_ARC9       15 /* DCORE1_TPC3 */
#define CPU_ID_TPC_QMAN_ARC10      16 /* DCORE1_TPC4 */
#define CPU_ID_TPC_QMAN_ARC11      17 /* DCORE1_TPC5 */
#define CPU_ID_TPC_QMAN_ARC12      18 /* DCORE2_TPC0 */
#define CPU_ID_TPC_QMAN_ARC13      19 /* DCORE2_TPC1 */
#define CPU_ID_TPC_QMAN_ARC14      20 /* DCORE2_TPC2 */
#define CPU_ID_TPC_QMAN_ARC15      21 /* DCORE2_TPC3 */
#define CPU_ID_TPC_QMAN_ARC16      22 /* DCORE2_TPC4 */
#define CPU_ID_TPC_QMAN_ARC17      23 /* DCORE2_TPC5 */
#define CPU_ID_TPC_QMAN_ARC18      24 /* DCORE3_TPC0 */
#define CPU_ID_TPC_QMAN_ARC19      25 /* DCORE3_TPC1 */
#define CPU_ID_TPC_QMAN_ARC20      26 /* DCORE3_TPC2 */
#define CPU_ID_TPC_QMAN_ARC21      27 /* DCORE3_TPC3 */
#define CPU_ID_TPC_QMAN_ARC22      28 /* DCORE3_TPC4 */
#define CPU_ID_TPC_QMAN_ARC23      29 /* DCORE3_TPC5 */
#define CPU_ID_TPC_QMAN_ARC24      30 /* DCORE0_TPC6 - Never present */

#define CPU_ID_MME_QMAN_ARC0       31 /* DCORE0_MME0 */
#define CPU_ID_MME_QMAN_ARC1       32 /* DCORE2_MME0 */

#define CPU_ID_EDMA_QMAN_ARC0      33 /* DCORE0_EDMA0 */
#define CPU_ID_EDMA_QMAN_ARC1      34 /* DCORE0_EDMA1 */
#define CPU_ID_EDMA_QMAN_ARC2      35 /* DCORE1_EDMA0 */
#define CPU_ID_EDMA_QMAN_ARC3      36 /* DCORE1_EDMA1 */
#define CPU_ID_EDMA_QMAN_ARC4      37 /* DCORE2_EDMA0 */
#define CPU_ID_EDMA_QMAN_ARC5      38 /* DCORE2_EDMA1 */
#define CPU_ID_EDMA_QMAN_ARC6      39 /* DCORE3_EDMA0 */
#define CPU_ID_EDMA_QMAN_ARC7      40 /* DCORE3_EDMA1 */

#define CPU_ID_PDMA_QMAN_ARC0      41 /* DCORE0_PDMA0 */
#define CPU_ID_PDMA_QMAN_ARC1      42 /* DCORE0_PDMA1 */

#define CPU_ID_ROT_QMAN_ARC0       43 /* ROT0 */
#define CPU_ID_ROT_QMAN_ARC1       44 /* ROT1 */

#define CPU_ID_NIC_QMAN_ARC0       45 /* NIC0_0 */
#define CPU_ID_NIC_QMAN_ARC1       46 /* NIC0_1 */
#define CPU_ID_NIC_QMAN_ARC2       47 /* NIC1_0 */
#define CPU_ID_NIC_QMAN_ARC3       48 /* NIC1_1 */
#define CPU_ID_NIC_QMAN_ARC4       49 /* NIC2_0 */
#define CPU_ID_NIC_QMAN_ARC5       50 /* NIC2_1 */
#define CPU_ID_NIC_QMAN_ARC6       51 /* NIC3_0 */
#define CPU_ID_NIC_QMAN_ARC7       52 /* NIC3_1 */
#define CPU_ID_NIC_QMAN_ARC8       53 /* NIC4_0 */
#define CPU_ID_NIC_QMAN_ARC9       54 /* NIC4_1 */
#define CPU_ID_NIC_QMAN_ARC10      55 /* NIC5_0 */
#define CPU_ID_NIC_QMAN_ARC11      56 /* NIC5_1 */
#define CPU_ID_NIC_QMAN_ARC12      57 /* NIC6_0 */
#define CPU_ID_NIC_QMAN_ARC13      58 /* NIC6_1 */
#define CPU_ID_NIC_QMAN_ARC14      59 /* NIC7_0 */
#define CPU_ID_NIC_QMAN_ARC15      60 /* NIC7_1 */
#define CPU_ID_NIC_QMAN_ARC16      61 /* NIC8_0 */
#define CPU_ID_NIC_QMAN_ARC17      62 /* NIC8_1 */
#define CPU_ID_NIC_QMAN_ARC18      63 /* NIC9_0 */
#define CPU_ID_NIC_QMAN_ARC19      64 /* NIC9_1 */
#define CPU_ID_NIC_QMAN_ARC20      65 /* NIC10_0 */
#define CPU_ID_NIC_QMAN_ARC21      66 /* NIC10_1 */
#define CPU_ID_NIC_QMAN_ARC22      67 /* NIC11_0 */
#define CPU_ID_NIC_QMAN_ARC23      68 /* NIC11_1 */

ここに、

#define NUM_ARC_CPUS            69

とあるので、69個も ARC CPU が載っているんですね。

おわりに

Linuxデバイスドライバを眺めてみてわかったこと。

Gaudi => Gauid2 になって、TPCが8個から24個。MMEが1個から2個、MediaEngine(DecoderとRotator)が追加されただけでなく、内部構造もかなり変わったようです。

関連ブログ

vengineer.hatenablog.com

vengineer.hatenablog.com

vengineer.hatenablog.com

vengineer.hatenablog.com

vengineer.hatenablog.com