已开启
Feat: 新增面向arch22的aclblasCaxpy任意incx/incy支持 #334
Feat: 新增面向arch22的aclblasCaxpy任意incx/incy支持 #334
已开启
guodong54_创建于 11 天前
guodong54_
guodong54_
11 天前

Feat: 新增面向arch22的aclblasCaxpy任意incx/incy支持及动态共享跨度流水线优化

描述

背景:功能补充

CAXPY 在 2026-07 之前的实现(67fe860 之前)只支持 incx=1, incy=1 的稠密场景:CalTilingData 直接把 n 按核数均分,kernel 只有一条连续读写路径,不识别任意步长。本次改动是在此基础上做的功能补充——让 aclblasCaxpy 按 BLAS 标准语义支持任意(含负数)incx/incy,同时把由此产生的多种步长组合按访问模式分类,分别派发到代价不同的 kernel 实现,而不是所有非 1 的步长都走同一条最慢的兜底路径。

分类讨论:为什么要按 stride 组合分类派发

incx/incy 一旦允许任意值,笛卡尔积上的组合很多,但从"访存模式代价"这个维度看可以收敛成几类(见 CaxpyStrideClass):

  • DENSEincx=1, incy=1):退化到原始稠密实现,x/y 都连续,直接搬运最快,没有理由为了统一接口牺牲这条路径。
  • X_ONLY_POSITIVE / Y_ONLY_POSITIVE(一侧步长为 1,另一侧为正数):一侧仍是连续读写,只有另一侧需要 strided gather/scatter,是"部分退化"场景。
  • DUAL_SYMMETRIC_POSITIVEincx==incy,且都为正):两侧步长相同,gather 和 scatter 用的 offset 表可以共用一份,省一次 offset 表生成。
  • DUAL_ASYMMETRIC_POSITIVE(都为正但不相等):两侧都要 strided 访问,且各自的 offset 表不同,是最一般的正步长情况。
  • NEGATIVE_MIXED(只要有一侧为负):BLAS 标准里负步长意味着逻辑索引要倒着映射到物理存储(最后一个逻辑元素在最前面的物理地址),这条语义和正步长的映射方式不同,必须单独分支,不能和正步长场景混在一套 offset 计算里。

分类之后,在真正的 strided 场景内部,进一步按"每核平均分到的元素数"分两条腿:

  • 数据量很小、每核分不到 CAXPY_STRIDED_SCALAR_MAX_PER_BLOCK(16)个元素时,走 STRIDED_SCALAR——用双缓冲/流水线的开销比数据量本身还大,标量逐元素处理更划算。
  • 数据量足够大时,才值得上流水线,此时再分 shared 和 disjoint 两种 tile 策略(见下)。

这一层分类判断本身不涉及任何具体的性能调优,只是把 BLAS 语义要求的步长组合按访存代价归类,让后面的 kernel 选择逻辑(SelectCaxpyKernelVariant)能对"这批数据该用哪种搬运方式"做出针对性判断,而不是所有非稠密场景共用一个保守兜底实现。

在此基础上的性能优化:动态共享跨度流水线

shared span-read pipeline 的可用范围从固定 |incx|<=9 改为运行时动态计算的 CaxpySharedTileCapacity(|incx|),tile 容量随 |incx| 收缩以保证跨度读取仍落在 38KiB lowScratch 缓冲区内:

tileCapacity = min(512, floor((38912/8 - 1) / |incx|) + 1)

通过 CaxpyTilingData.sharedTileCapacity 把这个运行时容量从 host 传到 device,shared pipeline 的 ping-pong 加载/计算/存储改用该值而非硬编码 512;disjoint 路径不受影响。

最终派发再叠加一个实测得到的性能上限 CAXPY_SHARED_SPAN_PERFORMANCE_MAX_INCREMENT=60incx<=60 走 shared,incx>=61 走 disjoint。同设备、同 Release 构建、n=1048576 稳态 A/B 测得 incx=16/32/41 比 disjoint 快约 10%~18%,incx=50/55 快约 4%,incx=60 附近打平,incx=150 在这个上限之外维持在旧基线噪声范围内(约 490µs)。

测试基础设施迁移

