---
title: 单进程单卡异步运行
description: "本章节给出使用异步运行接口，并使用Device内存运行Graph的示例。"
url: https://www.hiascend.com/document/detail/zh/canncommercial/latest/programug/graphdevg/atlasag_25_0035.html
sourcePath: /source/zh/canncommercial/900/programug/graphdevg/atlasag_25_0035.html
indexId: 6477df96cb0b9a32511b167b0f6f2db7c3c98a47eebb05747dd89462d973436870
---
# 单进程单卡异步运行

本章节给出使用异步运行接口，并使用Device内存运行Graph的示例。

#### 功能介绍

Atlas 200I/500 A2 推理产品 不支持该特性。

构建完Graph之后，如果您希望编译并异步运行Graph，获得Graph的运行结果，请参考本节内容。涉及的主要接口为：


1. 调用  GEInitializeV2(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0176.html)
进行系统初始化（也可在Graph构建前调用），申请系统资源。
2. 调用“aclInit(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0022.html)”接口，初始化acl。
3. 调用  Session构造函数(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0282.html)
创建Session类对象，申请Session资源。
4. 调用“aclrtSetDevice(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0039.html)”指定运行的Device，调用“aclrtCreateStream(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0066.html)”创建Stream，然后调用“aclrtMallocHost(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0101.html)”、“aclrtMalloc(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0095.html)”分别申请Host和Device内存。
5. 调用  AddGraph(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0170.html)
在Session类对象中添加定义好的图。
6. （可选）调用  CompileGraph(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0172.html)
完成图编译。
7. （可选）调用  LoadGraph(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0181.html)
（异步执行Graph场景），加载图模型到  4
创建的Stream上。
8. 调用  RunGraphWithStreamAsync(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0187.html)
异步运行接口，运行Graph：
  若在调用本接口前未执行LoadGraph完成图加载，则本接口将自动调用LoadGraph以完成加载；若在调用LoadGraph接口前未执行CompileGraph完成图编译，则LoadGraph将自动调用CompileGraph以完成编译。

9. 调用“aclrtSynchronizeStream(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0076.html)”阻塞程序运行，直到指定Stream中的所有任务都完成。
10. 调用“aclrtFree(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0100.html)”、“aclrtFreeHost(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0102.html)”释放内存；调用  GEFinalizeV2(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0173.html)
，释放系统资源；调用“aclFinalize(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/runtimeapi/aclcppdevg_03_0023.html)”释放相关资源。


#### 开发示例

1. 包含的头文件，包括acl、C或C++标准库的头文件。
  1 2 3 #include "ge_api_v2.h" #include "acl.h" #include "acl_rt.h"

2. 申请系统资源。
  Graph定义完成后，调用GEInitializeV2进行系统初始化（也可在Graph定义前调用），申请系统资源。示例代码如下：

  1 2 3 std::map<AscendString, AscendString>config = {{"ge.exec.deviceId", "0"}, {"ge.graphRunMode", "1"}}; Status ret = ge::GEInitializeV2(config);

  可以通过config配置传入GE运行的初始化信息，配置参数ge.exec.deviceId和ge.graphRunMode，分别用于指定GE实例运行设备，图执行模式（在线推理请配置为0，训练请配置为1）。更多配置请参考options参数说明(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0150.html)。

  GE options中的dump信息，与后续调用acl初始化接口时配置的dump信息，建议两者不要同时配置，否则可能导致异常。其他相同功能的参数类似。

