目录

    • ACL简介
  • ResNet简介
  • 程序运行效果
  • 代码注释版
  • 编译方法
    • 调整后的目录结构
    • 调整后的cmakelist
  • 运行结果

ACL简介

华为ACL(Ascend Compute Library)是一款基于华为昇腾芯片的AI推理加速库,提供了一系列高性能、高效能的计算接口,支持多种常见的深度学习模型的推理加速。ACL具有高度的灵活性和可扩展性,可以轻松地与各种服务器、云平台和数据中心集成,满足不同规模、不同应用场景下的需求。ACL提供了丰富的接口,包括数据输入输出、模型加载和推理计算等核心功能,同时还支持多种精度的计算方式,包括FP32、FP16和INT8等,可以满足不同场景下的需求。此外,ACL还提供了多种优化技术,包括算子融合、tensor核心优化、算子量化和内存复用等,可进一步提高推理性能和能效比。总之,华为ACL是一款强大、灵活、高效的AI推理加速库,为用户提供了全面的AI计算加速方案.

ResNet简介

ResNet(Residual Network)是一种深度卷积神经网络,由何凯明等人在2015年提出,是当年ImageNet图像识别比赛的冠军网络。ResNet通过引入残差块(Residual Block)来解决深度神经网络训练过程中的梯度消失和梯度爆炸问题。残差块的核心思想是将前一层的特征图直接传递到后一层中,避免了信息的损失,同时通过残差的方式将新的特征图与原有的特征图相加,从而实现了更深层次的网络训练。ResNet网络结构比较简单,主要由多个残差块和全局池化层组成,其中通过步长为2的卷积和降采样操作可以逐层减小特征图大小。ResNet在图像分类、物体检测、人脸识别等领域均取得了优秀的表现,并被广泛应用于实际场景中。

程序运行效果

代码注释版

