已合并
add new operator matmul_abft_verify #94
add new operator matmul_abft_verify #94
已合并
starfican创建于 16 天前
starfican
16 天前

变更摘要

本次 PR 新增 MatmulFt 矩阵乘法外挂容错算子,代码位于 reliability/matmul_abft_verify。

该算子面向输出精度为 FLOAT32 的矩阵乘法算子。调用方提供输入矩阵 A、B 以及待检测的矩阵乘法结果 C,MatmulAbftVerify 基于方差估计
自适应门限算法(V-ABFT),对 C 执行分块 checksum 校验,以检测并定位矩阵乘法过程中产生的静默计算错误。

算子支持 BFLOAT16 和 FLOAT32 两种输入精度,支持 Atlas A2/A3 系列产品,并配套提供算子定义、shape/dtype 推导、
host tiling、kernel 实现、aclnn 接口文档以及 BF16 调用样例。

主要改动

新增 MatmulAbftVerify 外挂容错算子

  • 接口功能:实现基于方差估计自适应门限算法(V-ABFT)的GEMM容错检测算子。算子接收矩阵A、B以及预先计算的矩阵乘结果C,对C进行分块ABFT校验,检测静默计算错误并输出逐行检测结果。

  • 特点

    • 自适应阈值: 该算子能够根据矩阵大小与值域自动确定用于比对的阈值,能够在保证检出率的同时避免误检。

    • 计算量显著小于基于重新计算的容错方案。在矩阵维度m=n=k=a时,本算子只需8a^2次浮点计算,而重算则需要2a^3次浮点计算。且容错阈值也与该算法相匹配

  • 计算公式:

    C=A×B,ARM×K,  BRK×N C = A \times B, \quad A \in \mathbb{R}^{M \times K},\; B \in \mathbb{R}^{K \times N}

    Cr=C×r,Br=B×r C^r = C\times r, B^r=B\times r

    其中阈值ThresholdiThreshold_i由输入矩阵A、B的局部统计特征(均值、标准差)动态估计,无需依赖C矩阵输出结果。

  • 算子功能说明:

  • 输入矩阵A、B和预先计算的C经过checksum编码、阈值估计和校验比对流程,输出压缩后的逐行故障检测结果张量comp_row,1表示正确,0表示检测到错误。

函数原型

每个算子分为两段式接口,必须先调用“aclnnMatmulAbftVerifyGetWorkspaceSize”接口获取入参并根据计算流程计算所需workspace大小,再调用“aclnnMatmulAbftVerify”接口执行计算。

aclnnStatus aclnnMatmulAbftVerifyGetWorkspaceSize(
    const aclTensor *a,
    const aclTensor *b,
    const aclTensor *c,
    const aclTensor *checksumWeight,
    double EMAX,
    const aclTensor *compRow,
    uint64_t *workspaceSize,
    aclOpExecutor **executor);
aclnnStatus aclnnMatmulAbftVerify(
    void *workspace,
    uint64_t workspaceSize,
    aclOpExecutor *executor,
    aclrtStream stream);

aclnnMatmulAbftVerifyGetWorkspaceSize

  • 参数说明:

    参数名 输入/输出 描述 使用说明 数据类型 数据格式 维度(shape) 非连续的Tensor
    a(aclTensor) 输入 矩阵乘法输入A。
    • 维度为2,shape为[M, K]。
    FLOAT16、BFLOAT16、FLOAT32 ND [M, K] -
    b(aclTensor) 输入 矩阵乘法输入B。
    • 维度为2,shape为[K, N]。
    FLOAT16、BFLOAT16、FLOAT32 ND [K, N] -
    c(aclTensor) 输入 预先计算的矩阵乘结果C = A × B,作为容错检测的数据输入。
    • 维度为2,shape为[M, N]。
    FLOAT32 ND [M, N] -
    checksumWeight(aclTensor) 输入 列编码值向量,对应ABFT中的行校验和编码向量$r$(加权向量)。
    • 维度为1,shape为[N]。
    FLOAT16、BFLOAT16、FLOAT32 ND [N] -
    EMAX(double) 输入 误差阈值系数,控制故障检测的灵敏度。
    • 默认值为0.001。
    • A,B为BF16精度,推荐值:0.001
    • A,B为FP32精度, 推荐值: 0.00002
    • 使用小于推荐值的EMAX会增大检出率,但是也可能会出现误检情况。
    • 在出现误报的时候,可以将EMAX调大。
    - - - -
    compRow(aclTensor) 输出 压缩后的行方向故障检测位流输出。
    • 每个bit表示一行一段的检测结果,1表示正确,0表示检测到错误。
    UINT8 ND [ceil(M/8) * splitN] -
    workspaceSize(uint64_t) 输出 返回需要在Device侧申请的workspace大小。 - - - - -
    executor(aclOpExecutor) 输出 返回op执行器,包含了算子计算流程。 - - - - -

    其中 splitN=N/256splitN = \lceil N / 256\rceil

    算子文档

    新增 reliability/matmul_abft_verify/docs/MatmulAbftVerify.md

    BF16 调用样例

    新增:

