Scal算子实现
概述
BLAS Scal算子实现,包含实数向量缩放(Sscal)和复数向量缩放(Cscal)。
Scal(Scale)算子实现了向量缩放运算,是BLAS基础线性代数库中的核心算子之一。
该算子包含以下接口:
- aclblasSscal:实数向量乘以标量,
x[i] = alpha * x[i] - aclblasCscal:复数向量乘以复数标量,
(a+bi)*(c+di) = (ac-bd) + (ad+bc)i
产品支持情况
| 产品 | 是否支持 | 架构 |
|---|---|---|
| Ascend 950PR / Ascend 950DT | ✓ | arch35 |
| Atlas A3 训练系列产品/Atlas A3 推理系列产品 | ✓ | arch22 |
| Atlas A2 训练系列产品/Atlas A2 推理系列产品 | ✓ | arch22 |
目录结构介绍
blas/scal/
├── README.md // 说明文档
├── arch22/
│ ├── cscal_host.cpp // Cscal Host 侧实现(arch22)
│ ├── cscal_kernel.cpp // Cscal Kernel 侧实现(arch22)
│ ├── sscal_host.cpp // Sscal Host 侧实现(arch22)
│ └── sscal_kernel.cpp // Sscal Kernel 侧实现(arch22)
└── arch35/
├── sscal_host.cpp // Sscal Host 侧实现(arch35)
├── sscal_kernel.cpp // Sscal Kernel 侧实现(arch35)
└── sscal_tiling_data.h // Sscal Tiling 数据结构(arch35)
测试代码位于 test/scal/:
test/scal/
├── cscal/
│ ├── CMakeLists.txt // 编译工程文件
│ └── arch22/
│ └── cscal_test.cpp // 精度测试(arch22)
└── sscal/
├── CMakeLists.txt // 编译工程文件
├── sscal_param.h // CSV 参数解析
├── sscal_golden.h // CPU golden(调用 cblas_sscal)
└── arch35/
├── sscal_test.cpp // GTest 精度测试(arch35)
├── sscal_test.csv // CSV 测试用例
└── sscal_npu_wrapper.h // NPU 调用封装
算子描述
Sscal(实数向量缩放)
- 算子功能:
sscal算子实现了实数向量x乘以标量alpha。对应的数学表达式为:
x[i] = alpha * x[i] (i = 0 .. n-1,步长为 incx)
- 对应的接口为:
aclblasStatus_t aclblasSscal(aclblasHandle_t handle, int n, const float* alpha, float* x, int incx);
| 参数 | sscal 参数说明 | |||
| 参数列表 | Param. | Memory | in/out | 含义 |
| handle | host | in | ACL 流 handle,用于传入 stream。 | |
| n | in | 向量 x 中的元素个数。 | ||
| alpha | host | in | 标量乘数(float 指针)。 | |
| x | device | in/out | float 向量,包含 n 个元素。 | |
-
算子规格:
算子类型 (OpType) Sscal 算子输入 name shape data type format x N float ND 算子输出 x N float ND 核函数名 sscal_kernel -
算子实现:
根据步长分两条路径:
- incx=1 路径(AIV):单kernel
sscal_aiv_kernel实现。Host侧通过GetAivCoreCount()获取AIV核数并均分元素到各核,Tiling数据通过值传递(无需GM分配)。使用 TPipe + TQue(VECIN/VECOUT) 双队列流水:(1) MTE3: DataCopy / DataCopyPad 将 x 从 GM 搬入 UB(32B 对齐,tail 用 Pad 补齐);(2) V: Muls 指令完成向量乘标量;(3) MTE3: DataCopy / DataCopyPad 将结果写回 GM。多核并行按 AIV core 数量均分 n 个元素,每个 core 处理perCoreN个(ELEMENTS_PER_BLOCK=8 对齐),末尾 core 吸收余数,Tile 循环避免 UB 溢出。 - incx≠1 路径(SIMT):单kernel
sscal_simt_kernel实现。通过SIMT多线程并行,每个线程按步长跨步访问向量元素并完成乘标量操作。
Host侧为异步执行,不包含流同步操作,由调用方负责同步。
- incx=1 路径(AIV):单kernel
Cscal(复数向量缩放)
- 算子功能:
cscal算子实现了复数向量x乘以复数标量alpha。对应的数学表达式为:
x = alpha * x
复数乘法公式:(real, imag) * (alpha_r, alpha_i) = (real*alpha_r - imag*alpha_i, real*alpha_i + imag*alpha_r)
- 对应的接口:
int aclblasCscal(aclblasHandle handle, std::complex<float> *x, const std::complex<float> alpha,
const int64_t n, const int64_t incx);
| 参数 | cscal 参数说明 | |||
| 参数列表 | Param. | Memory | in/out | 含义 |
| handle | host | in | ACL流handle,用于传入stream。 | |
| x | device | in/out | 复数向量,包含n个complex元素。 | |
| alpha | host | in | 用于乘法的复数标量。 | |
| n | in | 向量x中的复数元素个数。 | ||
| incx | in | x中连续元素之间的步长。 | ||
-
算子规格:
算子类型(OpType) Cscal 算子输入 name shape data type format x N complex ND 算子输出 x N complex ND 核函数名 cscal -
算子实现:
将复数向量从GM搬运到UB,使用vreducev2进行虚实分离,分别计算实部实部、实部虚部、虚部实部、虚部虚部,再使用add_v合并结果,最后通过vgather进行虚实合并并搬运回GM。
-
调用实现 使用内核调用符<<<>>>调用核函数。
测试用例覆盖
测试基于 GTest + CSV 驱动框架,golden 实现调用 Netlib BLAS cblas_sscal。
| 分组 | 用例数 | 覆盖场景 |
|---|---|---|
| 异常 | 5 | x空指针、n=0提前退出、n<0提前退出、incx=0无效入参 |
| L0 | 6 | AIV路径(incx=1):n=1/2/4/32/128/512 |
| L1 | 25 | AIV路径(incx=1):alpha=0/1/负/小/大、n=64~16384、全零/全一/NaN/Inf/Extreme特殊数据、非2幂n=7/33/100/1000 |
| L2 | 18 | SIMT路径(incx≠1):incx=2/3/5/7/11、负步长incx=-1/-2/-3、alpha=0/负/小 |
编译运行
在仓库根目录下执行如下步骤,编译并运行算子测试。
-
配置环境变量
source /usr/local/Ascend/cann/set_env.sh -
编译并执行测试
bash build.sh --ops=sscal --run --soc=ascend950 bash build.sh --ops=cscal --run执行结果如下,说明精度对比成功。
[PASS] sscal_test