3. acl资源初始化。
  1 2 3 4 5 6 7 std::string aclConfigPath = "xx/xx/xx"; aclError retInit = aclInit(aclConfigPath); if (retInit != ACL_ERROR_NONE) { // ... // ... return FAILED; }

4. 创建Session。
  若想使定义好的Graph运行起来，首先，要创建一个Session对象。Session中的options可以加载配置参数，支持的配置参数请参见options参数说明(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0150.html)。 1 2 3 4 5 6 7 8 9 10 11 12 std::map <AscendString, AscendString> options; // 创建Session对象 ge::GeSession* session = new GeSession(options); // 判断Session是否创建成功 if(session == nullptr) { std::cout << "Create session failed." << std::endl; // ... // ... // 释放资源 ge::GEFinalizeV2(); return FAILED; }

5. 指定运行的Device，创建Stream，申请内存。
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // 指定用于运算的Device int32_t deviceId = 0; retInit = aclrtSetDevice(deviceId); // 创建一个Stream aclrtStream stream = nullptr; aclError aclRet = aclrtCreateStream(&stream); // 申请Host上的内存 void* hostPtrA = NULL; size_t size = 1024; aclRet = aclrtMallocHost(&hostPtrA, size); // 申请Device上的内存 void* devPtrB = NULL; aclRet = aclrtMalloc(&devPtrB, size, ACL_MEM_MALLOC_HUGE_FIRST); // 内存复制，将Host上数据传输到Device // hostPtrA表示Host上源内存地址指针，devPtrB表示Device上目的内存地址指针，size表示内存大小 aclrtMemcpy(devPtrB, size, hostPtrA, size, ACL_MEMCPY_HOST_TO_DEVICE);

6. 添加Graph对象。
  调用AddGraph接口添加Graph。示例代码如下： 1 2 3 4 5 6 7 8 9 10 11 12 13 // 准备将要添加到Session的Graph ID，并创建空的Graph对象 uint32_t conv_graph_id = 0; ge::Graph conv_graph; // 将Graph添加到Session Status ret = session->AddGraph(conv_graph_id, conv_graph); if(ret != SUCCESS) { // ... // ... // 释放资源并销毁Session ge::GEFinalizeV2(); delete session; return FAILED; }

  用户可以通过传入options配置图运行相关配置信息，相关配置请参考Session构造函数(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0282.html)。其中图运行完之后的数据保存在Tensor output_cov中。

7. （可选）编译Graph。
  如果不调用CompileGraph接口，LoadGraph接口将自动调用CompileGraph以完成编译。 1 2 3 4 5 6 7 8 9 10 uint32_t graph_id = 0; ret = session->CompileGraph(graph_id); if(ret != SUCCESS) { // ... // ... // 释放资源 ge::GEFinalizeV2(); delete session; return FAILED; }

8. （可选）加载Graph到创建的Stream上。
  如果不调用LoadGraph接口，RunGraphWithStreamAsync接口将自动调用LoadGraph以完成加载。LoadGraph中的options可以加载配置参数，比如可以加载“ge.exec.frozenInputIndexes（设置地址不刷新的输入Tensor索引）”参数，该配置参数可以提升图执行性能；options中支持的更多配置参数请参见options参数说明(https://www.hiascend.comdocument/detail/zh/canncommercial/900/API/ascendgraphapi/atlasgeapi_07_0150.html)。 1 2 3 4 5 6 7 8 9 10 11 std::map <AscendString, AscendString> options; uint32_t graph_id = 0; ret = session->LoadGraph(graph_id, options, stream); if(ret != SUCCESS) { // ... // ... // 释放资源 ge::GEFinalizeV2(); delete session; return FAILED; }

9. 数据传输。
  1 2 3 // 内存复制，将Host上数据传输到Device // hostPtrA表示Host上源内存地址指针，devPtrB表示Device上目的内存地址指针，size表示内存大小 aclrtMemcpy(devPtrB, size, hostPtrA, size, ACL_MEMCPY_HOST_TO_DEVICE);

10. 异步执行Graph，输出执行结果。
  1 2 3 4 5 6 7 8 ret = session->RunGraphWithStreamAsync(graph_id, stream, input, output); // 调用aclrtSynchronizeStream接口，阻塞应用程序运行，直到指定Stream中的所有任务都完成 aclRet = aclrtSynchronizeStream(stream); // 内存复制，将Device数据传回Host // devPtrA表示Device上的源内存地址指针，hostPtrB表示Host上的目的内存地址指针，size表示内存大小 aclrtMemcpy(hostPtrB, size, devPtrA, size, ACL_MEMCPY_DEVICE_TO_HOST);

11. 释放资源。
  1 2 3 4 5 6 7 8 9 // 释放内存 ret = aclrtFree(devPtrB); ret = aclrtFreeHost(hostPtrA); // 释放Graph资源 ret = ge::GEFinalizeV2(); // acl去初始化 ret = aclFinalize();