reliability/matmul_abft_verify/examples/test_aclnn_matmul_abft_verify_bf16.cpp

  • ACL 运行环境初始化;
  • 输入、输出 Tensor 创建;
  • C 矩阵 Buffer 初始化;
  • workspace 查询与申请;
  • 算子调用;
  • 检测结果回拷和打印;
  • Device 资源释放。

由于前序矩阵乘法算子 aclnnGemm 暂时无法通过 ops-transformer 当前提供的脚本完成编译,仓库内样例仅展示 MatmulAbftVerify的调用方
式,没有在样例中串联实际的前序矩阵乘法,因此不构成完整的端到端容错演示。

包含前序矩阵乘法、多精度验证的完整样例可参考:

https://gitee.com/kanby123/matmul_abft_verify

约束说明

  • 确定性计算:

    • aclnnMatmulAbftVerify默认确定性实现。
  • 输入矩阵a、b和c必须为2维,shape分别为[M, K]、[K, N]和[M, N],且a的第1维(K)与b的第0维(K)必须相等。

  • 输入向量weight的shape必须为[N]。

  • 支持的数据类型组合为:

    a b c checksumWeight
    FLOAT16 FLOAT16 FLOAT32 FLOAT16
    BFLOAT16 BFLOAT16 FLOAT32 BFLOAT16
    FLOAT32 FLOAT32 FLOAT32 FLOAT32
  • 不支持的场景:

    • 不支持ND格式以外的数据格式。
    • 不支持非连续的Tensor。
    • 不支持a、b和c的维度不为2的场景。

Workspace使用设计

workspace由两部分组成:

  1. 固定的16 MiB系统workspace。
  2. user workspace,其中依次放置13个内部中间张量及FT内部临时区。

算子tiling阶段根据M、N、K和输入精度计算完整大小,并通过workspaceSize返回。调用者必须申请不少于该大小的连续device内存,不能只按compRow大小申请。所有中间张量的起始地址按32字节向上对齐。

定义:

splitN      = ceil(N / 256)
rowSplitLen = M * splitN
bStatLen    = ceil(splitN / 8) * 8 + 8
beLen       = K * splitN
align32(x)  = ceil(x / 32) * 32

W为user workspace首地址。在kernel内,W = AscendC::GetUserWorkspace(workspace);对于算子外部的device地址计算,当前实现等价于W = (uint8_t *)workspace + 16 MiB

以下偏移均相对W。令S0 = 0,每个张量的起始偏移为Oi = align32(Si),结束位置为Si+1 = Oi + 元素数 × 元素字节数

顺序 中间结果 起始地址 元素类型 元素数
0 z_row W + O0 FLOAT32 rowSplitLen
1 d_row W + O1 FLOAT32 rowSplitLen
2 threshold W + O2 FLOAT32 rowSplitLen
3 b_mean_abs W + O3 FLOAT32 bStatLen
4 b_mean_square W + O4 FLOAT32 bStatLen
5 b_var W + O5 FLOAT32 bStatLen
6 be W + O6 与a相同 beLen
7 be_for_aiv W + O7 a为FLOAT16时是FLOAT16,否则是FLOAT32 beLen
8 b_max_slice W + O8 FLOAT32 beLen
9 b_min_slice W + O9 FLOAT32 beLen
10 a_max W + O10 FLOAT32 M
11 a_mean W + O11 FLOAT32 M
12 a_min W + O12 FLOAT32 M
其中FLOAT16和BFLOAT16元素占2字节,FLOAT32元素占4字节。第13段之后再次按32字节对齐,剩余区域是FT内部临时区,其逻辑大小为:
M * (splitN + 1) * sizeof(float)

AMean计算使用的常量因子1/K不占用workspace。tiling阶段按输入精度生成该scalar,kernel在首次计算AMean时直接用它初始化FT的L1内部缓冲区,因此该因子不能作为workspace中间结果拷出。

如果需要调试并拷出某个中间结果,应在算子执行完成且workspace尚未释放或复用时,从上表对应的W + Oi开始执行device-to-host拷贝,拷贝字节数为“元素数 × 元素字节数”。对外读取workspace属于调试能力,不是稳定的公开输出接口;布局发生变更时,以matmul_abft_verify.cppWorkspace ABI注释下的地址切分代码为准,该代码也是偏移计算的示例实现。

验证情况

精度验证

  • 算子编译及执行测试通过;

  • BF16 FP32 aclnn 接口调用测试通过;

  • 测试数据类型:BF16、FP32。

  • 测试形状:矩阵乘形状按 (M, N, K) 表示,M/N/K 分别取 {1024, 2048, 4096, 8192},采用全组合覆盖,共 64 种形状/数据类
    型,合计 128 个测试用例。

  • 精度标杆:以 CPU 侧 Golden 计算结果为基准,校验 BMeanAbs、BMeanSquare、BVar、COMPRow、ZRow、BE/BEforAIV、DRow、
    AMean、AMin、AMax 和 Thre 共 11 项中间结果及检测结果。阈值计算参数 e_max 为:

    • BF16:0.001
    • FP32:0.00002
  • 通过标准:

    • 所有输出元素必须为有限值;
    • 当累计计算量 computeNum < 2048 时,允许误差为 1/256 × max(1, |Golden|);
    • 当 computeNum ≥ 2048 时,允许误差为 1/128 × max(1, |Golden|);
    • COMPRow 要求与无错误标杆值 255 完全一致;
    • 任一校验项出现不满足条件的元素,该用例即判定失败。
  • 测试结果:BF16 和 FP32 各 64/64 个形状全部执行成功;每个用例的 11 项 Golden 校验均为 PASSED,合计 128/128 个用例通
    过,1408/1408 项校验通过,无失败项,通过率 100%。

结论:MatmulAbftVerify 算子在本次覆盖的 BF16、FP32 数据类型及全部 64 种矩阵形状下,精度测试全部通过。

  • 完整的多精度测试见独立样例仓库。

FP32 C 错误注入实验

除无故障场景下的数值精度验证外,对待检测矩阵 (C) 进行了 bit-flip 错误注入,以验证算子对实际 SDC 的检测能力。

测试覆盖以下矩阵形状:

(M,K,N) =
(2048,4096,4096)
(2048,4096,8192)
(4096,4096,4096)
(4096,4096,8192)

并覆盖多种输入数据分布:

clamped_normal_0_1
normal_1_1
normal_1e-6_1
uniform_-1_1

对于 BF16 输入、FLOAT32 C 的实验,在 FP32 C 的 bit 27~29 注入错误时,四组矩阵 shape 的检出率基本保持稳定:

  • clamped_normal_0_1:约 95.12%~95.27%
  • normal_1_1100%
  • normal_1e-6_1:约 97.49%~97.60%
  • uniform_-1_1:约 92.51%~92.73%

例如 ((M,K,N)=(4096,4096,8192)) 时,bit 27~29 的检出率分别为约 95.20%、100%、97.60% 和 92.73%。

对于 FP32 输入,在测试的 bit 23~30 范围内,各数据分布的检出率整体保持在约 90%~100%。例如 ((4096,4096,4096)) 时,bit 23~30 的检出率最低约为 90.04%,多项测试达到 100%。

与此同时,在上述错误注入测试对应的正常数据检测中,各测试 bit、矩阵 shape 和数据分布均未观察到误报,False-positive rate 为 0%。例如 FP32 ((4096,4096,8192)) 的全部 bit 23~30 和四种数据分布误报率均为 0。

该结果说明,在当前错误注入覆盖范围内,自适应门限能够在保持零误报的同时,对会造成显著结果扰动的 bit-flip 错误维持较高检出率。

BF16 (M,K,N)=(2048,4096,4096) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
23 0.000000 0.000000 0.000000 0.000000
24 0.000000 0.000000 0.000000 0.000000
25 7.360000 0.000000 0.000000 14.684000
26 95.122000 0.000000 87.930000 92.506000
27 95.122000 100.000000 97.531000 92.506000
28 95.122000 100.000000 97.531000 92.506000
29 95.122000 100.000000 97.531000 92.506000
30 4.878000 0.000000 2.469000 7.494000

BF16 (M,K,N)=(2048,4096,8192) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
23 0.000000 0.000000 0.000000 0.000000
24 0.000000 0.000000 0.000000 0.000000
25 7.141000 0.000000 0.000000 14.735000
26 95.239000 0.000000 87.950000 92.666000
27 95.239000 100.000000 97.597000 92.666000
28 95.239000 100.000000 97.597000 92.666000
29 95.239000 100.000000 97.597000 92.666000
30 4.761000 0.000000 2.403000 7.334000

BF16 (M,K,N)=(4096,4096,4096) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
23 0.000000 0.000000 0.000000 0.000000
24 0.000000 0.000000 0.000000 0.000000
25 7.023000 0.000000 0.000000 14.665000
26 95.270000 0.000000 87.885000 92.584000
27 95.270000 100.000000 97.493000 92.584000
28 95.270000 100.000000 97.493000 92.584000
29 95.270000 100.000000 97.493000 92.584000
30 4.730000 0.000000 2.507000 7.416000

BF16 (M,K,N)=(4096,4096,8192) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
23 0.000000 0.000000 0.000000 0.000000
24 0.000000 0.000000 0.000000 0.000000
25 7.181000 0.000000 0.000000 14.679000
26 95.198000 0.000000 87.910000 92.731000
27 95.198000 100.000000 97.598000 92.731000
28 95.198000 100.000000 97.598000 92.731000
29 95.198000 100.000000 97.598000 92.731000
30 4.802000 0.000000 2.402000 7.269000

FP32 (M,K,N)=(2048,4096,4096) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
23 95.156000 100.000000 90.092000 94.035000
24 97.062000 100.000000 96.897000 96.453000
25 97.494000 100.000000 97.517000 96.770000
26 97.530000 100.000000 97.517000 96.774000
27 97.533000 100.000000 97.517000 96.771000
28 97.533000 100.000000 97.517000 96.771000
29 97.533000 100.000000 97.517000 96.771000
30 100.000000 100.000000 94.706000 100.000000

FP32 (M,K,N)=(2048,4096,8192) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
23 95.293000 100.000000 90.141000 94.155000
24 97.080000 100.000000 96.980000 96.517000
25 97.453000 100.000000 97.593000 96.831000
26 97.487000 100.000000 97.593000 96.824000
27 97.490000 100.000000 97.593000 96.817000
28 97.490000 100.000000 97.593000 96.817000
29 97.490000 100.000000 97.593000 96.817000
30 100.000000 100.000000 94.714000 100.000000

FP32 (M,K,N)=(4096,4096,4096) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
23 95.312000 100.000000 90.039000 94.145000
24 97.089000 100.000000 96.932000 96.519000
25 97.562000 100.000000 97.500000 96.805000
26 97.626000 100.000000 97.500000 96.790000
27 97.625000 100.000000 97.500000 96.788000
28 97.625000 100.000000 97.500000 96.789000
29 97.625000 100.000000 97.500000 96.789000
30 100.000000 100.000000 94.676000 100.000000

FP32 (M,K,N)=(4096,4096,8192) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
23 95.242000 100.000000 90.107000 94.252000
24 97.058000 100.000000 97.020000 96.618000
25 97.470000 100.000000 97.600000 96.928000
26 97.493000 100.000000 97.600000 96.894000
27 97.490000 100.000000 97.600000 96.897000
28 97.490000 100.000000 97.600000 96.897000
29 97.490000 100.000000 97.600000 96.897000
30 100.000000 100.000000 94.720000 100.000000

