【Ascend】AscendC编程接口,基础API和高阶API,tensor高维切分计算怎么理解?

本文主要是对官网中一些难以理解和混淆的内容做一些分析和记录。

1 AscendC编程接口

Ascend C提供一组类库API,开发者使用标准C++语法和类库API进行编程。Ascend C编程类库API示意图如下所示,分为:

  • Kernel API:用于实现算子核函数的API接口。包括:
    • 基本数据结构:kernel API中使用到的基本数据结构,比如GlobalTensor和LocalTensor。
    • 基础API:实现对硬件能力的抽象,开放芯片的能力,保证完备性和兼容性。标注为ISASI(Instruction Set Architecture Special Interface,硬件体系结构相关的接口)类别的API,不能保证跨硬件版本兼容。
    • 高阶API:实现一些常用的计算算法,用于提高编程开发效率,通常会调用多种基础API实现。高阶API包括数学库、Matmul、Softmax等API。高阶API可以保证兼容性。
  • Host API:
    • 高阶API配套的Tiling API:kernel侧高阶API配套的Tiling API,方便开发者获取kernel计算时所需的Tiling参数。
    • Ascend C算子原型注册与管理API:用于Ascend C算子原型定义和注册的API。
    • Tiling数据结构注册API:用于Ascend C算子TilingData数据结构定义和注册的API。
    • 平台信息获取API:在实现Host侧的Tiling函数时,可能需要获取一些硬件平台的信息,来支撑Tiling的计算,比如获取硬件平台的核数等信息。平台信息获取API提供获取这些平台信息的功能。
  • 算子调测API:用于算子调测的API,包括孪生调试,性能调测等。

进行Ascend C算子Host侧编程时,需要使用基础数据结构和API,请参考基础数据结构与接口;完成算子开发后,需要使用Runtime API完成算子的调用,请参考“AscendCL API(C)”。

放大

说明
Ascend C API所在头文件目录为:

  • 基础API:${INSTALL_DIR}/include/ascendc/basic_api/interface

  • 高阶API:(注意,如下目录头文件中包含的接口如果未在资料中声明,属于间接调用接口,开发者无需关注)

    • ${INSTALL_DIR}/include/ascendc/highlevel_api/lib
    • ${INSTALL_DIR}/include/tiling

    ${INSTALL_DIR}请替换为CANN软件安装后文件存储路径。若安装的Ascend-cann-toolkit软件包,以root安装举例,则安装后文件存储路径为:/usr/local/Ascend/ascend-toolkit/latest。

全量的API接口,可以参考:Ascend C API列表

2 基础API概述

对于基础API,主要分为以下几类:

  • 标量计算API,实现调用Scalar计算单元执行计算的功能。
  • 矢量计算API,实现调用Vector计算单元执行计算的功能。
  • 矩阵计算API,实现调用Cube计算单元执行计算的功能。
  • 数据搬运API,计算API基于Local Memory数据进行计算,所以数据需要先从Global Memory搬运至Local Memory,再使用计算API完成计算,最后从Local Memory搬出至Global Memory。执行搬运过程的接口称之为数据搬运API,比如DataCopy接口。
  • 内存管理与同步控制API
    • 内存管理API,用于分配管理内存,比如AllocTensor、FreeTensor接口;
    • 同步控制API,完成任务间的通信和同步,比如EnQue、DeQue接口。不同的API指令间有可能存在依赖关系,从抽象硬件架构可知,不同的指令异步并行执行,为了保证不同指令队列间的指令按照正确的逻辑关系执行,需要向不同的组件发送同步指令。同步控制API内部即完成这个发送同步指令的过程,开发者无需关注内部实现逻辑,使用简单的API接口即可完成。

对于基础API中的计算API,根据对数据操作方法的不同,分为以下几种计算方式

  • 整个tensor参与计算:通过运算符重载的方式实现,支持“+, -, *, /, |, &, <, >, <=, >=, ==, !=”,实现计算的简化表达。例如:
    dst=src1+src2
  • tensor前n个数据计算:针对源操作数的连续n个数据进行计算并连续写入目的操作数,解决一维tensor的连续计算问题。例如:
    Add(dst, src1, src2, n);
  • tensor高维切分计算:功能灵活的计算API,充分发挥硬件优势,支持对每个操作数的DataBlock Stride,Repeat Stride,Mask等参数的操作。
    下图以矢量加法为例,展示了几种计算方式的特点。
    计算API几种计算方式的特点
    针对tensor高维切分计算进行打开理解。

2.1 tensor高维切分计算

如何使用Tensor高维切分计算API

使用tensor高维切分计算API可充分发挥硬件优势,支持开发者控制指令的迭代执行和操作数的地址间隔,功能更加灵活。

矢量计算通过Vector计算单元完成,矢量计算的源操作数和目的操作数均通过Unified Buffer(UB)来进行存储。Vector计算单元每个迭代会从UB中取出8个datablock(每个datablock数据块内部地址连续,长度32Byte,总共256Byte),进行计算,并写入对应的8个datablock中

本文主要对mask参数进行理解说明

mask参数
mask用于控制每次迭代内参与计算的元素。可通过连续模式逐bit模式两种方式进行设置。

  • 连续模式:表示前面连续的多少个元素参与计算。数据类型为uint64_t。取值范围和源操作数的数据类型有关,数据类型不同,每次迭代内能够处理的元素个数最大值不同(当前数据类型单次迭代时能处理的元素个数最大值为:256 / sizeof(数据类型))。当操作数的数据类型占bit位16位时(如half/uint16_t),mask∈[1, 128];当操作数为32位时(如float/int32_t),mask∈[1, 64]。

具体样例如下:

// int16_t数据类型单次迭代能处理的元素个数最大值为256/sizeof(int16_t) = 128,mask = 64,mask∈[1, 128],所以是合法输入
// repeatTimes = 1, 共128个元素,单次迭代能处理128个元素,故repeatTimes = 1
// dstBlkStride, src0BlkStride, src1BlkStride = 1, 单次迭代内连续读取和写入数据
// dstRepStride, src0RepStride, src1RepStride = 8, 迭代间的数据连续读取和写入
uint64_t mask = 64;
AscendC::Add(dstLocal, src0Local, src1Local, mask, 1, { 1, 1, 1, 8, 8, 8 });

结果示例如下:

输入数据(src0Local): [1 2 3 ... 64 ...128]
输入数据(src1Local): [1 2 3 ... 64 ...128]
输出数据(dstLocal): [2 4 6 ... 128 undefined...undefined]

上述示例中,只有64个元素参与计算,65~128的元素是没有参与计算的,所以是undefined。

// int32_t数据类型单次迭代能处理的元素个数最大值为256/sizeof(int32_t) = 64,mask = 64,mask∈[1, 64],所以是合法输入
// repeatTimes = 1, 共64个元素,单次迭代能处理64个元素,故repeatTimes = 1
// dstBlkStride, src0BlkStride, src1BlkStride = 1, 单次迭代内连续读取和写入数据
// dstRepStride, src0RepStride, src1RepStride = 8, 迭代间的数据连续读取和写入(8个表示连续,是根据UB每次取8个dataBlock)
uint64_t mask = 64;
AscendC::Add(dstLocal, src0Local, src1Local, mask, 1, { 1, 1, 1, 8, 8, 8 });

结果示例如下:

输入数据(src0Local): [1 2 3 ... 64]
输入数据(src1Local): [1 2 3 ... 64]
输出数据(dstLocal): [2 4 6 ... 128]
  • 逐bit模式:可以按位控制哪些元素参与计算,bit位的值为1表示参与计算,0表示不参与
    mask为数组形式,数组长度和数组元素的取值范围和操作数的数据类型有关。当操作数为16位时,数组长度为2,mask[0]、mask[1]∈[0, 2^64-1]并且不同时为0;当操作数为32位时,数组长度为1,mask[0]∈(0, 2^64-1];当操作数为64位时,数组长度为1,mask[0]∈(0, 2^32-1]。

具体样例如下:

// 数据类型为int16_t
uint64_t mask[2] = {6148914691236517205, 6148914691236517205};
// repeatTimes = 1, 共128个元素,单次迭代能处理128个元素,故repeatTimes = 1。
// dstBlkStride, src0BlkStride, src1BlkStride = 1, 单次迭代内连续读取和写入数据。
// dstRepStride, src0RepStride, src1RepStride = 8, 迭代间的数据连续读取和写入。
AscendC::Add(dstLocal, src0Local, src1Local, mask, 1, { 1, 1, 1, 8, 8, 8 });

结果示例如下:

输入数据(src0Local): [1 2 3 ... 64 ...127 128]
输入数据(src1Local): [1 2 3 ... 64 ...127 128]
输出数据(dstLocal): [2 undefined 6 ... undefined ...254 undefined]

mask过程如下:

mask={6148914691236517205, 6148914691236517205}(注:6148914691236517205表示64位二进制数0b010101…01,mask按照低位到高位的顺序排布)
在这里插入图片描述
这里有没想过,为什么16位时,数组长度为2?
分析:当数据是16位,也就是2Byte,ub一次处理256Byte,也就是能处理128个数;那么掩码mask也就需要128个数,一个mask用64位表示,那么128个数,总共就需要2个这样的mask。

// 数据类型为int32_t
uint64_t mask[1] = {6148914691236517205};
// repeatTimes = 1, 共64个元素,单次迭代能处理64个元素,故repeatTimes = 1。
// dstBlkStride, src0BlkStride, src1BlkStride = 1, 单次迭代内连续读取和写入数据。
// dstRepStride, src0RepStride, src1RepStride = 8, 迭代间的数据连续读取和写入。
AscendC::Add(dstLocal, src0Local, src1Local, mask, 1, { 1, 1, 1, 8, 8, 8 });

结果示例如下:

输入数据(src0Local): [1 2 3 … 63 64]
输入数据(src1Local): [1 2 3 … 63 64]
输出数据(dstLocal): [2 undefined 6 … 126 undefined]
mask过程如下:

mask={6148914691236517205, 0}(注:6148914691236517205表示64位二进制数0b010101…01)

在这里插入图片描述
分析:当数据是32位,也就是4Byte,ub一次处理256Byte,也就是能处理64个数;那么掩码mask也就需要64个数,那么只需要一个mask用64位表示即可。

那么当操作数为64位时,数组长度为1,mask[0]∈(0, 2^32-1],这又如何分析呢?
分析见文章底部。

3 高阶API概述

高阶API一般是基于单核对常见算法的抽象和封装,用于提高编程开发效率,通常会调用多种基础API实现。高阶API包括数学库、Matmul、Softmax等API。

如下图所示,实现一个矩阵乘操作,使用基础API需要的步骤较多,需要关注格式转换、数据切分等逻辑;使用高阶API则无需关注这些逻辑,可以快速实现功能。
在这里插入图片描述

由于AI处理器的Scalar计算单元执行能力有限,为减少算子Kernel侧的Scalar计算,将部分计算在Host端执行,这需要编写Host端Tiling代码。注意,在程序中调用高阶API的Tiling接口或者使用高阶API的Tiling结构体参数时,需要引入依赖的头文件,示例如下:

#include "tiling/tiling_api.h"

问题:当操作数为64位时,数组长度为1,mask[0]∈(0, 2^32-1]?
分析:当数据是64位,也就是8Byte,ub一次处理256Byte,也就是能处理32个数;那么掩码mask也就需要32个数,那么只需要一个mask用32位表示即可。

内容概要:本文详细介绍了一个基于MATLAB实现的RF-XGBoost混合集成模型,用于多特征分类预测的完整项目。该项目融合随机森林(RF)极端梯度提升(XGBoost)两种算法的优势,构建了多层混合集成架构,涵盖数据预处理、特征筛选、降维、模型训练、调优、评估与可视化全流程。通过RF进行特征重要性分析初步筛选,结合PCA降维后输入XGBoost进行精细建模,有效提升了高维、多类别数据的分类准确率与模型泛化能力。项目包含完整的代码实现、GUI界面设计、系统部署方案及未来优化方向,强调可解释性、工程化架构与实际应用落地。; 适合人群:具备一定机器学习基础MATLAB编程经验的数据科学从业者、高校研究生、算法工程师及希望将AI模型应用于医疗、金融、制造等实际场景的技术人员。; 使用场景及目标:①解决高维多特征数据下的分类难题,如疾病诊断、金融风控、质量检测等;②学习如何结合RF与XGBoost构建高性能集成模型;③掌握从数据预处理到模型部署的全流程开发方法;④构建可解释、可扩展、具备GUI交互的企业级预测分析平台。; 阅读建议:建议读者结合文档中的代码逐模块运行与调试,重点理解RF特征筛选与XGBoost建模的衔接逻辑,关注参数调优、过拟合防控与多指标评估策略。同时可基于提供的GUI框架进行功能扩展,深入体会工程化系统的设计思路与实际部署要点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值