Skip to content

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

@MengqingCao

Description

@MengqingCao

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

如何打印详细日志?

# 设置全局日志级别(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算子开发揭秘

Metadata

Metadata

Assignees

No one assigned

    Labels

    AscendSomething isn't workingpublishNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions