OpenCV算子开发及其NPU调用方式

OpenCV目前通过调用CANN提供的接口的方式调用NPU,其中调用的接口主要包括数据内存的申请、拷贝和释放、算子执行。

了解CANN

CANN的官方介绍:

CANN(Compute Architecture for Neural Networks)是华为针对AI场景推出的异构计算架构,对上支持多种AI框架,对下服务AI处理器与编程,发挥承上启下的关键作用,是提升昇腾AI处理器计算效率的关键平台。同时针对多样化应用场景,提供高效易用的编程接口,支持用户快速构建基于昇腾平台的AI应用和业务。

image

CANN中面向开发者的即为AscendCL,开发者通过AscendC编程,而CANN则根据编译后的指令通过任务调度将任务下发给不同的处理单元,通过驱动完成对计算资源的调用。这里计算资源主要指AI Core和AI CPU,根据处理数据的不同,即AI Core负责矩阵、向量、标量计算密集的算子计算,而AI CPU则负责非矩阵类、逻辑复杂的分支密集型计算,目前,AI Core还承担了部分无法执行在AI Core的计算密集算子计算。

OpenCV昇腾算子开发

CANN主要的功能特性包括推理应用开发、模型训练和算子开发,OpenCV昇腾算子的开发目前属于推理应用开发,后续提升算子支持完整度过程中会加入自定义算子开发。

开发流程

CANN应用开发基于AscendCL实现,因此应用开发的基础是掌握AscendCL的架构及基本概念和接口的典型调用流程。本篇主要集中于算子调用流程,媒体数据处理的详细解析见dvpp接口调用

image

常用接口

在OpenCV应用开发中,常用的算子包括ACL(去)初始化接口、设备设置接口、device内存操作接口、Stream管理接口和具体的算子接口。ACL(去)初始化接口用来初始化系统内部资源;设备设置接口用来获取device信息、指定或切换device等;device内存操作口用来实现device和host侧的数据搬移;Stream管理接口用来管理任务的并行,一个Stream内部的任务保序执行,即Stream根据发送过来的任务依次执行;不同Stream中的任务并行执行。具体的算子接口则实现具体的计算功能。

下面表格中为除具体算子接口外的常用接口列表,其详细用法参见昇腾文档。

算子类别 接口名称 功能
ACL(去)初始化接口 aclInit(const char *configPath) 初始化ACL系统,用在程序开始时
aclFinalize() 去初始化ACL系统,用在程序退出时
设备设置接口 aclrtGetDevice(int32_t *deviceId) 获取当前线程的目标设备ID
aclrtResetDevice(int32_t deviceId) 重置当前操作的设备并释放设备资源
aclrtGetDeviceCount(uint32_t *count) 获取设备数量
device内存操作接口 aclrtMalloc(void **devPtr,size_t size,aclrtMemMallocPolicy policy) 申请设备内存(真实申请的内存是32bytes对齐的)
aclrtFree(void *devPtr) 释放设备内存
aclrtMemcpy(void *dst, size_t destMax, const void *src,size_t count,aclrtMemcpyKind kind) HOST和DEVICE之间的同步内存复制
aclrtMemcpyAsync(void *dst, size_t destMax,const void *src,size_t count, aclrtMemcpyKind kind, aclrtStream stream) HOST和DEVICE之间的异步内存复制
aclrtMemcpy2d(void *dst,size_t dpitch,const void *src, size_t spitch,size_t width,size_t height,aclrtMemcpyKind kind) HOST和DEVICE之间二维矩阵的同步内存复制
aclrtMemcpy2dAsync(void *dst,size_t dpitch,const void *src, size_t spitch,size_t width,size_t height,aclrtMemcpyKind kind,aclrtStream stream) HOST和DEVICE之间二维矩阵的异步内存复制
aclrtMemset(void *devPtr, size_t maxCount, int32_t value, size_t count) 同步内存初始化
aclrtMemsetAsync(void *devPtr,size_t maxCount,int32_t value, size_t count,aclrtStream stream) 异步内存初始化
Stream管理接口 aclrtCreateStream(aclrtStream *stream) 创建一个Stream
aclrtSynchronizeStream(aclrtStream stream) 阻塞应用程序运行,直到指定Stream中的所有任务都完成

QA

如何确定算子执行在AI Core还是AI CPU?

  1. 查看CANN算子清单
  2. 算子清单由于更新迭代问题不一定最准确,此时可以查看~/Ascend/ascend-toolkit/XXX(CANN版本号)/opp/built-in/op_impl/ai_core/tbe/config/ascendXXX(NPU型号)下的json文件,查看当前设备支持的AI Core算子清单;相应地,AI CPU的则位于/usr/local/Ascend/ascend-toolkit/XXX(CANN版本号)/opp/built-in/op_impl/aicpu/aicpu_kernel/config

如何打印详细日志?

1
2
3
4
5
# 设置全局日志级别(0:DEBUG;1:INFO; 2:WARNING; 3:ERROR; 4NULL(不输出))
- export ASCEND_GLOBAL_LOG_LEVEL=0

# 是否开启日志打屏。开启后,日志将不会保存在log文件中,而是将产生的日志直接打屏显示。
- export ASCEND_SLOG_PRINT_TO_STDOUT=1

参考

  1. 昇腾CANN文档
  2. 昇腾CANN算子开发揭秘

从零开始编译OpenCV NPU教程

从零开始编译OpenCV NPU教程

本文介绍如何从零开始,成功编译OpenCV NPU项目。

本示例使用的机器为华为云昇腾310虚拟机。

1
2
3
实例类型:AI加速型Ai1s
操作系统:Ubuntu 18.04
IDE:VSCode
Read more

OpenCV社区洞察

OpenCV背景

OpenCV是1998年在Intel公司内的CVL(计算机视觉库)项目,由Gary Bradski发起,并由Vadim Pisarevsky担任技术主管,于1999年开源,2000年首次公开发布。2008年OpenCV的核心成员加入Willow GarageItseez公司继续开发。Itseez公司在2016年被Intel收购,核心开发团队重回Intel。

目前主要由Intel公司赞助OpenCV核心开发团队,并且很多OpenCV的开发者是Intel的雇员。这是一个由Intel公司主导,OpenCV.org非盈利基金会运营的开源项目。2019年以来,核心开发团队由Intel,OpenCV中国团队和xperience.ai公司组成。

Read more

昇腾虚拟机固件与驱动安装

作者:@wangxiyuan

华为云目前提供了基于Ascend 310的虚拟机,实例类型为Ai1,支持的OS为ubuntu 18.04和centos 7.6。本文以ubuntu 18.04的4U16G并搭载两块ascend 310的VM为例,说明如何初始化开发环境。

Read more