首页
/ CPython 标准库 "Superseded modules" 全解读:getopt 与 profile 的现状、定位与迁移指南

CPython 标准库 "Superseded modules" 全解读:getopt 与 profile 的现状、定位与迁移指南

2026-09-07 20:15:53作者:余洋婵Anita

本指南以 CPython 文档体系中的 Superseded modules 章节 为主线,系统讲解"已被更优方案取代但仍为向后兼容保留"的标准库模块的分级与判定标准,并完整展开该章节当前收录的两个成员——命令行解析模块 getopt 与纯 Python 剖析器 profile 的功能细节、API 用法与迁移路径。读完本文,你将能够判断"一个模块为何会被列为 Superseded",准确使用 getopt / gnu_getopt,并掌握从 profile 迁移到新式剖析模块的方法与原理。


一、Superseded modules 是什么:一个"继任者驱动"的文档章节

打开 CPython 源码树的 Doc/library/ 目录可以看到,标准库文档并不是按"是否还在维护"一刀切,而是专门设立了 superseded.rst 这一章节页,收纳那些"在多数使用场景下已被其他模块取代、保留主要是为了向后兼容"的模块。

该章节(Doc/library/superseded.rst)明确定义了模块进入此章节的两种典型原因:

  • 覆盖范围过窄,存在更通用的替代方案:例如 getopt 只解决"在 Python 中复刻 C 语言 getopt API"这一非常具体的问题,而 optparseargparse 提供了更宽泛的命令行选项与参数解析能力;
  • 被彻底弃用(deprecated outright),等待在未来版本中移除;或处于 soft deprecated 状态,新项目不鼓励使用。

1.1 Soft deprecation 与普通弃用的区别

Superseded 章节正文引用了术语 soft deprecated,其精确定义见 Doc/glossary.rst

软弃用(soft deprecated)的 API 不应在新代码中使用,但已有代码继续使用它是安全的。该 API 仍会保持文档化与测试覆盖,只是不会再获得功能增强;软弃用不像普通弃用那样计划移除 API,也不会发出告警(即运行时不产生 DeprecationWarning)。

软弃用与 PEP 387 的软弃用概念一脉相承,本质上是一种"降级但不驱逐"的治理手段。

1.2 PEP 594 之后:章节内的状态分布

章节文档还提到,随着 PEP 594(移除一批过时的标准库模块)的落地,当前章节内已不再有处于 soft deprecated 状态的模块。结合当前代码树中的三个文档可以拼出完整的图谱:

模块 所属文档 状态 继任者
getopt Doc/library/getopt.rst 功能完备、被取代但未弃用 argparseoptparse
profile Doc/library/profile.rst 已弃用,计划在 Python 3.17 移除 profiling.tracing
(PEP 594 移除的 aifcaudioop 等) 已彻底移除

需要留意的是,本仓库是处于开发期的版本:Include/patchlevel.h 显示其为 3.16.0a0。因此文中出现的"移除于 3.17"等时间线是当前开发分支文档的规划,实际以最终发布版本为准。

章节通过 toctree 收纳两个成员页面:getopt.rstprofile.rst。下文分别深入解读。


二、getopt:为"复刻 C 风格解析"而生的模块

2.1 定位:刻意保持"小而窄"

Doc/library/getopt.rst 开篇即声明:

本模块被视为功能完备(feature complete),不再演进。更声明式、可扩展的替代 API 由 optparse 模块提供;命令行参数处理的进一步功能增强则由 PyPI 上的第三方模块或 argparse 提供。

它的作用非常聚焦:帮助脚本解析 sys.argv 中的命令行参数,支持与 Unix getopt 函数相同的约定(包括 '-''--' 的特殊含义),并可通过可选的第三个参数支持类似 GNU 软件的长选项。其纯 Python 实现位于 Lib/getopt.py,源码头部的文档字符串与 __all__ = ["GetoptError", "error", "getopt", "gnu_getopt"] 精确呼应了官方 API 表面。

2.2 核心 API 与参数约定

模块共提供两个函数、一个异常(外加一个向后兼容别名)

getopt(args, shortopts, longopts=[])

  • args:待解析的参数列表,不含程序名,通常就是 sys.argv[1:]
  • shortopts:需要识别的短选项字母字符串。需要参数的选项后跟一个冒号 ':'接受可选参数的选项后跟两个冒号 '::'——与 Unix getopt 格式一致;
  • longopts:长选项名列表,不写前导 '--'必选参数用尾随等号 '=' 表示,可选参数'=?' 表示。若只想接受长选项,shortopts 传空字符串即可;若 longopts 本身是字符串,会被当作单元素列表处理。