BF16 C 转 FP32 后的错误检测实验

由于 MatmulAbftVerify 当前对外接口要求待检测矩阵 (C) 为 FLOAT32,而实际业务中前序矩阵乘可能产生 BF16 输出,因此额外验证如下使用路径:
首先在 BF16 的矩阵乘结果中注入错误,再将结果转换为 FLOAT32,最后作为 C 输入 MatmulAbftVerify。

测试同样覆盖:

(M,K,N) =
(2048,4096,4096)
(2048,4096,8192)
(4096,4096,4096)
(4096,4096,8192)

以及四种数据分布。

实验结果显示,对于 BF16 bit 11~13 的错误:

  • clamped_normal_0_1:检出率约 95.12%~95.27%
  • normal_1_1100%
  • normal_1e-6_1:约 97.49%~97.60%
  • uniform_-1_1:约 92.51%~92.73%

例如 ((2048,4096,4096)) 时,bit 11~13 在四种数据分布下的检出率分别为 95.122%、100%、97.531% 和 92.506%。

对于较低 bit,随着注入扰动幅度降低,检测率也会下降。例如该组实验的 bit 7~8 未产生可检出的结果,bit 9~10 的检出率则依数据分布和 bit 位置不同而变化。

四组矩阵 shape 下的误报率均为 0%。例如 ((4096,4096,8192)) 时,从 bit 7 到 bit 14、四种数据分布下的 False-positive rate 全部为 0。

因此,对于“前序矩阵乘结果为 BF16、转换为 FP32 后再进行外挂校验”的使用场景,当前实现同样能够对具有足够数值影响的错误保持较高检测能力,并在本次测试范围内未观察到误报。

BF16 (M,K,N)=(2048,4096,4096) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
7 0.000000 0.000000 0.000000 0.000000
8 0.000000 0.000000 0.000000 0.000000
9 7.360000 0.000000 0.000000 14.684000
10 95.122000 0.000000 87.930000 92.506000
11 95.122000 100.000000 97.531000 92.506000
12 95.122000 100.000000 97.531000 92.506000
13 95.122000 100.000000 97.531000 92.506000
14 4.878000 0.000000 2.469000 7.494000

BF16 (M,K,N)=(2048,4096,8192) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
7 0.000000 0.000000 0.000000 0.000000
8 0.000000 0.000000 0.000000 0.000000
9 7.141000 0.000000 0.000000 14.735000
10 95.239000 0.000000 87.950000 92.666000
11 95.239000 100.000000 97.597000 92.666000
12 95.239000 100.000000 97.597000 92.666000
13 95.239000 100.000000 97.597000 92.666000
14 4.761000 0.000000 2.403000 7.334000

BF16 (M,K,N)=(4096,4096,4096) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
7 0.000000 0.000000 0.000000 0.000000
8 0.000000 0.000000 0.000000 0.000000
9 7.023000 0.000000 0.000000 14.665000
10 95.270000 0.000000 87.885000 92.584000
11 95.270000 100.000000 97.493000 92.584000
12 95.270000 100.000000 97.493000 92.584000
13 95.270000 100.000000 97.493000 92.584000
14 4.730000 0.000000 2.507000 7.416000

BF16 (M,K,N)=(4096,4096,8192) — Detection rate (%)

Bit clamped_normal_0_1 normal_1_1 normal_1e-6_1 uniform_-1_1
7 0.000000 0.000000 0.000000 0.000000
8 0.000000 0.000000 0.000000 0.000000
9 7.181000 0.000000 0.000000 14.679000
10 95.198000 0.000000 87.910000 92.731000
11 95.198000 100.000000 97.598000 92.731000
12 95.198000 100.000000 97.598000 92.731000
13 95.198000 100.000000 97.598000 92.731000
14 4.802000 0.000000 2.402000 7.269000

性能测试

对 MatmulAbftVerify 单独执行延时以及同 shape 下 aclnnGemm 的执行延时进行了测试,并使用:

