已合并
【PR】: 简要描述 #3171
shi-qiong创建于 6月26日
【PR】: 简要描述 #3171
已合并
共 15 个文件变更+1081-0
| @@ -0,0 +1,27 @@ | |||
| 1 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 10 | + | ||
| 11 | +cmake_minimum_required(VERSION 3.16.0) | ||
| 12 | + | ||
| 13 | +project(Runtime_Cross_Version_Compatibility_Sample) | ||
| 14 | + | ||
| 15 | +include_directories(${ASCEND_CANN_PACKAGE_PATH}/include | ||
| 16 | + ${CMAKE_CURRENT_SOURCE_DIR}/../../..) | ||
| 17 | +link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) | ||
| 18 | + | ||
| 19 | +add_executable(main main.cpp) | ||
| 20 | + | ||
| 21 | +target_compile_options(main PRIVATE | ||
| 22 | + -O2 -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -Wall -Werror | ||
| 23 | +) | ||
| 24 | + | ||
| 25 | +target_link_libraries(main PRIVATE | ||
| 26 | + ${ASCEND_CANN_PACKAGE_PATH}/lib64/libacl_rt.so | ||
| 27 | +) | ||
| @@ -0,0 +1,68 @@ | |||
| 1 | +# 0_runtime_compatibility | ||
| 2 | + | ||
| 3 | +## 描述 | ||
| 4 | + | ||
| 5 | +本样例演示跨版本兼容场景中的基础探测方法,包括查询 CANN 软件版本、查询当前环境支持的 CANN 特性、检查当前 SoC 架构兼容性,以及查询 Device 能力。样例用于帮助用户在不同 CANN 版本或不同产品环境中编写可分支处理的 Runtime 程序。 | ||
| 6 | + | ||
| 7 | +## 产品支持情况 | ||
| 8 | + | ||
| 9 | +本样例支持以下产品: | ||
| 10 | + | ||
| 11 | +| 产品 | 是否支持 | | ||
| 12 | +| --- | :---: | | ||
| 13 | +| Ascend 950PR/Ascend 950DT | √ | | ||
| 14 | +| Atlas A3 训练系列产品/Atlas A3 推理系列产品 | √ | | ||
| 15 | +| Atlas A2 训练系列产品/Atlas A2 推理系列产品 | √ | | ||
| 16 | + | ||
| 17 | +## 编译运行 | ||
| 18 | + | ||
| 19 | +1. 下载样例代码至安装 CANN 软件的环境,切换到样例目录。 | ||
| 20 | + | ||
| 21 | +```bash | ||
| 22 | +cd ${git_clone_path}/example/0_quickstart/3_cross_version/0_runtime_compatibility | ||
| 23 | +``` | ||
| 24 | + | ||
| 25 | +2. 设置环境变量。 | ||
| 26 | + | ||
| 27 | +```bash | ||
| 28 | +# ${install_root} 替换为 CANN 安装根目录,默认安装在 `/usr/local/Ascend` 目录 | ||
| 29 | +source ${install_root}/cann/set_env.sh | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +3. 执行以下命令运行样例。 | ||
| 33 | + | ||
| 34 | +```bash | ||
| 35 | +bash run.sh | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +## CANN RUNTIME API | ||
| 39 | + | ||
| 40 | +在该 Sample 中,涉及的关键功能点及其关键接口如下所示: | ||
| 41 | + | ||
| 42 | +- 初始化与 Device 管理 | ||
| 43 | + - 调用 `aclInit` 接口完成 ACL 初始化。 | ||
| 44 | + - 调用 `aclrtSetDevice` 接口指定用于查询的 Device。 | ||
| 45 | + - 调用 `aclrtResetDeviceForce` 接口复位当前 Device。 | ||
| 46 | + - 调用 `aclFinalize` 接口完成 ACL 去初始化。 | ||
| 47 | +- 版本与能力查询 | ||
| 48 | + - 调用 `aclsysGetVersionStr` 和 `aclsysGetVersionNum` 接口查询 CANN 软件包版本信息。 | ||
| 49 | + - 调用 `aclGetCannAttributeList` 接口查询当前环境支持的 CANN 特性列表。 | ||
| 50 | + - 调用 `aclGetCannAttribute` 接口查询指定 CANN 特性是否支持。 | ||
| 51 | + - 调用 `aclrtGetSocName` 接口查询当前 SoC 名称。 | ||
| 52 | + - 调用 `aclrtCheckArchCompatibility` 接口检查当前 SoC 架构兼容性。 | ||
| 53 | + - 调用 `aclrtGetDeviceCapability` 接口查询指定 Device 能力。 | ||
| 54 | + | ||
| 55 | +## 示例输出 | ||
| 56 | + | ||
| 57 | +```text | ||
| 58 | +[INFO] CANN package [runtime] version string: 9.1.0 | ||
| 59 | +[INFO] CANN package [runtime] version number: 90100000 | ||
| 60 | +[INFO] CANN attribute count: 3 | ||
| 61 | +[INFO] CANN attribute ACL_CANN_ATTR_INF_NAN support value: 1 | ||
| 62 | +[INFO] CANN attribute ACL_CANN_ATTR_BF16 support value: 1 | ||
| 63 | +[INFO] CANN attribute ACL_CANN_ATTR_JIT_COMPILE support value: 1 | ||
| 64 | +[INFO] Architecture compatibility for Ascend910B3: 1 | ||
| 65 | +[INFO] Device capability ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV: 1 | ||
| 66 | +[INFO] [SUCCESS] Runtime compatibility sample completed successfully | ||
| 67 | +[SUCCESS] Runtime compatibility sample executed successfully. | ||
| 68 | +``` | ||
| @@ -0,0 +1,68 @@ | |||
| 1 | +# 0_runtime_compatibility | ||
| 2 | + | ||
| 3 | +## Description | ||
| 4 | + | ||
| 5 | +This sample demonstrates basic detection methods for cross-version compatibility scenarios, including querying the CANN software version, querying CANN attributes supported by the current environment, checking SoC architecture compatibility, and querying Device capabilities. It helps users write Runtime programs with conditional compatibility handling across CANN versions and product environments. | ||
| 6 | + | ||
| 7 | +## Product Support | ||
| 8 | + | ||
| 9 | +This sample supports the following products: | ||
| 10 | + | ||
| 11 | +| Product | Supported | | ||
| 12 | +| --- | :---: | | ||
| 13 | +| Ascend 950PR/Ascend 950DT | Yes | | ||
| 14 | +| Atlas A3 training series products/Atlas A3 inference series products | Yes | | ||
| 15 | +| Atlas A2 training series products/Atlas A2 inference series products | Yes | | ||
| 16 | + | ||
| 17 | +## Compile and Run | ||
| 18 | + | ||
| 19 | +1. Download the sample code to the environment where CANN is installed. Switch to the sample directory. | ||
| 20 | + | ||
| 21 | +```bash | ||
| 22 | +cd ${git_clone_path}/example/0_quickstart/3_cross_version/0_runtime_compatibility | ||
| 23 | +``` | ||
| 24 | + | ||
| 25 | +2. Set environment variables. | ||
| 26 | + | ||
| 27 | +```bash | ||
| 28 | +# Replace ${install_root} with the CANN installation root directory. The default installation is in `/usr/local/Ascend`. | ||
| 29 | +source ${install_root}/cann/set_env.sh | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +3. Run the following command to execute the sample. | ||
| 33 | + | ||
| 34 | +```bash | ||
| 35 | +bash run.sh | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +## CANN RUNTIME API | ||
| 39 | + | ||
| 40 | +The key functionality points and their key interfaces involved in this sample are as follows: | ||
| 41 | + | ||
| 42 | +- Initialization and Device Management | ||
| 43 | + - Call `aclInit` for ACL initialization. | ||
| 44 | + - Call `aclrtSetDevice` to specify the Device for queries. | ||
| 45 | + - Call `aclrtResetDeviceForce` to reset the current Device. | ||
| 46 | + - Call `aclFinalize` for ACL finalization. | ||
| 47 | +- Version and Capability Query | ||
| 48 | + - Call `aclsysGetVersionStr` and `aclsysGetVersionNum` to query CANN package version information. | ||
| 49 | + - Call `aclGetCannAttributeList` to query the CANN attributes supported by the current environment. | ||
| 50 | + - Call `aclGetCannAttribute` to query whether a specified CANN attribute is supported. | ||
| 51 | + - Call `aclrtGetSocName` to query the current SoC name. | ||
| 52 | + - Call `aclrtCheckArchCompatibility` to check SoC architecture compatibility. | ||
| 53 | + - Call `aclrtGetDeviceCapability` to query a specified Device capability. | ||
| 54 | + | ||
| 55 | +## Sample Output | ||
| 56 | + | ||
| 57 | +```text | ||
| 58 | +[INFO] CANN package [runtime] version string: 9.1.0 | ||
| 59 | +[INFO] CANN package [runtime] version number: 90100000 | ||
| 60 | +[INFO] CANN attribute count: 3 | ||
| 61 | +[INFO] CANN attribute ACL_CANN_ATTR_INF_NAN support value: 1 | ||
| 62 | +[INFO] CANN attribute ACL_CANN_ATTR_BF16 support value: 1 | ||
| 63 | +[INFO] CANN attribute ACL_CANN_ATTR_JIT_COMPILE support value: 1 | ||
| 64 | +[INFO] Architecture compatibility for Ascend910B3: 1 | ||
| 65 | +[INFO] Device capability ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV: 1 | ||
| 66 | +[INFO] [SUCCESS] Runtime compatibility sample completed successfully | ||
| 67 | +[SUCCESS] Runtime compatibility sample executed successfully. | ||
| 68 | +``` | ||
| @@ -0,0 +1,110 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | +namespace { | ||
| 19 | +const char *CannAttrToString(aclCannAttr attr) | ||
| 20 | +{ | ||
| 21 | + switch (attr) { | ||
| 22 | + case ACL_CANN_ATTR_INF_NAN: | ||
| 23 | + return "ACL_CANN_ATTR_INF_NAN"; | ||
| 24 | + case ACL_CANN_ATTR_BF16: | ||
| 25 | + return "ACL_CANN_ATTR_BF16"; | ||
| 26 | + case ACL_CANN_ATTR_JIT_COMPILE: | ||
| 27 | + return "ACL_CANN_ATTR_JIT_COMPILE"; | ||
| 28 | + default: | ||
| 29 | + return "ACL_CANN_ATTR_UNKNOWN"; | ||
| 30 | + } | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +int QueryCannVersion() | ||
| 34 | +{ | ||
| 35 | + char pkgName[] = "runtime"; | ||
| 36 | + char versionStr[ACL_PKG_VERSION_MAX_SIZE] = {}; | ||
| 37 | + int32_t versionNum = 0; | ||
| 38 | + | ||
| 39 | + CHECK_ERROR(aclsysGetVersionStr(pkgName, versionStr)); | ||
| 40 | + CHECK_ERROR(aclsysGetVersionNum(pkgName, &versionNum)); | ||
| 41 | + INFO_LOG("CANN package [%s] version string: %s", pkgName, versionStr); | ||
| 42 | + INFO_LOG("CANN package [%s] version number: %d", pkgName, versionNum); | ||
| 43 | + return 0; | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +int QueryCannAttributes() | ||
| 47 | +{ | ||
| 48 | + const aclCannAttr *attrList = nullptr; | ||
| 49 | + size_t attrCount = 0; | ||
| 50 | + CHECK_ERROR(aclGetCannAttributeList(&attrList, &attrCount)); | ||
| 51 | + INFO_LOG("CANN attribute count: %zu", attrCount); | ||
| 52 | + | ||
| 53 | + const size_t printCount = std::min<size_t>(attrCount, 3); | ||
| 54 | + for (size_t i = 0; i < printCount; ++i) { | ||
| 55 | + int32_t value = 0; | ||
| 56 | + CHECK_ERROR(aclGetCannAttribute(attrList[i], &value)); | ||
| 57 | + INFO_LOG("CANN attribute %s support value: %d", CannAttrToString(attrList[i]), value); | ||
| 58 | + } | ||
| 59 | + return 0; | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +int QueryCompatibilityAndCapability(int32_t deviceId) | ||
| 63 | +{ | ||
| 64 | + const char *socName = aclrtGetSocName(); | ||
| 65 | + if (socName == nullptr || std::strlen(socName) == 0U) { | ||
| 66 | + WARN_LOG("aclrtGetSocName returned empty soc name. Skip architecture compatibility check."); | ||
| 67 | + } else { | ||
| 68 | + int32_t canCompatible = 0; | ||
| 69 | + CHECK_ERROR(aclrtCheckArchCompatibility(socName, &canCompatible)); | ||
| 70 | + INFO_LOG("Architecture compatibility for %s: %d", socName, canCompatible); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + int32_t capability = 0; | ||
| 74 | + CHECK_ERROR(aclrtGetDeviceCapability(deviceId, ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV, &capability)); | ||
| 75 | + INFO_LOG("Device capability ACL_FEATURE_TSCPU_TASK_UPDATE_SUPPORT_AIC_AIV: %d", capability); | ||
| 76 | + return 0; | ||
| 77 | +} | ||
| 78 | +} // namespace | ||
| 79 | + | ||
| 80 | +int32_t main() | ||
| 81 | +{ | ||
| 82 | + constexpr int32_t deviceId = 0; | ||
| 83 | + | ||
| 84 | + CHECK_ERROR(aclInit(nullptr)); | ||
| 85 | + CHECK_ERROR(aclrtSetDevice(deviceId)); | ||
| 86 | + | ||
| 87 | + int ret = QueryCannVersion(); | ||
| 88 | + if (ret == 0) { | ||
| 89 | + ret = QueryCannAttributes(); | ||
| 90 | + } | ||
| 91 | + if (ret == 0) { | ||
| 92 | + ret = QueryCompatibilityAndCapability(deviceId); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + aclError cleanupRet = aclrtResetDeviceForce(deviceId); | ||
| 96 | + if (cleanupRet != ACL_SUCCESS) { | ||
| 97 | + ERROR_LOG("Operation failed: aclrtResetDeviceForce(deviceId) returned error code %d", | ||
| 98 | + static_cast<int32_t>(cleanupRet)); | ||
| 99 | + ret = ret == 0 ? -1 : ret; | ||
| 100 | + } | ||
| 101 | + cleanupRet = aclFinalize(); | ||
| 102 | + if (cleanupRet != ACL_SUCCESS) { | ||
| 103 | + ERROR_LOG("Operation failed: aclFinalize() returned error code %d", static_cast<int32_t>(cleanupRet)); | ||
| 104 | + ret = ret == 0 ? -1 : ret; | ||
| 105 | + } | ||
| 106 | + if (ret == 0) { | ||
| 107 | + INFO_LOG("[SUCCESS] Runtime compatibility sample completed successfully"); | ||
| 108 | + } | ||
| 109 | + return ret; | ||
| 110 | +} | ||
| @@ -0,0 +1,47 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 3 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 4 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 5 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 11 | + | ||
| 12 | +set -euo pipefail | ||
| 13 | + | ||
| 14 | +_ASCEND_CANN_PATH="${ASCEND_HOME_PATH:-}" | ||
| 15 | +if [[ -z "${_ASCEND_CANN_PATH}" ]]; then | ||
| 16 | + echo "[ERROR]: ASCEND_HOME_PATH is not set." | ||
| 17 | + echo "[ERROR]: Please source CANN set_env.sh before running this sample." | ||
| 18 | + exit 1 | ||
| 19 | +fi | ||
| 20 | + | ||
| 21 | +if [[ ! -f "${_ASCEND_CANN_PATH}/bin/setenv.bash" ]]; then | ||
| 22 | + echo "[ERROR]: ${_ASCEND_CANN_PATH}/bin/setenv.bash does not exist." | ||
| 23 | + exit 1 | ||
| 24 | +fi | ||
| 25 | + | ||
| 26 | +source "${_ASCEND_CANN_PATH}/bin/setenv.bash" | ||
| 27 | + | ||
| 28 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| 29 | +cd "${SCRIPT_DIR}" | ||
| 30 | + | ||
| 31 | +rm -rf build | ||
| 32 | +cmake -B build \ | ||
| 33 | + -DASCEND_CANN_PACKAGE_PATH="${_ASCEND_CANN_PATH}" | ||
| 34 | +cmake --build build -j | ||
| 35 | + | ||
| 36 | +file_path=output_msg.txt | ||
| 37 | +if ! ./build/main | tee "${file_path}"; then | ||
| 38 | + echo "[FAILURE] Runtime compatibility sample failed." | ||
| 39 | + exit 1 | ||
| 40 | +fi | ||
| 41 | + | ||
| 42 | +if grep -q "\\[SUCCESS\\] Runtime compatibility sample completed successfully" "${file_path}"; then | ||
| 43 | + echo "[SUCCESS] Runtime compatibility sample executed successfully." | ||
| 44 | +else | ||
| 45 | + echo "[FAILURE] Runtime compatibility sample did not print the expected success marker." | ||
| 46 | + exit 1 | ||
| 47 | +fi | ||
| @@ -0,0 +1,26 @@ | |||
| 1 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 2 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 3 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 4 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 5 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 6 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 7 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 8 | + | ||
| 9 | +cmake_minimum_required(VERSION 3.16.0) | ||
| 10 | + | ||
| 11 | +project(Runtime_Context_Query_Sample) | ||
| 12 | + | ||
| 13 | +include_directories(${ASCEND_CANN_PACKAGE_PATH}/include | ||
| 14 | + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../include/external | ||
| 15 | + ${CMAKE_CURRENT_SOURCE_DIR}/../../..) | ||
| 16 | +link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) | ||
| 17 | + | ||
| 18 | +add_executable(main main.cpp) | ||
| 19 | + | ||
| 20 | +target_compile_options(main PRIVATE | ||
| 21 | + -O2 -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -Wall -Werror | ||
| 22 | +) | ||
| 23 | + | ||
| 24 | +target_link_libraries(main PRIVATE | ||
| 25 | + ${ASCEND_CANN_PACKAGE_PATH}/lib64/libacl_rt.so | ||
| 26 | +) | ||
| @@ -0,0 +1,66 @@ | |||
| 1 | +# 0_context_query | ||
| 2 | + | ||
| 3 | +## 描述 | ||
| 4 | + | ||
| 5 | +本样例演示如何在单 Device、单线程场景下创建 Context、设置当前线程 Context,并查询当前 Context、默认 Stream 和当前线程资源限制。 | ||
| 6 | + | ||
| 7 | +## 产品支持情况 | ||
| 8 | + | ||
| 9 | +本样例支持以下产品: | ||
| 10 | + | ||
| 11 | +| 产品 | 是否支持 | | ||
| 12 | +| --- | :---: | | ||
| 13 | +| Atlas A3 训练系列产品/Atlas A3 推理系列产品 | √ | | ||
| 14 | +| Atlas A2 训练系列产品/Atlas A2 推理系列产品 | √ | | ||
| 15 | + | ||
| 16 | +## 编译运行 | ||
| 17 | + | ||
| 18 | +1. 下载样例代码至安装 CANN 软件的环境,切换到样例目录。 | ||
| 19 | + | ||
| 20 | +```bash | ||
| 21 | +cd ${git_clone_path}/example/1_basic_features/context/0_context_query | ||
| 22 | +``` | ||
| 23 | + | ||
| 24 | +2. 设置环境变量。 | ||
| 25 | + | ||
| 26 | +```bash | ||
| 27 | +# ${install_root} 替换为 CANN 安装根目录,默认安装在 `/usr/local/Ascend` 目录 | ||
| 28 | +source ${install_root}/cann/set_env.sh | ||
| 29 | +``` | ||
| 30 | + | ||
| 31 | +3. 执行以下命令运行样例。 | ||
| 32 | + | ||
| 33 | +```bash | ||
| 34 | +bash run.sh | ||
| 35 | +``` | ||
| 36 | + | ||
| 37 | +## CANN RUNTIME API | ||
| 38 | + | ||
| 39 | +在该 Sample 中,涉及的关键功能点及其关键接口如下所示: | ||
| 40 | + | ||
| 41 | +- 初始化与 Device 管理 | ||
| 42 | + - 调用 `aclInit` 接口完成 ACL 初始化。 | ||
| 43 | + - 调用 `aclrtSetDevice` 接口指定用于运算的 Device。 | ||
| 44 | + - 调用 `aclrtResetDeviceForce` 接口复位当前 Device。 | ||
| 45 | + - 调用 `aclFinalize` 接口完成 ACL 去初始化。 | ||
| 46 | +- Context 管理 | ||
| 47 | + - 调用 `aclrtCreateContext` 接口创建 Context。 | ||
| 48 | + - 调用 `aclrtSetCurrentContext` 接口设置当前线程 Context。 | ||
| 49 | + - 调用 `aclrtGetCurrentContext` 接口查询当前线程 Context。 | ||
| 50 | + - 调用 `aclrtCtxGetCurrentDefaultStream` 接口查询当前 Context 的默认 Stream。 | ||
| 51 | + - 调用 `aclrtDestroyContext` 接口销毁 Context。 | ||
| 52 | +- 资源限制查询 | ||
| 53 | + - 调用 `aclrtGetResInCurrentThread` 接口查询当前线程资源限制。 | ||
| 54 | + | ||
| 55 | +## 示例输出 | ||
| 56 | + | ||
| 57 | +样例运行成功时,输出如下: | ||
| 58 | + | ||
| 59 | +```text | ||
| 60 | +[INFO] Get current context successfully | ||
| 61 | +[INFO] Get current default stream successfully, stream=<stream_pointer> | ||
| 62 | +[INFO] Get current thread cube core limit: <cube_core_limit> | ||
| 63 | +[INFO] Get current thread vector core limit: <vector_core_limit> | ||
| 64 | +[INFO] [SUCCESS] Context query sample completed successfully | ||
| 65 | +[SUCCESS] Context query sample executed successfully. | ||
| 66 | +``` | ||
| @@ -0,0 +1,66 @@ | |||
| 1 | +# 0_context_query | ||
| 2 | + | ||
| 3 | +## Description | ||
| 4 | + | ||
| 5 | +This sample demonstrates how to create a Context, set it as the current thread Context, and query the current Context, default Stream, and current thread resource limits in a single-device and single-thread scenario. | ||
| 6 | + | ||
| 7 | +## Product Support | ||
| 8 | + | ||
| 9 | +This sample supports the following products: | ||
| 10 | + | ||
| 11 | +| Product | Supported | | ||
| 12 | +| --- | :---: | | ||
| 13 | +| Atlas A3 training series products/Atlas A3 inference series products | Yes | | ||
| 14 | +| Atlas A2 training series products/Atlas A2 inference series products | Yes | | ||
| 15 | + | ||
| 16 | +## Compile and Run | ||
| 17 | + | ||
| 18 | +1. Download the sample code to the environment where CANN is installed. Switch to the sample directory. | ||
| 19 | + | ||
| 20 | +```bash | ||
| 21 | +cd ${git_clone_path}/example/1_basic_features/context/0_context_query | ||
| 22 | +``` | ||
| 23 | + | ||
| 24 | +2. Set environment variables. | ||
| 25 | + | ||
| 26 | +```bash | ||
| 27 | +# Replace ${install_root} with the CANN installation root directory. The default installation is in `/usr/local/Ascend`. | ||
| 28 | +source ${install_root}/cann/set_env.sh | ||
| 29 | +``` | ||
| 30 | + | ||
| 31 | +3. Run the following command to execute the sample. | ||
| 32 | + | ||
| 33 | +```bash | ||
| 34 | +bash run.sh | ||
| 35 | +``` | ||
| 36 | + | ||
| 37 | +## CANN RUNTIME API | ||
| 38 | + | ||
| 39 | +The key functionality points and their key interfaces involved in this sample are as follows: | ||
| 40 | + | ||
| 41 | +- Initialization and Device Management | ||
| 42 | + - Call `aclInit` for ACL initialization. | ||
| 43 | + - Call `aclrtSetDevice` to specify the Device. | ||
| 44 | + - Call `aclrtResetDeviceForce` to reset the current Device. | ||
| 45 | + - Call `aclFinalize` for ACL finalization. | ||
| 46 | +- Context Management | ||
| 47 | + - Call `aclrtCreateContext` to create a Context. | ||
| 48 | + - Call `aclrtSetCurrentContext` to set the current thread Context. | ||
| 49 | + - Call `aclrtGetCurrentContext` to query the current thread Context. | ||
| 50 | + - Call `aclrtCtxGetCurrentDefaultStream` to query the default Stream of the current Context. | ||
| 51 | + - Call `aclrtDestroyContext` to destroy the Context. | ||
| 52 | +- Resource Limit Query | ||
| 53 | + - Call `aclrtGetResInCurrentThread` to query the current thread resource limit. | ||
| 54 | + | ||
| 55 | +## Sample Output | ||
| 56 | + | ||
| 57 | +When the sample runs successfully, the output is as follows: | ||
| 58 | + | ||
| 59 | +```text | ||
| 60 | +[INFO] Get current context successfully | ||
| 61 | +[INFO] Get current default stream successfully, stream=<stream_pointer> | ||
| 62 | +[INFO] Get current thread cube core limit: <cube_core_limit> | ||
| 63 | +[INFO] Get current thread vector core limit: <vector_core_limit> | ||
| 64 | +[INFO] [SUCCESS] Context query sample completed successfully | ||
| 65 | +[SUCCESS] Context query sample executed successfully. | ||
| 66 | +``` | ||
| @@ -0,0 +1,94 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +namespace { | ||
| 17 | +constexpr int32_t kDeviceId = 0; | ||
| 18 | + | ||
| 19 | +class ContextGuard { | ||
| 20 | +public: | ||
| 21 | + explicit ContextGuard(aclrtContext context) : context_(context) {} | ||
| 22 | + | ||
| 23 | + ~ContextGuard() | ||
| 24 | + { | ||
| 25 | + if (context_ != nullptr) { | ||
| 26 | + CHECK_ERROR_WITHOUT_RETURN(aclrtDestroyContext(context_)); | ||
| 27 | + } | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + ContextGuard(const ContextGuard &) = delete; | ||
| 31 | + ContextGuard &operator=(const ContextGuard &) = delete; | ||
| 32 | + | ||
| 33 | + aclError Destroy() | ||
| 34 | + { | ||
| 35 | + if (context_ == nullptr) { | ||
| 36 | + return ACL_SUCCESS; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + aclError ret = aclrtDestroyContext(context_); | ||
| 40 | + if (ret == ACL_SUCCESS) { | ||
| 41 | + context_ = nullptr; | ||
| 42 | + } | ||
| 43 | + return ret; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | +private: | ||
| 47 | + aclrtContext context_; | ||
| 48 | +}; | ||
| 49 | + | ||
| 50 | +int32_t RunContextQuerySample() | ||
| 51 | +{ | ||
| 52 | + aclrtContext context = nullptr; | ||
| 53 | + aclrtStream defaultStream = nullptr; | ||
| 54 | + uint32_t cubeCoreLimit = 0; | ||
| 55 | + uint32_t vectorCoreLimit = 0; | ||
| 56 | + | ||
| 57 | + CHECK_ERROR(aclrtCreateContext(&context, kDeviceId)); | ||
| 58 | + ContextGuard contextGuard(context); | ||
| 59 | + CHECK_ERROR(aclrtSetCurrentContext(context)); | ||
| 60 | + | ||
| 61 | + aclrtContext currentContext = nullptr; | ||
| 62 | + CHECK_ERROR(aclrtGetCurrentContext(¤tContext)); | ||
| 63 | + if (currentContext != context) { | ||
| 64 | + ERROR_LOG("Current context is different from the created context."); | ||
| 65 | + return -1; | ||
| 66 | + } | ||
| 67 | + INFO_LOG("Get current context successfully"); | ||
| 68 | + | ||
| 69 | + CHECK_ERROR(aclrtCtxGetCurrentDefaultStream(&defaultStream)); | ||
| 70 | + INFO_LOG("Get current default stream successfully, stream=%p", defaultStream); | ||
| 71 | + | ||
| 72 | + CHECK_ERROR(aclrtGetResInCurrentThread(ACL_RT_DEV_RES_CUBE_CORE, &cubeCoreLimit)); | ||
| 73 | + INFO_LOG("Get current thread cube core limit: %u", cubeCoreLimit); | ||
| 74 | + | ||
| 75 | + CHECK_ERROR(aclrtGetResInCurrentThread(ACL_RT_DEV_RES_VECTOR_CORE, &vectorCoreLimit)); | ||
| 76 | + INFO_LOG("Get current thread vector core limit: %u", vectorCoreLimit); | ||
| 77 | + | ||
| 78 | + CHECK_ERROR(contextGuard.Destroy()); | ||
| 79 | + INFO_LOG("[SUCCESS] Context query sample completed successfully"); | ||
| 80 | + return 0; | ||
| 81 | +} | ||
| 82 | +} // namespace | ||
| 83 | + | ||
| 84 | +int32_t main() | ||
| 85 | +{ | ||
| 86 | + CHECK_ERROR(aclInit(nullptr)); | ||
| 87 | + CHECK_ERROR(aclrtSetDevice(kDeviceId)); | ||
| 88 | + | ||
| 89 | + int32_t ret = RunContextQuerySample(); | ||
| 90 | + | ||
| 91 | + CHECK_ERROR(aclrtResetDeviceForce(kDeviceId)); | ||
| 92 | + CHECK_ERROR(aclFinalize()); | ||
| 93 | + return ret; | ||
| 94 | +} | ||
| @@ -0,0 +1,47 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 3 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 4 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 5 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 11 | + | ||
| 12 | +set -euo pipefail | ||
| 13 | + | ||
| 14 | +_ASCEND_CANN_PATH="${ASCEND_HOME_PATH:-}" | ||
| 15 | +if [[ -z "${_ASCEND_CANN_PATH}" ]]; then | ||
| 16 | + echo "[ERROR]: ASCEND_HOME_PATH is not set." | ||
| 17 | + echo "[ERROR]: Please source CANN set_env.sh before running this sample." | ||
| 18 | + exit 1 | ||
| 19 | +fi | ||
| 20 | + | ||
| 21 | +if [[ ! -f "${_ASCEND_CANN_PATH}/bin/setenv.bash" ]]; then | ||
| 22 | + echo "[ERROR]: ${_ASCEND_CANN_PATH}/bin/setenv.bash does not exist." | ||
| 23 | + exit 1 | ||
| 24 | +fi | ||
| 25 | + | ||
| 26 | +source "${_ASCEND_CANN_PATH}/bin/setenv.bash" | ||
| 27 | + | ||
| 28 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| 29 | +cd "${SCRIPT_DIR}" | ||
| 30 | + | ||
| 31 | +rm -rf build | ||
| 32 | +cmake -B build \ | ||
| 33 | + -DASCEND_CANN_PACKAGE_PATH="${_ASCEND_CANN_PATH}" | ||
| 34 | +cmake --build build -j | ||
| 35 | + | ||
| 36 | +file_path=output_msg.txt | ||
| 37 | +if ! ./build/main | tee "${file_path}"; then | ||
| 38 | + echo "[FAILURE] Context query sample failed." | ||
| 39 | + exit 1 | ||
| 40 | +fi | ||
| 41 | + | ||
| 42 | +if grep -q "\\[SUCCESS\\] Context query sample completed successfully" "${file_path}"; then | ||
| 43 | + echo "[SUCCESS] Context query sample executed successfully." | ||
| 44 | +else | ||
| 45 | + echo "[FAILURE] Context query sample did not print the expected success marker." | ||
| 46 | + exit 1 | ||
| 47 | +fi | ||
| @@ -0,0 +1,28 @@ | |||
| 1 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 2 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 10 | + | ||
| 11 | +cmake_minimum_required(VERSION 3.16.0) | ||
| 12 | + | ||
| 13 | +project(Runtime_Stream_Config_Query_Sample) | ||
| 14 | + | ||
| 15 | +include_directories(${ASCEND_CANN_PACKAGE_PATH}/include | ||
| 16 | + ${CMAKE_CURRENT_SOURCE_DIR}/../../..) | ||
| 17 | +link_directories(${ASCEND_CANN_PACKAGE_PATH}/lib64) | ||
| 18 | + | ||
| 19 | +add_executable(main main.cpp) | ||
| 20 | + | ||
| 21 | +target_compile_options(main PRIVATE | ||
| 22 | + -O2 -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -Wall -Werror | ||
| 23 | +) | ||
| 24 | + | ||
| 25 | +target_link_libraries(main PRIVATE | ||
| 26 | + ${ASCEND_CANN_PACKAGE_PATH}/lib64/libacl_rt.so | ||
| 27 | + dl | ||
| 28 | +) | ||
| @@ -0,0 +1,78 @@ | |||
| 1 | +# 3_stream_config_query | ||
| 2 | + | ||
| 3 | +## 描述 | ||
| 4 | + | ||
| 5 | +本样例演示如何使用 Stream 配置对象创建 Stream,并查询创建后的 Stream ID、Flag 和 Priority。样例在单 Device 上运行,用于展示配置化 Stream 创建和属性查询的基础流程。 | ||
| 6 | + | ||
| 7 | +## 产品支持情况 | ||
| 8 | + | ||
| 9 | +本样例支持以下产品: | ||
| 10 | + | ||
| 11 | +| 产品 | 是否支持 | | ||
| 12 | +| --- | :---: | | ||
| 13 | +| Ascend 950PR/Ascend 950DT | √ | | ||
| 14 | +| Atlas A3 训练系列产品/Atlas A3 推理系列产品 | √ | | ||
| 15 | +| Atlas A2 训练系列产品/Atlas A2 推理系列产品 | √ | | ||
| 16 | + | ||
| 17 | +## 编译运行 | ||
| 18 | + | ||
| 19 | +1. 下载样例代码至安装 CANN 软件的环境,切换到样例目录。 | ||
| 20 | + | ||
| 21 | +```bash | ||
| 22 | +cd ${git_clone_path}/example/1_basic_features/stream/3_stream_config_query | ||
| 23 | +``` | ||
| 24 | + | ||
| 25 | +2. 设置环境变量。 | ||
| 26 | + | ||
| 27 | +```bash | ||
| 28 | +# ${install_root} 替换为 CANN 安装根目录,默认安装在 `/usr/local/Ascend` 目录 | ||
| 29 | +source ${install_root}/cann/set_env.sh | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +3. 执行以下命令运行样例。 | ||
| 33 | + | ||
| 34 | +```bash | ||
| 35 | +bash run.sh | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +## CANN RUNTIME API | ||
| 39 | + | ||
| 40 | +在该 Sample 中,涉及的关键功能点及其关键接口如下所示: | ||
| 41 | + | ||
| 42 | +- 初始化与 Device 管理 | ||
| 43 | + - 调用 `aclInit` 接口完成 ACL 初始化。 | ||
| 44 | + - 调用 `aclrtSetDevice` 接口指定用于运算的 Device。 | ||
| 45 | + - 调用 `aclrtResetDeviceForce` 接口复位当前 Device。 | ||
| 46 | + - 调用 `aclFinalize` 接口完成 ACL 去初始化。 | ||
| 47 | +- Stream 配置与创建 | ||
| 48 | + - 调用 `aclrtCreateStreamConfigHandle` 接口创建 Stream 配置对象。 | ||
| 49 | + - 调用 `aclrtSetStreamConfigOpt` 接口设置 Stream 配置属性。 | ||
| 50 | + - 调用 `aclrtCreateStreamV2` 接口根据配置对象创建 Stream。 | ||
| 51 | + - 调用 `aclrtDestroyStreamConfigHandle` 接口销毁 Stream 配置对象。 | ||
| 52 | +- Stream 查询与同步 | ||
| 53 | + - 调用 `aclrtStreamGetId` 接口查询 Stream ID。 | ||
| 54 | + - 调用 `aclrtStreamGetFlags` 接口查询 Stream Flag。 | ||
| 55 | + - 调用 `aclrtStreamGetPriority` 接口查询 Stream Priority。 | ||
| 56 | + - 调用 `aclrtSynchronizeStream` 接口等待 Stream 上任务完成。 | ||
| 57 | + - 调用 `aclrtDestroyStream` 接口销毁 Stream。 | ||
| 58 | + | ||
| 59 | +## 示例输出 | ||
| 60 | + | ||
| 61 | +```text | ||
| 62 | +[INFO] Create stream config handle successfully | ||
| 63 | +[INFO] Set stream config flags=0 priority=0 | ||
| 64 | +[INFO] Create stream with config successfully | ||
| 65 | +[INFO] Stream id: 1 | ||
| 66 | +[INFO] Stream flags: 0 | ||
| 67 | +[INFO] Stream priority: 0 | ||
| 68 | +[INFO] [SUCCESS] Stream config query sample completed successfully | ||
| 69 | +[SUCCESS] Stream config query sample executed successfully. | ||
| 70 | +``` | ||
| 71 | + | ||
| 72 | +如果当前 Runtime 库未导出完整的 Stream Config API,样例会打印跳过信息并正常退出: | ||
| 73 | + | ||
| 74 | +```text | ||
| 75 | +[WARN] Symbol aclrtCreateStreamConfigHandle is not exported by the current Runtime library. | ||
| 76 | +[INFO] [SKIP] Stream config query sample skipped because the current Runtime library does not export all stream config APIs. | ||
| 77 | +[SUCCESS] Stream config query sample skipped because the current environment does not support stream config. | ||
| 78 | +``` | ||
| @@ -0,0 +1,78 @@ | |||
| 1 | +# 3_stream_config_query | ||
| 2 | + | ||
| 3 | +## Description | ||
| 4 | + | ||
| 5 | +This sample demonstrates how to create a Stream with a Stream configuration handle and query the Stream ID, flags, and priority after creation. The sample runs on a single Device and shows the basic flow of configured Stream creation and attribute query. | ||
| 6 | + | ||
| 7 | +## Product Support | ||
| 8 | + | ||
| 9 | +This sample supports the following products: | ||
| 10 | + | ||
| 11 | +| Product | Supported | | ||
| 12 | +| --- | :---: | | ||
| 13 | +| Ascend 950PR/Ascend 950DT | Yes | | ||
| 14 | +| Atlas A3 training series products/Atlas A3 inference series products | Yes | | ||
| 15 | +| Atlas A2 training series products/Atlas A2 inference series products | Yes | | ||
| 16 | + | ||
| 17 | +## Compile and Run | ||
| 18 | + | ||
| 19 | +1. Download the sample code to the environment where CANN is installed. Switch to the sample directory. | ||
| 20 | + | ||
| 21 | +```bash | ||
| 22 | +cd ${git_clone_path}/example/1_basic_features/stream/3_stream_config_query | ||
| 23 | +``` | ||
| 24 | + | ||
| 25 | +2. Set environment variables. | ||
| 26 | + | ||
| 27 | +```bash | ||
| 28 | +# Replace ${install_root} with the CANN installation root directory. The default installation is in `/usr/local/Ascend`. | ||
| 29 | +source ${install_root}/cann/set_env.sh | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +3. Run the following command to execute the sample. | ||
| 33 | + | ||
| 34 | +```bash | ||
| 35 | +bash run.sh | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +## CANN RUNTIME API | ||
| 39 | + | ||
| 40 | +The key functionality points and their key interfaces involved in this sample are as follows: | ||
| 41 | + | ||
| 42 | +- Initialization and Device Management | ||
| 43 | + - Call `aclInit` for ACL initialization. | ||
| 44 | + - Call `aclrtSetDevice` to specify the Device. | ||
| 45 | + - Call `aclrtResetDeviceForce` to reset the current Device. | ||
| 46 | + - Call `aclFinalize` for ACL finalization. | ||
| 47 | +- Stream Configuration and Creation | ||
| 48 | + - Call `aclrtCreateStreamConfigHandle` to create a Stream configuration handle. | ||
| 49 | + - Call `aclrtSetStreamConfigOpt` to set Stream configuration attributes. | ||
| 50 | + - Call `aclrtCreateStreamV2` to create a Stream from the configuration handle. | ||
| 51 | + - Call `aclrtDestroyStreamConfigHandle` to destroy the Stream configuration handle. | ||
| 52 | +- Stream Query and Synchronization | ||
| 53 | + - Call `aclrtStreamGetId` to query the Stream ID. | ||
| 54 | + - Call `aclrtStreamGetFlags` to query the Stream flags. | ||
| 55 | + - Call `aclrtStreamGetPriority` to query the Stream priority. | ||
| 56 | + - Call `aclrtSynchronizeStream` to wait for Stream tasks to finish. | ||
| 57 | + - Call `aclrtDestroyStream` to destroy the Stream. | ||
| 58 | + | ||
| 59 | +## Sample Output | ||
| 60 | + | ||
| 61 | +```text | ||
| 62 | +[INFO] Create stream config handle successfully | ||
| 63 | +[INFO] Set stream config flags=0 priority=0 | ||
| 64 | +[INFO] Create stream with config successfully | ||
| 65 | +[INFO] Stream id: 1 | ||
| 66 | +[INFO] Stream flags: 0 | ||
| 67 | +[INFO] Stream priority: 0 | ||
| 68 | +[INFO] [SUCCESS] Stream config query sample completed successfully | ||
| 69 | +[SUCCESS] Stream config query sample executed successfully. | ||
| 70 | +``` | ||
| 71 | + | ||
| 72 | +If the current Runtime library does not export all Stream Config APIs, the sample prints a skip message and exits normally: | ||
| 73 | + | ||
| 74 | +```text | ||
| 75 | +[WARN] Symbol aclrtCreateStreamConfigHandle is not exported by the current Runtime library. | ||
| 76 | +[INFO] [SKIP] Stream config query sample skipped because the current Runtime library does not export all stream config APIs. | ||
| 77 | +[SUCCESS] Stream config query sample skipped because the current environment does not support stream config. | ||
| 78 | +``` | ||
| @@ -0,0 +1,229 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | +namespace { | ||
| 20 | +constexpr int32_t kDeviceId = 0; | ||
| 21 | +constexpr uint32_t kStreamFlags = 0; | ||
| 22 | +constexpr uint32_t kStreamPriority = 0; | ||
| 23 | + | ||
| 24 | +int CheckAcl(aclError ret, const char *expr) | ||
| 25 | +{ | ||
| 26 | + if (ret != ACL_SUCCESS) { | ||
| 27 | + fprintf(stderr, "[ERROR] Operation failed: %s returned error code %d\n", expr, static_cast<int32_t>(ret)); | ||
| 28 | + fflush(stderr); | ||
| 29 | + return -1; | ||
| 30 | + } | ||
| 31 | + return 0; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +using CreateStreamConfigHandleFunc = aclrtStreamConfigHandle *(*)(); | ||
| 35 | +using DestroyStreamConfigHandleFunc = aclError (*)(aclrtStreamConfigHandle *); | ||
| 36 | +using SetStreamConfigOptFunc = aclError (*)(aclrtStreamConfigHandle *, aclrtStreamConfigAttr, const void *, size_t); | ||
| 37 | +using CreateStreamV2Func = aclError (*)(aclrtStream *, const aclrtStreamConfigHandle *); | ||
| 38 | + | ||
| 39 | +struct StreamConfigApi { | ||
| 40 | + CreateStreamConfigHandleFunc createConfigHandle; | ||
| 41 | + DestroyStreamConfigHandleFunc destroyConfigHandle; | ||
| 42 | + SetStreamConfigOptFunc setConfigOpt; | ||
| 43 | + CreateStreamV2Func createStreamV2; | ||
| 44 | +}; | ||
| 45 | + | ||
| 46 | +class StreamConfigHandleGuard { | ||
| 47 | +public: | ||
| 48 | + StreamConfigHandleGuard(const StreamConfigApi &api, aclrtStreamConfigHandle *handle) | ||
| 49 | + : api_(api), handle_(handle) | ||
| 50 | + { | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + ~StreamConfigHandleGuard() | ||
| 54 | + { | ||
| 55 | + if (handle_ != nullptr) { | ||
| 56 | + CHECK_ERROR_WITHOUT_RETURN(api_.destroyConfigHandle(handle_)); | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + StreamConfigHandleGuard(const StreamConfigHandleGuard &) = delete; | ||
| 61 | + StreamConfigHandleGuard &operator=(const StreamConfigHandleGuard &) = delete; | ||
| 62 | + | ||
| 63 | + aclError Destroy() | ||
| 64 | + { | ||
| 65 | + if (handle_ == nullptr) { | ||
| 66 | + return ACL_SUCCESS; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + aclError ret = api_.destroyConfigHandle(handle_); | ||
| 70 | + if (ret == ACL_SUCCESS) { | ||
| 71 | + handle_ = nullptr; | ||
| 72 | + } | ||
| 73 | + return ret; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | +private: | ||
| 77 | + const StreamConfigApi &api_; | ||
| 78 | + aclrtStreamConfigHandle *handle_; | ||
| 79 | +}; | ||
| 80 | + | ||
| 81 | +class StreamGuard { | ||
| 82 | +public: | ||
| 83 | + explicit StreamGuard(aclrtStream stream) : stream_(stream) {} | ||
| 84 | + | ||
| 85 | + ~StreamGuard() | ||
| 86 | + { | ||
| 87 | + if (stream_ != nullptr) { | ||
| 88 | + CHECK_ERROR_WITHOUT_RETURN(aclrtDestroyStream(stream_)); | ||
| 89 | + } | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + StreamGuard(const StreamGuard &) = delete; | ||
| 93 | + StreamGuard &operator=(const StreamGuard &) = delete; | ||
| 94 | + | ||
| 95 | + aclError Destroy() | ||
| 96 | + { | ||
| 97 | + if (stream_ == nullptr) { | ||
| 98 | + return ACL_SUCCESS; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + aclError ret = aclrtDestroyStream(stream_); | ||
| 102 | + if (ret == ACL_SUCCESS) { | ||
| 103 | + stream_ = nullptr; | ||
| 104 | + } | ||
| 105 | + return ret; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | +private: | ||
| 109 | + aclrtStream stream_; | ||
| 110 | +}; | ||
| 111 | + | ||
| 112 | +template <typename Func> | ||
| 113 | +bool LoadSymbol(void *handle, const char *name, Func *func) | ||
| 114 | +{ | ||
| 115 | + *func = reinterpret_cast<Func>(dlsym(handle, name)); | ||
| 116 | + if (*func == nullptr) { | ||
| 117 | + WARN_LOG("Symbol %s is not exported by the current Runtime library.", name); | ||
| 118 | + return false; | ||
| 119 | + } | ||
| 120 | + return true; | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +bool LoadStreamConfigApi(StreamConfigApi *api) | ||
| 124 | +{ | ||
| 125 | + bool ok = true; | ||
| 126 | + ok = LoadSymbol(RTLD_DEFAULT, "aclrtCreateStreamConfigHandle", &api->createConfigHandle) && ok; | ||
| 127 | + ok = LoadSymbol(RTLD_DEFAULT, "aclrtDestroyStreamConfigHandle", &api->destroyConfigHandle) && ok; | ||
| 128 | + ok = LoadSymbol(RTLD_DEFAULT, "aclrtSetStreamConfigOpt", &api->setConfigOpt) && ok; | ||
| 129 | + ok = LoadSymbol(RTLD_DEFAULT, "aclrtCreateStreamV2", &api->createStreamV2) && ok; | ||
| 130 | + return ok; | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +int SetStreamConfigOptions(const StreamConfigApi &api, aclrtStreamConfigHandle *configHandle) | ||
| 134 | +{ | ||
| 135 | + if (CheckAcl(api.setConfigOpt(configHandle, ACL_RT_STREAM_FLAG, &kStreamFlags, sizeof(kStreamFlags)), | ||
| 136 | + "aclrtSetStreamConfigOpt(ACL_RT_STREAM_FLAG)") != 0) { | ||
| 137 | + return -1; | ||
| 138 | + } | ||
| 139 | + if (CheckAcl(api.setConfigOpt(configHandle, ACL_RT_STREAM_PRIORITY, &kStreamPriority, sizeof(kStreamPriority)), | ||
| 140 | + "aclrtSetStreamConfigOpt(ACL_RT_STREAM_PRIORITY)") != 0) { | ||
| 141 | + return -1; | ||
| 142 | + } | ||
| 143 | + INFO_LOG("Set stream config flags=%u priority=%u", kStreamFlags, kStreamPriority); | ||
| 144 | + return 0; | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +int QueryStreamInfo(aclrtStream stream) | ||
| 148 | +{ | ||
| 149 | + int32_t streamId = -1; | ||
| 150 | + if (CheckAcl(aclrtStreamGetId(stream, &streamId), "aclrtStreamGetId") != 0) { | ||
| 151 | + return -1; | ||
| 152 | + } | ||
| 153 | + INFO_LOG("Stream id: %d", streamId); | ||
| 154 | + | ||
| 155 | + uint32_t flags = 0; | ||
| 156 | + if (CheckAcl(aclrtStreamGetFlags(stream, &flags), "aclrtStreamGetFlags") != 0) { | ||
| 157 | + return -1; | ||
| 158 | + } | ||
| 159 | + INFO_LOG("Stream flags: %u", flags); | ||
| 160 | + | ||
| 161 | + uint32_t priority = 0; | ||
| 162 | + if (CheckAcl(aclrtStreamGetPriority(stream, &priority), "aclrtStreamGetPriority") != 0) { | ||
| 163 | + return -1; | ||
| 164 | + } | ||
| 165 | + INFO_LOG("Stream priority: %u", priority); | ||
| 166 | + return 0; | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +int RunStreamConfigQuerySample() | ||
| 170 | +{ | ||
| 171 | + StreamConfigApi api = {}; | ||
| 172 | + if (!LoadStreamConfigApi(&api)) { | ||
| 173 | + INFO_LOG("[SKIP] Stream config query sample skipped because the current Runtime library does not export all stream config APIs."); | ||
| 174 | + return 0; | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + aclrtStreamConfigHandle *configHandle = api.createConfigHandle(); | ||
| 178 | + if (configHandle == nullptr) { | ||
| 179 | + INFO_LOG("[SKIP] Stream config query sample skipped because aclrtCreateStreamConfigHandle returned nullptr."); | ||
| 180 | + return 0; | ||
| 181 | + } | ||
| 182 | + StreamConfigHandleGuard configHandleGuard(api, configHandle); | ||
| 183 | + INFO_LOG("Create stream config handle successfully"); | ||
| 184 | + | ||
| 185 | + if (SetStreamConfigOptions(api, configHandle) != 0) { | ||
| 186 | + return -1; | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + aclrtStream stream = nullptr; | ||
| 190 | + if (CheckAcl(api.createStreamV2(&stream, configHandle), "aclrtCreateStreamV2") != 0) { | ||
| 191 | + return -1; | ||
| 192 | + } | ||
| 193 | + StreamGuard streamGuard(stream); | ||
| 194 | + INFO_LOG("Create stream with config successfully"); | ||
🟡 Medium Priority
具体 leak 点:
触发条件: 建议:在 ![]() ![]() | |||
| 195 | + | ||
| 196 | + if (QueryStreamInfo(stream) != 0) { | ||
| 197 | + return -1; | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + if (CheckAcl(aclrtSynchronizeStream(stream), "aclrtSynchronizeStream") != 0) { | ||
| 201 | + return -1; | ||
| 202 | + } | ||
| 203 | + if (CheckAcl(streamGuard.Destroy(), "aclrtDestroyStream") != 0) { | ||
| 204 | + return -1; | ||
| 205 | + } | ||
| 206 | + if (CheckAcl(configHandleGuard.Destroy(), "aclrtDestroyStreamConfigHandle") != 0) { | ||
| 207 | + return -1; | ||
| 208 | + } | ||
| 209 | + INFO_LOG("[SUCCESS] Stream config query sample completed successfully"); | ||
| 210 | + return 0; | ||
| 211 | +} | ||
| 212 | +} // namespace | ||
| 213 | + | ||
| 214 | +int32_t main() | ||
| 215 | +{ | ||
| 216 | + if (CheckAcl(aclInit(nullptr), "aclInit") != 0) { | ||
| 217 | + return -1; | ||
| 218 | + } | ||
| 219 | + if (CheckAcl(aclrtSetDevice(kDeviceId), "aclrtSetDevice") != 0) { | ||
| 220 | + CHECK_ERROR(aclFinalize()); | ||
| 221 | + return -1; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + int ret = RunStreamConfigQuerySample(); | ||
| 225 | + | ||
| 226 | + CHECK_ERROR(aclrtResetDeviceForce(kDeviceId)); | ||
| 227 | + CHECK_ERROR(aclFinalize()); | ||
| 228 | + return ret; | ||
| 229 | +} | ||
| @@ -0,0 +1,49 @@ | |||
| 1 | +#!/bin/bash | ||
| 2 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 3 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 4 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 5 | +# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | +# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | +# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | +# ----------------------------------------------------------------------------------------------------------- | ||
| 11 | + | ||
| 12 | +set -euo pipefail | ||
| 13 | + | ||
| 14 | +_ASCEND_CANN_PATH="${ASCEND_HOME_PATH:-}" | ||
| 15 | +if [[ -z "${_ASCEND_CANN_PATH}" ]]; then | ||
| 16 | + echo "[ERROR]: ASCEND_HOME_PATH is not set." | ||
| 17 | + echo "[ERROR]: Please source CANN set_env.sh before running this sample." | ||
| 18 | + exit 1 | ||
| 19 | +fi | ||
| 20 | + | ||
| 21 | +if [[ ! -f "${_ASCEND_CANN_PATH}/bin/setenv.bash" ]]; then | ||
| 22 | + echo "[ERROR]: ${_ASCEND_CANN_PATH}/bin/setenv.bash does not exist." | ||
| 23 | + exit 1 | ||
| 24 | +fi | ||
| 25 | + | ||
| 26 | +source "${_ASCEND_CANN_PATH}/bin/setenv.bash" | ||
| 27 | + | ||
| 28 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
| 29 | +cd "${SCRIPT_DIR}" | ||
| 30 | + | ||
| 31 | +rm -rf build | ||
| 32 | +cmake -B build \ | ||
| 33 | + -DASCEND_CANN_PACKAGE_PATH="${_ASCEND_CANN_PATH}" | ||
| 34 | +cmake --build build -j | ||
| 35 | + | ||
| 36 | +file_path=output_msg.txt | ||
| 37 | +if ! ./build/main | tee "${file_path}"; then | ||
| 38 | + echo "[FAILURE] Stream config query sample failed." | ||
| 39 | + exit 1 | ||
| 40 | +fi | ||
| 41 | + | ||
| 42 | +if grep -q "\\[SUCCESS\\] Stream config query sample completed successfully" "${file_path}"; then | ||
| 43 | + echo "[SUCCESS] Stream config query sample executed successfully." | ||
| 44 | +elif grep -q "\\[SKIP\\] Stream config query sample skipped" "${file_path}"; then | ||
| 45 | + echo "[SUCCESS] Stream config query sample skipped because the current environment does not support stream config." | ||
| 46 | +else | ||
| 47 | + echo "[FAILURE] Stream config query sample did not print the expected success marker." | ||
| 48 | + exit 1 | ||
| 49 | +fi | ||


🟡 Medium Priority
RunContextQuerySample()中,aclrtCreateContext(&context, kDeviceId)成功后(第 26 行),后续多条CHECK_ERROR失败时都会直接return -1退出函数,而没有先调用aclrtDestroyContext(context)销毁已创建的 Context。受影响的行包括第 27 行(aclrtSetCurrentContext失败)、第 30 行(aclrtGetCurrentContext失败)、第 38 行(aclrtCtxGetCurrentDefaultStream失败)、第 41 行和第 44 行(aclrtGetResInCurrentThread失败)。只有在正常流程末尾(第 47 行)和
currentContext != context的错误分支(第 33 行)才会销毁 Context,其余所有错误路径均存在 Context 泄漏。触发条件:
aclrtCreateContext成功后任一后续 CANN API 调用失败。建议:在
RunContextQuerySample中采用统一的错误处理路径(如 goto cleanup 或 RAII wrapper),确保所有 CHECK_ERROR 失败路径都先销毁 Context 再返回。