- 人工智能
- 编译器
- 模型编译
- 高性能计算
- 深度学习
- CANN
【免费下载链接】pypto
PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。
导读
本文围绕 CANN PyPTO(Parallel Tensor/Tile Operation 编程范式)中的元素级除法算子pypto.div,系统讲解其功能语义、函数原型、参数与返回值规则、精度模式选择(HIGH_PRECISION / INTRINSIC)、数据类型与广播约束,并结合仓库源码与系统测试给出可复现的调用示例与 TileShape 切分配置方法。读完本文,你将掌握如何在 Ascend 训练/推理产品上正确使用pypto.div完成张量除法、标量除法与广播除法,并能针对精度与性能诉求做出合理的精度模式选择。
产品支持情况
pypto.div在以下产品上获得支持:
- Ascend 950PR / Ascend 950DT:支持
- Atlas A3 训练系列产品 / Atlas A3 推理系列产品:支持
- Atlas A2 训练系列产品 / Atlas A2 推理系列产品:支持
需要说明的是,各产品对输入数据类型与精度模式的支持范围存在差异(详见后文“约束说明”),其中HIGH_PRECISION 高精度模式仅在 Ascend 950PR/Ascend 950DT 上支持,A3 与 A2 系列仅能使用 INTRINSIC 指令模式。这一点在选择精度模式时务必注意,避免在编译期收到“不支持”的报错。
功能说明
pypto.div执行元素级除法:将input的每个元素除以other中对应位置的元素,计算公式为:
$$ res_i = input_i \div other_i $$
该算子支持两个 Tensor 之间逐元素相除,也支持 Tensor 与标量(float / int)相除,还支持输入张量之间按维度进行广播后相除。
从源码结构看,pypto.div在 python/pypto/op/math.py 中通过@op_wrapper装饰器定义,其内部实现会根据other的类型走两条路径(详见下文“底层实现解析”)。
函数原型
div(input: Tensor, other: Union[Tensor, float, int], precision_type: PrecisionType = PrecisionType.HIGH_PRECISION) -> Tensorinput:被除数,Tensor 类型;other:除数,可以是 Tensor、float 或 int;precision_type:精度模式枚举,默认PrecisionType.HIGH_PRECISION(高精度模式),其完整定义参见 PrecisionType 说明。
参数说明
| 参数名 | 输入/输出 | 说明 |
|---|---|---|
| input | 输入 | 源操作数(被除数)。支持的类型为:Tensor。不同型号支持的数据类型有所差异,详细请参见约束说明。不支持空Tensor;支持的维度:1-4维;支持多维度广播到相同形状;Shape Size不大于2147483647(即INT32_MAX)。 |
| other | 输入 | 源操作数(除数)。支持的类型为:Tensor、float、int。不同型号支持的数据类型有所差异,详细请参见约束说明。不支持空Tensor;支持的维度:1-4维;支持多维度广播到相同形状;Shape Size不大于2147483647(即INT32_MAX)。 |
| precision_type | 输入 | 精度模式枚举类型,用以控制除法计算的精度模式,具体定义为:PrecisionType。默认为HIGH_PRECISION(高精度模式)。 |
关于precision_type的两个取值(枚举原型来自 PrecisionType 文档):
| 参数值 | 说明 |
|---|---|
| HIGH_PRECISION | 高精度模式。在底层实现中使用更高精度的计算方式,可以有效减少精度损失,提高计算结果的准确性。 |
| INTRINSIC | 指令模式。直接使用芯片指令进行计算,性能更高,但对精度要求不高的场景适用。 |
返回值说明
返回输出 Tensor,Shape 为input和other广播后的大小。
- 当输入为浮点类型时,输出数据类型与输入相同;当输入为 DT_INT16 或 DT_INT32 时,输出数据类型为 DT_FP32。
- 对于 Ascend 950PR/Ascend 950DT,当输入为 DT_INT64 或 DT_UINT64 时,输出数据类型与输入相同。
约束说明
使用pypto.div时必须满足以下约束,否则会编译报错或产生非预期结果:
- 数据类型一致:
input和other都为 Tensor 时,数据类型应该相同。 - 标量(scalar)类型规则:
other为 scalar 时,- 若
input为浮点类型,则 scalar 支持整型(自动转为浮点); - 若
input为整型,则 scalar 不支持浮点类型(会报错)。
- 若
- Tensor 数据类型说明(按产品区分):
- Ascend 950PR/Ascend 950DT:DT_FP16,DT_FP32,DT_BF16,DT_INT16,DT_INT32,DT_INT64,DT_UINT64。
- Atlas A3 训练系列产品/Atlas A3 推理系列产品:DT_FP16,DT_FP32,DT_BF16,DT_INT16,DT_INT32。
- Atlas A2 训练系列产品/Atlas A2 推理系列产品:DT_FP16,DT_FP32,DT_BF16,DT_INT16,DT_INT32。
- 精度模式说明:
- HIGH_PRECISION(高精度模式):默认模式,在底层实现中会使用更高精度的计算方式。在不同型号上的支持情况:
- Ascend 950PR/Ascend 950DT:支持
- Atlas A3 训练系列产品/Atlas A3 推理系列产品:不支持
- Atlas A2 训练系列产品/Atlas A2 推理系列产品:不支持
- INTRINSIC(指令模式):直接使用芯片指令进行计算。
- HIGH_PRECISION(高精度模式):默认模式,在底层实现中会使用更高精度的计算方式。在不同型号上的支持情况:
- 格式约束:Tensor 类型输入不支持
TileOpFormat.TILEOP_NZ格式。 - 整型输入约束:
- 当输入为 DT_INT16 或 DT_INT32 时,内部会将输入转换为 DT_FP32 进行计算(float32 尾数为 24 位)。在 $[-2^{24},\ 2^{24}]$ 范围内的整数可精确转换,超出范围的整数在转换时可能丢失低位精度。
- 对于 Ascend 950PR/Ascend 950DT,当输入为 DT_INT64 或 DT_UINT64 时,不进行类型转换,直接按整数除法计算。
约束规则的源码印证
上述约束第 2 条(scalar 类型检查)与第 6 条(整型转换)可在 python/pypto/op/math.py 中找到对应实现。当other不是 Tensor 时,div内部会调用_check_scalar_type("div", input.dtype, other)做类型校验,再调用_clip_scalar_to_dtype将标量裁剪到输入 dtype 对应的取值范围后,包装成pypto_impl.Element(input.dtype, other)参与计算;当other是 Tensor 时,则直接调用pypto_impl.Div(input, other, precision_type)。这说明标量除法的类型校验、裁剪和元素包装发生在 Python 前端层,而 Tensor-Tensor 除法直接透传到底层实现。
调用示例
TileShape 设置示例
调用该 operation 接口前,应通过set_vec_tile_shapes设置 TileShape。
- TileShape 维度应和输出一致。
- 非广播场景:输入 input shape 为 [m, n],other 为 [m, n],输出为 [m, n],TileShape 设置为 [m1, n1],则 m1、n1 分别用于切分 m、n 轴。
- 广播场景:输入 input shape 为 [m, n],other 为 [m, 1],输出为 [m, n],TileShape 设置为 [m1, n1],则 m1、n1 分别用于切分 m、n 轴。
pypto.set_vec_tile_shapes(4, 16)从源码看,set_vec_tile_shapes定义于 python/pypto/_controller.py,它接受可变数量的整型参数(也支持SymbolicScalar,内部通过concrete()求值),并通过pypto_impl.SetScope({"vec_tile_shapes": concrete_shapes})写入当前编译作用域,供后续向量算子的 Tile 切分使用;对应的读取接口为pypto.get_vec_tile_shapes()。
接口调用示例
基本用法(默认使用高精度模式)
a = pypto.tensor([1, 3], pypto.DT_FP32) b = pypto.tensor([1, 3], pypto.DT_FP32) out = pypto.div(a, b) # 默认使用HIGH_PRECISION模式结果示例如下:
输入数据a: [[2.0 4.0 6.0]] 输入数据b: [[2.0 2.0 2.0]] 输出数据out: [[1.0 2.0 3.0]]显式指定高精度模式
a = pypto.tensor([1, 3], pypto.DT_FP16) b = pypto.tensor([1, 3], pypto.DT_FP16) out = pypto.div(a, b, pypto.PrecisionType.HIGH_PRECISION)使用指令模式
a = pypto.tensor([1, 3], pypto.DT_FP32) b = pypto.tensor([1, 3], pypto.DT_FP32) out = pypto.div(a, b, pypto.PrecisionType.INTRINSIC)使用运算符(自动使用高精度模式)
a = pypto.tensor([1, 3], pypto.DT_FP16) b = pypto.tensor([1, 3], pypto.DT_FP16) out = a / b # 自动使用HIGH_PRECISION模式 out = a.div(b) # 自动使用HIGH_PRECISION模式其中a / b与a.div(b)都经由 python/pypto/tensor.py 中Tensor.div方法转发到模块级pypto.div,因此同样默认采用 HIGH_PRECISION 模式。
精度模式选择建议
结合 PrecisionType 文档 中的使用建议,可按下述原则选择精度模式:
- 默认行为:不指定精度模式时,默认使用
HIGH_PRECISION模式,以确保计算精度。 - 精度要求高的场景:推荐使用
HIGH_PRECISION模式,可以有效减少精度损失,提高计算结果的准确性。 - 对精度要求不高但追求性能的场景:可以使用
INTRINSIC模式,直接使用芯片指令进行计算。 - 注意平台限制:HIGH_PRECISION 仅在 Ascend 950PR/Ascend 950DT 上受支持;在 Atlas A3、A2 系列上请使用 INTRINSIC 模式。
除div外,PrecisionType同样作用于 fmod(取模)、remainder(余数)、pow(幂)、exp(指数)、sqrt(开方)、rsqrt(开方倒数)、log/log2/log10(对数)、reciprocal(倒数)等元素级算子,选择逻辑可复用。
实战进阶:结合循环、视图与 assemble 的完整 Kernel 写法
pypto.div通常不会孤立使用,而是作为向量 Kernel 的算子片段出现在 Tile 化编程中。以仓库系统测试 python/tests/st/operation/vector/test_div.py 中的div_2d_2input_kernel为例,其完整流程为:
- 在
@pypto.frontend.jit装饰的 Kernel 函数内,先调用pypto.set_vec_tile_shapes(*config.tile_shape)设置 TileShape; - 通过
pypto.loop按 execution view shape 切分循环; - 对广播场景,将 shape 为 1 的轴 offset 置 0(对应代码中的
0 if config.input_shapes[0][axis] == 1 else offsets[axis]),用pypto.view取输入视图; - 调用
pypto.div(input0_view, input1_view)得到结果视图; - 通过
pypto.assemble(result, output_offset, output)将结果写回输出 Tensor。
对应的测试用例定义在 python/tests/st/operation/vector/vector_testcase/div_test_case.py,其中两个典型用例分别是:
Div_test_14:input0 shape 为 (16, 512)(fp32),input1 shape 为 (16, 1)(fp32),输出 shape 为 (16, 512)——这是一个典型的列广播除法用例,view_shape为 (5, 152),tile_shape为 (33, 32);Div_test_15:input0 与 input1 均为 (2048, 127, 1)(fp32),输出 (2048, 127, 1)——三维元素级除法,view_shape为 (460, 32, 2),tile_shape为 (34, 8, 2)。
测试通过torch.div(*inputs_cpu)生成期望结果,并在 NPU 上执行 Kernel 后与期望值对比(assert_outputs),验证广播除法与逐元素除法的正确性。这套“TileShape + loop + view + div + assemble”的组合写法,正是 PyPTO 向量编程的标准范式。
常见问题与注意事项
- Shape 限制:
input与other均不支持空 Tensor,支持 1-4 维,Shape Size 不能超过 INT32_MAX(2147483647)。Tensor 之间广播后形状不一致会触发广播失败错误。 - 格式限制:Tensor 输入不支持
TileOpFormat.TILEOP_NZ格式,请使用 ND 等兼容格式。 - 整型除法精度:DT_INT16/DT_INT32 输入会先转 DT_FP32 计算再输出 DT_FP32,超出 $[-2^{24}, 2^{24}]$ 的整数可能丢失低位精度;若需要 64 位整型精确除法,请确认目标产品为 Ascend 950PR/Ascend 950DT(支持直接整数除法)。
- 标量类型:整型 Tensor 与浮点标量相除会报错;浮点 Tensor 与整型标量相除时标量会自动转为浮点。
- 产品差异:HIGH_PRECISION 模式与 DT_INT64/DT_UINT64 支持仅限 Ascend 950 系列,跨平台开发时建议按产品分支适配,或直接使用 INTRINSIC 指令模式保证兼容性。
小结
pypto.div是 CANN PyPTO 向量编程中最常用的元素级除法算子,支持 Tensor-Tensor、Tensor-标量以及广播除法三种形态,并可通过PrecisionType在精度与性能之间权衡。本文完整覆盖了它的产品支持、函数原型、参数语义、返回值、约束规则与调用示例,并结合仓库源码(math.py、tensor.py、_controller.py)与系统测试(test_div.py)给出了底层实现与实战写法的印证。开发者可直接以本文的示例为模板,结合set_vec_tile_shapes、loop、view、assemble组合出完整的除法 Kernel。
- 人工智能
- 编译器
- 模型编译
- 高性能计算
- 深度学习
- CANN
【免费下载链接】pypto
PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。
相关推荐
CANN PyPTO 逐元素减法算子 pypto.sub:API 详解、广播规则与 TileShape 切分实践
CANN PyPTO 逐元素减法算子 pypto.sub:API 详解、广播规则与 TileShape 切分实践 pypto.sub 是 CANN PyPTO
人工智能编译器模型编译高性能计算深度学习CANNCANN PyPTO 逐元素乘法 pypto.mul 详解:接口语义、广播规则、TileShape 切分与源码验证
CANN PyPTO 逐元素乘法 pypto.mul 详解:接口语义、广播规则、TileShape 切分与源码验证 导读 pypto.mul 是 CANN Py
人工智能编译器模型编译高性能计算深度学习CANNpypto.Tensor.div 详解:CANN PyPTO 元素级除法算子的精度模式与工程实践
pypto.Tensor.div 详解:CANN PyPTO 元素级除法算子的精度模式与工程实践 导读 pypto.Tensor.div 是 CANN PyPT
人工智能编译器模型编译高性能计算深度学习CANN
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考