#include "acl/acl.h"
#include <iostream>
#include <fstream>
#include <cstring>
#include <map>
using namespace std;
size_t pictureDataSize = 0;
void *pictureHostData;
void *pictureDeviceData;
//申请内存,使用C/C++标准库的函数将测试图片读入内存
void ReadPictureTotHost(const char *picturePath)
{// 将picturePath赋值给fileName
string fileName = picturePath;
// 以二进制模式打开fileName指定的文件,并存储在binFile对象中
ifstream binFile(fileName, ifstream::binary);
// 将文件指针移动到文件结尾处
//参数是偏移量off和偏移起始位置way。off表示要移动的字节数,可以是正数或负数;way表示偏移的起始位置
binFile.seekg(0, binFile.end);
// 获取文件大小
pictureDataSize = binFile.tellg();
// 将文件指针移动到文件开头处
binFile.seekg(0, binFile.beg);
// 使用aclrtMallocHost函数在主机内存中分配pictureDataSize字节的空间,并将指针赋值给pictureHostData
aclError ret = aclrtMallocHost(&pictureHostData, pictureDataSize);
// 读取binFile中pictureDataSize字节的数据,并存储到pictureHostData指向的内存空间中
binFile.read((char*)pictureHostData, pictureDataSize);
// 关闭binFile文件流
binFile.close();
}//申请Device侧的内存,再以内存复制的方式将内存中的图片数据传输到Device
void CopyDataFromHostToDevice()
{//第三个参数代表申请内存的相关策略
aclError ret = aclrtMalloc(&pictureDeviceData, pictureDataSize, ACL_MEM_MALLOC_HUGE_FIRST);
//进行主机内存到设备内存间的复制
ret = aclrtMemcpy(pictureDeviceData, pictureDataSize, pictureHostData, pictureDataSize,
ACL_MEMCPY_HOST_TO_DEVICE);
}
void LoadPicture(const char* picturePath)
{ReadPictureTotHost(picturePath);
CopyDataFromHostToDevice();
}int32_t deviceId = 0;
void InitResource()
{//指定当前进程或线程中用于运算的Device,同时隐式创建默认Context。同步接口。
aclError ret = aclInit(nullptr);
ret = aclrtSetDevice(deviceId);
}
uint32_t modelId;
void LoadModel(const char* modelPath)
{//模型ID的指针。
//系统成功加载模型后会返回的模型ID。
aclError ret = aclmdlLoadFromFile(modelPath, &modelId);
}
void DestroyResource()
{//复位当前运算的Device,释放Device上的资源,包括默认Context、默认Stream以及默认Context下创建的所有Stream,同步接口。若默认Context或默认Stream下的任务还未完成,系统会等待任务完成后再释放。
aclError ret = aclrtResetDevice(deviceId);
aclFinalize();
}
aclmdlDataset *inputDataSet;
aclDataBuffer *inputDataBuffer;
aclmdlDataset *outputDataSet;
aclDataBuffer *outputDataBuffer;
aclmdlDesc *modelDesc;
size_t outputDataSize = 0;
void *outputDeviceData;
// 准备模型推理的输入数据结构
void CreateModelInput()
{// 创建aclmdlDataset类型的数据,描述模型推理的输入
//使用aclmdlDesc类型的数据描述模型基本信息(例如输入/输出的个数、名称、数
//据类型、Format、维度信息等)。
//模型加载成功后,用户可根据模型的ID,调用该数据类型下的操作接口获取该模
//型的描述信息,进而从模型的描述信息中获取模型输入/输出的个数、内存大小、
//维度信息、Format、数据类型等信息。
//● 使用aclDataBuffer类型的数据来描述每个输入/输出的内存地址、内存大小。
//调用aclDataBuffer类型下的操作接口获取内存地址、内存大小等,便于向内存中存放输入数据、获取输出数据。
//● 使用aclmdlDataset类型的数据描述模型的输入/输出数据。
//模型可能存在多个输入、多个输出,调用aclmdlDataset类型的操作接口添加多个aclDataBuffer类型的数据。
inputDataSet = aclmdlCreateDataset();
inputDataBuffer = aclCreateDataBuffer(pictureDeviceData, pictureDataSize);
aclError ret = aclmdlAddDatasetBuffer(inputDataSet, inputDataBuffer);
}
// 准备模型推理的输出数据结构
void CreateModelOutput()
{// 创建模型描述信息
modelDesc = aclmdlCreateDesc();
aclError ret = aclmdlGetDesc(modelDesc, modelId);
// 创建aclmdlDataset类型的数据,描述模型推理的输出
outputDataSet = aclmdlCreateDataset();
// 获取模型输出数据需占用的内存大小,单位为Byte
outputDataSize = aclmdlGetOutputSizeByIndex(modelDesc, 0);
// 申请输出内存
ret = aclrtMalloc(&outputDeviceData, outputDataSize, ACL_MEM_MALLOC_HUGE_FIRST);
outputDataBuffer = aclCreateDataBuffer(outputDeviceData, outputDataSize);
ret = aclmdlAddDatasetBuffer(outputDataSet, outputDataBuffer);
}
// 执行模型
void Inference()
{CreateModelInput();
CreateModelOutput();
aclError ret = aclmdlExecute(modelId, inputDataSet, outputDataSet);
}
void *outputHostData;void PrintResult()
{// 获取推理结果数据
aclError ret = aclrtMallocHost(&outputHostData, outputDataSize);
ret = aclrtMemcpy(outputHostData, outputDataSize, outputDeviceData, outputDataSize,
ACL_MEMCPY_DEVICE_TO_HOST);
// 将内存中的数据转换为float类型
float* outFloatData = reinterpret_cast<float *>(outputHostData);
// 屏显测试图片的top5置信度的类别编号
map<float, unsigned int, greater<float>> resultMap;
for (unsigned int j = 0; j < outputDataSize / sizeof(float);++j)
{resultMap[*outFloatData] = j;
outFloatData++;
}
int cnt = 0;
for (auto it = resultMap.begin();it != resultMap.end();++it)
{if(++cnt > 5)
{break;
}
printf("top %d: index[%d] value[%lf] \n", cnt, it->second, it->first);
}}
void UnloadModel()
{// 释放模型描述信息
aclmdlDestroyDesc(modelDesc);
// 卸载模型
aclmdlUnload(modelId);
}
void UnloadPicture()
{aclError ret = aclrtFreeHost(pictureHostData);
pictureHostData = nullptr;
ret = aclrtFree(pictureDeviceData);
pictureDeviceData = nullptr;
aclDestroyDataBuffer(inputDataBuffer);
inputDataBuffer = nullptr;
aclmdlDestroyDataset(inputDataSet);
inputDataSet = nullptr;
ret = aclrtFreeHost(outputHostData);
outputHostData = nullptr;
ret = aclrtFree(outputDeviceData);
outputDeviceData = nullptr;
aclDestroyDataBuffer(outputDataBuffer);
outputDataBuffer = nullptr;
aclmdlDestroyDataset(outputDataSet);
outputDataSet = nullptr;
}
int main()
{// 1.定义一个资源初始化的函数,用于AscendCL初始化、运行管理资源申请(指定计算设备)
InitResource();
// 2.定义一个模型加载的函数,加载图片分类的模型,用于后续推理使用
const char *modelPath = "../model/resnet50.om";
LoadModel(modelPath);
// 3.定义一个读图片数据的函数,将测试图片数据读入内存,并传输到Device侧,用于后续推理使用
const char *picturePath = "../data/dog1_1024_683.bin";
LoadPicture(picturePath);
// 4.定义一个推理的函数,用于执行推理
Inference();
// 5.定义一个推理结果数据处理的函数,用于在终端上屏显测试图片的top5置信度的类别编号
PrintResult();
// 6.定义一个模型卸载的函数,卸载图片分类的模型
UnloadModel();
// 7.定义一个函数,用于释放内存、销毁推理相关的数据类型,防止内存泄露
UnloadPicture();
// 8.定义一个资源去初始化的函数,用于AscendCL去初始化、运行管理资源释放(释放计算设备)
DestroyResource();
}

编译方法

调整后的目录结构

调整后的cmakelist

# Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.# CMake lowest version requirement
cmake_minimum_required(VERSION 3.5.1)# project information
project(ACL_RESNET50)# Compile options
add_compile_options(-std=c++11)#设置环境变量
set(NPU_HOST_LIB  "/home/HwHiAiUser/Ascend/ascend-toolkit/latest/aarch64-linux/devlib/")
set(DDK_PATH "/home/HwHiAiUser/Ascend/ascend-toolkit/latest/")set(CMAKE_RUNTIME_OUTPUT_DIRECTORY  "../../out")
set(CMAKE_CXX_FLAGS_DEBUG "-fPIC -O0 -g -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "-fPIC -O2 -Wall")set(INC_PATH ${DDK_PATH})set(LIB_PATH ${NPU_HOST_LIB})# Header path
include_directories(${INC_PATH}/acllib/include/)if(target STREQUAL "Simulator_Function")add_compile_options(-DFUNC_SIM)
endif()# add host lib path
link_directories(${LIB_PATH}
)file(GLOB_RECURSE cpp_srcs ${PROJECT_SOURCE_DIR}/src/*.cpp)
add_executable(main ${cpp_srcs})if (target STREQUAL "Simulator_Function")target_link_libraries(main funcsim)
else ()if (${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows")target_link_libraries(mainlibascendcl)else ()target_link_libraries(mainascendcl stdc++)endif ()
endif ()install(TARGETS main DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})

运行结果

省去图片及om模型转换的过程

【Atlas200】使用华为ACL库实现ResNet 推理(C++版本)相关推荐

  1. 使用 acl 库编写发送邮件的客户端程序

    2019独角兽企业重金招聘Python工程师标准>>> 邮件做为最早和最广的互联应网用之一,已经与人们的生活息息相关.我们虽然经常使用 Outlook Express/Outlook ...

  2. MFC开发IM-第二十四篇、使用 acl 库针对 C++ 对象进行序列化及反序列编程

    在开发网络应用程序时,各个模块之间的数据通信可谓是家常便饭,为了应对这些数据通信时数据交换的要求,程序员发明了各种数据格式:采用二进制数据结构(早期 C 程序员).采用 XML.采用SOAP(坑人的设 ...

  3. 华为ACL配置(基本ACL+高级ACL+综合应用)

    一.基本ACL 1.PC1不能ping通Server1 2.PC2可以ping通Server1 3.PC1可以ping通 PC2 R1配置 [R1]interface g0/0/0 [R1-Gigab ...

  4. 华为acl怎么生效_华为交换机ACL配置的一些东西

    这是华为ACL配置中流策略的配置命令.华为设备配置ACL不像Cisco的那样可以直接在接口下配置ACL来应用.华为需要先配ACL,然后配流分类(traffic classifier tc1),将ACL ...

  5. linux acl库编译与使用,acl 的编译与使用

    acl 下其实有四个库:lib_acl (基础库).lib_protocol(http 和 icmp 协议库).lib_acl_cpp(封装了 lib_acl 和 lib_protocol 两个 C ...

  6. 华为p40pro怎么用鸿蒙,数码知识:华为p40pro是鸿蒙系统吗系统版本

    如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多小技巧的,这些技巧很多小伙伴一般都是不知道如何来实用的,就好比最近就有很多小伙伴们想要知道华为p40pro是鸿蒙系统吗系统版本, ...

  7. 什么时候可以升级HarmonyOS,华为鸿蒙OS即将迎来升级 手机版本或仍需时间

    原标题:华为鸿蒙OS即将迎来升级 手机版本或仍需时间 在2019年的华为开发者大会上,华为消费者业务CEO余承东正式对外发布了HarmonyOS.时隔一年后,华为开发者大会2020即将拉开帷幕.此次大 ...

  8. Python第三方库的安装,升级以及版本查看

    方法:通过电脑的cmd命令行来进行python第三方库的安装,升级以及版本查看 安装和升级pip 安装pip方法1 在cmd命令行输入以下命令: python -m ensurepip #当提示不存在 ...

  9. 华为云GuassDB(for Redis)发布全新版本推出:Lua脚本和SSL连接加密

    摘要:9月8日,华为云GuassDB(for Redis)正式推出全新版本.新版本内核带来性能提升.无损升级.慢日志统计等多维度产品体验,同时推出Lua脚本和SSL连接加密两大重要功能,让业务设计更加 ...

最新文章

  1. RMAN duplicate database到新主机
  2. 5G+AI,中国版无人驾驶可以有多猛?
  3. 四边形可以分为几类_四边形有几种类型
  4. 汇编语言实现计算器---可加减乘除括号负数混合运算
  5. python 与别的程序通信_《Python》进程之间的通信(IPC)、进程之间的数据共享、进程池...
  6. sublime for mac 注册码
  7. 三角学——极坐标_2
  8. mysql报错注入实战_手工注入——MySQL手工注入实战和分析
  9. C#基础知识---匿名方法使用
  10. 中兴F412光猫超级密码破解、破解用户限制、关闭远程控制、恢复路由器拨号
  11. iOS开发之UIView常用的一些方法小记之setNeedsDisplay和setNeedsLayout
  12. 车牌分割python_车牌字符分割python打开
  13. 关于【Windows 资源保护找到了损坏文件,但其中有一些文件无法修复】的解决方法
  14. GIS真正的魅力在哪?
  15. 从0到1详解推荐系统的基础知识与整体框架
  16. LCD1602显示字母和数字--51
  17. Ubuntu中编写C语言程序
  18. 魔界中的黑V天險(1)
  19. 智能网联汽车——网联化
  20. kylin-v10安装达梦数据库

热门文章

  1. \t\t终身受用!告诉你关于PDF文件的一切
  2. 如何平衡创造性和可靠性?
  3. Word文档选择文本
  4. 六十星系之28天同独坐卯酉
  5. 计算机主板提示ahci,老主板开启ahci经验总结,跑分还显示intelide的进来看吧
  6. css下拉菜单全代码
  7. MULTI-CHANNEL SPEECH ENHANCEMENT USING GRAPH NEURAL NETWORKS 文献翻译
  8. Pointofix下载、安装和使用快捷键
  9. 他找到了区块链世界的灵魂:共识无价
  10. CSDN发布文章如何设置字体颜色、类型、大小和字体背景