体系化学习AscendCL应用开发流程,目标为对昇腾CANN有初步了解并且可以基于昇腾CANN独立开发一个CV类图片应用。
【2023 · CANN训练营第一季】应用开发深入讲解① AscendCL概述
【2023 · CANN训练营第一季】应用开发深入讲解② 华为弹性云服务器(ECS)搭建介绍
【2023 · CANN训练营第一季】应用开发深入讲解③ 快速入门(基于ResNet-50网络模型的图片分类应用)
【2023 · CANN训练营第一季】应用开发深入讲解④ 模型转换(ATC工具)
通过本部分内容,了解ACL(AdcendCL)的功能架构、基本概念以及接口的典型应用流程与实现方法,能够基于本部分的样例,来扩展进行其他应用的开发。
目录
1 ACL简介
2 ACL基本概念
Host
Device
同步/异步
进程/线程
Context
Stream
Event
AIPP
3 主要接口调用流程
ACL的Hellow World代码
AscendCL(Ascend Computing Language,昇腾计算语言)接口是昇腾计算开放编程框架,是对低层昇腾计算服务接口的封装。它提供运行时资源(例如设备、内存等)管理、模型加载与执行、算子加载与执行、图片数据编解码/剪裁/缩放处理等API库实现在昇腾CANN平台上进行深度学习推理计算、图形图像预处理、单算子加速计算等能力。简单来说,就是同一的API框架,实现对所有资源的调用。
● AscendCL的优势如下:
1、高度抽象:算子编译、加载和执行的API归一,相比每个算子一个API,AcendCL大幅减少API数量,降低了复杂度;
2、向后兼容:AsendCL能够向后兼容,以确保软件升级后,基于旧版本进行编译的程序依然可以在新版本上运行;
3、零感知芯片:同一套AsendCL接口可以实现应用代码统一,对于多款昇腾处理器可以无差异运行。
● AscendCL的主要应用场景如下:
1、开发应用:用户可以直接调用AscendCL提供的接口,来开发图片分类、目标识别等应用;
2、供第三方框架调用:用户可以通过第三方框架调用AscendCL接口,以便使用昇腾AI处理器的计算能力;
3、供第三方开发lib库:用户可以使用AscendCL封装实现第三方lib库,以便提供昇腾AI处理的运行管理、资源管理等能力。
指与Device相连的X86服务器、ARM服务器等,利用其提供的NN(Neural-Network)计算能力完成业务。
指安装了芯片的硬件设备,利用PCIe接口与Host侧连接,为Host提供NN计算能力。
同步或异步是站在调用者和执行者角度观察的。在当前场景下,若在Host调用接口后需要等待Device执行完成后再返回,则表示Host的调度是同步的;若在Host调用接口后不等待Device执行完成再返回,则表示Host的调度是异步的。
如无特别注明,则表示是Host上的进程/线程。
Context作为一个容器,管理所有对象(包括Stream、Event、设备内存等)的生命周期。不同的Context的Stream、Event是完全隔离的,无法建立同步等待关系。
Context分为两种:
默认Context:调用aclrtSetDevice接口来指定用于运算的Device时,系统会自动隐式地创建一个默认Context,一个Device对应一个默认Context,默认Context不能通过aclrtDestroyContext接口来释放。
显式创建的Context:在进程或线程中调用aclrtCreateContext接口,以显式地创建一个Context。
Stream用于维护一些异步操作的执行顺序,以确保按照应用程序中的代码调用顺序在Device上执行。基于Stream的kernel执行和数据传输能够实现以下几种类型的并行:
1、Host运算操作和Device运算操作并行;
2、Host运算操作和“Host到Device的数据传输”并行;
3、Device运算操作和“Host到Device的数据传输”并行;
4、Device内的运算并行。
Stream分两种:
默认Stream:调用aclrtSetDevice接口指定用于运算的Device时, 系统会自动隐式地创建一个默认Stream,一个Device对应一个默认Stream,默认Stream不能通过aclrtDestroyStream接来释放。
显式创建的Stream:在进程或线程中调用aclrtCreateStream接口,以显式地创建一个Stream。
支持调用ACL接口来同步Stream之间的任务,包括同步Host与Device之间的任务、Device与Device间的任务。
例如,若stream2的任务依赖stream1 的任务,如果要保证stream1中的任务先完成,这时可创建一个Event,并将Event插入到stream1,在执行stream2的任务前,先同步等待Event完成。
AIPP(AI Preprocessing)用于在Al Core上完成图像预处理,主要有:
色域转换:转换图像格式;
图像归一化:减均值/乘系数;
抠图:指定抠图起始点,抠出神经网络需要大小的图片。
AIPP区分为静态AIPP和动态AIPP。静态AIPP和动态AIPP只可选择一种来处理图片,不能同时配置静态AIPP和动态AIPP两种方式。
● 静态AIPP:
模型转换时设置AIPP模式为静态,同时设置AIPP参数,模型生成后,AIPP参数值被保存在离线模型(*.om) 中,每次模型推理过程采用固定的AIPP预处理参数(无法修改)。如果使用静态AIPP方式,多Batch情况下共用同一份AIPP参数。
● 动态AIPP:
模型转换时仅设置AIPP模式为动态,每次模型推理前,根据需求,在执行模型前设置动态AIPP参数值,然后在模型执行时可使用不同的AIPP参数。设置动态AIPP参数值的接口请参见设置动态AIPP参数。如果使用动态AIPP方式,多Batch可使用不同的AIPP参数。
任何编程语言都有自己的Hellow World代码,接下来同样展示ACL的Hellow World代码,以对其有一个初步的认识。以下代码功能为初始化ACL,初始化成功后即去初始化并结束:
#include
#include "acl/acl.h"
#define INFO_LOG(fmt, args...) fprintf(stdout, "[INFO] " fmt "\n", ##args)
#define WARN_LOG(fmt, args...) fprintf(stdout, "[WARN] " fmt "\n", ##args)
#define ERROR_LOG(fmt, args...) fprintf(stdout, "[ERROR] " fmt "\n", ##args)
using namespace std;
int main()
{
INFO_ LOG("ACL Hello World.");
// ACL init
const char *aclConfigPath = "acl.json";
aclError ret = acllnit(aclConfigPath);
if (ret != ACL_ ERROR_ NONE){
ERROR LOG("acl init failed");
}
INFO_ LOG("acl init success");
ret = aclFinalize();
if (ret != ACL_ ERROR_ NONE) (
ERROR LOG("finalize acl failed");
}
INFO_ LOG("end to finalize acl");
return 0;
}
通过华为云资源,在集成了昇腾310处理器(Device)的x86架构的主机上运行(Host),能够得到以下运行结果: