首页 > 技术知识 > 正文

上一篇 AscendCL快速入门——运行资源管理篇(上)

主要描述了AscendCL的基本概念,本篇将介绍AscendCL特性之运行资源管理。

AscendCL特性之运行资源管理

1.初始化

写代码前,在.h或.cpp文件中包含AscendCL的头文件

#include “acl/acl.h” #pragma add_include_path(“/usr/local/Ascend/ascend-toolkit/latest/x86_64-linux /acllib/include/”) #pragma add_library_path(“/usr/local/Ascend/ascend-toolkit/latest/x86_64-linux /acllib/lib64/”) #pragma cling load(“libascendcl.so”) #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) #include <iostream> #include <stdio.h> #include “acl/acl.h”

在进行任何其他AscendCL接口调用之前,首先要调用的是其初始化接口,接口原型:

aclError aclInit(const char *configPath);

其中,configPath这个参数指的是在初始化时加载的配置文件的路径,可以通过这个配置文件来配置参数DUMP功能用于比对精度、配置profiling信息用于调试性能以及配置算子缓存信息老化功能,从而节约内存和平衡调用性能。不过在当前这个阶段我们并不需要额外的配置来初始化AscendCL运行时环境,所以这里我们就传一个nullptr进去就可以了。

aclError aclFinalize();

运行下方的代码,观察结果。这是对AscendCL接口的最小调用,也就是一个初始化,一个去初始化。

INFO_LOG(“AscendCL Hello World.”); // AscendCL init const char *aclConfigPath = nullptr; aclError ret = aclInit(aclConfigPath); if ((ret != ACL_ERROR_NONE) && (ret != ACL_ERROR_REPEAT_INITIALIZE)) { ERROR_LOG(“AscendCL init failed.”); return 0; } INFO_LOG(“AscendCL init success.”); ret = aclFinalize(); if ((ret != ACL_ERROR_NONE)&& (ret != ACL_ERROR_REPEAT_FINALIZE)) { ERROR_LOG(“finalize AscendCL failed.”); return 0; } INFO_LOG(“End to finalize AscendCL.”); return 0; // 运行结果如下 [INFO] AscendCL Hello World. [INFO] AscendCL init success. [INFO] End to finalize AscendCL.

2.AscendCL运行资源

Device管理

狭义的Device特指芯片,这里的“芯片”,在AscendCL运行时环境中其实是逻辑芯片,以下这个接口用来指定计算要分配哪个设备:

aclError aclrtSetDevice(int32_t deviceId);

获取设备的逻辑ID,调用这个接口之后,这个“count”就指明了当前环境下一共有多少个逻辑设备可用。

aclError aclrtGetDeviceCount(uint32_t *count);

对设备进行释放

aclError aclrtResetDevice(int32_t deviceId);

这里是对上边三个接口的调用示例,只是获取的设备数量,占用设备,释放设备,并没有做任何其他操作。

INFO_LOG(“ACL Hello World.”); // ACL init ret = aclInit(aclConfigPath); if ((ret != ACL_ERROR_NONE) && (ret != ACL_ERROR_REPEAT_INITIALIZE)) {  ERROR_LOG(“ACL init failed.”);  return 0; } INFO_LOG(“ACL init success.”); int32_t deviceId = 0; uint32_t count = 0; ret = aclrtGetDeviceCount(&count); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“AclrtGetDeviceCount failed %d.”,ret); } INFO_LOG(“Device count: %d.”, count); ret = aclrtSetDevice(deviceId); if (ret != ACL_ERROR_NONE) { ERROR_LOG(“AclrtSetDevice failed %d.”,ret);  return 0; } INFO_LOG(“Set device %d success.”, deviceId); ret = aclrtResetDevice(deviceId); INFO_LOG(“Reset device %d success.”,deviceId); ret = aclFinalize(); if ((ret != ACL_ERROR_NONE)&& (ret != ACL_ERROR_REPEAT_FINALIZE)) {  ERROR_LOG(“Finalize acl failed %d.”,ret); } INFO_LOG(“End to finalize acl.”); return 0; // 运行结果如下 [INFO] ACL Hello World. [INFO] ACL init success. [INFO] Device count: 1. [INFO] Set device 0 success. [INFO] Reset device 0 success. [INFO] End to finalize acl.
<

可以用这个接口来获取当前正在使用的DeviceID:

aclError aclrtGetDevice(int32_t *deviceId)

阅读下面代码,观察结果

INFO_LOG(“ACL Hello World.”); // ACL init ret = aclInit(aclConfigPath); if ((ret != ACL_ERROR_NONE) && (ret != ACL_ERROR_REPEAT_INITIALIZE)) {  ERROR_LOG(“ACL init failed.”); } INFO_LOG(“ACL init success.”); count = 0; ret = aclrtGetDeviceCount(&count); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“AclrtGetDeviceCount failed %d.”,ret); } INFO_LOG(“Device count: %d.”, count); for(int i = 0; i < count; i++)  {  deviceId =i;  ret = aclrtSetDevice(deviceId);  if (ret != ACL_ERROR_NONE) {   ERROR_LOG(“AclrtSetDevice failed %d.”,ret);  }  INFO_LOG(“Set device %d success.”, deviceId);  ret = aclrtGetDevice(&deviceId);  if (ret != ACL_ERROR_NONE) {   ERROR_LOG(“AclrtGetDevice failed %d.”,ret);  }  INFO_LOG(“Current deviceID: %d.”, deviceId);  ret = aclrtResetDevice(deviceId);  if (ret != ACL_ERROR_NONE) {   ERROR_LOG(“AclrtResetDevice %d failed %d.”,deviceId,ret);  }  else {   INFO_LOG(“Reset device %d success.”,deviceId);  } } ret = aclFinalize(); if ((ret != ACL_ERROR_NONE)&& (ret != ACL_ERROR_REPEAT_FINALIZE)) {  ERROR_LOG(“Finalize acl failed.”); } INFO_LOG(“End to finalize acl.”); return 0; // 运行结果如下 [INFO] ACL Hello World. [INFO] ACL init success. [INFO] Device count: 1. [INFO] Set device 0 success. [INFO] Current deviceID: 0. [INFO] Reset device 0 success. [INFO] End to finalize acl.
<
Context管理

(1)增,创建Context的接口原型如下:

aclError aclrtCreateContext(aclrtContext *context, int32_t deviceId)

(2)删

aclError aclrtDestroyContext(aclrtContext context)

(3)改,创建了多个Context,在运行过程中可能需要在Context之间切换:

aclError aclrtSetCurrentContext(aclrtContext context)

(4)查,和Device一样,设置来设置去,都不知道当前Context是哪个了,用这个接口来查一下:

aclError aclrtGetCurrentContext(aclrtContext *context)

INFO_LOG(“ACL Hello World.”); // ACL init ret = aclInit(aclConfigPath); if ((ret != ACL_ERROR_NONE) && (ret != ACL_ERROR_REPEAT_INITIALIZE)) {  ERROR_LOG(“ACL init failed.”); } INFO_LOG(“ACL init success.”); deviceId = 0; ret = aclrtCreateContext(&context1, deviceId); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“ACL create context1 failed.”); } INFO_LOG(“Create context1 success.”); aclrtContext context2; ret = aclrtCreateContext(&context2, deviceId); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“ACL create context2 failed.”); } INFO_LOG(“Create context2 success.”); aclrtContext context3; ret = aclrtGetCurrentContext(&context3); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“ACL get current context failed.”); } INFO_LOG(“Get current context success.”); if(context2 == context3){  INFO_LOG(“Current context is context2.”); }else if(context1 == context3){ “ ”,INFO_LOG(“Current context is context1.”); }else{ “ ”,ERROR_LOG(“Current context compare failed.”); } ret = aclrtSetCurrentContext(context1); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“ACL set current context failed.”); } INFO_LOG(“Set current context success.”); ret = aclrtGetCurrentContext(&context3); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“ACL get current context failed.”); } INFO_LOG(“Get current context success.”); if(context2 == context3){  INFO_LOG(“Current context is context2.”); }else if(context1 == context3){  INFO_LOG(“Current context is context1.”); }else{  ERROR_LOG(“Current context compare failed.”); }   ret = aclrtDestroyContext(context1); INFO_LOG(“Context1 is destroyed.”); ret = aclrtDestroyContext(context2); INFO_LOG(“Context2 is destroyed.”); ret = aclFinalize(); if ((ret != ACL_ERROR_NONE)&& (ret != ACL_ERROR_REPEAT_FINALIZE)) {  ERROR_LOG(“Finalize acl failed.”); } INFO_LOG(“End to finalize acl.”); return 0;   // 运行结果如下 [INFO] ACL Hello World. [INFO] ACL init success. [INFO] Create context1 success. [INFO] Create context2 success. [INFO] Get current context success. [INFO] Current context is context2. [INFO] Set current context success. [INFO] Get current context success. [INFO] Current context is context1. [INFO] Context1 is destroyed. [INFO] Context2 is destroyed. [INFO] End to finalize acl.
<
Stream管理

Stream更多被用于同步异步特性中,所以这里我们只介绍Stream管理中两 个最基 础的接口,即创建和删除接:

aclError aclrtCreateStream(aclrtStream *stream) aclError aclrtDestroyStream(aclrtStream stream)

阅读下面代码,观察运行结果

INFO_LOG(“ACL Hello World.”); // ACL init ret = aclInit(aclConfigPath); if ((ret != ACL_ERROR_NONE) && (ret != ACL_ERROR_REPEAT_INITIALIZE)) {  ERROR_LOG(“ACL init failed.”); } INFO_LOG(“ACL init success.”); ret = aclrtSetDevice(deviceId); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“AclrtSetDevice %d failed %d.”,deviceId,ret); } INFO_LOG(“Set device %d success.”,deviceId); //deviceId = 0; ret = aclrtCreateContext(&context1, deviceId); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“ACL create context1 failed.”); } INFO_LOG(“Create context1 success.”); aclrtStream stream; ret = aclrtCreateStream(&stream); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“ACL create stream failed %d.”, ret); } INFO_LOG(“Create stream success.”); ret = aclrtDestroyStream(stream); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“Destroy stream failed.”); } INFO_LOG(“End to destroy stream.”); ret = aclrtDestroyContext(context1); if (ret != ACL_ERROR_NONE) {  ERROR_LOG(“AclrtDestroyContext 1 failed %d.”,ret); } INFO_LOG(“Context1 is destroyed.”); ret = aclFinalize(); if ((ret != ACL_ERROR_NONE)&& (ret != ACL_ERROR_REPEAT_FINALIZE)) {  ERROR_LOG(“Finalize acl failed %d.”,ret); } INFO_LOG(“End to finalize acl.”); return 0; // 运行结果如下 [INFO] ACL Hello World. [INFO] ACL init success.、 [INFO] Set device 0 success. [INFO] Create context1 success.、 [INFO] Create stream success. [INFO] End to destroy stream. [INFO] Context1 is destroyed. [INFO] End to finalize acl.
<

下一篇将介绍AscendCL快速入门——内存管理篇

猜你喜欢