ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CANN SiP HcgemvBatched:半精度批量复数矩阵向量乘 C++ 实战指南

CANN SiP HcgemvBatched:半精度批量复数矩阵向量乘 C++ 实战指南 CANN SiP HcgemvBatched半精度批量复数矩阵向量乘 C 实战指南【免费下载链接】sip本项目是CANN提供的一款高效、可靠的高性能信号处理算子加速库基于华为Ascend AI处理器专门为信号处理领域而设计。项目地址: https://gitcode.com/cann/sipCANN 信号处理加速库SiPAsdSip为批量复数矩阵-向量乘法提供了半精度接口asdBlasHCgemvBatched适用于一次处理多个小尺寸复数向量运算如信号批处理的场景。本文基于示例目录 example/A2/BLAS/hcgemv_batched/README.md 与配套示例 example/A2/BLAS/hcgemv_batched/example_hcgemv_batched.cpp完整讲解从环境配置、SiP 编译到 Demo 运行的全过程并结合源码 core/blas/cgemv_batched.cpp 剖析 Plan 机制与参数约束帮助你在 Atlas A2/A3 系列设备上完成半精度批量复数 GEMV 的接入与调试。功能定位半精度批量复数矩阵向量乘该算子执行的核心功能为半精度、批量计算复数矩阵与向量的乘积计算公式为$$ \mathbf{y} \alpha \cdot op(A) \cdot \mathbf{x} \beta \cdot \mathbf{y} $$其中$A$ 为复数矩阵$\mathbf{x}, \mathbf{y}$ 为复数向量$\alpha, \beta$ 为复数标量$op(A[k])$ 可以是 $A[k]$也可以是 $A[k]^H$共轭转置。从接口命名可以推断出它在 SiP BLAS 算子族中的位置公开头文件 include/blas_api.h 中同时声明了asdBlasHCgemvBatchedH 前缀半精度与asdBlasCgemvBatched单精度 complex64两个同构接口二者参数签名完全一致仅标量类型从std::complexfloat变为std::complexop::fp16_t。也就是说HCGEMV 是 CGEMV Batched 在半精度COMPLEX32下的对应版本面向对带宽敏感、批量较小的复数向量运算场景。接口原型与参数约束两个接口的函数原型定义见 include/blas_api.h 与 include/blas_api.hAspbStatus asdBlasMakeHCgemvBatchedPlan(asdBlasHandle handle, asdBlasOperation_t trans, const int64_t m); AspbStatus asdBlasHCgemvBatched(asdBlasHandle handle, asdBlasOperation_t trans, const int64_t m, const int64_t n, const std::complexop::fp16_t alpha, aclTensor *A, const int64_t lda, aclTensor *x, const int64_t incx, const std::complexop::fp16_t beta, aclTensor *y, const int64_t incy, const int64_t batchCount);关键参数及其取值约束详见 API 文档 docs/zh/API_Reference/BLAS/HCgemvBatched.md参数类型说明handleasdBlasHandle算子句柄由asdBlasCreate创建transasdBlasOperation_tASDBLAS_OP_N不转置ASDBLAS_OP_T转置ASDBLAS_OP_C共轭转置mint64_t单批次矩阵 A 的行数nint64_t单批次矩阵 A 的列数alphastd::complexop::fp16_t复数标量当前版本取值只能为 10iAaclTensor*行主序COMPLEX32ND 格式shape 为[batchCount, m, n]ldaint64_tA 相邻元素间的内存地址偏移量当前约束为 mxaclTensor*非转置时 shape 为[batchCount, n]共轭转置时 shape 为[batchCount, m]incxint64_t向量 x 的步长当前约束为 1betastd::complexop::fp16_t复数标量当前版本取值只能为 00iyaclTensor*输入/输出。非转置时 shape 为[batchCount, m]共轭转置时 shape 为[batchCount, n]incyint64_t向量 y 的步长当前约束为 1batchCountint64_t批次数量取值范围为[2, 314496]注意alpha只能取 10i、beta只能取 00i、lda固定为m、incx/incy固定为 1这些是当前版本的能力边界。公式中的标量乘法与累加项在这些取值下退化为y op(A) * x示例代码也是按此约束构造数据的。环境配置与 SiP 编译配置 CANN 环境变量source [CANN安装路径]/set_env.sh默认路径为source /usr/local/Ascend/ascend-toolkit/set_env.sh。编译 SiP 加速库进入 SiP 仓库根目录执行编译并设置加速库环境变量cd ${SiP_root_path} bash build.sh source output/set_env.sh特别说明与 build.sh 的实际行为对应上述编译方式仅支持通过 git 下载的加速库以 zip 压缩包方式下载的加速库不支持该编译方式编译过程需要联网下载依赖库因此编译环境需要联网该编译过程包括获取 ascend-boost-comm昇腾分布式通信加速库组件并编译该组件以及编译信号处理加速库两个步骤。更多命令介绍可查看仓库根目录的 build.sh 文件完整编译说明参考 docs/compilation_build.md。编译成功后output/set_env.sh会导出ASDSIP_HOME_PATH等环境变量后续的示例构建脚本正是依赖该路径找到头文件与库文件。运行 Demo逐段解读 example_hcgemv_batched.cpp示例程序 example_hcgemv_batched.cpp 的完整运行流程如下。示例中生成的数据不代表实际场景可根据具体使用场景进行数据修改。1. 参数与数据准备int64_t batch 3; int64_t m 3; int64_t n 3; int64_t lda m; int incx 1; int incy 1; std::complexop::fp16_t alpha std::complexop::fp16_t(1.0, 0.0); std::complexop::fp16_t beta std::complexop::fp16_t(0.0, 0.0); asdBlasOperation_t trans asdBlasOperation_t::ASDBLAS_OP_N;参数取值严格遵守上文约束alpha 10i、beta 00i、lda m、incx incy 1、trans为不转置batch 3落在[2, 314496]范围内。三个张量的元素个数分别为batch*m*nA、batch*nx、batch*my并按行主序在 host 侧填充std::complexop::fp16_t数据半精度复数对。2. ACL 初始化与设备侧 Tensor 创建Init函数是固定的 ACL 初始化写法aclInit→aclrtSetDevice(deviceId)→aclrtCreateStream。CreateAclTensor模板函数完成了三件事aclrtMalloc申请 device 侧内存ACL_MEM_MALLOC_HUGE_FIRST策略aclrtMemcpy将 host 数据以ACL_MEMCPY_HOST_TO_DEVICE拷入按 shape 从后往前计算连续张量的 strides再用aclCreateTensor创建ACL_COMPLEX32、ACL_FORMAT_ND格式的张量aclTensor *inputA aclCreateTensor(shape.data(), shape.size(), aclDataType::ACL_COMPLEX32, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(), *deviceAddr);示例中三个张量的 shape 分别为A 为{batch, m, n}、x 为{batch, n}、y 为{batch, m}。3. 句柄创建、Plan 初始化与工作区分配SiP BLAS 采用「句柄 Plan」两段式使用模型asdBlasHandle handle; asdBlasCreate(handle); size_t lwork 0; void *buffer nullptr; asdBlasMakeHCgemvBatchedPlan(handle, trans, m); // 初始化算子配置 asdBlasGetWorkspaceSize(handle, lwork); // 查询所需工作区大小 if (lwork 0) { aclrtMalloc(buffer, static_castint64_t(lwork), ACL_MEM_MALLOC_HUGE_FIRST); } asdBlasSetWorkspace(handle, buffer); // 绑定工作区 asdBlasSetStream(handle, stream); // 绑定执行流从源码 core/blas/cgemv_batched.cpp 可以看到asdBlasMakeHCgemvBatchedPlan内部转调asdBlasMakeCgemvBatchedPlanImpl以ASD_C_32F数据类型构造BlasCgemvBatchedPlan并注册到BlasPlanCache中且 Plan 创建逻辑带有重复绑定守卫——同一个 handle 只允许初始化一次重复调用 MakePlan 会返回参数错误。因此「一个 handle 对应一套 Plan 配置」若切换trans或m需要创建新的 handle 重新走 Plan 流程。工作区workspace机制则与其他 SiP BLAS 算子一致先GetWorkspaceSize查询再按需申请并SetWorkspace绑定。4. 发起计算、同步与结果回传asdBlasHCgemvBatched(handle, trans, m, n, alpha, inputA, lda, inputX, incx, beta, inputY, incy, batch); asdBlasSynchronize(handle); asdBlasDestroy(handle);计算为异步提交asdBlasSynchronize等待完成后再将结果张量inputY用aclrtMemcpyACL_MEMCPY_DEVICE_TO_HOST拷回 host 并打印。清理阶段依次执行aclDestroyTensor× 3、aclrtFree× 3、aclrtDestroyStream、aclrtResetDevice与aclFinalize。源码层面的实现印证asdBlasHCgemvBatched的入口实现位于 core/blas/cgemv_batched.cpp。几处实现细节与前述约束相互印证AspbStatus asdBlasHCgemvBatched(asdBlasHandle handle, asdBlasOperation_t trans, const int64_t m, const int64_t n, const std::complexop::fp16_t alpha, aclTensor* A, const int64_t lda, aclTensor* x, const int64_t incx, const std::complexop::fp16_t beta, aclTensor* y, const int64_t incy, const int64_t batchCount) { (void)alpha; (void)beta; // aclGetDataType does not support complex32 now, so no check datatype. ... return asdBlasCgemvBatchedImpl(handle, {trans, asdDataType_t::ASD_C_32F, m, n, batchCount, A, x, y}); }源码中alpha、beta参数被(void)显式丢弃从源码结构看这正对应文档「alpha 只能为 10i、beta 只能为 00i」的约束——实现层面尚未真正使用这两个标量由于当前aclGetDataType不支持 complex32该半精度路径跳过了张量类型校验源码注释已说明而单精度asdBlasCgemvBatched路径则对 A/x/y 均校验ACL_COMPLEX64最终调用asdBlasCgemvBatchedImpl以ASD_C_32FCOMPLEX32数据类型复用与单精度共用的批量 GEMV 执行实现。此外接口在入口处对lda 0、incx 0、incy 0只记录 INFO 日志见 core/blas/cgemv_batched.cpp实际取值合法性仍以参数说明中的约束为准示例中直接传入满足约束的lda m、incx incy 1。示例构建脚本build.sh 的编译细节示例目录下的 build.sh 封装了「进入示例目录并执行bash build.sh」这一步的实际工作检查环境变量ASDSIP_HOME_PATH是否已设置且路径存在兼容以latest结尾的路径并加入LD_LIBRARY_PATH使用g编译并链接 ACL 与 SiP 库g example_hcgemv_batched.cpp \ -I${ASCEND_HOME_PATH}/include/aclnn \ -I${ASCEND_HOME_PATH}/include \ -L${ASCEND_HOME_PATH}/lib64/ -lascendcl -lopapi -lnnopbase \ -I${ASDSIP_HOME_PATH}/include \ -L${ASDSIP_HOME_PATH}/lib -lmki \ -L${ASDSIP_HOME_PATH}/lib -lasdsip \ -L${ASDSIP_HOME_PATH}/lib -lasdsip_core \ -L${ASDSIP_HOME_PATH}/lib -lasdsip_host \ -o example编译完成后直接执行./example运行并在结束后清理产物。因此 README 中的「运行 demo」步骤完整命令为cd ${示例所在目录} # example/A2/BLAS/hcgemv_batched bash build.sh前提是该目录之前的 SiP 编译步骤已执行过source output/set_env.sh保证ASDSIP_HOME_PATH与ASCEND_HOME_PATH均已导出。产品支持情况根据示例 README 与 API 文档HcgemvBatched算子适用于Atlas A2/A3 训练系列产品、Atlas 800I A2 推理产品、Atlas A3 推理系列产品Atlas 200I/500 A2 推理产品、Atlas 推理系列产品310P、Ascend 950PR/950DT 等不支持该算子支持矩阵详见 docs/zh/API_Reference/BLAS/HCgemvBatched.md。小结能力asdBlasHCgemvBatched在半精度COMPLEX32下批量完成y alpha·op(A)·x beta·y批次范围 2 ~ 314496接入四步环境配置 →bash build.sh编译 SiP → 示例目录bash build.sh→ 检查输出张量使用约束alpha 固定 10i、beta 固定 00i、lda 为 m、incx/incy 为 1handle 与 Plan 一对一绑定重复 MakePlan 会被拒绝进一步阅读参数与返回值定义见 include/blas_api.hPlan 缓存与类型分发逻辑见 core/blas/cgemv_batched.cpp编译流程见 docs/compilation_build.md。【免费下载链接】sip本项目是CANN提供的一款高效、可靠的高性能信号处理算子加速库基于华为Ascend AI处理器专门为信号处理领域而设计。项目地址: https://gitcode.com/cann/sip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表