symv算子实现
概述
BLAS symv算子实现。
symv(Symmetric Matrix-Vector Multiplication)算子实现了对称矩阵与向量的乘法运算,是BLAS基础线性代数库中的核心算子之一。
该算子针对对称矩阵的存储特性进行了优化,并高效完成矩阵与向量的乘加运算。
产品支持情况
| 产品 | 是否支持 | 架构 |
|---|---|---|
| Ascend 950PR / Ascend 950DT | ✓ | arch35 |
| Atlas A3 训练系列产品/Atlas A3 推理系列产品 | ✓ | arch22 |
| Atlas A2 训练系列产品/Atlas A2 推理系列产品 | ✓ | arch22 |
目录结构介绍
blas/symv/
├── README.md // 说明文档
├── arch22/
│ ├── ssymv_host.cpp // Host 侧实现(arch22)
│ └── ssymv_kernel.cpp // Kernel 侧实现(arch22)
└── arch35/
├── ssymv_host.cpp // Host 侧实现(arch35)
├── ssymv_kernel.cpp // Kernel 侧实现(arch35)
└── ssymv_tiling_data.h // Tiling 数据结构(arch35)
test/symv/ssymv/
├── CMakeLists.txt // 测试构建文件
├── ssymv_param.h // CSV 参数解析结构体
├── ssymv_golden.h // CPU golden(cblas_ssymv)
├── arch22/
│ └── ssymv_test.cpp // 测试代码(arch22)
└── arch35/
├── ssymv_test.cpp // 测试代码(arch35,GTest 参数化)
├── ssymv_test.csv // CSV 测试用例
└── ssymv_npu_wrapper.h // NPU wrapper
算子描述
- 算子功能:
symv算子实现了对称矩阵乘以向量。对应的数学表达式为:
y = alpha * A * x + beta * y
A为对称矩阵,x和y是向量,alpha和beta是标量。结果直接写回y(in-place)。
对称矩阵A仅存储上三角或下三角部分(由uplo参数指定),未存储的部分通过对称性推断。矩阵按列主序(column-major)存储,主维为lda。
对应的接口为:
aclblasStatus_t aclblasSsymv(aclblasHandle_t handle, aclblasFillMode_t uplo, int n, const float *alpha,
const float *A, int lda, const float *x, int incx,
const float *beta, float *y, int incy);
| 参数 | symv 参数说明 | |||
| 参数列表 | Param. | Memory | in/out | 含义 |
| uplo | in | 指定矩阵 A 存储上三角(ACLBLAS_UPPER)或下三角(ACLBLAS_LOWER)。 | ||
| n | in | 对称矩阵 A 的行数和列数。 | ||
| alpha | host/device | in | 用于乘法的 float 标量。 | |
| A | device | in | 对称矩阵 float 数组,维度为 lda x n。仅存储 uplo 指定的三角部分。 | |
| lda | in | 用于存储矩阵A的二维数组的主维,lda >= max(1, n)。 | ||
| x | device | in | float 向量,包含 n 个元素。 | |
| incx | in | x 中连续元素之间的步长,incx != 0。 | ||
| beta | host/device | in | 用于乘法的 float 标量。如果 beta == 0,则 y 不必是有效输入。 | |
| y | device | in/out | float 向量,包含 n 个元素。输入为初始 y 值,输出为计算结果。 | |
| incy | in | y 中连续元素之间的步长,incy != 0。 | ||
-
算子规格:
算子类型(OpType) symv 算子输入 name shape data type format A lda x N float ND x N float ND y N float ND alpha 1 float ND beta 1 float ND 算子输出 y N float ND 核函数名 ssymv_kernel (arch35) / symv_kernel (arch22) -
算子实现:
arch35 (SIMT):采用 SIMT 编程模型,使用 grid-stride loop 实现线程级并行。每个线程计算输出向量 y 的一个或多个元素,通过
asc_vf_call分发到不同模板特化(按 uplo 区分 UPPER/LOWER)。Tiling 数据通过传值方式(by value)从 host 传入 kernel,无需分配 GM 设备内存。Host 侧通过GetAivCoreCount()获取 AIV 核数,异步 launch kernel 后直接返回。arch22 (AscendC):采用 AscendC 编程模型,使用 tile-based 分块计算。将输入数据从 A、x、y 的 GM 地址分块搬运到 UB,进行计算后再搬出到 z(临时缓冲区)所在的 GM 地址,最后拷贝回 y。Tiling 数据通过 GM 地址传入 kernel(结构体较大,不适合传值)。
-
调用实现
使用内核调用符<<<>>>调用核函数。
编译运行
在本样例根目录下执行如下步骤,编译并执行算子。
-
配置环境变量
请根据当前环境上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=symv --run # --ops=<算子名> --run可选参数,执行测试样例执行结果如下,说明所有测试用例通过。
[ PASSED ] 32 tests.