原分支的功能测试是硬编码 C++ 数组 + 手写 main()。核对同为 arch22 complex level-1 算子的邻近实现后发现,仓库里更新的算子(如 cdgmm)已经统一改用 CSV + GoogleTest 参数化用例(GetCasesFromCsv + BlasTest<Param> fixture),本次交付照此约定把 CAXPY 的测试迁移过去:拆出 caxpy_param.h(CSV 行解析)、caxpy_golden.h(host 端参考实现)、caxpy_npu_wrapper.h(设备内存管理封装)、caxpy_test.csv(原 78 个用例 1:1 迁移,覆盖 dense/strided/负 stride/多核/多wave/shared-tile-tail 及本次新增的动态阈值边界)。

关联的Issue

无(功能补充 + 性能优化 + 测试基础设施对齐,非 Issue 驱动)。

测试

  • 基线:upstream/master(官方 cann/ops-blas),release 分支从此处拉平并 squash 为若干阶段性提交(功能实现 / UB 布局重构 / 动态 tile 性能优化 / 50 行函数限制重构 / CSV 测试迁移)。
  • 每次改动均在最终精确 commit 上从零 git archive + 容器内解压 + Release 构建 + 运行,不复用早期或未 squash 分支的测试结果作为证据。
  • 最终验证(Ascend 910B3 / CANN 9.0 A3,容器 cann9-a3-test-priv,Release 构建):
    • caxpy_test:80/80 通过(78 个 CSV 参数化用例,覆盖上述全部 stride 分类及正负步长组合 + 2 个 null 校验用例)。
    • caxpy_dispatch_policy_test:独立运行 EXIT_0
    • git diff --check 无空白错误;git diff upstream/master caxpy-release 仅覆盖 CAXPY 相关文件。
  • 性能证据(同设备,Release 构建,warmup=200 iterations=2000n=1048576 稳态):
    • incx=16/32/41:动态 shared 比旧固定阈值 disjoint 快约 10%~18%。
    • incx=50/55:快约 4%。
    • incx=60:噪声范围内持平(cross-over 点)。
    • incx=150:回到旧基线噪声范围内(约 490µs vs 502µs)。

文档更新

无独立文档改动;stride 分类依据、动态容量公式、性能上限的来源已作为代码注释写入 caxpy_dispatch_policy.hcaxpy_kernel.cpp

类型标签

likedislike
合并受阻
guodong54_guodong54_
11 天前 创建了 pull request,commit 3a45bc75
atomgit-bot
atomgit-bot
11 天前 评论:

变更摘要

该 PR 面向 arch22aclblasCaxpy 补充 BLAS 标准语义下的任意(含负数)incx/incy 支持,并在此基础之上引入按步长访存代价分类派发与动态共享跨度流水线优化。改动新增 caxpy_dispatch_policy.h 定义 CaxpyStrideClassCaxpyKernelVariantSelectCaxpyKernelVariant 等派发策略,重构 caxpy_host.cpp 以完成参数校验、mask 偏移表缓存、分块调度与多 kernel 入口选择,同时新增 caxpy_tiling_data.h 统一 host/device 共享的 tiling 布局,并将测试迁移为 CSV 参数化用例与独立的派发策略单测。

主要改动

  • 步长分类与 kernel 派发策略: 新增 caxpy_dispatch_policy.h,通过 ClassifyCaxpyStrideincx/incy 归入 DENSEX_ONLY_POSITIVEY_ONLY_POSITIVEDUAL_SYMMETRIC_POSITIVEDUAL_ASYMMETRIC_POSITIVENEGATIVE_MIXED 六类,并由 SelectCaxpyKernelVariant 按数据量、负步长及 directStrided 等条件选择 DENSE_PIPELINED_ATOMICSTRIDED_SCALARSTRIDED_SHARED/DISJOINT 等 variant。

  • 动态共享跨度 tile 容量与性能上限: 新增 CaxpySharedTileCapacity(|incx|),将共享流水线可用范围从固定阈值改为按 38KiB lowScratch 缓冲区动态收缩 tile,并结合 CAXPY_SHARED_MIN_USABLE_TILE_CAPACITY 正确性下限与 CAXPY_SHARED_SPAN_PERFORMANCE_MAX_INCREMENT=60 实测性能上限,通过 UseCaxpySharedXSpanPipeline 决定 shared/disjoint 路径。

  • Host 侧执行流程重构: caxpy_host.cpp 新增 ValidateCaxpyArgumentsBuildCaxpyExecutionGetCaxpyMaskCacheLaunchCaxpy 等函数,实现参数与地址跨度校验、按 |incx|/|incy| 缓存 mask 偏移表、负步长物理索引映射 PhysicalIndex,以及 strided 路径下 prefix/tail 分段调度;非 strided 场景通过 packX/packY 将向量打包后回退稠密 kernel。

  • Tiling 数据布局统一: 新增 caxpy_tiling_data.h,以 CaxpyTilingData 结构体作为 host 与 device 共享的单一布局,首字通过 packedFloatCount/activeBlocks 联合体复用,新增 totalNincxincysharedTileCapacity 字段,并用 static_assert 固定各字段偏移量以避免两侧字节偏移漂移。

  • Handle 缓存与测试基础设施: _aclblas_handle 新增 caxpy_mask_cachecaxpy_mask_cache_incxcaxpy_mask_cache_incy 字段并在 aclblasDestroy 中释放缓存;测试侧新增 caxpy_dispatch_policy_test.cpp 覆盖分类与派发策略,新增 caxpy_npu_wrapper.hcaxpy_golden.hcaxpy_param.h,并将 caxpy_test.cpp 迁移为带 guard 区的 CSV 参数化用例。

