gbmv算子实现
概述
BLAS gbmv算子实现。
gbmv(General Banded Matrix-Vector Multiplication)算子实现了带状矩阵与向量的乘法运算,针对带状矩阵的稀疏存储特性进行了优化,支持转置操作和多核并行归约。
产品支持情况
| 产品 | 是否支持 |
|---|---|
| Ascend 950PR/Ascend 950DT | ✓ |
| Atlas A3 训练系列产品/Atlas A3 推理系列产品 | ✓ |
| Atlas A2 训练系列产品/Atlas A2 推理系列产品 | ✓ |
目录结构介绍
blas/gbmv/
├── README.md // 说明文档
└── arch35/
├── sgbmv_host.cpp // Host 侧实现
├── sgbmv_kernel.cpp // Kernel 侧实现
└── sgbmv_tiling_data.h // Tiling 数据结构
测试代码位于 test/gbmv/:
test/gbmv/
├── CMakeLists.txt // 编译工程文件
├── sgbmv_param.h // 参数结构体(继承 BlasTestParamBase)
├── sgbmv_golden.h // CPU golden(签名与 BLAS API 一致)
└── arch35/
├── sgbmv_npu_wrapper.h // NPU wrapper(封装 aclrtMalloc/H2D/kernel/D2H/free)
├── sgbmv_test.cpp // 精度测试(GTest 入口)
└── sgbmv_test.csv // 精度测试用例表
算子描述
- 算子功能:
gbmv算子实现了带状矩阵乘以向量的运算。对应的数学表达式为:
y = alpha * op(A) * x + beta * y
A为带状矩阵,x和y是向量,alpha和beta是标量,op(A)可以是A或A的转置。
带状矩阵A采用LAPACK带状存储格式,需要lda * n个元素存储,其中lda >= kl + ku + 1。元素A(i,j)存储在位置ku + i - j + j * lda,仅对满足max(0, j-ku) <= i <= min(m-1, j+kl)的位置有效。
对应的接口为:
aclblasStatus_t aclblasSgbmv(
aclblasHandle_t handle,
aclblasOperation_t trans,
int64_t m,
int64_t n,
int64_t kl,
int64_t ku,
const float *alpha,
const float *A,
int64_t lda,
const float *x,
int64_t incx,
const float *beta,
float *y,
int64_t incy);
| 参数 | gbmv 参数说明 | |||
| 参数列表 | Param. | Memory | in/out | 含义 |
| handle | in | aclbLAS 库上下文句柄。 | ||
| trans | in | 矩阵操作类型:ACLBLAS_OP_N(不转置)、ACLBLAS_OP_T(转置)、ACLBLAS_OP_C(共轭转置,实数下同T)。 | ||
| m | in | 矩阵 A 的行数。 | ||
| n | in | 矩阵 A 的列数。 | ||
| kl | in | A 的下带宽(主对角线以下的非零对角线数)。 | ||
| ku | in | A 的上带宽(主对角线以上的非零对角线数)。 | ||
| alpha | host/device | in | 用于乘法的 <type> 标量。 | |
| A | device | in | 带状矩阵 <type> 数组,维度为 lda x n。 | |
| lda | in | 带状矩阵 A 存储的主维长度,lda >= kl + ku + 1。 | ||
| x | device | in | <type> 向量,trans='N'时包含n个元素,否则包含m个元素。 | |
| incx | in | x 中连续元素之间的步长。 | ||
| beta | host/device | in | 用于乘法的 <type> 标量。如果 beta == 0,则 y 不必是有效输入。 | |
| y | device | in/out | <type> 向量,trans='N'时包含m个元素,否则包含n个元素。 | |
| incy | in | y 中连续元素之间的步长。 | ||
-
算子规格:
算子类型(OpType) gbmv 算子输入 name shape data type format A lda * N float ND x X_COUNT float ND y Y_COUNT float ND alpha 1 float ND beta 1 float ND 算子输出 y Y_COUNT float ND 核函数名 gbmv_kernel -
算子实现:
输入数据通过Host侧GatherStrided将带步长的向量收集为连续内存,经H2D拷贝到Device。Kernel将矩阵列段和向量数据从GM分块搬运到UB,完成乘加计算后,通过SetAtomicAdd多核并行归约到输出向量。结果通过ScatterStrided按输出步长写回Host。
-
调用实现
使用内核调用符<<<>>>调用核函数。
测试用例覆盖
| 分组 | 用例数 | 覆盖场景 |
|---|---|---|
| L0 trans=N | 7 | 基础功能、alpha/beta边界值、非单位步长、矩形矩阵 |
| L0 trans=T/C | 7 | 转置基础功能、beta=0、矩形、共轭转置 |
| L1 trans=N | 19 | 带宽变体、边界形状、负步长、非紧凑lda、大规模、全零输出 |
| L1 trans=T/C | 18 | 转置带宽变体、负步长、大规模矩形、全零输出 |
编译运行
在本样例根目录下执行如下步骤,编译并执行算子。
-
配置环境变量
请根据当前环境上CANN开发套件包的安装方式,选择对应配置环境变量的命令。-
默认路径,root用户安装CANN软件包
source /usr/local/Ascend/cann/set_env.sh -
默认路径,非root用户安装CANN软件包
source $HOME/Ascend/cann/set_env.sh -
指定路径install_path,安装CANN软件包
source ${install_path}/cann/set_env.sh
-
-
样例执行
bash build.sh --ops=gbmv --soc=ascend950 --run其中
--soc为可选参数,用于指定目标硬件平台(与上文「产品支持情况」对应)。按实际硬件选用:产品 --soc取值Ascend 950PR / Ascend 950DT ascend950Atlas A3 训练系列产品 / Atlas A3 推理系列产品 ascend910_93Atlas A2 训练系列产品 / Atlas A2 推理系列产品 ascend910b执行结果如下,说明精度对比成功。
[PASS] gbmv_test