PPU多卡ID映射

更新时间:
复制为 MD 格式

1. 背景

在驱动在初始化 PPU 的时候会按照一定的顺序给每个 PPU 配置 PPU-id,这个 id 的顺序就是 ppudbg、ppu-smi 和 CUDA_VISIBLE_DEVICES 这些上层工具应用看到的 PPU 顺序。

以 ppu-smi 截图为例,红框中的数字就是 PPU-id。

image.png

而在 16卡 810E 机型中,通常存在两个机尾,每个机尾的 8 张 PPU 在物理距离上是更近的,但是驱动默认的初始化顺序不是按照相同机尾的顺序而是 os 枚举的顺序(通常是 lspci 看到的 PCIE 设备顺序)来配置 PPU-id。

这就造成上层应用很多时候需要通过 CUDA_VISIBLE_DEVICES 来指定 PPU 执行程序,为了更好的提升 PCCL 通信库和其他应用在驱动默认配置下的性能,驱动会在 16 卡机型上面对 PPU 进行一次排序,来保证同一个机尾的 PPU 被分配到的 PPU-id 是连续的。

2. 哪些驱动版本会做这个排序

排序只在这些 KMD 驱动版本上生效:1.3.0-63f79b 或 1.3.1-xxxx。

目前会有两种排序方法,section 4 会详细介绍

1.3.0-63f79b 采用 排序方法1

1.3.1-xxxx 采用 排序方法2

3. 哪些机型会做这个排序

驱动当且仅当在 16 卡 810E 机型上面对 PPU 进行一次排序,来保证同一个机尾的 PPU 被分配到的 PPU-id 是连续的。8 卡多卡机型不受影响。

4. 排序规则

驱动会按照 UNIQUE-id 从小到大排序之后的顺依次配置 PPU-id,n 卡机器对应的 PPU-id 是 [0, n-1]。

UNIQUE-id 在不同的排序规则中格式不同,下面将分别介绍。

4.1 排序方法1

4.1.1 REAR-id

首先 16 卡机型目前的 PCIE BDF 都是固定的,如下图所示:

image.png

驱动在初始化 PPU 的时候,会根据图中 BDF 来确定这个 PPU 的机尾 id(REARid),例如 0000:c7:00.0 对应的 REARid 就是 1 ,其他的以此类推。按照图中 PCIE-bdf 来确定机尾 id,如果不属于图中机尾 2 列出来的 8 个 PCIE-bdf,机尾 id 就会默认是 1。

4.1.2 UNIQUE-id

随后驱动会根据 REAR-id,PCIE-domain-id,PCIE-bus-id,PCIE-slot-id,PCIE-func-id 生成一个 UNIQUE-id 来对 PPU 进行从小到大排序,UNIQUE-id 的格式如下:

union {
    struct {
        uint64_t PCIE-func-id   : 3;
        uint64_t PCIE-slot-id   : 5;
        uint64_t PCIE-bus-id    : 8;
        uint64_t PCIE-domain-id : 16;
        uint64_t REAR-id        : 32;
    };
    uint64_t UNIQUE-id;
};

4.2 排序方法2

排序方法 1 有很大的局限性,那就是认为 16 卡 PCIE BDF 是不会变化的,这在新机型或者 vm passthrough 的时候就会打破这个规则,因此这里引入一种新的排序方式,将 PPU-id 和真正的 PCIE 物理槽位对应起来,来确保不同的 16 卡场景也能拥有相同的 PPU-id 配置。

4.2.1 MODULE-id

还是下面这张图:

image.png

图中从右数第二列对应的 OAMx 编号叫做 MODULE-id,例如 0000:c7:00.0 的 MODULE-id 就是 6,PPU 可以通过读取寄存器的方式获取 MODULE-id,就不会和 PCIE BDF 绑定在一起了,也就是说这个图中 PCIE-bdf 再如何变更,MODULE-id 是不变的。

4.2.2 REAR-id

随后我们需要通过另一种方式获取 REAR-id,如下图:

image.png

在 PCIE config space 内部,有一个 slot capability 的字段,这个字段对应的 [31:19] 是 BOX-id 和 SLOT-number 的组合,我们读取 BOX-id 作为 REAR-id。

需要额外注意的是,PCIE EP 通常是没有 slot capability 的,必须读取 EP 上一级 bridge 的 slot capability,具体的说明见 PCIE 规范:

image.png

驱动通过读取 PPU 上一级 bridge 的 config space 获取到 REAR-id。

4.2.3 UNIQUE-id

现在我们拥有了两个和 PCIE 物理槽位强绑定的 id

随后驱动会根据 REAR-id,MODULE-id 生成一个 UNIQUE-id 来对 PPU 进行从小到大排序,UNIQUE-id 的格式如下:

union {
    struct {
        uint64_t MODULE-id : 32;
        uint64_t REAR-id   : 32;
    };
    uint64_t UNIQUE-id;
};

5. PCIE-bdf 和 Module-id PPU-id 的对应关系

PCIE-bdf

Moudle-id
十进制

PPU-id
排序前十进制

PPU-id
排序方法1十进制

PPU-id
排序方法2十进制

0000:08:00.0

4

0

8

12

0000:09:00.0

5

1

9

13

0000:7e:00.0

4

2

0

4

0000:7f:00.0

5

3

1

5

0000:a2:00.0

7

4

10

15

0000:a3:00.0

6

5

11

14

0000:c6:00.0

7

6

2

7

0000:c7:00.0

6

7

3

6

0001:0a:00.0

2

8

12

10

0001:0b:00.0

3

9

13

11

0001:80:00.0

2

10

4

2

0001:81:00.0

3

11

5

3

0001:a4:00.0

1

12

14

9

0001:a5:00.0

0

13

15

8

0001:c8:00.0

1

14

6

1

0001:c9:00.0

0

15

7

0

5.1 排序前拓扑图

画板

5.2 排序后拓扑图

5.2.1 排序方法1

画板

5.2.2 排序方法2

画板