Page 107 - 《软件学报》2025年第7期
P. 107

3028                                                       软件学报  2025  年第  36  卷第  7  期


                 发生的逻辑缺陷.
                    ● 张量形状错误. 这类缺陷是指与张量形状             (shape) 或布局  (layout) 相关的问题. 张量的形状与布局对模型的
                 性能起着重要的作用, 其中张量形状代表了每个维度中的元素数量, 而布局则描述了张量在内存中的表示方式                                   [7] .
                 而且这类缺陷大部分发生在张量形状匹配、张量形状转换、张量形状推理、数据布局转换等操作过程中.
                    ● API 误用. 这类缺陷主要源于开发者对          API 的理解或使用不当而产生. 具体表现为在编程过程中错误地选
                 择了  API、运用了不恰当的参数、在          API 使用过程中遗漏或过度进行了条件检查, 以及不必要或缺失的                   API 调用
                 等情况.
                    ● 类型错误. 这类缺陷包含类型转换和类型推理等类型相关问题. DL                       编译器以计算图为核心, 其中节点
                 (node) 代表深度学习运算符      (operator), 而边  (edge) 则代表张量数据  (tensor). 此类别包含  3  个子类. (1) 节点类型错
                 误: 这个类别是指涉及节点类型定义或使用的问题. 在                DL  编译器中, 每个节点的输入可以是          0  个或多个张量, 输
                 出为一个或多个张量. (2) 张量类型错误: 这个类别是指涉及张量数据类型的问题. 张量是一个包含单一数据类型
                 元素的多维数组      (或称为多维矩阵), 用于表示深度学习中的数据和参数. (3) 传统数据类型错误: 这个类别是指涉
                 及  DL  编译器中除了节点和张量之外, 还使用到的常规数据类型的问题. 这些常规数据类型包括传统软件系统中
                 广泛使用的整型、浮点型、字符串等, 它们用于描述编译器内部状态、配置参数等.
                    ● 异常处理错误. 此类缺陷是对异常情况的错误管理. 包括在理应触发异常的情形下, 编译器未能正确抛出异
                 常; 或者在正常情况下错误地抛出了异常. 同时还包括提供不准确或有误导性的异常信息, 使得调试和故障排除变
                 得困难.
                    ● 配置错误. 该类型的缺陷是由         DL  编译器中的错误的配置选项引起的, 例如            CmakeLists.txt 文件的错误配置
                 信息.
                    ● 赋值错误. 这类缺陷包括变量的错误初始化或赋值, 包括变量在使用前未进行声明或初始化就直接被引用,
                 或者变量被赋予了与预期不符的值.
                    ● 并发问题. 此类缺陷涉及面向并发结构            (比如, 线程、临界区、锁) 的错误操作. 如死锁, 线程过多导致内存
                 溢出等.
                    ● 不兼容. 此类缺陷是由       DL  编译器内部各个组件之间或         DL  编译器与第三方库      (例如, PyTorch  和  cuDNN)
                 之间的接口、功能或规范不匹配造成的. 不兼容缺陷通常与技术差异、版本不匹配、缺少必要的支持等因素密切
                 相关.
                    ● 数值计算错误. 这类缺陷包括错误的数值类计算或使用, 例如不正确的使用运算符或操作数、非法除零、
                 缺少操作符或操作数等.
                    ● 注册问题. 此类缺陷包括头文件的缺失或者错误引入, API 或者类的属性缺少注册时直接调用.
                    ● 拼写错误. 这类缺陷是由于开发人员粗心导致的代码拼写错字, 比如将变量名“annotations”误写为“annotation”.
                    ● 其他. 当缺陷的根因不常见, 并且不属于上述任何一类时, 本文将其归纳为此类别.
                    注册问题为本文识别出来的           DL  编译器缺陷根因, 此类缺陷主要因为缺少            API 注册而直接调用而导致的. 14
                 个此类缺陷中有      12  个出现在  TVM  中, 占比  85.71%. 分析发现, 这类缺陷与     TVM  中复杂的双向跨语言       API 调用
                 密切相关. 具体而言, TVM      使用外部函数接口       (FFI) 实现  Python  和  C++代码双向调用功能, API 跨语言调用需要
                 先注册再调用. 缺少注册而直接调用跨语言声明的                 API 将会导致程序崩溃. 尽管这个根因是新识别的根因, 但在
                 Shen  等人  [8] 收集的缺陷中已包含了    5  个此类缺陷, 由于数量不够显著, 被归纳为其他. 除了注册问题以外, 其他缺
                 陷根因类别都已经被已有工作识别出来的, 因此, DL              编译器迭代更新几乎不会引入新的缺陷类别.
                    发现  1. 尽管  DL  编译器经历了长时间、大幅度迭代更新, 但缺陷根因的类别已近乎被全面识别.

                 4.1.2    根因分布情况
                    图  2  描述了  DL  编译器不同根因的缺陷数量分布对比情况. 其中旧数据                (图的左半部分) 是指已有工作        [8] 中研
                 究的  603  个早期  DL  编译器缺陷, 新数据    (图的右半部分) 是指本文研究的          613  个近期被修复的     DL  编译器缺陷.
                 从图中可以看出, 逻辑错误是当下          DL  编译器最常见的缺陷根因. 118       个此类缺陷中, 包括      73  个是由错误的优化代
   102   103   104   105   106   107   108   109   110   111   112