likedislike
atomgit-bot
atomgit-bot
11 天前 评论:

代码审查

✅ 未发现问题

likedislike
CANN-robotCANN-robot成员
11 天前 添加了label:stat/needs-squash
CANN-robotCANN-robot成员
11 天前 添加了label:cann-cla/yes
CANN-robot
CANN-robot成员
11 天前 评论:

Thanks for your pull-request.
The full list of commands accepted by me can be found at here
You can get sig-info at here


PR Approval Progress

⚠️ This PR does not yet meet the following requirements:lgtm (requires ≥ 2 person(s) per module)、approve (requires ≥ 1 person(s) per module)

Module Approval Details

module lgtm status approve status
repo-cann/ops-blas ❌ (0/2)(You can also ask: xutianze, 王子韬, 尹祺然, 唐超力, zizhongchen) ❌ (0/1)(You can also ask: 王子韬, 朱志明, 尹祺然, chenbinbin199309, 张浩)

💡 Tip:

  • Committer can comment /approve or /lgtm
  • Commenting /approve implies both code review (lgtm) and intent to merge (approve)

CLA Signature Pass

guodong54_, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
CANN-robotCANN-robot成员
11 天前 将chenbinbin199309,luowen203_gg123,QK_25415,MaskHunter2008,songkai111,xutianze,wangzitao_leo,nino888,zhaoyingchao2,demoauguste,zizhongchen设为评审人
CANN-robotCANN-robot成员
11 天前 将chenbinbin199309,luowen203_gg123,QK_25415,MaskHunter2008,songkai111,xutianze,wangzitao_leo,nino888,zhaoyingchao2,demoauguste,zizhongchen设为审查人
guodong54_guodong54_
11 天前 修改了pull request 的描述
guodong54_
guodong54_
11 天前 评论:

/compile

likedislike
CANN-robotCANN-robot成员
11 天前 添加了label:ci-pipeline-running
CANN-robot
CANN-robot成员
11 天前 评论:

流水线任务触发成功
任务链接 [b1b330ecae1842979a36e9ceb091263d][流水线指导]

任务名称状态日志下载链接
Compile_Ascend_X86_A2 ✅ SUCCESS >>>>> >>>>>
Compile_Ascend_X86_A5 ✅ SUCCESS >>>>> >>>>>
Compile_Ascend_ARM_A2 ✅ SUCCESS >>>>> >>>>>
Compile_Ascend_ARM_A5 ✅ SUCCESS >>>>> >>>>>
codecheck ❌ FAILED >>>>>
SCA ✅ SUCCESS >>>>>
antipoison ✅ SUCCESS >>>>>
pre_comment ✅ SUCCESS >>>>>
Compile_Ascend_X86_A2_ubuntu24 ✅ SUCCESS >>>>> >>>>>
Compile_Ascend_X86_A5_ubuntu24 ✅ SUCCESS >>>>> >>>>>
Compile_Ascend_ARM_A2_ubuntu24 ✅ SUCCESS >>>>> >>>>>
Compile_Ascend_ARM_A5_ubuntu24 ✅ SUCCESS >>>>> >>>>>
codecheck_codestyle ⚠️ WARNING >>>>>
precommit ⚠️ WARNING >>>>> >>>>>
likedislike
CANN-robotCANN-robot成员
11 天前 删除了label:ci-pipeline-running
CANN-robotCANN-robot成员
11 天前 添加了label:ci-pipeline-failed