ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

pyasc proposal_concat 接口详解:将连续元素合入 Region Proposal 指定字段(昇腾 AI 处理器算子开发)

pyasc proposal_concat 接口详解:将连续元素合入 Region Proposal 指定字段(昇腾 AI 处理器算子开发) pyasc proposal_concat 接口详解将连续元素合入 Region Proposal 指定字段昇腾 AI 处理器算子开发【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyascasc.language.basic.proposal_concat是 pyasc 中面向目标检测 Region Proposal区域建议场景的基础向量算子接口用于将一段连续排列的元素批量合入目的操作数中 Region Proposals 的指定字段位置其语义与 Ascend C 的AscendC::ProposalConcat一一对应。本文基于当前仓库的接口文档与源码实现完整讲解该接口的函数原型、参数取值、数据布局规则、使用约束并结合仓库中的 IR 定义、代码生成测试与单元测试还原从 Python 调用到 Ascend C 代码生成的完整链路帮助开发者在 pyasc 内核中正确、安全地组织 Region Proposal 数据。一、功能定位Region Proposal 数据操作族的一员在目标检测如 Faster R-CNN 的 RPN 阶段中网络会产出大量 Region Proposal每个 Proposal 通常由 6 个字段组成左上角坐标x1、y1右下角坐标x2、y2置信度score与类别标签label。这类数据在 Ascend C 中的典型组织方式是按 proposal 分组的内存布局而参与计算的张量往往只有某一类字段例如只有 score因此需要专门的接口完成两类布局之间的合入concat与抽取extract。proposal_concat的功能是将连续元素合入 Region Proposal 内对应位置每次迭代会将 16 个连续元素合入到 16 个 Region Proposals 的对应位置里。在 pyasc 的asc.language.basic模块中它与下列接口共同构成 Region Proposal / 排序类操作族proposal_extract功能与proposal_concat相反从 Region Proposals 内将相应位置的单个元素抽取后重排每次迭代处理 16 个 Region Proposals抽取 16 个元素后连续排列rp_sort16根据 Region Proposals 中的score域对其排序score 大的排前面每次排 16 个 Region Proposalssort/sort32/mrg_sort/mrg_sort4通用降序排序与多路归并排序接口get_sort_len/get_sort_offset/get_mrg_sort_result排序结构辅助接口。接口总览见 basic 模块 API 索引proposal_concat与proposal_extract分别对应其中的合入与抽取两个方向二者配合rp_sort16等排序接口即可搭建 RPN 打分-排序-重组的完整数据通路。二、函数原型与对应的 Ascend C 函数Python 接口签名如下def proposal_concat(dst: LocalTensor, src: LocalTensor, repeat_time: int, mode_number: int) - None参数说明LocalTensor定义见 LocalTensor 文档dst目的操作数LocalTensor类型内存中按 Region Proposal 分组存放每个 Proposal 含 6 个字段。src源操作数LocalTensor类型存放连续排列的目标字段元素数据类型需要与 dst 保持一致。repeat_time重复迭代次数。每次迭代完成 16 个元素合入到 16 个 Region Proposals 里下次迭代跳至相邻的下一组 16 个 Region Proposals 和下一组 16 个元素。取值范围repeat_time ∈ [0, 255]。mode_number合入位置参数取值范围mode_number ∈ [0, 5]指定 16 个元素具体合入 dst 中每个 Proposal 的哪个字段0合入x11合入y12合入x23合入y24合入score5合入label该接口与 Ascend C 的原型完全对应template typename T __aicore__ inline void ProposalConcat(const LocalTensorT dst, const LocalTensorT src, const int32_t repeatTime, const int32_t modeNumber)从原型可见Ascend C 侧以模板参数T决定元素类型而 pyasc 侧的元素类型由两个LocalTensor声明时指定的 dtype 共同决定——这也是src 与 dst 数据类型必须一致这一约束的来源。2.1 数据布局与迭代次数怎么算结合接口语义可以推断出如下布局关系dst 按 proposal 连续存放每个 proposal 占 6 个元素x1/y1/x2/y2/score/label因此 dst 的有效长度至少为16 × repeat_time × 6个元素src 是连续字段流有效长度至少为16 × repeat_time个元素第i次迭代i从 0 开始读取 src 中第[i×16, i×1615]个元素分别写入 dst 中第[i×16, i×1615]个 proposal 的mode_number对应字段位置。因此若需合入 N 个 proposal 的同一字段应取repeat_time ceil(N / 16)且 N 向上取整到 16 的倍数后不超过 16×2554080超过时需分段调用。三、约束说明越界与对齐接口文档给出的约束必须逐条遵守否则会出现 tensor 越界错误dst 容量约束用户需保证 dst 中存储的 proposal 数目大于等于实际所需数目即不小于16 × repeat_time个 proposal否则存在 tensor 越界错误src 容量约束用户需保证 src 中存储的元素大于等于实际所需数目即不小于16 × repeat_time个元素否则存在 tensor 越界错误地址对齐约束操作数地址对齐要求参见《Ascend C 算子开发接口》中的通用说明和约束-通用地址对齐约束即 LocalTensor 地址需满足向量接口通用 32 字节对齐要求。在 pyasc 中通过asc.LocalTensor(..., addr..., tile_size...)声明时地址与长度的取法同样受该约束限制。四、调用示例最小调用示例接口文档示例asc.proposal_concat(dst, src, repeat_time2, mode_number4)即将 src 中前 32 个连续元素分两次迭代合入 dst 中前 32 个 Region Proposals 的score字段mode_number4。结合 pyasc 的 JIT 内核写法仓库单元测试 test_common_api.py 给出了一个可直接运行的完整形态asc.jit def kernel_proposal_concat() - None: dst asc.LocalTensor(dtypeasc.float16, posasc.TPosition.VECOUT, addr0, tile_size256) src asc.LocalTensor(dtypeasc.float16, posasc.TPosition.VECIN, addr0, tile_size256) asc.proposal_concat(dst, src, repeat_time2, mode_number4) kernel_proposal_concat[1]() # 在 1 个 AI Core 上启动内核要点两个操作数均为LocalTensordtype 一致asc.float16分别绑定VECOUT/VECIN位置repeat_time2表示合入 2 组、共 32 个 proposal 的score字段故 dst 需容纳 32×6 个元素的 proposal 区示例中按 256 元素分配满足容量约束该测试通过 mock launcher 断言内核被正确编译与启动验证了接口在asc.jit装饰的函数体内可直接调用。五、源码级实现链路从 Python 调用到 Ascend C 代码生成从源码结构看pyasc 将proposal_concat实现为前端包装 → IR Op → 后端代码发射三层链路Python 前端proposal.py 中定义了该接口装饰器require_jit保证它只能在asc.jit编译上下文中调用set_common_docstring(api_nameproposal_concat)负责把接口文档同步到 docstring生成的 API 文档即由此产生。函数体将repeat_time、mode_number通过materialize_ir_value物化后调用create_asc_ProposalConcatOp创建 IR 操作require_jit set_common_docstring(api_nameproposal_concat) def proposal_concat(dst: LocalTensor, src: LocalTensor, repeat_time: RuntimeInt, mode_number: RuntimeInt) - None: global_builder.get_ir_builder().create_asc_ProposalConcatOp(dst.to_ir(), src.to_ir(), _mat(repeat_time).to_ir(), _mat(mode_number).to_ir())IR 层定义该操作定义在 OpProposal.tdOp 名称为proposal_concat携带[AscFunc]接口并绑定发射名ProposalConcat操作数依次为dst、src两个 LocalTensor 及repeatTime、modeNumber两个任意整型操作数——这与 Ascend C 原型中的const int32_t参数一一对应def AscendC_ProposalConcatOp : VectorOpproposal_concat, ProposalConcat, [AscFunc] { let description Merge continuous elements into the corresponding positions within the Region Proposal; let arguments (ins AscendC_LocalTensor:$dst, AscendC_LocalTensor:$src, AnyType:$repeatTime, AnyType:$modeNumber); }其反向接口proposal_extract在同一文件中以完全对称的方式定义OpProposal.td。后端代码发射仓库的 lit 测试 vec_proposal.mlir 用 FileCheck 固化了最终生成结果——ascendc.proposal_concat操作被翻译为对AscendC::ProposalConcat的直接调用repeat_time、mode_number作为int32_t常量传参func.func emit_proposal_concat(%arg0: memref?xui64, 22) { ascendc.set_ffts_base_addr %arg0 : memref?xui64, 22 %c256 emitc.constant() {value 256 : ui32} : () - ui32 %c0 emitc.constant() {value 0 : ui32} : () - ui32 %c2_i32 arith.constant 2 : i32 %c4_i32 arith.constant 4 : i32 %dst ascendc.local_tensor_v2 vecout, %c0, %c256 : !ascendc.local_tensor*xf16 %src ascendc.local_tensor_v2 vecin, %c0, %c256 : !ascendc.local_tensor*xf16 ascendc.proposal_concat %dst, %src, %c2_i32, %c4_i32 : !ascendc.local_tensor*xf16, !ascendc.local_tensor*xf16, i32, i32 return }对应的 CHECK 结果确认最终 C 代码为AscendC::LocalTensorhalf v4 AscendC::LocalTensorhalf(AscendC::TPosition::VECOUT, v3, v2); AscendC::LocalTensorhalf v5 AscendC::LocalTensorhalf(AscendC::TPosition::VECIN, v3, v2); AscendC::ProposalConcat(v4, v5, c2_i32, c4_i32);这说明 pyasc 生成的内核与直接手写AscendC::ProposalConcat的代码在语义上完全等价开发者可以把 pyasc 接口视作 Ascend C 模板函数的类型安全 Python 封装。六、与 proposal_extract 的对照及典型用法proposal_concat合入与proposal_extract抽取互为逆操作二者参数结构完全相同dst、src、repeat_time ∈ [0,255]、mode_number ∈ [0,5]区别仅在于数据流方向接口数据方向典型场景proposal_concatsrc连续字段流→ dstproposal 分组的指定字段把网络算出的 32 个连续 score 合入 32 个 proposal 的 score 域proposal_extractsrcproposal 分组的指定字段→ dst连续字段流把 32 个 proposal 的 score 域抽出为连续张量供rp_sort16/sort等排序接口使用可以推断在 RPN 类融合算子中二者常与rp_sort16组合使用先用proposal_extract取 score 域连续化 → 排序取 topN 索引 → 再按索引重组或由sort/mrg_sort完成。mode_number的六个取值0~5 对应 x1/y1/x2/y2/score/label使同一套接口能覆盖所有字段的重排需求无需为每个字段编写单独的搬运逻辑。七、关键文件索引接口文档asc.language.basic.proposal_concat.mdPython 前端实现proposal.pyIR Op 定义OpProposal.td代码生成测试vec_proposal.mlir单元测试test_common_api.py反向接口文档asc.language.basic.proposal_extract.md综上proposal_concat以每次迭代 16 元素合入 16 个 Region Proposal 的指定字段为基本粒度通过repeat_time控制批量、mode_number选择字段是 pyasc 中构建目标检测 Proposal 数据通路的核心基础接口使用时务必同时满足 dst/src 的容量约束与向量接口通用地址对齐要求方可避免越界错误。【免费下载链接】pyasc本项目为Python用户提供算子编程接口支持在昇腾AI处理器上加速计算接口与Ascend C一一对应并遵守Python原生语法。项目地址: https://gitcode.com/cann/pyasc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表