长选项支持前缀匹配:只要所给前缀能唯一对应一个已声明选项即可识别。例如 longopts=['foo', 'frob']--fo 可唯一匹配 --foo,而 --f 同时匹配两个选项,将抛出 GetoptError

返回值为二元组:

  • 第一个元素是 (option, value) 对列表。短选项以单个连字符为前缀(如 '-x'),长选项以双连字符为前缀(如 '--long-option');无参数的选项其 value 为空字符串;
  • 第二个元素是剥离选项后剩余的位置参数(args 的尾切片);
  • 选项在结果列表中的顺序与命令行出现顺序一致,因此同一选项可以多次出现,长短选项可以混用。

一个文档内直接给出的注解值得强调:与 GNU getopt 不同getopt() 在遇到第一个非选项参数后,后续所有参数都被视为非选项——这与非 GNU 的 Unix 系统行为一致。

gnu_getopt(args, shortopts, longopts=[])

工作方式与 getopt() 相同,但默认采用 GNU 扫描模式,即选项与非选项参数可以交错出现,而 getopt() 一旦遇到非选项参数即停止处理选项。

它同时支持两个特殊的 shortopts 前导字符与一个环境变量:

  • shortopts 首字符为 '+',或设置了环境变量 POSIXLY_CORRECT,则遇到第一个非选项参数后即停止选项处理(回归 POSIX 行为);
  • shortopts 首字符为 '-',则把"被选项夹住"的非选项参数也加入选项对列表,形式为 (None, [非选项参数列表])

此时返回值的第二个元素是最后一个选项之后剩下的程序参数。

版本注意(与代码仓库一致的文档标注):可选参数支持按序返回交错选项/非选项参数均标注为 Python 3.14 起的行为变化。

异常 GetoptError 与别名 error

当参数列表中出现无法识别的选项、或"需要参数的选项没有收到参数"时抛出 GetoptError;对长选项而言,给不需要参数的选项提供了参数同样会触发。异常携带两个属性:msg(错误信息)与 opt(涉及的选项;若无具体相关选项则为空字符串)。为保持向后兼容,还提供了 error 作为 GetoptError 的别名——在 Lib/getopt.py 中可以看到 error = GetoptError 这一行。

2.3 文档示例逐段对照

官方文档用四个 doctest 分别演示了核心能力,下面完整复述:

仅 Unix 风格短选项——-cfoo 会被解析为 -c 携带参数 foo

>>> import getopt
>>> args = '-a -b -cfoo -d bar a1 a2'.split()
>>> args
['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'abc:d:')
>>> optlist
[('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
>>> args
['a1', 'a2']

长短选项混用——condition=output-file= 要求参数,testing 不需要:

>>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
>>> args = s.split()
>>> args
['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'x', [
...     'condition=', 'output-file=', 'testing'])
>>> optlist
[('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')]
>>> args
['a1', 'a2']

可选参数(Python 3.14+)必须显式给出——C::color=? 声明可选参数,紧跟在选项后的值才会被吸收:

>>> s = '-Con -C --color=off --color a1 a2'
>>> args = s.split()
>>> args
['-Con', '-C', '--color=off', '--color', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'C::', ['color=?'])
>>> optlist
[('-C', 'on'), ('-C', ''), ('--color', 'off'), ('--color', '')]
>>> args
['a1', 'a2']

gnu_getopt 保持交错顺序——注意短选项串以 '-' 开头,因此非选项参数 a1a3 a4 被包装为 (None, [...]) 对:

>>> s = 'a1 -x a2 a3 a4 --long a5 a6'
>>> args = s.split()
>>> args
['a1', '-x', 'a2', 'a3', 'a4', '--long', 'a5', 'a6']
>>> optlist, args = getopt.gnu_getopt(args, '-x:', ['long='])
>>> optlist
[(None, ['a1']), ('-x', 'a2'), (None, ['a3', 'a4']), ('--long', 'a5')]
>>> args
['a6']

2.4 脚本中的典型用法(可直接套用)

官方文档给出的完整脚本骨架如下,建议读者对照注释理解"先解析、后分发"的结构:

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err)  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-o", "--output"):
            output = a
        else:
            assert False, "unhandled option"
    process(args, output=output, verbose=verbose)

if __name__ == "__main__":
    main()

几个工程要点值得展开:

  • sys.argv[1:] 掐头:args 约定不含程序名;
  • try/except GetoptError 是必需的错误边界:出错时通常打印用法并 sys.exit(2)(与 Unix 工具惯例一致,2 表示命令行用法错误);
  • 因为返回的是 (option, value) 对列表而非 dict,同一选项多次出现(例如 -v -v)时遍历即可自然处理;
  • error 别名保留了早期字符串异常的调用习惯,但新代码应统一捕获 GetoptError

2.5 为什么文档推荐你换掉它:与 optparse / argparse 的对照

getopt 之所以被列入 Superseded,不是因为它有 bug,而是因为"手写循环分发选项"本身就是低层劳动。文档逐一给出了等价的更上层实现,供对照决策。

optparse 写同样接口(声明式,代码更少,自动带帮助与错误信息):

import optparse

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-o', '--output')
    parser.add_option('-v', dest='verbose', action='store_true')
    opts, args = parser.parse_args()
    process(args, output=opts.output, verbose=opts.verbose)

argparse 写近似接口(rest 负责收拢余下的位置参数):

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output')
    parser.add_argument('-v', dest='verbose', action='store_true')
    parser.add_argument('rest', nargs='*')
    args = parser.parse_args()
    process(args.rest, output=args.output, verbose=args.verbose)

文档特别提示:argparse 版本与 optparse/getopt 版本在行为细节上有差异(例如互斥组、子命令、自动生成的帮助文本与 --version 支持),选择前可结合 argparseoptparse 的完整文档评估。

选型速记:对 Unix getopt 不熟悉 → 直接用 argparse;熟悉 getopt 且想少写代码、获得更好帮助与报错 → 用 optparse;只有当你确实需要逐字复刻 C getopt 的解析行为(例如在某个移植工具中)时,getopt 才是不可替代的正确答案。这一"three-tier"建议正是整个 Superseded 章节"按问题空间选择工具"思想的缩影。


三、profile:已进入移除倒计时的纯 Python 剖析器

3.1 弃用时间线与迁移总原则

Doc/library/profile.rst 在页面顶部用 .. deprecated-removed:: 3.15 3.17 明确标注:

profile 模块已弃用,并将在 Python 3.17 中移除。请改用 profiling.tracing

理由非常直接:profile纯 Python 实现的确定性剖析器,理解剖析器内部原理或通过子类化扩展剖析行为时仍有价值,但相比基于 C 的 profiling.tracing,其运行开销显著更大。

对于不同场景,官方推荐的默认选择是:

  • 生产环境调试:用 profiling.sampling(零开销的统计采样);
  • 开发与测试:用 profiling.tracing(确定性的精确追踪)。

3.2 平滑迁移:一行 import 的替换

由于两套 API 相互兼容,迁移几乎是机械性的:

# Old (deprecated)
import profile
profile.run('my_function()')

# New (recommended)
import profiling.tracing
profiling.tracing.run('my_function()')

对大多数代码而言,把 import profile 换成 import profiling.tracing,并在全文使用新模块名即可完成迁移。一个重要的兼容性兜底是:cProfile 仍作为 profiling.tracing 的向后兼容别名保留import cProfile 的存量代码无需改动即可继续运行。这一设计在仓库中得到了源码印证——Lib/cProfile.py 的正文即:

"""Compatibility wrapper for cProfile module.

This module maintains backward compatibility by importing from the new
profiling.tracing module.
"""

from profiling.tracing import run, runctx, Profile

而更早的 C 实现 _lsprof 则位于 Modules/_lsprof.c

3.3 共享的模块级函数

profileprofiling.tracing 都提供如下模块级函数:

run(command, filename=None, sort=-1)

接收一个可传给 exec 的字符串与可选文件名。所有情况下它都执行

exec(command, __main__.__dict__, __main__.__dict__)

并在执行过程中收集剖析统计。未提供文件名时,自动创建 Stats 实例并打印一份简明的剖析报告;提供了 sort 时,该值会被传给该 Stats 实例以控制结果排序方式。

runctx(command, globals, locals, filename=None, sort=-1)

run 类似,但额外接收 globalslocals 映射来指定 command 字符串的执行环境,执行的是

exec(command, globals, locals)

3.4 Profile 类:需要更精细控制时的入口

文档指出,Profile 类通常只在需要比 run() 更精细的控制时才被使用(例如不想把剖析数据写盘,直接格式化结果)。

构造函数签名(两模块共享):Profile(timer=None, timeunit=0.0, subcalls=True, builtins=True)

  • 自定义计时器通过 timer 传入,必须是返回单个数字代表当前时刻的函数;
  • 若该数字是整数,timeunit 是每个时间单位所代表的真实时长乘数——例如计时器以千分之一秒为单位,则 timeunit=0.001

不落盘、直接格式化输出的推荐写法(注意这里使用新模块名):

import profiling.tracing
import pstats
import io
from pstats import SortKey

pr = profiling.tracing.Profile()
pr.enable()
# ... do something ...
pr.disable()
s = io.StringIO()
sortby = SortKey.CUMULATIVE
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print(s.getvalue())

作为上下文管理器使用(此能力仅在 profiling.tracing 中提供,弃用的 profile 模块不支持;上下文管理器机制的通用文档见 参考语言手册中的 typecontextmanager 条目Profile 自 Python 3.8 起支持该用法):

import profiling.tracing

with profiling.tracing.Profile() as pr:
    # ... do something ...

    pr.print_stats()

Profile 对象的方法集如下:

方法 作用 备注
enable() 开始收集剖析数据 profiling.tracing
disable() 停止收集剖析数据 profiling.tracing
create_stats() 停止收集并把结果在内部记录为当前 profile
print_stats(sort=-1) 基于当前 profile 创建 Stats 对象并打印到 stdout sort 接受单个键或键元组以支持多级排序,Python 3.13 起支持元组
dump_stats(filename) 把当前 profile 结果写入 filename
run(cmd) 通过 exec 剖析 cmd
runctx(cmd, globals, locals) 在指定全局/局部环境下通过 exec 剖析 cmd
runcall(func, /, *args, **kwargs) 剖析一次 func(*args, **kwargs) 调用

一个容易被忽略的运行前提:剖析只在被调用的命令/函数正常返回时生效。若解释器在调用期间被终止(例如执行中调用了 sys.exit),将不会打印任何剖析结果。

3.5 与 profiling.tracing 的差异清单

profileprofiling.tracing 的核心差异(也是你评估"要不要现在迁移"的依据):

  • 更高开销:纯 Python 实现显著慢于 C 实现,不适合剖析长时间运行的程序或性能敏感代码;
  • 校准支持profile 支持通过校准补偿剖析自身开销;profiling.tracing 无需校准,因为其 C 实现开销可忽略;
  • 自定义计时器:两者都支持,但 profile 接受返回元组的计时函数(如 os.times),而 profiling.tracing 要求返回单个数字的函数;
  • 可子类化性:纯 Python 实现更易于子类化扩展自定义剖析行为——这是 profile 在彻底移除前仍保有的"教学/研究价值"。

四、深入原理:确定性剖析、统计剖析与剖析精度

4.1 什么是确定性剖析(deterministic profiling)

文档为这个概念给出了严谨定义:确定性剖析意味着所有函数调用函数返回异常事件都被监控,并对这些事件之间的间隔(即用户代码运行期间)做精确计时。与之相对,统计剖析(statistical profiling)(由 profiling.sampling 模块提供)则是周期性采样有效的指令指针,据此推断时间花在了哪里——后者传统上开销更低(代码无需插桩),但只能给出时间消耗的相对指示

Python 中做确定性剖析有一个天然优势:解释器执行期间始终在场,因此无需插桩代码——Python 会自动为每个事件提供 hook(可选回调)。同时,解释执行本身带来的开销较大,相对地,确定性剖析叠加的处理开销反而显得很小。结论是:确定性剖析"并不昂贵",却能提供关于程序执行的丰富运行时统计。

关于统计指标的使用,文档给出了一套经典方法论:

  • 调用计数:用于发现代码 bug(意外的高/低计数)与识别潜在的内联展开点(高调用次数的小函数);
  • 内部时间(internal time):用于定位需要谨慎优化的 "hot loops";
  • 累积时间(cumulative time):用于发现算法选型层面的高层错误;
  • 值得注意:该剖析器对递归算法累积时间的特殊处理,使得递归实现与迭代实现可以直接对比统计结果

4.2 精度限制:为什么时钟分辨率会引入误差

剖析精度有两个根本性限制(详见 profile 文档的 Limitations 一节):

  1. 底层"时钟"通常约以 0.001 秒为步长滴答,因此任何测量都不可能比底层时钟更精确;测量足够多时,误差在平均意义上趋于抵消;
  2. 从事件分发到剖析器真正读到时钟状态存在延迟,退出事件处理器时同样存在滞后。因此"被调用很多次、或调用了很多函数"的函数会持续累积这一误差——单次误差通常小于一个时钟滴答,但可能累积到非常显著

这一问题是弃用的 profile 模块(纯 Python、事件处理更重)比低开销的 profiling.tracing 更突出。正因如此,profile 提供了校准机制,在概率平均意义上消除该误差;校准后结果的均方误差更小,但在调用计数极低时偶尔会算出负数——文档特意安抚:不要被负数吓到,它们只应在校准后出现,且此时结果实际上优于未校准状态。

4.3 校准实操(针对弃用的 profile

profile 剖析器会从每次事件处理时间中减去一个常数,以补偿"调用计时函数并保存结果"的开销;默认该常数为 0。获取更佳常数的标准流程如下:

import profile
pr = profile.Profile()
for i in range(5):
    print(pr.calibrate(10000))

calibrate(10000) 会让参数指定的 Python 调用量在"直接执行"与"剖析器之下执行"各跑一遍,分别计时,算出每个剖析事件背后的隐藏开销并作为 float 返回。文档给出的参照:在 1.8GHz Intel Core i5 的 macOS 上、以 time.process_time() 作为计时器时,该值约为 4.04e-6

校准目标是获得相当一致的结果;若机器非常快或计时器分辨率差,可能需要把参数提高到 100000 甚至 1000000。得到一致的 bias 值后,有三种应用方式:

import profile

# 1. Apply computed bias to all Profile instances created hereafter.
profile.Profile.bias = your_computed_bias

# 2. Apply computed bias to a specific Profile instance.
pr = profile.Profile()
pr.bias = your_computed_bias

# 3. Specify computed bias in instance constructor.
pr = profile.Profile(bias=your_computed_bias)

若可以选择,倾向于选较小的常数——这样统计结果"较少"出现负值。

4.4 使用自定义计时器

想改变"当前时间"的测定方式(例如强制使用墙钟时间或进程消耗时间)时,把计时函数传给 Profile 构造函数即可:

pr = profile.Profile(your_time_func)

计时函数返回值的解释方式取决于用的是哪个模块:

  • profile.Profileyour_time_func 应返回单个数字,或一组数字列表(其和代表当前时间,如 os.times 的返回值)。若返回单个时间数字、或返回列表长度为 2,会走一个特别快的分发例程。文档提醒:选好计时函数后务必校准(见上节);对大多数机器而言,返回单个整数的计时器在"低剖析开销"上表现最佳(os.times 因为返回浮点元组而"相当糟糕");若想以最干净的方式替换计时器,推荐派生子类并硬编码专用的分发方法连同合适的校准常数;
  • profiling.tracing.Profileyour_time_func 必须返回单个数字;若返回整数,可用第二个构造参数指定每个单位的真实时长,例如计时单位是千分之一秒时写作 profiling.tracing.Profile(your_integer_time_func, 0.001)。由于该 C 实现类无法校准,自定义计时函数应谨慎使用并尽量快——最理想的情况下,可能需要把自定义计时器硬编码进内部 _lsprof 模块的 C 源码中(见 Modules/_lsprof.c)。

自 Python 3.3 起,time 模块新增了多个可用于精确测量进程时间或墙钟时间的函数,例如 time.perf_counter,它们通常比 os.times 更适合作为计时来源。


五、决策指南与延伸阅读

回到 Superseded 章节设计的初衷:"被取代"不等于"坏掉了",它只意味着"从零开始的新代码有更合适的选择"。据此可给出如下实操判断:

  1. 命令行解析:新脚本一律从 argparse 起步;需要脚本化、声明式快速生成时考虑 optparse;只有必须逐字复刻 C getopt 语义(含 '-''--' 与"首个非选项后全为非选项"等边界行为)时才用 getopt,并明确其自 Python 3.14 起新增的可选参数与 GNU 交错解析能力;
  2. 性能剖析:新代码直接使用 profiling.tracing(开发期确定性剖析)与 profiling.sampling(生产期零开销采样);profile 模块仅服务于"研究剖析器内部机制"或"通过子类化扩展剖析行为"的场景,且需清醒认识到它已进入移除倒计时(文档标注移除于 Python 3.17);存量 import cProfile 代码可继续工作,因为 Lib/cProfile.py 已转为对 profiling.tracing 的兼容包装;
  3. 语义理解:"soft deprecated"(见 Doc/glossary.rst)意味着不计划移除、不发告警,但也不再增强——遇到这类 API 时请默认为"维护模式"而非"终将消失"。

各模块的完整实现与测试证据可继续深入 Lib/getopt.pyLib/profile.pyModules/_lsprof.c;剖析结果的分析与格式化工具见 pstats,标准库剖析工具的总体导览见 profiling 包文档。理解"为何被取代、被谁取代、如何迁移",正是正确使用这些遗留模块的前提。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
916
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388