Fault Tolerance Overhead=TMatmulAbftVerifyTGEMM×100%\text{Fault Tolerance Overhead} = \frac{T_{\text{MatmulAbftVerify}}} {T_{\text{GEMM}}} \times100\%

衡量外挂检测算子相对于原始矩阵乘的额外时间成本。

部分代表性测试结果如下:

数据精度 (M,N,K) MatmulAbftVerify / ms aclnnGemm / ms 容错成本
BF16 1024,1024,1024 0.0705 0.0295 238.98%
BF16 2048,4096,4096 0.1672 0.2389 69.99%
BF16 4096,4096,4096 0.2205 0.4573 48.22%
BF16 4096,4096,8192 0.3361 0.9199 36.54%
BF16 8192,8192,8192 0.7536 3.8666 19.49%
FP32 1024,1024,1024 0.0766 0.0410 186.83%
FP32 2048,4096,4096 0.1705 0.8202 20.79%
FP32 4096,4096,4096 0.2313 1.6172 14.30%
FP32 4096,4096,8192 0.3845 3.2192 11.94%
FP32 8192,8192,8192 1.0695 12.5441 8.53%

测试结果与算法复杂度的预期一致:对于较小矩阵,外挂算子本身的固定启动及统计计算开销占比较高;随着矩阵规模增大,GEMM 计算量按 (O(a^3)) 增长,而容错检测主要按 (O(a^2)) 增长,因此相对容错成本明显下降。

例如对于 (8192^3):

  • BF16 GEMM:3.8666 ms
  • BF16 MatmulAbftVerify:0.7536 ms
  • 相对容错成本约:19.49%

而对于 FP32:

  • FP32 GEMM:12.5441 ms
  • FP32 MatmulAbftVerify:1.0695 ms
  • 相对容错成本约:8.53%

说明在较大规模矩阵乘场景下,该方案能够以明显低于重新执行一次完整 GEMM 的额外延时完成结果校验。

likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 starfican 的贡献)
Sstarfican
16 天前 创建了 pull request,commit 1705bc97
CANN-robot
CANN-robot成员
16 天前 评论:

Hi @starfican, welcome to submitting your first PR to ops-ras!

PR Merge Steps

1. CLA Signing

If the current PR label includes cann-cla/yes, it means you have signed the CLA and can proceed to the next step. If the label includes cann-cla/no, please sign the CLA first. If you have any questions, please refer to the FAQ.

2. CI Check

Please comment /compile to trigger the CI pipeline check. If the CI run is successful, the PR will be tagged with ci-pipeline-passed and you can proceed to the next step. If the CI run fails, the PR will be tagged with ci-pipeline-failed, please check the CI logs to fix the issues in the PR. If you have any questions, please refer to the FAQ.

3. Code Review

After CI passes, please refer to the PR Approval Progress and proactively @ the committers in the table to review the code. After approval, committers will comment /lgtm and /approve. Once the lgtm and approved labels are successfully added, the PR will be merged automatically.

likedislike
CANN-robotCANN-robot成员
16 天前 添加了label:cann-cla/no
CANN-robot
CANN-robot成员
16 天前 评论:

Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
For more, you also can visit HICANN.


PR Approval Progress

Congratulations! All modules have met the lgtm and approve requirements.

Module Approval Details

module lgtm status approve status
repo-cann/ops-ras 冯彤, 於欣洁 (2/2) 於欣洁 (1/1)

💡 Tip:

  • Committer can comment /approve or /lgtm
  • Commenting /approve implies both code review (lgtm) and intent to merge (approve)

CLA Signature Pass

starfican, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
Sstarfican
16 天前 预合并成功(commit_id: 52901ea1ce5af610a296ba089ac728fb80983a80)
此处折叠了436条消息 查看更多
於欣洁成员
5 天前 评论:

/lgtm
/approve

likedislike
CANN-robotCANN-robot成员
5 天前 添加了label:approved
rxtfeng成员
5 天前 评论:

/lgtm

likedislike
CANN-robotCANN-robot成员
5 天前 添加了label:lgtm
CANN-robotCANN-robot成员
5 天前 合入了pull request