ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

pyasc 反正弦算子 asin 接口全解析:从 Python 调用到 Ascend C 代码发射

pyasc 反正弦算子 asin 接口全解析:从 Python 调用到 Ascend C 代码发射 pyasc 反正弦算子 asin 接口全解析从 Python 调用到 Ascend C 代码发射【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc本篇技术指南围绕 CANN pyasc 项目中高级向量数学接口asc.language.adv.asin按元素反正弦计算展开完整讲解其函数签名、参数语义、地址对齐约束与临时缓冲区temp_buffer使用方式并结合仓库源码揭示从 Python 侧math_op_impl到create_asc_AsinOp、再到 Ascend CAsin模板函数的底层调用链与代码发射原理。读者读完本篇后将掌握在asc.jit内核中正确使用asc.adv.asin进行逐元素反正弦计算的方法并能举一反三理解 pyasc 高级数学算子家族acos/acosh/atan/atanh 等的统一实现模式。接口概述面向昇腾 AI 处理器的逐元素反正弦算子asc.language.adv.asin是 pyasc 为 Python 开发者提供的昇腾 AI 处理器向量计算接口与 Ascend C 中的Asin接口一一对应遵循 Python 原生语法。其功能为按元素对输入张量做反正弦arcsine函数计算即对源操作数中的每个元素 x 计算arcsin(x)结果写入目的操作数。该接口位于python/asc/language/adv/__init__.py的导出列表中与asin、asinh一同导出实际实现定义在 python/asc/language/adv/math.py归属于 pyasc 的「高级adv」向量数学算子集合。函数签名asc.language.adv.asin(dst: LocalTensor, src: LocalTensor, count: int | None None, temp_buffer: LocalTensor | None None, is_reuse_source: bool False) → None从源码 math.py 可以看到该函数同时声明了overload版本与正式实现版本后者使用RuntimeInt、RuntimeBool等 IR 运行时类型以支持在 JIT 编译期内联常量并通过require_jit装饰器要求仅在asc.jit内核上下文中调用overload def asin(dst: LocalTensor, src: LocalTensor, count: Optional[int] None, temp_buffer: Optional[LocalTensor] None, is_reuse_source: bool False) - None: ... require_jit set_math_docstring(api_nameAsin, append_text按元素做反正弦函数计算。) def asin(dst: LocalTensor, src: LocalTensor, count: Optional[RuntimeInt] None, temp_buffer: Optional[LocalTensor] None, is_reuse_source: RuntimeBool False) - None: math_op_impl((dst, src), count, temp_buffer, is_reuse_source, create_asc_AsinOp)对应的 Ascend C 函数原型pyasc 的asin封装了 Ascend C 中Asin的 4 种模板重载对应不同的临时缓冲区与计算个数组合在 utils.py 的set_math_docstring中由api_nameAsin动态生成最终呈现为以下 C 原型template typename T, bool isReuseSource false __aicore__ inline void Asin(const LocalTensorT dstTensor, const LocalTensorT srcTensor, const LocalTensoruint8_t sharedTmpBuffer, const uint32_t calCount) template typename T, bool isReuseSource false __aicore__ inline void Asin(const LocalTensorT dstTensor, const LocalTensorT srcTensor, const LocalTensoruint8_t sharedTmpBuffer) template typename T, bool isReuseSource false __aicore__ inline void Asin(const LocalTensorT dstTensor, const LocalTensorT srcTensor, const uint32_t calCount) template typename T, bool isReuseSource false __aicore__ inline void Asin(const LocalTensorT dstTensor, const LocalTensorT srcTensor)也就是说Python 侧参数dst/src/temp_buffer/count/is_reuse_source分别映射到 C 侧的dstTensor/srcTensor/sharedTmpBuffer/calCount/isReuseSource模板参数。sharedTmpBuffer的类型固定为LocalTensoruint8_t即临时缓冲按字节寻址。参数说明dst目的操作数。类型为LocalTensor支持的 TPosition 为VECIN/VECCALC/VECOUT。src源操作数。类型为LocalTensor支持的 TPosition 为VECIN/VECCALC/VECOUT。源操作数的数据类型需要与目的操作数保持一致。count参与计算的元素个数类型为int可选参数默认None表示按整块计算。当输入张量长度大于实际参与计算元素数例如涉及尾块处理或 mask 场景时通过该参数精确指定计算个数。temp_buffer临时缓存类型为LocalTensor对应 C 侧LocalTensoruint8_t可选参数。由于反正弦为超越函数Ascend C 向量实现需要一块中间缓冲传入该参数可避免内部重复申请。is_reuse_source是否允许修改源操作数类型为bool默认False。置为True时允许在计算过程中复用源操作数空间可能带来性能收益但前提是调用方不关心源数据在调用后的完整性。在 math.py 的math_op_impl中可以看到这些参数的 JIT 期类型校验与 IR 物化逻辑count必须为RuntimeInt若提供则物化为int32常量temp_buffer必须为LocalTensoris_reuse_source被物化为 bit 类型。随后统一调用getattr(global_builder.get_ir_builder(), build_method)(*(t.to_ir() for t in tensors), sharedTmpBuffertemp_buffer, calCountcount, isReuseSourceis_reuse_source)其中build_method即create_asc_AsinOp说明asin与acos、acosh、atan、atanh、sin、cos等一元数学算子共享同一套参数处理框架仅通过不同的 IR Op 构建方法区分。约束说明地址重叠限制不支持源操作数与目的操作数地址重叠。临时缓冲隔离不支持temp_buffer与源操作数和目的操作数地址重叠。地址对齐要求操作数地址对齐要求请参见《Ascend C 算子开发接口》中的“通用说明和约束-通用地址对齐约束”。从约束可以看出asin属于破坏性向量计算temp_buffer在计算过程中会写入中间结果因此必须与输入输出张量在内存空间上完全隔离同时is_reuse_sourceTrue仅放宽源可被修改的限制并不解除地址重叠的禁止项。调用示例以下示例继承自接口文档asc.language.adv.asin展示了在 pyasc 算子内核中使用 TQue 申请临时缓冲并调用asc.adv.asin的标准流程pipe asc.Tpipe() tmp_que asc.TQue(asc.TPosition.VECCALC, 1) pipe.init_buffer(quetmp_que, num1, lenbuffer_size) # buffer_size 通过Host侧tiling参数获取 shared_tmp_buffer tmp_que.alloc_tensor(asc.uint8) # 输入tensor长度为1024算子输入的数据类型为half实际计算个数为512 asc.adv.Asin(dst, src, count512, temp_buffershared_tmp_buffer)要点解读临时缓冲必须显式管理通过asc.TQue(asc.TPosition.VECCALC, 1)在 VECCALC 位置创建深度为 1 的队列再由pipe.init_buffer按buffer_size由 Host 侧 tiling 参数计算得出单位为字节初始化最后alloc_tensor(asc.uint8)申请出 byte 型临时张量。这与 C 侧sharedTmpBuffer的uint8_t类型严格对应。count 用于尾块/部分计算当输入张量长度1024 个 half 元素大于实际计算个数512时通过count512精确控制剩余元素不参与反正弦计算。两种省略形式temp_buffer与count均可省略。Ascend C 提供的 4 种重载在 Python 侧表现为(dst, src)、(dst, src, count...)、(dst, src, temp_buffer...)、(dst, src, count..., temp_buffer...)四种组合。与单元测试中的最小内核对应仓库单元测试 python/test/unit/language/adv/test_ops.py 给出了可直接运行的最小 JIT 内核验证了asin的两种调用形态带/不带临时缓冲def test_asin_kernel(mock_launcher_run): asc.jit def asin_kernel(): x_local asc.LocalTensor(dtypeasc.float16, posasc.TPosition.VECIN, addr0, tile_size512) z_local asc.LocalTensor(dtypeasc.float16, posasc.TPosition.VECOUT, addr0, tile_size512) tmp asc.LocalTensor(dtypeasc.uint8, posasc.TPosition.VECCALC, addr0, tile_size512) asc.adv.asin(z_local, x_local, count512, temp_buffertmp) asc.adv.asin(z_local, x_local, count512) asin_kernel[1]() assert mock_launcher_run.call_count 1该测试同时验证了输入输出数据类型为float16half且保持一致、temp_buffer使用uint8类型、count512与tile_size512一致且一次内核调用中可先后执行两次asin一次带临时缓冲、一次不带两者编译共存而互不干扰。源码级实现Python 接口如何发射为 Ascend C 代码从 Python 调用到 IR Opasc.adv.asin(dst, src, ...)的调用链为内核函数被asc.jit装饰后进入 pyasc 的 codegen 阶段python/asc/codegenmath_op_impl将dst、src通过LocalTensor.to_ir()物化为 IR 值并附带sharedTmpBuffer、calCount、isReuseSource三个关键字参数通过global_builder.get_ir_builder()调用create_asc_AsinOp在 IR 中创建ascendc::AsinOp在发射阶段lib/Target/AscendC/Translation.cpp 中将ascendc::AsinOp与 Ascend C 的Asin模板函数绑定。从该文件可以看到AsinOp与AcosOp、AcoshOp、AsinhOp、AtanOp、AtanhOp等一同注册为 UnaryMathOp一元数学算子族由统一的发射逻辑生成AsinT(dstTensor, srcTensor, sharedTmpBuffer, calCount)形式的 C 内核代码生成的 C 代码最终经昇腾编译工具链编译为 AI Core 指令在 Vector 计算单元上完成逐元素反正弦计算。文档字符串的自动生成机制值得关注的是asin的接口文档即关联文档 asc.language.adv.asin本身也是由代码生成的装饰器set_math_docstring(api_nameAsin, append_text按元素做反正弦函数计算。)会调用 utils.py 中的set_math_docstring根据api_name动态拼接 4 个 Ascend C 原型、参数说明、约束说明再结合append_text生成接口简介。这就是为什么asin与acos等接口的文档结构高度一致——它们共享同一套文档模板仅 API 名称与功能描述不同。这也意味着阅读本篇对asin的理解可以直接迁移到整个一元数学算子家族。在真实算子工程中的落地建议结合文档示例与测试用例在完整算子例如基于 examples 中算子工程的 快速入门 模式中使用asin的推荐流程如下Host 侧 tiling在 tiling 阶段根据输入 shape 计算buffer_size临时缓冲字节数与calCount实际参与计算的元素个数通过 tiling 结构体传给内核设备侧初始化创建asc.Tpipe()与asc.TQue(asc.TPosition.VECCALC, 1)pipe.init_buffer申请临时缓冲alloc_tensor(asc.uint8)得到temp_buffer张量准备通过asc.data_copy等接口将 Global Memory 输入搬运到 VECIN 位置的LocalTensorsrc确保dst与src数据类型一致如均为asc.float16且地址不重叠调用计算asc.adv.asin(dst, src, countcal_count, temp_buffershared_tmp_buffer)结果回写将dst从 VECOUT 拷贝回 Global Memory供 Host 侧获取。注意事项清单若尾块元素数不足整块大小务必使用count指定实际个数避免对未初始化数据做无效计算当多个算子交替使用同一块临时缓冲时需通过 TQue 的队列深度与同步机制参见 fwk.md 中 TQue/Tpipe 相关接口保证读写次序防止temp_buffer被并发复用若源数据在本次计算后不再使用可将is_reuse_source置为True以放宽实现优化空间否则保持默认False并注意它不豁免源/目的地址不得重叠的硬约束涉及局部地址偏移的张量切片使用时需满足 Ascend C 通用地址对齐约束操作数首地址对齐要求与数据类型相关详见《Ascend C 算子开发接口》通用说明章节。总结asc.language.adv.asin是 pyasc 高级向量数学算子家族的标准成员它以极简的 Python 签名dst、src、可选count/temp_buffer/is_reuse_source封装了 Ascend CAsin的 4 种模板重载通过math_op_impl→create_asc_AsinOp→Translation.cpp的统一流水线完成 IR 构建与 C 代码发射。其核心使用要点包括源/目的数据类型一致、地址与临时缓冲不重叠、count精确控制计算元素个数、临时缓冲通过 TQue 在 VECCALC 位置显式管理。掌握该接口的使用与实现即可顺藤摸瓜理解acos、asinh、atan、atanh等全部一元超越函数算子的相同模式。【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表