已合并
add hostlaunch #60
bluesky901创建于 7月31日
add hostlaunch #60
已合并
共 21 个文件变更+4866-1
| @@ -0,0 +1,51 @@ | |||
| 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) | ||
| 12 | + | ||
| 13 | +project(asc_comm LANGUAGES C CXX) | ||
| 14 | + | ||
| 15 | +set(CMAKE_C_STANDARD 11) | ||
| 16 | +set(CMAKE_C_STANDARD_REQUIRED ON) | ||
| 17 | +set(CMAKE_CXX_STANDARD 17) | ||
| 18 | +set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
| 19 | + | ||
| 20 | +option(ASCCOMM_BUILD_CCU "Build asc-comm CCU launch wrapper library" ON) | ||
| 21 | + | ||
| 22 | +if(CUSTOM_ASCEND_CANN_PACKAGE_PATH) | ||
| 23 | + set(_ASCCOMM_CANN_PACKAGE_PATH "${CUSTOM_ASCEND_CANN_PACKAGE_PATH}") | ||
| 24 | +elseif(ASCEND_CANN_PACKAGE_PATH) | ||
| 25 | + set(_ASCCOMM_CANN_PACKAGE_PATH "${ASCEND_CANN_PACKAGE_PATH}") | ||
| 26 | +elseif(DEFINED ENV{ASCEND_HOME_PATH}) | ||
| 27 | + set(_ASCCOMM_CANN_PACKAGE_PATH "$ENV{ASCEND_HOME_PATH}") | ||
| 28 | +elseif(DEFINED ENV{ASCEND_CANN_PACKAGE_PATH}) | ||
| 29 | + set(_ASCCOMM_CANN_PACKAGE_PATH "$ENV{ASCEND_CANN_PACKAGE_PATH}") | ||
| 30 | +elseif(DEFINED ENV{ASCEND_OPP_PATH}) | ||
| 31 | + get_filename_component(_ASCCOMM_CANN_PACKAGE_PATH "$ENV{ASCEND_OPP_PATH}/.." ABSOLUTE) | ||
| 32 | +else() | ||
| 33 | + set(_ASCCOMM_CANN_PACKAGE_PATH "/usr/local/Ascend/cann") | ||
| 34 | +endif() | ||
| 35 | +set(ASCEND_CANN_PACKAGE_PATH "${_ASCCOMM_CANN_PACKAGE_PATH}" CACHE PATH "CANN package path") | ||
| 36 | + | ||
| 37 | +if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm") | ||
| 38 | + set(_ASCCOMM_CANN_ARCH "aarch64-linux") | ||
| 39 | +else() | ||
| 40 | + set(_ASCCOMM_CANN_ARCH "x86_64-linux") | ||
| 41 | +endif() | ||
| 42 | +set(ASCCOMM_CANN_ARCH_DIR "${ASCEND_CANN_PACKAGE_PATH}/${_ASCCOMM_CANN_ARCH}" CACHE PATH | ||
| 43 | + "Architecture-specific CANN package path") | ||
| 44 | +if(ASCEND_CANN_PACKAGE_PATH AND NOT EXISTS "${ASCCOMM_CANN_ARCH_DIR}") | ||
| 45 | + set(ASCCOMM_CANN_ARCH_DIR "${ASCEND_CANN_PACKAGE_PATH}/aarch64-linux" CACHE PATH | ||
| 46 | + "Architecture-specific CANN package path" FORCE) | ||
| 47 | +endif() | ||
| 48 | + | ||
| 49 | +if(ASCCOMM_BUILD_CCU) | ||
| 50 | + add_subdirectory(src/ccu) | ||
| 51 | +endif() | ||
| @@ -14,7 +14,9 @@ | |||
| 14 | <policylist> | 14 | <policylist> |
| 15 | <policy name="projectPolicy" desc="Project allowed licenses"> | 15 | <policy name="projectPolicy" desc="Project allowed licenses"> |
| 16 | <policyitem type="license" name="CANN-2.0" path=".*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc="Approved CANN license"/> | 16 | <policyitem type="license" name="CANN-2.0" path=".*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc="Approved CANN license"/> |
| 17 | + <policyitem type="license" name="BSD-style" path="src/ccu/xxhash_impl\.inc" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter" desc="Approved xxHash BSD 2-Clause license"/> | ||
G | |||
| 17 | <policyitem type="copyright" name="Huawei Technologies Co., Ltd." path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Approved copyright owner"/> | 18 | <policyitem type="copyright" name="Huawei Technologies Co., Ltd." path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Approved copyright owner"/> |
| 19 | + <policyitem type="copyright" name="Yann Collet" path="src/ccu/xxhash_impl\.inc" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Approved xxHash copyright owner"/> | ||
| 18 | <policyitem type="filetype" name="!binary" path=".*" rule="must" group="defaultGroup" filefilter="binaryFileTypePolicyFilter" desc="Reject binary files unless explicitly filtered"/> | 20 | <policyitem type="filetype" name="!binary" path=".*" rule="must" group="defaultGroup" filefilter="binaryFileTypePolicyFilter" desc="Reject binary files unless explicitly filtered"/> |
| 19 | </policy> | 21 | </policy> |
| 20 | </policylist> | 22 | </policylist> |
| @@ -22,3 +22,22 @@ Redistribution and use in source and binary forms, with or without modification, | |||
| 22 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. | 22 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
| 23 | 23 | ||
| 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 | + | ||
| 26 | +Software: xxHash | ||
| 27 | +Copyright notice: | ||
| 28 | +Copyright (C) 2012-2023 Yann Collet | ||
| 29 | +All rights reserved. | ||
| 30 | + | ||
| 31 | +License: BSD 2-Clause License | ||
| 32 | +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | ||
| 33 | + | ||
| 34 | +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | ||
| 35 | + | ||
| 36 | +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | ||
| 37 | + | ||
| 38 | +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 39 | +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 40 | +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
| 41 | +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | ||
| 42 | +AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
| 43 | +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| @@ -0,0 +1,73 @@ | |||
| 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 | +find_package(ASC REQUIRED) | ||
| 13 | +project(hccl_examples_custom_ops_allgather_ccu_direct LANGUAGES CXX ASC) | ||
| 14 | + | ||
| 15 | +if(NOT DEFINED ASCEND_CANN_PACKAGE_PATH) | ||
| 16 | + if(DEFINED ENV{ASCEND_HOME_PATH}) | ||
| 17 | + set(ASCEND_CANN_PACKAGE_PATH $ENV{ASCEND_HOME_PATH}) | ||
| 18 | + elseif(DEFINED ENV{ASCEND_OPP_PATH}) | ||
| 19 | + get_filename_component(ASCEND_CANN_PACKAGE_PATH "$ENV{ASCEND_OPP_PATH}/.." ABSOLUTE) | ||
| 20 | + else() | ||
| 21 | + message(FATAL_ERROR "ASCEND_CANN_PACKAGE_PATH or ASCEND_HOME_PATH must be set") | ||
| 22 | + endif() | ||
| 23 | +endif() | ||
| 24 | + | ||
| 25 | +add_executable(demo | ||
| 26 | + main.asc | ||
| 27 | +) | ||
| 28 | + | ||
| 29 | +target_include_directories(demo PRIVATE | ||
| 30 | + # CANN Toolkit头文件 | ||
| 31 | + ${ASCEND_CANN_PACKAGE_PATH}/include | ||
| 32 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hccl | ||
| 33 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm | ||
B 缺少asc/include/头文件路径包含 ![]() ![]() | |||
| 34 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm/ccu | ||
| 35 | + ${ASCEND_CANN_PACKAGE_PATH}/asc/include/comm_api/ccu | ||
| 36 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc | ||
| 37 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/hcomm | ||
| 38 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/hcomm/ccu | ||
| 39 | +) | ||
| 40 | + | ||
| 41 | +target_compile_features(demo PRIVATE cxx_std_14) | ||
| 42 | +target_compile_options(demo PRIVATE | ||
| 43 | + -Werror | ||
| 44 | + -fstack-protector-strong | ||
| 45 | + -fPIE | ||
| 46 | + -O2 | ||
| 47 | + # -s | ||
| 48 | +) | ||
| 49 | +set(CMAKE_ASC_ARCHITECTURES "dav-3510" CACHE STRING "CMAKE_ASC_ARCHITECTURES, e.g. dav-3510") | ||
| 50 | +target_compile_options(demo PRIVATE | ||
| 51 | + $<$<COMPILE_LANGUAGE:ASC>:--npu-arch=${CMAKE_ASC_ARCHITECTURES}> | ||
| 52 | +) | ||
| 53 | + | ||
| 54 | +target_compile_definitions(demo PRIVATE | ||
| 55 | + _GLIBCXX_USE_CXX11_ABI=0 | ||
| 56 | +) | ||
| 57 | +target_link_options(demo PRIVATE | ||
| 58 | + -pie | ||
| 59 | + -Wl,-z,relro | ||
| 60 | + -Wl,-z,now | ||
| 61 | + -Wl,-z,noexecstack | ||
| 62 | +) | ||
| 63 | +target_link_directories(demo PRIVATE | ||
| 64 | + ${ASCEND_CANN_PACKAGE_PATH}/lib64 | ||
| 65 | +) | ||
| 66 | +target_link_libraries(demo PRIVATE | ||
| 67 | + hcomm | ||
| 68 | + asccomm_ccu | ||
| 69 | + c_sec | ||
| 70 | + ascendcl | ||
| 71 | + acl_rt | ||
| 72 | + ascendc_runtime | ||
| 73 | +) | ||
| @@ -0,0 +1,112 @@ | |||
| 1 | +# CCU Direct AllGather样例 | ||
| 2 | + | ||
| 3 | +## 概述 | ||
| 4 | + | ||
| 5 | +本样例展示如何基于HCCL通信域和CCU数据面接口,以直调`<<<>>>`方式实现AllGather集合通信操作。 | ||
| 6 | + | ||
| 7 | +样例会根据当前环境中的NPU数量创建通信域,每个Device对应一个rank。每个rank输入一段FP32数据,CCU | ||
| 8 | +Kernel完成AllGather后,每个rank的输出Buffer中按rank顺序保存所有rank的输入数据。 | ||
| 9 | + | ||
| 10 | +## 本样例支持的产品及CANN软件版本 | ||
| 11 | + | ||
| 12 | +| 产品 | CANN软件版本 | | ||
| 13 | +| --- | --- | | ||
| 14 | +| Ascend 950PR/Ascend 950DT | >= CANN 9.1.0 | | ||
| 15 | + | ||
| 16 | +## 目录结构介绍 | ||
| 17 | + | ||
| 18 | +```text | ||
| 19 | +01_allgather | ||
| 20 | +├── CMakeLists.txt // 编译工程文件 | ||
| 21 | +├── README.md // 中文样例说明 | ||
| 22 | +├── README_en.md // 英文样例说明 | ||
| 23 | +└── main.asc // Host侧流程和CCU AllGather Kernel实现 | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +## 样例描述 | ||
| 27 | + | ||
| 28 | +### 功能说明 | ||
| 29 | + | ||
| 30 | +每个rank的输入为`sendCount`个FP32元素。AllGather完成后,每个rank的`recvBuf`按rank顺序保存所有rank | ||
| 31 | +的输入: | ||
| 32 | + | ||
| 33 | +```text | ||
| 34 | +rank r sendBuf = segment_r | ||
| 35 | +rank p recvBuf = [segment_0 | segment_1 | ... | segment_N-1] | ||
| 36 | +``` | ||
| 37 | + | ||
D 应加上支持的cann版本 ![]() ![]() | |||
| 38 | +### 样例规格 | ||
| 39 | + | ||
| 40 | +| 项目 | 说明 | | ||
| 41 | +| --- | --- | | ||
| 42 | +| 通信模式 | HCCL通信域内CCU AllGather | | ||
| 43 | +| 调用方式 | CCU Kernel直调`<<<>>>` | | ||
| 44 | +| 数据类型 | FP32 | | ||
| 45 | +| 单rank输入规模 | 256个FP32元素 | | ||
| 46 | +| 输出规模 | `rankSize * 256`个FP32元素 | | ||
| 47 | +| 支持rank数 | 不超过`CCU_MAX_RANK_SIZE`,当前样例中为16 | | ||
| 48 | + | ||
| 49 | +### 实现流程 | ||
| 50 | + | ||
| 51 | +1. 初始化ACL和HCCL通信域,获取当前环境中的NPU数量。 | ||
| 52 | +2. 每个Device创建一个rank,并初始化输入Buffer。 | ||
| 53 | +3. 基于HCCL通信域申请CCU Channel和CCU实例资源。 | ||
| 54 | +4. 通过`HcommCcuGetMemToken`获取输入内存Token,并准备CCU任务参数。 | ||
| 55 | +5. 通过`CcuAllGatherMesh1DMem2MemKernel<<<schd, insHandle, stream>>>`直调CCU Kernel。 | ||
| 56 | +6. 同步Stream后将结果拷贝回Host侧并打印。 | ||
| 57 | +7. 销毁HCCL通信域、Stream和Device侧内存。 | ||
| 58 | + | ||
| 59 | +## 编译运行 | ||
| 60 | + | ||
| 61 | +在本样例根目录下执行如下步骤,编译并运行样例。本样例仅支持NPU运行模式。 | ||
| 62 | + | ||
| 63 | +- 配置环境变量 | ||
| 64 | + | ||
| 65 | + 请根据当前环境上CANN开发套件包的安装方式配置环境变量,并开启CCU调度模式。 | ||
| 66 | + | ||
| 67 | + ```bash | ||
| 68 | + source ${install_path}/cann/set_env.sh | ||
| 69 | + export HCCL_OP_EXPANSION_MODE=CCU_SCHED | ||
| 70 | + ``` | ||
| 71 | + | ||
| 72 | + > **说明:** `${install_path}`为CANN包安装目录,未指定安装目录时默认安装至`/usr/local/Ascend`。 | ||
| 73 | + | ||
| 74 | +- 样例执行 | ||
| 75 | + | ||
| 76 | + 在本样例目录下执行如下命令。 | ||
| 77 | + | ||
| 78 | + ```bash | ||
| 79 | + mkdir -p build | ||
| 80 | + cd build | ||
| 81 | + cmake -DCMAKE_ASC_ARCHITECTURES=dav-3510 .. | ||
| 82 | + make -j | ||
| 83 | + ./demo | ||
| 84 | + ``` | ||
| 85 | + | ||
| 86 | +- 编译选项说明 | ||
| 87 | + | ||
| 88 | + | 选项 | 可选值 | 说明 | | ||
| 89 | + | --- | --- | --- | | ||
| 90 | + | `CMAKE_ASC_RUN_MODE` | `npu`(默认) | 运行模式,本样例仅支持NPU运行 | | ||
| 91 | + | `CMAKE_ASC_ARCHITECTURES` | `dav-3510` | NPU架构,对应Ascend 950PR/Ascend 950DT | | ||
| 92 | + | ||
| 93 | +- 执行结果 | ||
| 94 | + | ||
| 95 | + 两卡场景下,rank `d`的输入元素初始化为`d + 1`。运行成功后终端会输出类似以下信息: | ||
| 96 | + | ||
| 97 | + ```text | ||
| 98 | + Found 2 NPU device(s) available | ||
| 99 | + rankId: 0, input: [ 1 1 1 ... ] | ||
| 100 | + rankId: 1, input: [ 2 2 2 ... ] | ||
| 101 | + rankId: 0, recvBuf: [ 1 1 1 ... 2 2 2 ... ] | ||
| 102 | + rankId: 1, recvBuf: [ 1 1 1 ... 2 2 2 ... ] | ||
| 103 | + ``` | ||
| 104 | + | ||
| 105 | + 每个rank的`recvBuf`均包含所有rank的输入数据,表示样例执行成功。 | ||
| 106 | + | ||
| 107 | +## 注意事项 | ||
| 108 | + | ||
| 109 | +- 运行样例需要至少2张NPU;单卡环境仅支持编译验证。 | ||
| 110 | +- 运行前必须设置`HCCL_OP_EXPANSION_MODE=CCU_SCHED`。 | ||
| 111 | +- 当前样例默认使用`dav-3510`架构,仅覆盖Ascend 950PR/Ascend 950DT场景。 | ||
| 112 | +- 当前样例会使用环境中可见的全部NPU设备,设备数量不能超过`CCU_MAX_RANK_SIZE`。 | ||
| @@ -0,0 +1,114 @@ | |||
| 1 | +# CCU Direct AllGather Sample | ||
| 2 | + | ||
| 3 | +## Overview | ||
| 4 | + | ||
| 5 | +This sample demonstrates how to implement AllGather collective communication over an HCCL communication domain and | ||
| 6 | +CCU data-plane APIs by directly launching the CCU kernel with `<<<>>>`. | ||
| 7 | + | ||
| 8 | +The sample creates one rank for each available NPU device. Each rank provides one FP32 input segment. After the | ||
| 9 | +CCU kernel completes AllGather, the output buffer on every rank contains all rank input segments in rank order. | ||
| 10 | + | ||
| 11 | +## Supported Products and CANN Software Versions | ||
| 12 | + | ||
| 13 | +| Product | CANN Software Version | | ||
| 14 | +| --- | --- | | ||
| 15 | +| Ascend 950PR/Ascend 950DT | >= CANN 9.1.0 | | ||
| 16 | + | ||
| 17 | +## Directory Structure | ||
| 18 | + | ||
| 19 | +```text | ||
| 20 | +01_allgather | ||
| 21 | +├── CMakeLists.txt // Build configuration file | ||
| 22 | +├── README.md // Chinese documentation | ||
| 23 | +├── README_en.md // English documentation | ||
| 24 | +└── main.asc // Host flow and CCU AllGather kernel implementation | ||
| 25 | +``` | ||
| 26 | + | ||
| 27 | +## Sample Description | ||
| 28 | + | ||
| 29 | +### Functionality | ||
| 30 | + | ||
| 31 | +Each rank input contains `sendCount` FP32 elements. After AllGather, `recvBuf` on every rank stores all rank input | ||
| 32 | +segments in rank order: | ||
| 33 | + | ||
| 34 | +```text | ||
| 35 | +rank r sendBuf = segment_r | ||
| 36 | +rank p recvBuf = [segment_0 | segment_1 | ... | segment_N-1] | ||
| 37 | +``` | ||
| 38 | + | ||
| 39 | +### Specifications | ||
| 40 | + | ||
| 41 | +| Item | Description | | ||
| 42 | +| --- | --- | | ||
| 43 | +| Communication mode | CCU AllGather in an HCCL communication domain | | ||
| 44 | +| Launch mode | Direct CCU kernel launch with `<<<>>>` | | ||
| 45 | +| Data type | FP32 | | ||
| 46 | +| Input size per rank | 256 FP32 elements | | ||
| 47 | +| Output size | `rankSize * 256` FP32 elements | | ||
| 48 | +| Supported ranks | No more than `CCU_MAX_RANK_SIZE`, which is 16 in this sample | | ||
| 49 | + | ||
| 50 | +### Implementation Flow | ||
| 51 | + | ||
| 52 | +1. Initialize ACL and the HCCL communication domain, and query the number of NPU devices. | ||
| 53 | +2. Create one rank for each device and initialize the input buffer. | ||
| 54 | +3. Acquire CCU channels and CCU instance resources from the HCCL communication domain. | ||
| 55 | +4. Obtain the input memory token through `HcommCcuGetMemToken` and prepare CCU task arguments. | ||
| 56 | +5. Directly launch the CCU kernel through `CcuAllGatherMesh1DMem2MemKernel<<<schd, insHandle, stream>>>`. | ||
| 57 | +6. Synchronize the stream, copy the result back to the host, and print it. | ||
| 58 | +7. Destroy the HCCL communication domain, streams, and device memory. | ||
| 59 | + | ||
| 60 | +## Build and Run | ||
| 61 | + | ||
| 62 | +Perform the following steps in the sample root directory. This sample supports NPU run mode only. | ||
| 63 | + | ||
| 64 | +- Set Environment Variables | ||
| 65 | + | ||
| 66 | + Configure CANN environment variables according to your installation and enable CCU scheduling mode. | ||
| 67 | + | ||
| 68 | + ```bash | ||
| 69 | + source ${install_path}/cann/set_env.sh | ||
| 70 | + export HCCL_OP_EXPANSION_MODE=CCU_SCHED | ||
| 71 | + ``` | ||
| 72 | + | ||
| 73 | + > **Note:** `${install_path}` is the CANN installation directory. The default installation directory is | ||
| 74 | + > `/usr/local/Ascend`. | ||
| 75 | + | ||
| 76 | +- Run the Sample | ||
| 77 | + | ||
| 78 | + Run the following commands in the sample directory. | ||
| 79 | + | ||
| 80 | + ```bash | ||
| 81 | + mkdir -p build | ||
| 82 | + cd build | ||
| 83 | + cmake -DCMAKE_ASC_ARCHITECTURES=dav-3510 .. | ||
| 84 | + make -j | ||
| 85 | + ./demo | ||
| 86 | + ``` | ||
| 87 | + | ||
| 88 | +- Build Options | ||
| 89 | + | ||
| 90 | + | Option | Values | Description | | ||
| 91 | + | --- | --- | --- | | ||
| 92 | + | `CMAKE_ASC_RUN_MODE` | `npu` (default) | Run mode. This sample supports NPU execution only | | ||
| 93 | + | `CMAKE_ASC_ARCHITECTURES` | `dav-3510` | NPU architecture for Ascend 950PR/Ascend 950DT | | ||
| 94 | + | ||
| 95 | +- Expected Output | ||
| 96 | + | ||
| 97 | + In a two-device run, the input elements of rank `d` are initialized to `d + 1`. The output is similar to: | ||
| 98 | + | ||
| 99 | + ```text | ||
| 100 | + Found 2 NPU device(s) available | ||
| 101 | + rankId: 0, input: [ 1 1 1 ... ] | ||
| 102 | + rankId: 1, input: [ 2 2 2 ... ] | ||
| 103 | + rankId: 0, recvBuf: [ 1 1 1 ... 2 2 2 ... ] | ||
| 104 | + rankId: 1, recvBuf: [ 1 1 1 ... 2 2 2 ... ] | ||
| 105 | + ``` | ||
| 106 | + | ||
| 107 | + The sample succeeds when `recvBuf` on every rank contains all rank input segments. | ||
| 108 | + | ||
| 109 | +## Notes | ||
| 110 | + | ||
| 111 | +- At least two NPU devices are required to run the sample. Single-device environments support compilation only. | ||
| 112 | +- Set `HCCL_OP_EXPANSION_MODE=CCU_SCHED` before running the sample. | ||
| 113 | +- The sample uses `dav-3510` by default and covers Ascend 950PR/Ascend 950DT. | ||
| 114 | +- The sample uses all visible NPU devices, and the device count must not exceed `CCU_MAX_RANK_SIZE`. | ||
| @@ -0,0 +1,73 @@ | |||
| 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 | +find_package(ASC REQUIRED) | ||
| 13 | +project(hccl_examples_custom_ops_allgather_ccu_direct LANGUAGES CXX ASC) | ||
| 14 | + | ||
| 15 | +if(NOT DEFINED ASCEND_CANN_PACKAGE_PATH) | ||
| 16 | + if(DEFINED ENV{ASCEND_HOME_PATH}) | ||
| 17 | + set(ASCEND_CANN_PACKAGE_PATH $ENV{ASCEND_HOME_PATH}) | ||
| 18 | + elseif(DEFINED ENV{ASCEND_OPP_PATH}) | ||
| 19 | + get_filename_component(ASCEND_CANN_PACKAGE_PATH "$ENV{ASCEND_OPP_PATH}/.." ABSOLUTE) | ||
| 20 | + else() | ||
| 21 | + message(FATAL_ERROR "ASCEND_CANN_PACKAGE_PATH or ASCEND_HOME_PATH must be set") | ||
| 22 | + endif() | ||
| 23 | +endif() | ||
| 24 | + | ||
| 25 | +add_executable(demo | ||
| 26 | + main.asc | ||
| 27 | +) | ||
| 28 | + | ||
| 29 | +target_include_directories(demo PRIVATE | ||
| 30 | + # CANN Toolkit头文件 | ||
| 31 | + ${ASCEND_CANN_PACKAGE_PATH}/include | ||
| 32 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hccl | ||
| 33 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm | ||
B 缺少asc/include/头文件路径包含 ![]() ![]() | |||
| 34 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm/ccu | ||
| 35 | + ${ASCEND_CANN_PACKAGE_PATH}/asc/include/comm_api/ccu | ||
| 36 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc | ||
| 37 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/hcomm | ||
| 38 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/hcomm/ccu | ||
| 39 | +) | ||
| 40 | + | ||
| 41 | +target_compile_features(demo PRIVATE cxx_std_14) | ||
| 42 | +target_compile_options(demo PRIVATE | ||
| 43 | + -Werror | ||
| 44 | + -fstack-protector-strong | ||
| 45 | + -fPIE | ||
| 46 | + -O2 | ||
| 47 | + # -s | ||
| 48 | +) | ||
| 49 | +set(CMAKE_ASC_ARCHITECTURES "dav-3510" CACHE STRING "CMAKE_ASC_ARCHITECTURES, e.g. dav-3510") | ||
| 50 | +target_compile_options(demo PRIVATE | ||
| 51 | + $<$<COMPILE_LANGUAGE:ASC>:--npu-arch=${CMAKE_ASC_ARCHITECTURES}> | ||
| 52 | +) | ||
| 53 | + | ||
| 54 | +target_compile_definitions(demo PRIVATE | ||
| 55 | + _GLIBCXX_USE_CXX11_ABI=0 | ||
| 56 | +) | ||
| 57 | +target_link_options(demo PRIVATE | ||
| 58 | + -pie | ||
| 59 | + -Wl,-z,relro | ||
| 60 | + -Wl,-z,now | ||
| 61 | + -Wl,-z,noexecstack | ||
| 62 | +) | ||
| 63 | +target_link_directories(demo PRIVATE | ||
| 64 | + ${ASCEND_CANN_PACKAGE_PATH}/lib64 | ||
| 65 | +) | ||
| 66 | +target_link_libraries(demo PRIVATE | ||
| 67 | + hcomm | ||
| 68 | + asccomm_ccu | ||
| 69 | + c_sec | ||
| 70 | + ascendcl | ||
| 71 | + acl_rt | ||
| 72 | + ascendc_runtime | ||
| 73 | +) | ||
| @@ -0,0 +1,114 @@ | |||
| 1 | +# CCU Direct AllGather + Add样例 | ||
| 2 | + | ||
| 3 | +## 概述 | ||
| 4 | + | ||
| 5 | +本样例展示如何先通过CCU以直调`<<<>>>`方式完成AllGather通信,再通过AICore vector kernel对AllGather | ||
| 6 | +结果执行Add计算。 | ||
| 7 | + | ||
| 8 | +样例会根据当前环境中的NPU数量创建通信域,每个Device对应一个rank。每个rank输入一段FP32数据,先完成 | ||
| 9 | +跨rank AllGather,再将聚合后的结果作为AICore计算输入。 | ||
| 10 | + | ||
| 11 | +## 本样例支持的产品及CANN软件版本 | ||
| 12 | + | ||
| 13 | +| 产品 | CANN软件版本 | | ||
| 14 | +| --- | --- | | ||
| 15 | +| Ascend 950PR/Ascend 950DT | >= CANN 9.1.0 | | ||
| 16 | + | ||
| 17 | +## 目录结构介绍 | ||
| 18 | + | ||
| 19 | +```text | ||
| 20 | +02_allgather_add | ||
| 21 | +├── CMakeLists.txt // 编译工程文件 | ||
| 22 | +├── README.md // 中文样例说明 | ||
| 23 | +├── README_en.md // 英文样例说明 | ||
| 24 | +└── main.asc // Host侧流程、CCU AllGather Kernel和AICore Add Kernel实现 | ||
| 25 | +``` | ||
| 26 | + | ||
| 27 | +## 样例描述 | ||
| 28 | + | ||
| 29 | +### 功能说明 | ||
| 30 | + | ||
| 31 | +每个rank的输入为`sendCount`个FP32元素。样例先将各rank输入AllGather到每个rank的`recvBuf`,再通过 | ||
| 32 | +AICore vector kernel读取`recvBuf`并将Add结果写入`computeBuf`。 | ||
| 33 | + | ||
| 34 | +```text | ||
| 35 | +sendBuf -> CCU AllGather -> recvBuf -> AICore Add -> computeBuf | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +### 样例规格 | ||
| 39 | + | ||
| 40 | +| 项目 | 说明 | | ||
| 41 | +| --- | --- | | ||
| 42 | +| 通信模式 | HCCL通信域内CCU AllGather | | ||
| 43 | +| 调用方式 | CCU Kernel直调`<<<>>>`,AICore Kernel直调`<<<>>>` | | ||
| 44 | +| 数据类型 | FP32 | | ||
| 45 | +| 单rank输入规模 | 256个FP32元素 | | ||
| 46 | +| AllGather输出规模 | `rankSize * 256`个FP32元素 | | ||
| 47 | +| Add输出规模 | `rankSize * 256`个FP32元素 | | ||
| 48 | +| 支持rank数 | 不超过`CCU_MAX_RANK_SIZE`,当前样例中为16 | | ||
| 49 | + | ||
| 50 | +### 实现流程 | ||
| 51 | + | ||
| 52 | +1. 初始化ACL和HCCL通信域,获取当前环境中的NPU数量。 | ||
| 53 | +2. 每个Device创建一个rank,并初始化输入Buffer。 | ||
| 54 | +3. 基于HCCL通信域申请CCU Channel、CCU实例、CCU变量和CCU事件资源。 | ||
| 55 | +4. 通过`HcommCcuGetMemToken`获取输入内存Token,并准备CCU任务参数。 | ||
| 56 | +5. 通过`CcuAllGatherMesh1DMem2MemKernel<<<schd, insHandle, streamCcu>>>`直调CCU Kernel完成AllGather。 | ||
| 57 | +6. 通过`vector_add<<<1, nullptr, streamAiv>>>`直调AICore vector kernel,对AllGather结果执行Add计算。 | ||
| 58 | +7. 同步AIV和CCU Stream后将`computeBuf`拷贝回Host侧并打印。 | ||
| 59 | +8. 销毁HCCL通信域、Stream和Device侧内存。 | ||
| 60 | + | ||
| 61 | +## 编译运行 | ||
| 62 | + | ||
| 63 | +在本样例根目录下执行如下步骤,编译并运行样例。本样例仅支持NPU运行模式。 | ||
| 64 | + | ||
| 65 | +- 配置环境变量 | ||
| 66 | + | ||
| 67 | + 请根据当前环境上CANN开发套件包的安装方式配置环境变量,并开启CCU调度模式。 | ||
| 68 | + | ||
| 69 | + ```bash | ||
| 70 | + source ${install_path}/cann/set_env.sh | ||
| 71 | + export HCCL_OP_EXPANSION_MODE=CCU_SCHED | ||
| 72 | + ``` | ||
| 73 | + | ||
| 74 | + > **说明:** `${install_path}`为CANN包安装目录,未指定安装目录时默认安装至`/usr/local/Ascend`。 | ||
| 75 | + | ||
| 76 | +- 样例执行 | ||
| 77 | + | ||
| 78 | + 在本样例目录下执行如下命令。 | ||
| 79 | + | ||
| 80 | + ```bash | ||
| 81 | + mkdir -p build | ||
| 82 | + cd build | ||
| 83 | + cmake -DCMAKE_ASC_ARCHITECTURES=dav-3510 .. | ||
| 84 | + make -j | ||
| 85 | + ./demo | ||
| 86 | + ``` | ||
| 87 | + | ||
| 88 | +- 编译选项说明 | ||
| 89 | + | ||
| 90 | + | 选项 | 可选值 | 说明 | | ||
| 91 | + | --- | --- | --- | | ||
| 92 | + | `CMAKE_ASC_RUN_MODE` | `npu`(默认) | 运行模式,本样例仅支持NPU运行 | | ||
| 93 | + | `CMAKE_ASC_ARCHITECTURES` | `dav-3510` | NPU架构,对应Ascend 950PR/Ascend 950DT | | ||
| 94 | + | ||
| 95 | +- 执行结果 | ||
| 96 | + | ||
| 97 | + 两卡场景下,rank `d`的输入元素初始化为`d + 1`。运行成功后终端会输出类似以下信息: | ||
| 98 | + | ||
| 99 | + ```text | ||
| 100 | + Found 2 NPU device(s) available | ||
| 101 | + rankId: 0, input: [ 1 1 1 ... ] | ||
| 102 | + rankId: 1, input: [ 2 2 2 ... ] | ||
| 103 | + rankId: 0, computeBuf: [ 9 9 9 ... 10 10 10 ... ] | ||
| 104 | + rankId: 1, computeBuf: [ 9 9 9 ... 10 10 10 ... ] | ||
| 105 | + ``` | ||
| 106 | + | ||
| 107 | + 每个rank均完成AllGather并输出AICore Add后的结果,表示样例执行成功。 | ||
| 108 | + | ||
| 109 | +## 注意事项 | ||
| 110 | + | ||
| 111 | +- 运行样例需要至少2张NPU;单卡环境仅支持编译验证。 | ||
| 112 | +- 运行前必须设置`HCCL_OP_EXPANSION_MODE=CCU_SCHED`。 | ||
| 113 | +- 当前样例默认使用`dav-3510`架构,仅覆盖Ascend 950PR/Ascend 950DT场景。 | ||
| 114 | +- 当前样例会使用环境中可见的全部NPU设备,设备数量不能超过`CCU_MAX_RANK_SIZE`。 | ||
| @@ -0,0 +1,116 @@ | |||
| 1 | +# CCU Direct AllGather + Add Sample | ||
| 2 | + | ||
| 3 | +## Overview | ||
| 4 | + | ||
| 5 | +This sample demonstrates how to complete AllGather communication by directly launching a CCU kernel with `<<<>>>`, | ||
| 6 | +and then run an AICore vector kernel to perform Add computation on the AllGather result. | ||
| 7 | + | ||
| 8 | +The sample creates one rank for each available NPU device. Each rank provides one FP32 input segment. The sample | ||
| 9 | +first gathers all rank inputs to every rank and then uses the gathered data as the input of the AICore computation. | ||
| 10 | + | ||
| 11 | +## Supported Products and CANN Software Versions | ||
| 12 | + | ||
| 13 | +| Product | CANN Software Version | | ||
| 14 | +| --- | --- | | ||
| 15 | +| Ascend 950PR/Ascend 950DT | >= CANN 9.1.0 | | ||
| 16 | + | ||
| 17 | +## Directory Structure | ||
| 18 | + | ||
| 19 | +```text | ||
| 20 | +02_allgather_add | ||
| 21 | +├── CMakeLists.txt // Build configuration file | ||
| 22 | +├── README.md // Chinese documentation | ||
| 23 | +├── README_en.md // English documentation | ||
| 24 | +└── main.asc // Host flow, CCU AllGather kernel, and AICore Add kernel implementation | ||
| 25 | +``` | ||
| 26 | + | ||
| 27 | +## Sample Description | ||
| 28 | + | ||
| 29 | +### Functionality | ||
| 30 | + | ||
| 31 | +Each rank input contains `sendCount` FP32 elements. The sample first gathers all rank inputs to `recvBuf` on every | ||
| 32 | +rank, and then an AICore vector kernel reads `recvBuf` and writes the Add result to `computeBuf`. | ||
| 33 | + | ||
| 34 | +```text | ||
| 35 | +sendBuf -> CCU AllGather -> recvBuf -> AICore Add -> computeBuf | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +### Specifications | ||
| 39 | + | ||
| 40 | +| Item | Description | | ||
| 41 | +| --- | --- | | ||
| 42 | +| Communication mode | CCU AllGather in an HCCL communication domain | | ||
| 43 | +| Launch mode | Direct CCU kernel launch with `<<<>>>` and direct AICore kernel launch with `<<<>>>` | | ||
| 44 | +| Data type | FP32 | | ||
| 45 | +| Input size per rank | 256 FP32 elements | | ||
| 46 | +| AllGather output size | `rankSize * 256` FP32 elements | | ||
| 47 | +| Add output size | `rankSize * 256` FP32 elements | | ||
| 48 | +| Supported ranks | No more than `CCU_MAX_RANK_SIZE`, which is 16 in this sample | | ||
| 49 | + | ||
| 50 | +### Implementation Flow | ||
| 51 | + | ||
| 52 | +1. Initialize ACL and the HCCL communication domain, and query the number of NPU devices. | ||
| 53 | +2. Create one rank for each device and initialize the input buffer. | ||
| 54 | +3. Acquire CCU channels, a CCU instance, CCU variables, and CCU events from the HCCL communication domain. | ||
| 55 | +4. Obtain the input memory token through `HcommCcuGetMemToken` and prepare CCU task arguments. | ||
| 56 | +5. Directly launch the CCU kernel through `CcuAllGatherMesh1DMem2MemKernel<<<schd, insHandle, streamCcu>>>`. | ||
| 57 | +6. Directly launch the AICore vector kernel through `vector_add<<<1, nullptr, streamAiv>>>` to compute the | ||
| 58 | + AllGather result. | ||
| 59 | +7. Synchronize the AIV and CCU streams, copy `computeBuf` back to the host, and print it. | ||
| 60 | +8. Destroy the HCCL communication domain, streams, and device memory. | ||
| 61 | + | ||
| 62 | +## Build and Run | ||
| 63 | + | ||
| 64 | +Perform the following steps in the sample root directory. This sample supports NPU run mode only. | ||
| 65 | + | ||
| 66 | +- Set Environment Variables | ||
| 67 | + | ||
| 68 | + Configure CANN environment variables according to your installation and enable CCU scheduling mode. | ||
| 69 | + | ||
| 70 | + ```bash | ||
| 71 | + source ${install_path}/cann/set_env.sh | ||
| 72 | + export HCCL_OP_EXPANSION_MODE=CCU_SCHED | ||
| 73 | + ``` | ||
| 74 | + | ||
| 75 | + > **Note:** `${install_path}` is the CANN installation directory. The default installation directory is | ||
| 76 | + > `/usr/local/Ascend`. | ||
| 77 | + | ||
| 78 | +- Run the Sample | ||
| 79 | + | ||
| 80 | + Run the following commands in the sample directory. | ||
| 81 | + | ||
| 82 | + ```bash | ||
| 83 | + mkdir -p build | ||
| 84 | + cd build | ||
| 85 | + cmake -DCMAKE_ASC_ARCHITECTURES=dav-3510 .. | ||
| 86 | + make -j | ||
| 87 | + ./demo | ||
| 88 | + ``` | ||
| 89 | + | ||
| 90 | +- Build Options | ||
| 91 | + | ||
| 92 | + | Option | Values | Description | | ||
| 93 | + | --- | --- | --- | | ||
| 94 | + | `CMAKE_ASC_RUN_MODE` | `npu` (default) | Run mode. This sample supports NPU execution only | | ||
| 95 | + | `CMAKE_ASC_ARCHITECTURES` | `dav-3510` | NPU architecture for Ascend 950PR/Ascend 950DT | | ||
| 96 | + | ||
| 97 | +- Expected Output | ||
| 98 | + | ||
| 99 | + In a two-device run, the input elements of rank `d` are initialized to `d + 1`. The output is similar to: | ||
| 100 | + | ||
| 101 | + ```text | ||
| 102 | + Found 2 NPU device(s) available | ||
| 103 | + rankId: 0, input: [ 1 1 1 ... ] | ||
| 104 | + rankId: 1, input: [ 2 2 2 ... ] | ||
| 105 | + rankId: 0, computeBuf: [ 9 9 9 ... 10 10 10 ... ] | ||
| 106 | + rankId: 1, computeBuf: [ 9 9 9 ... 10 10 10 ... ] | ||
| 107 | + ``` | ||
| 108 | + | ||
| 109 | + The sample succeeds when every rank completes AllGather and prints the AICore Add result. | ||
| 110 | + | ||
| 111 | +## Notes | ||
| 112 | + | ||
| 113 | +- At least two NPU devices are required to run the sample. Single-device environments support compilation only. | ||
| 114 | +- Set `HCCL_OP_EXPANSION_MODE=CCU_SCHED` before running the sample. | ||
| 115 | +- The sample uses `dav-3510` by default and covers Ascend 950PR/Ascend 950DT. | ||
| 116 | +- The sample uses all visible NPU devices, and the device count must not exceed `CCU_MAX_RANK_SIZE`. | ||
| @@ -0,0 +1,73 @@ | |||
| 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 | +find_package(ASC REQUIRED) | ||
| 13 | +project(hccl_examples_custom_ops_allgather_ccu_direct LANGUAGES CXX ASC) | ||
| 14 | + | ||
| 15 | +if(NOT DEFINED ASCEND_CANN_PACKAGE_PATH) | ||
| 16 | + if(DEFINED ENV{ASCEND_HOME_PATH}) | ||
| 17 | + set(ASCEND_CANN_PACKAGE_PATH $ENV{ASCEND_HOME_PATH}) | ||
| 18 | + elseif(DEFINED ENV{ASCEND_OPP_PATH}) | ||
| 19 | + get_filename_component(ASCEND_CANN_PACKAGE_PATH "$ENV{ASCEND_OPP_PATH}/.." ABSOLUTE) | ||
| 20 | + else() | ||
| 21 | + message(FATAL_ERROR "ASCEND_CANN_PACKAGE_PATH or ASCEND_HOME_PATH must be set") | ||
| 22 | + endif() | ||
| 23 | +endif() | ||
| 24 | + | ||
| 25 | +add_executable(demo | ||
| 26 | + main.asc | ||
| 27 | +) | ||
| 28 | + | ||
| 29 | +target_include_directories(demo PRIVATE | ||
| 30 | + # CANN Toolkit头文件 | ||
| 31 | + ${ASCEND_CANN_PACKAGE_PATH}/include | ||
| 32 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hccl | ||
| 33 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm | ||
| 34 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm/ccu | ||
B 缺少asc/include/头文件路径包含 ![]() ![]() | |||
| 35 | + ${ASCEND_CANN_PACKAGE_PATH}/asc/include/comm_api/ccu | ||
| 36 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc | ||
| 37 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/hcomm | ||
| 38 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/hcomm/ccu | ||
| 39 | +) | ||
| 40 | + | ||
| 41 | +target_compile_features(demo PRIVATE cxx_std_14) | ||
| 42 | +target_compile_options(demo PRIVATE | ||
| 43 | + -Werror | ||
| 44 | + -fstack-protector-strong | ||
| 45 | + -fPIE | ||
| 46 | + -O2 | ||
| 47 | + # -s | ||
| 48 | +) | ||
| 49 | +set(CMAKE_ASC_ARCHITECTURES "dav-3510" CACHE STRING "CMAKE_ASC_ARCHITECTURES, e.g. dav-3510") | ||
| 50 | +target_compile_options(demo PRIVATE | ||
| 51 | + $<$<COMPILE_LANGUAGE:ASC>:--npu-arch=${CMAKE_ASC_ARCHITECTURES}> | ||
| 52 | +) | ||
| 53 | + | ||
| 54 | +target_compile_definitions(demo PRIVATE | ||
| 55 | + _GLIBCXX_USE_CXX11_ABI=0 | ||
| 56 | +) | ||
| 57 | +target_link_options(demo PRIVATE | ||
| 58 | + -pie | ||
| 59 | + -Wl,-z,relro | ||
| 60 | + -Wl,-z,now | ||
| 61 | + -Wl,-z,noexecstack | ||
| 62 | +) | ||
| 63 | +target_link_directories(demo PRIVATE | ||
| 64 | + ${ASCEND_CANN_PACKAGE_PATH}/lib64 | ||
| 65 | +) | ||
| 66 | +target_link_libraries(demo PRIVATE | ||
| 67 | + hcomm | ||
| 68 | + asccomm_ccu | ||
| 69 | + c_sec | ||
| 70 | + ascendcl | ||
| 71 | + acl_rt | ||
| 72 | + ascendc_runtime | ||
| 73 | +) | ||
| @@ -0,0 +1,114 @@ | |||
| 1 | +# CCU Direct Add + AllGather样例 | ||
| 2 | + | ||
| 3 | +## 概述 | ||
| 4 | + | ||
| 5 | +本样例展示如何先通过AICore vector kernel执行Add计算,再以计算结果作为输入,通过CCU以直调`<<<>>>` | ||
| 6 | +方式执行AllGather通信。 | ||
| 7 | + | ||
| 8 | +样例会根据当前环境中的NPU数量创建通信域,每个Device对应一个rank。每个rank先对本地输入执行AICore | ||
| 9 | +Add计算,再将计算结果通过CCU AllGather同步到所有rank。 | ||
| 10 | + | ||
| 11 | +## 本样例支持的产品及CANN软件版本 | ||
| 12 | + | ||
| 13 | +| 产品 | CANN软件版本 | | ||
| 14 | +| --- | --- | | ||
| 15 | +| Ascend 950PR/Ascend 950DT | >= CANN 9.1.0 | | ||
| 16 | + | ||
| 17 | +## 目录结构介绍 | ||
| 18 | + | ||
| 19 | +```text | ||
| 20 | +03_add_allgather | ||
| 21 | +├── CMakeLists.txt // 编译工程文件 | ||
| 22 | +├── README.md // 中文样例说明 | ||
| 23 | +├── README_en.md // 英文样例说明 | ||
| 24 | +└── main.asc // Host侧流程、AICore Add Kernel和CCU AllGather Kernel实现 | ||
| 25 | +``` | ||
| 26 | + | ||
| 27 | +## 样例描述 | ||
| 28 | + | ||
| 29 | +### 功能说明 | ||
| 30 | + | ||
| 31 | +每个rank的输入为`sendCount`个FP32元素。样例先通过AICore vector kernel将本地输入写入`computeBuf`, | ||
| 32 | +再以`computeBuf`作为CCU AllGather输入,将所有rank的计算结果同步到每个rank的`recvBuf`。 | ||
| 33 | + | ||
| 34 | +```text | ||
| 35 | +sendBuf -> AICore Add -> computeBuf -> CCU AllGather -> recvBuf | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +### 样例规格 | ||
| 39 | + | ||
| 40 | +| 项目 | 说明 | | ||
| 41 | +| --- | --- | | ||
| 42 | +| 通信模式 | HCCL通信域内CCU AllGather | | ||
| 43 | +| 调用方式 | AICore Kernel直调`<<<>>>`,CCU Kernel直调`<<<>>>` | | ||
| 44 | +| 数据类型 | FP32 | | ||
| 45 | +| 单rank输入规模 | 256个FP32元素 | | ||
| 46 | +| Add输出规模 | 256个FP32元素 | | ||
| 47 | +| AllGather输出规模 | `rankSize * 256`个FP32元素 | | ||
| 48 | +| 支持rank数 | 不超过`CCU_MAX_RANK_SIZE`,当前样例中为16 | | ||
| 49 | + | ||
| 50 | +### 实现流程 | ||
| 51 | + | ||
| 52 | +1. 初始化ACL和HCCL通信域,获取当前环境中的NPU数量。 | ||
| 53 | +2. 每个Device创建一个rank,并初始化输入Buffer。 | ||
| 54 | +3. 基于HCCL通信域申请CCU Channel、CCU实例、CCU变量和CCU事件资源。 | ||
| 55 | +4. 通过`vector_add<<<1, nullptr, streamAiv>>>`直调AICore vector kernel,生成本地计算结果。 | ||
| 56 | +5. 通过`HcommCcuGetMemToken`获取`computeBuf`内存Token,并准备CCU任务参数。 | ||
| 57 | +6. 通过`CcuAllGatherMesh1DMem2MemKernel<<<schd, insHandle, streamCcu>>>`直调CCU Kernel完成AllGather。 | ||
| 58 | +7. 同步AIV和CCU Stream后将`recvBuf`拷贝回Host侧并打印。 | ||
| 59 | +8. 销毁HCCL通信域、Stream和Device侧内存。 | ||
| 60 | + | ||
| 61 | +## 编译运行 | ||
| 62 | + | ||
| 63 | +在本样例根目录下执行如下步骤,编译并运行样例。本样例仅支持NPU运行模式。 | ||
| 64 | + | ||
| 65 | +- 配置环境变量 | ||
| 66 | + | ||
| 67 | + 请根据当前环境上CANN开发套件包的安装方式配置环境变量,并开启CCU调度模式。 | ||
| 68 | + | ||
| 69 | + ```bash | ||
| 70 | + source ${install_path}/cann/set_env.sh | ||
| 71 | + export HCCL_OP_EXPANSION_MODE=CCU_SCHED | ||
| 72 | + ``` | ||
| 73 | + | ||
| 74 | + > **说明:** `${install_path}`为CANN包安装目录,未指定安装目录时默认安装至`/usr/local/Ascend`。 | ||
| 75 | + | ||
| 76 | +- 样例执行 | ||
| 77 | + | ||
| 78 | + 在本样例目录下执行如下命令。 | ||
| 79 | + | ||
| 80 | + ```bash | ||
| 81 | + mkdir -p build | ||
| 82 | + cd build | ||
| 83 | + cmake -DCMAKE_ASC_ARCHITECTURES=dav-3510 .. | ||
| 84 | + make -j | ||
| 85 | + ./demo | ||
| 86 | + ``` | ||
| 87 | + | ||
| 88 | +- 编译选项说明 | ||
| 89 | + | ||
| 90 | + | 选项 | 可选值 | 说明 | | ||
| 91 | + | --- | --- | --- | | ||
| 92 | + | `CMAKE_ASC_RUN_MODE` | `npu`(默认) | 运行模式,本样例仅支持NPU运行 | | ||
| 93 | + | `CMAKE_ASC_ARCHITECTURES` | `dav-3510` | NPU架构,对应Ascend 950PR/Ascend 950DT | | ||
| 94 | + | ||
| 95 | +- 执行结果 | ||
| 96 | + | ||
| 97 | + 两卡场景下,rank `d`的输入元素初始化为`d + 1`。运行成功后终端会输出类似以下信息: | ||
| 98 | + | ||
| 99 | + ```text | ||
| 100 | + Found 2 NPU device(s) available | ||
| 101 | + rankId: 0, input: [ 1 1 1 ... ] | ||
| 102 | + rankId: 1, input: [ 2 2 2 ... ] | ||
| 103 | + rankId: 0, recvBuf: [ 2 2 2 ... 3 3 3 ... ] | ||
| 104 | + rankId: 1, recvBuf: [ 2 2 2 ... 3 3 3 ... ] | ||
| 105 | + ``` | ||
| 106 | + | ||
| 107 | + 每个rank的`recvBuf`均包含所有rank执行AICore Add后的结果,表示样例执行成功。 | ||
| 108 | + | ||
| 109 | +## 注意事项 | ||
| 110 | + | ||
| 111 | +- 运行样例需要至少2张NPU;单卡环境仅支持编译验证。 | ||
| 112 | +- 运行前必须设置`HCCL_OP_EXPANSION_MODE=CCU_SCHED`。 | ||
| 113 | +- 当前样例默认使用`dav-3510`架构,仅覆盖Ascend 950PR/Ascend 950DT场景。 | ||
| 114 | +- 当前样例会使用环境中可见的全部NPU设备,设备数量不能超过`CCU_MAX_RANK_SIZE`。 | ||
| @@ -0,0 +1,117 @@ | |||
| 1 | +# CCU Direct Add + AllGather Sample | ||
| 2 | + | ||
| 3 | +## Overview | ||
| 4 | + | ||
| 5 | +This sample demonstrates how to run Add computation with an AICore vector kernel first, and then use the computed | ||
| 6 | +result as the input of AllGather communication by directly launching the CCU kernel with `<<<>>>`. | ||
| 7 | + | ||
| 8 | +The sample creates one rank for each available NPU device. Each rank first runs AICore Add on its local input, and | ||
| 9 | +then synchronizes the computed result to all ranks through CCU AllGather. | ||
| 10 | + | ||
| 11 | +## Supported Products and CANN Software Versions | ||
| 12 | + | ||
| 13 | +| Product | CANN Software Version | | ||
| 14 | +| --- | --- | | ||
| 15 | +| Ascend 950PR/Ascend 950DT | >= CANN 9.1.0 | | ||
| 16 | + | ||
| 17 | +## Directory Structure | ||
| 18 | + | ||
| 19 | +```text | ||
| 20 | +03_add_allgather | ||
| 21 | +├── CMakeLists.txt // Build configuration file | ||
| 22 | +├── README.md // Chinese documentation | ||
| 23 | +├── README_en.md // English documentation | ||
| 24 | +└── main.asc // Host flow, AICore Add kernel, and CCU AllGather kernel implementation | ||
| 25 | +``` | ||
| 26 | + | ||
| 27 | +## Sample Description | ||
| 28 | + | ||
| 29 | +### Functionality | ||
| 30 | + | ||
| 31 | +Each rank input contains `sendCount` FP32 elements. The sample first writes the local Add result to `computeBuf` | ||
| 32 | +through an AICore vector kernel, and then uses `computeBuf` as the CCU AllGather input so that `recvBuf` on every | ||
| 33 | +rank contains all rank computation results. | ||
| 34 | + | ||
| 35 | +```text | ||
| 36 | +sendBuf -> AICore Add -> computeBuf -> CCU AllGather -> recvBuf | ||
| 37 | +``` | ||
| 38 | + | ||
| 39 | +### Specifications | ||
| 40 | + | ||
| 41 | +| Item | Description | | ||
| 42 | +| --- | --- | | ||
| 43 | +| Communication mode | CCU AllGather in an HCCL communication domain | | ||
| 44 | +| Launch mode | Direct AICore kernel launch with `<<<>>>` and direct CCU kernel launch with `<<<>>>` | | ||
| 45 | +| Data type | FP32 | | ||
| 46 | +| Input size per rank | 256 FP32 elements | | ||
| 47 | +| Add output size | 256 FP32 elements | | ||
| 48 | +| AllGather output size | `rankSize * 256` FP32 elements | | ||
| 49 | +| Supported ranks | No more than `CCU_MAX_RANK_SIZE`, which is 16 in this sample | | ||
| 50 | + | ||
| 51 | +### Implementation Flow | ||
| 52 | + | ||
| 53 | +1. Initialize ACL and the HCCL communication domain, and query the number of NPU devices. | ||
| 54 | +2. Create one rank for each device and initialize the input buffer. | ||
| 55 | +3. Acquire CCU channels, a CCU instance, CCU variables, and CCU events from the HCCL communication domain. | ||
| 56 | +4. Directly launch the AICore vector kernel through `vector_add<<<1, nullptr, streamAiv>>>` to generate the local | ||
| 57 | + computation result. | ||
| 58 | +5. Obtain the `computeBuf` memory token through `HcommCcuGetMemToken` and prepare CCU task arguments. | ||
| 59 | +6. Directly launch the CCU kernel through `CcuAllGatherMesh1DMem2MemKernel<<<schd, insHandle, streamCcu>>>`. | ||
| 60 | +7. Synchronize the AIV and CCU streams, copy `recvBuf` back to the host, and print it. | ||
| 61 | +8. Destroy the HCCL communication domain, streams, and device memory. | ||
| 62 | + | ||
| 63 | +## Build and Run | ||
| 64 | + | ||
| 65 | +Perform the following steps in the sample root directory. This sample supports NPU run mode only. | ||
| 66 | + | ||
| 67 | +- Set Environment Variables | ||
| 68 | + | ||
| 69 | + Configure CANN environment variables according to your installation and enable CCU scheduling mode. | ||
| 70 | + | ||
| 71 | + ```bash | ||
| 72 | + source ${install_path}/cann/set_env.sh | ||
| 73 | + export HCCL_OP_EXPANSION_MODE=CCU_SCHED | ||
| 74 | + ``` | ||
| 75 | + | ||
| 76 | + > **Note:** `${install_path}` is the CANN installation directory. The default installation directory is | ||
| 77 | + > `/usr/local/Ascend`. | ||
| 78 | + | ||
| 79 | +- Run the Sample | ||
| 80 | + | ||
| 81 | + Run the following commands in the sample directory. | ||
| 82 | + | ||
| 83 | + ```bash | ||
| 84 | + mkdir -p build | ||
| 85 | + cd build | ||
| 86 | + cmake -DCMAKE_ASC_ARCHITECTURES=dav-3510 .. | ||
| 87 | + make -j | ||
| 88 | + ./demo | ||
| 89 | + ``` | ||
| 90 | + | ||
| 91 | +- Build Options | ||
| 92 | + | ||
| 93 | + | Option | Values | Description | | ||
| 94 | + | --- | --- | --- | | ||
| 95 | + | `CMAKE_ASC_RUN_MODE` | `npu` (default) | Run mode. This sample supports NPU execution only | | ||
| 96 | + | `CMAKE_ASC_ARCHITECTURES` | `dav-3510` | NPU architecture for Ascend 950PR/Ascend 950DT | | ||
| 97 | + | ||
| 98 | +- Expected Output | ||
| 99 | + | ||
| 100 | + In a two-device run, the input elements of rank `d` are initialized to `d + 1`. The output is similar to: | ||
| 101 | + | ||
| 102 | + ```text | ||
| 103 | + Found 2 NPU device(s) available | ||
| 104 | + rankId: 0, input: [ 1 1 1 ... ] | ||
| 105 | + rankId: 1, input: [ 2 2 2 ... ] | ||
| 106 | + rankId: 0, recvBuf: [ 2 2 2 ... 3 3 3 ... ] | ||
| 107 | + rankId: 1, recvBuf: [ 2 2 2 ... 3 3 3 ... ] | ||
| 108 | + ``` | ||
| 109 | + | ||
| 110 | + The sample succeeds when `recvBuf` on every rank contains the AICore Add result from all ranks. | ||
| 111 | + | ||
| 112 | +## Notes | ||
| 113 | + | ||
| 114 | +- At least two NPU devices are required to run the sample. Single-device environments support compilation only. | ||
| 115 | +- Set `HCCL_OP_EXPANSION_MODE=CCU_SCHED` before running the sample. | ||
| 116 | +- The sample uses `dav-3510` by default and covers Ascend 950PR/Ascend 950DT. | ||
| 117 | +- The sample uses all visible NPU devices, and the device count must not exceed `CCU_MAX_RANK_SIZE`. | ||
| @@ -0,0 +1,96 @@ | |||
| 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 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +typedef enum { | ||
| 31 | + CCU_SUCCESS = 0, | ||
| 32 | + CCU_E_PARA = 1, | ||
| 33 | + CCU_E_PTR = 2, | ||
| 34 | + CCU_E_INTERNAL = 4, | ||
| 35 | + CCU_E_NOT_SUPPORT = 5, | ||
| 36 | + CCU_E_NOT_FOUND = 6, | ||
| 37 | + CCU_E_UNAVAIL = 7, | ||
| 38 | + CCU_E_RUNTIME = 15, | ||
| 39 | + CCU_E_DRV_START = 4096, | ||
| 40 | + CCU_E_DRV_INIT_FAILED = 4097, | ||
| 41 | + CCU_E_DRV_BUSY = 4098, | ||
| 42 | + CCU_E_DRV_END = 4224, | ||
| 43 | + CCU_E_RESERVED = 9216 | ||
| 44 | +} CcuResult; | ||
| 45 | + | ||
| 46 | +typedef uint64_t CcuInsHandle; | ||
| 47 | +typedef void* aclrtStream; | ||
| 48 | + | ||
| 49 | + | ||
| 50 | + | ||
| 51 | +extern "C" { | ||
| 52 | + | ||
| 53 | + | ||
| 54 | +typedef struct { | ||
| 55 | + uint32_t num_blocks; // mission 个数 | ||
| 56 | + uint32_t reserved; | ||
| 57 | + uint64_t phy_die_mask; // 按位表示 0x01表示die0 0x02表示die1 | ||
| 58 | + uint64_t binary_cache_tag; | ||
| 59 | +} asccomm_ccu_schd; | ||
| 60 | + | ||
| 61 | +typedef struct { | ||
| 62 | + asccomm_ccu_schd ccu_schd; | ||
| 63 | + CcuInsHandle ccu_ins; | ||
| 64 | + aclrtStream stream; | ||
| 65 | + void* attrs; | ||
| 66 | +} asccomm_launch_kernel_cfg; | ||
| 67 | + | ||
| 68 | +typedef struct { | ||
| 69 | + uint32_t numBlocks; // mission 个数 | ||
| 70 | + uint32_t reserved; | ||
| 71 | + uint64_t phyDieMask; // 按位表示 0x01表示die0 0x02表示die1 | ||
| 72 | + uint64_t binaryCacheTag; | ||
| 73 | +} HcommCcuSchd; | ||
| 74 | + | ||
| 75 | +typedef struct { | ||
| 76 | + HcommCcuSchd ccuSchd; | ||
| 77 | + CcuInsHandle ccuIns; | ||
| 78 | + aclrtStream stream; | ||
| 79 | + void* attrs; | ||
| 80 | +} HcommLaunchKernelCfg; | ||
| 81 | + | ||
| 82 | +typedef CcuResult ccu_result; | ||
| 83 | + | ||
| 84 | +extern ccu_result asccomm_ccu_host_kernel_launch( | ||
| 85 | + const void* kernel_func, const asccomm_launch_kernel_cfg* cfg, void* args); | ||
| 86 | + | ||
| 87 | +extern CcuResult HcommCcuHostKernelLaunch(const void* kernel_func, const HcommLaunchKernelCfg* cfg, void* args); | ||
| 88 | + | ||
| 89 | +extern uint64_t HcommCcuGetLaunchHashTag(const char* tag); | ||
| 90 | +extern uint64_t asccomm_ccu_get_launch_hash_tag(const char* tag); | ||
| 91 | + | ||
| 92 | + | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | + | ||
| 96 | + | ||
| @@ -0,0 +1,207 @@ | |||
| 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 | +set(ASCCOMM_CCU_ROOT ${CMAKE_CURRENT_LIST_DIR}) | ||
| 12 | +get_filename_component(ASCCOMM_ROOT ${ASCCOMM_CCU_ROOT}/../.. ABSOLUTE) | ||
| 13 | + | ||
| 14 | +if(NOT ASCEND_CANN_PACKAGE_PATH) | ||
| 15 | + if(DEFINED ENV{ASCEND_HOME_PATH}) | ||
| 16 | + set(ASCEND_CANN_PACKAGE_PATH "$ENV{ASCEND_HOME_PATH}") | ||
| 17 | + elseif(DEFINED ENV{ASCEND_CANN_PACKAGE_PATH}) | ||
| 18 | + set(ASCEND_CANN_PACKAGE_PATH "$ENV{ASCEND_CANN_PACKAGE_PATH}") | ||
| 19 | + endif() | ||
| 20 | +endif() | ||
| 21 | + | ||
| 22 | +if(NOT ASCCOMM_CANN_ARCH_DIR OR NOT EXISTS "${ASCCOMM_CANN_ARCH_DIR}") | ||
| 23 | + foreach(_candidate | ||
| 24 | + "${ASCEND_CANN_PACKAGE_PATH}/${CMAKE_SYSTEM_PROCESSOR}-linux" | ||
| 25 | + "${ASCEND_CANN_PACKAGE_PATH}/aarch64-linux" | ||
| 26 | + "${ASCEND_CANN_PACKAGE_PATH}/x86_64-linux" | ||
| 27 | + "${ASCEND_CANN_PACKAGE_PATH}") | ||
| 28 | + if(EXISTS "${_candidate}") | ||
| 29 | + set(ASCCOMM_CANN_ARCH_DIR "${_candidate}") | ||
| 30 | + break() | ||
| 31 | + endif() | ||
| 32 | + endforeach() | ||
| 33 | +endif() | ||
| 34 | + | ||
| 35 | +if(NOT ASCCOMM_CANN_ARCH_DIR) | ||
| 36 | + set(ASCCOMM_CANN_ARCH_DIR "${ASCEND_CANN_PACKAGE_PATH}/${CMAKE_SYSTEM_PROCESSOR}-linux") | ||
| 37 | +endif() | ||
| 38 | + | ||
| 39 | +function(asccomm_collect_header_dirs out_var) | ||
| 40 | + set(_dirs) | ||
| 41 | + foreach(_root IN LISTS ARGN) | ||
| 42 | + if(EXISTS "${_root}") | ||
| 43 | + file(GLOB_RECURSE _headers CONFIGURE_DEPENDS | ||
| 44 | + "${_root}/*.h" | ||
| 45 | + "${_root}/*.hpp" | ||
| 46 | + ) | ||
| 47 | + foreach(_header IN LISTS _headers) | ||
| 48 | + get_filename_component(_dir "${_header}" DIRECTORY) | ||
| 49 | + list(APPEND _dirs "${_dir}") | ||
| 50 | + endforeach() | ||
| 51 | + endif() | ||
| 52 | + endforeach() | ||
| 53 | + list(REMOVE_DUPLICATES _dirs) | ||
| 54 | + set(${out_var} ${_dirs} PARENT_SCOPE) | ||
| 55 | +endfunction() | ||
| 56 | + | ||
| 57 | +set(ASCCOMM_HCOMM_HEADER_DIRS) | ||
| 58 | +if(ASCCOMM_HCOMM_SOURCE_DIR AND EXISTS "${ASCCOMM_HCOMM_SOURCE_DIR}") | ||
| 59 | + asccomm_collect_header_dirs(ASCCOMM_HCOMM_HEADER_DIRS | ||
| 60 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src | ||
| 61 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/include | ||
| 62 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc | ||
| 63 | + ) | ||
| 64 | +endif() | ||
| 65 | +set(ASCCOMM_CANN_BASE_INCLUDE_DIRS) | ||
| 66 | +if(ASCEND_CANN_PACKAGE_PATH) | ||
| 67 | + list(APPEND ASCCOMM_CANN_BASE_INCLUDE_DIRS | ||
| 68 | + ${ASCEND_CANN_PACKAGE_PATH}/include | ||
| 69 | + ${ASCEND_CANN_PACKAGE_PATH}/runtime/include | ||
| 70 | + ) | ||
| 71 | +endif() | ||
| 72 | +if(ASCCOMM_CANN_ARCH_DIR) | ||
| 73 | + list(APPEND ASCCOMM_CANN_BASE_INCLUDE_DIRS | ||
| 74 | + ${ASCCOMM_CANN_ARCH_DIR}/include | ||
| 75 | + ${ASCCOMM_CANN_ARCH_DIR}/include/hcomm/ccu | ||
| 76 | + ${ASCCOMM_CANN_ARCH_DIR}/include/hccl | ||
| 77 | + ${ASCCOMM_CANN_ARCH_DIR}/pkg_inc | ||
| 78 | + ) | ||
| 79 | +endif() | ||
| 80 | +asccomm_collect_header_dirs(ASCCOMM_CANN_HEADER_DIRS | ||
| 81 | + ${ASCCOMM_CANN_BASE_INCLUDE_DIRS} | ||
| 82 | +) | ||
| 83 | + | ||
| 84 | +set(ASCCOMM_HCOMM_PUBLIC_INCLUDE_DIRS) | ||
| 85 | +set(ASCCOMM_HCOMM_PRIVATE_INCLUDE_DIRS) | ||
| 86 | +if(ASCCOMM_HCOMM_SOURCE_DIR AND EXISTS "${ASCCOMM_HCOMM_SOURCE_DIR}") | ||
| 87 | + set(ASCCOMM_HCOMM_PUBLIC_INCLUDE_DIRS | ||
| 88 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/include | ||
| 89 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/include/hccl | ||
| 90 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc | ||
| 91 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc/hcomm/ccu | ||
| 92 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc/legacy | ||
| 93 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc/legacy/hccl | ||
| 94 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/third_party/json/include | ||
| 95 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/third_party/json/single_include | ||
| 96 | + ) | ||
| 97 | + set(ASCCOMM_HCOMM_PRIVATE_INCLUDE_DIRS | ||
| 98 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src | ||
| 99 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/base_comm | ||
| 100 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/base_comm/common | ||
| 101 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend910/framework/common/src | ||
| 102 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend910/framework/common/src/mgr | ||
| 103 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend950 | ||
| 104 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend950/common | ||
| 105 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend950/common/utils | ||
| 106 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend950/common/exception | ||
| 107 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend950/unified_platform | ||
| 108 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend950/unified_platform/pub_inc | ||
| 109 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend910/framework/hcom | ||
| 110 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend910/framework/inc | ||
| 111 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend910/framework/common/src/exception | ||
| 112 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend910/pub_inc | ||
| 113 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend910/pub_inc/inner | ||
| 114 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/legacy/ascend910/pub_inc/new | ||
| 115 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/base_comm/resources | ||
| 116 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/base_comm/resources/hccp/inc | ||
| 117 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/base_comm/resources/endpoint_pairs/channels | ||
| 118 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/base_comm/resources/common | ||
| 119 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/base_comm/resources/southbound_adpt | ||
| 120 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/src/base_comm/resources/hccp/external_depends | ||
| 121 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/include | ||
| 122 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/include/hccl | ||
| 123 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc | ||
| 124 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc/hccl | ||
| 125 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc/legacy | ||
| 126 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/pkg_inc/legacy/hccl | ||
| 127 | + ${ASCCOMM_HCOMM_SOURCE_DIR}/test/ut/platform/hccp/rdma_service_normal/include | ||
| 128 | + ${ASCCOMM_HCOMM_HEADER_DIRS} | ||
| 129 | + ) | ||
| 130 | +endif() | ||
| 131 | + | ||
| 132 | +add_library(asccomm_ccu_headers INTERFACE) | ||
| 133 | +target_include_directories(asccomm_ccu_headers INTERFACE | ||
| 134 | + ${ASCCOMM_ROOT}/include | ||
| 135 | + ${ASCCOMM_HCOMM_PUBLIC_INCLUDE_DIRS} | ||
| 136 | +) | ||
| 137 | + | ||
| 138 | +add_library(asccomm_ccu_obj OBJECT | ||
| 139 | + ${ASCCOMM_CCU_ROOT}/ccu_host_launch.cpp | ||
| 140 | +) | ||
| 141 | +target_link_libraries(asccomm_ccu_obj PRIVATE | ||
| 142 | + asccomm_ccu_headers | ||
| 143 | + $<$<TARGET_EXISTS:intf_pub>:intf_pub> | ||
| 144 | + $<$<TARGET_EXISTS:error_manager_headers>:error_manager_headers> | ||
| 145 | + $<$<TARGET_EXISTS:acl_rt_headers>:acl_rt_headers> | ||
| 146 | + $<$<TARGET_EXISTS:asc_host_headers>:asc_host_headers> | ||
| 147 | + $<$<TARGET_EXISTS:ascend_hal_headers>:ascend_hal_headers> | ||
| 148 | + $<$<TARGET_EXISTS:kernel_tiling_headers>:kernel_tiling_headers> | ||
| 149 | + $<$<TARGET_EXISTS:atrace_headers>:atrace_headers> | ||
| 150 | + $<$<TARGET_EXISTS:mmpa_headers>:mmpa_headers> | ||
| 151 | + $<$<TARGET_EXISTS:runtime_headers>:runtime_headers> | ||
| 152 | + $<$<TARGET_EXISTS:rdma_core_headers>:rdma_core_headers> | ||
| 153 | + $<$<TARGET_EXISTS:hccl_legacy_headers>:hccl_legacy_headers> | ||
| 154 | + $<$<TARGET_EXISTS:json>:json> | ||
| 155 | + $<$<TARGET_EXISTS:c_sec_headers>:c_sec_headers> | ||
| 156 | + $<$<TARGET_EXISTS:unified_dlog>:unified_dlog> | ||
| 157 | +) | ||
| 158 | +target_include_directories(asccomm_ccu_obj PRIVATE | ||
| 159 | + ${ASCCOMM_CCU_ROOT} | ||
| 160 | + ${ASCCOMM_HCOMM_PRIVATE_INCLUDE_DIRS} | ||
| 161 | +) | ||
| 162 | +target_include_directories(asccomm_ccu_obj SYSTEM PRIVATE | ||
| 163 | + ${ASCCOMM_CANN_BASE_INCLUDE_DIRS} | ||
| 164 | + ${ASCCOMM_CANN_HEADER_DIRS} | ||
| 165 | +) | ||
| 166 | +target_compile_definitions(asccomm_ccu_obj PRIVATE | ||
| 167 | + BUILD_OPEN_PROJECT | ||
| 168 | + CANN_VERSION_NUM=90100000 | ||
| 169 | +) | ||
| 170 | +target_compile_features(asccomm_ccu_obj PUBLIC cxx_std_17) | ||
| 171 | +target_compile_options(asccomm_ccu_obj PRIVATE | ||
| 172 | + -fPIC | ||
| 173 | + -Wall | ||
| 174 | + -Werror | ||
| 175 | +) | ||
| 176 | + | ||
| 177 | +add_library(asccomm_ccu SHARED | ||
| 178 | + $<TARGET_OBJECTS:asccomm_ccu_obj> | ||
| 179 | +) | ||
| 180 | +if(NOT ASCCOMM_LIBRARY_OUTPUT_DIRECTORY) | ||
| 181 | + set(ASCCOMM_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) | ||
| 182 | +endif() | ||
| 183 | +set_target_properties(asccomm_ccu PROPERTIES | ||
| 184 | + OUTPUT_NAME asccomm_ccu | ||
| 185 | + LIBRARY_OUTPUT_DIRECTORY ${ASCCOMM_LIBRARY_OUTPUT_DIRECTORY} | ||
| 186 | +) | ||
| 187 | +target_link_libraries(asccomm_ccu PRIVATE asccomm_ccu_headers) | ||
| 188 | + | ||
| 189 | +if(NOT INSTALL_LIBRARY_DIR) | ||
| 190 | + set(INSTALL_LIBRARY_DIR lib64) | ||
| 191 | +endif() | ||
| 192 | +if(NOT INSTALL_PKG_INCLUDE_DIR) | ||
| 193 | + set(INSTALL_PKG_INCLUDE_DIR pkg_inc) | ||
| 194 | +endif() | ||
| 195 | + | ||
| 196 | +install(TARGETS asccomm_ccu | ||
| 197 | + LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR} ${INSTALL_OPTIONAL} | ||
| 198 | + COMPONENT hcomm) | ||
| 199 | + | ||
| 200 | +if(EXISTS "${ASCCOMM_ROOT}/include/ccu") | ||
| 201 | + install(DIRECTORY ${ASCCOMM_ROOT}/include/ccu/ | ||
| 202 | + DESTINATION ${INSTALL_PKG_INCLUDE_DIR}/ccu | ||
| 203 | + COMPONENT hcomm | ||
| 204 | + FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp") | ||
| 205 | +endif() | ||
| 206 | + | ||
| 207 | +add_custom_target(asccomm_ccu_compile_check DEPENDS asccomm_ccu) | ||
| @@ -0,0 +1,325 @@ | |||
| 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 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +int32_t HcclGetThreadDeviceId(); | ||
| 25 | + | ||
| 26 | + | ||
| 27 | + | ||
| 28 | + | ||
| 29 | + | ||
| 30 | + | ||
| 31 | +typedef uint64_t CcuKernelHandle; | ||
| 32 | +typedef void* CcuKernelArg; | ||
| 33 | + | ||
| 34 | + | ||
| 35 | +extern "C" { | ||
| 36 | +extern CcuResult HcommCcuKernelRegisterStart(CcuInsHandle insHandle) HCOMM_WEAK_SYMBOL; | ||
| 37 | +extern CcuResult HcommCcuKernelRegister( | ||
| 38 | + CcuInsHandle insHandle, uint32_t dieId, const char* kernelFuncName, const void* kernelFunc, const void** kernelArgs, | ||
| 39 | + uint32_t argNum, CcuKernelHandle* kernelHandle) HCOMM_WEAK_SYMBOL; | ||
| 40 | +extern CcuResult HcommCcuKernelRegisterEnd(CcuInsHandle insHandle) HCOMM_WEAK_SYMBOL; | ||
| 41 | +extern CcuResult HcommCcuGetTaskArgsNum(CcuKernelHandle kernelHandle, uint32_t* taskArgsNum) HCOMM_WEAK_SYMBOL; | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +namespace hcomm { | ||
| 45 | +constexpr uint32_t CCU_SQE_ARGS_LEN = 13; | ||
| 46 | + | ||
| 47 | +struct CcuTaskParam { | ||
| 48 | + uint8_t dieId; | ||
| 49 | + uint8_t missionId; | ||
| 50 | + uint16_t timeout; | ||
| 51 | + uint32_t instStartId; | ||
| 52 | + uint32_t instCnt; | ||
| 53 | + uint32_t key; | ||
| 54 | + uint32_t argSize; | ||
| 55 | + uint64_t args[CCU_SQE_ARGS_LEN]; | ||
| 56 | +}; | ||
| 57 | + | ||
| 58 | +class CcuKernel { | ||
| 59 | +public: | ||
| 60 | + CcuResult GeneTaskParams(const uint64_t* taskArgs, uint32_t argsNum, std::vector<CcuTaskParam>& taskParams); | ||
| 61 | +}; | ||
| 62 | + | ||
| 63 | +class CcuKernelMgr { | ||
| 64 | +public: | ||
| 65 | + static CcuKernelMgr& GetInstance(int32_t deviceLogicId); | ||
| 66 | + CcuKernel* GetKernel(CcuKernelHandle kernelHandle); | ||
| 67 | +}; | ||
| 68 | +} // namespace hcomm | ||
| 69 | + | ||
| 70 | +namespace { | ||
| 71 | +constexpr uint32_t NOTIFY_DEFAULT_WAIT_TIME = 27U * 68U; // notifywait默认1836等待时长 | ||
| 72 | +constexpr uint64_t CCU_DIE0_MASK = 0x01U; | ||
| 73 | +constexpr uint64_t CCU_DIE1_MASK = 0x02U; | ||
| 74 | +constexpr uint32_t CCU_DIE0_ID = 0U; | ||
| 75 | +constexpr uint32_t CCU_DIE1_ID = 1U; | ||
| 76 | +constexpr uint32_t CCU_SUPPORTED_NUM_BLOCKS = 1U; | ||
| 77 | + | ||
| 78 | +bool IsCcuKernelLaunchApiAvailable() | ||
| 79 | +{ | ||
| 80 | + auto registerStart = HcommCcuKernelRegisterStart; | ||
| 81 | + auto registerKernel = HcommCcuKernelRegister; | ||
| 82 | + auto registerEnd = HcommCcuKernelRegisterEnd; | ||
| 83 | + auto getTaskArgsNum = HcommCcuGetTaskArgsNum; | ||
| 84 | + return registerStart != nullptr && registerKernel != nullptr && registerEnd != nullptr && getTaskArgsNum != nullptr; | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +bool IsSupportedSingleDieMask(uint64_t phyDieMask) | ||
| 88 | +{ | ||
| 89 | + return phyDieMask == CCU_DIE0_MASK || phyDieMask == CCU_DIE1_MASK; | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | +uint32_t GetDieIdByMask(uint64_t phyDieMask) { return phyDieMask == CCU_DIE1_MASK ? CCU_DIE1_ID : CCU_DIE0_ID; } | ||
| 93 | + | ||
| 94 | +CcuResult ValidateLaunchCfg(const asccomm_launch_kernel_cfg* cfg) | ||
| 95 | +{ | ||
| 96 | + if (cfg->ccu_schd.num_blocks != CCU_SUPPORTED_NUM_BLOCKS) { | ||
| 97 | + return CCU_E_PARA; | ||
| 98 | + } | ||
| 99 | + if (!IsSupportedSingleDieMask(cfg->ccu_schd.phy_die_mask)) { | ||
| 100 | + return CCU_E_PARA; | ||
| 101 | + } | ||
| 102 | + return CCU_SUCCESS; | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +using VoidPackedCcuKernel = void (*)(void*); | ||
| 106 | + | ||
| 107 | +struct VoidKernelRegisterCtx { | ||
| 108 | + const void* kernelFunc; | ||
| 109 | + void* packedArgs; | ||
| 110 | +}; | ||
| 111 | + | ||
| 112 | +CcuResult VoidKernelTrampoline(CcuKernelArg arg); | ||
| 113 | + | ||
| 114 | +CcuResult RegisterCcuKernel( | ||
| 115 | + const void* kernelFunc, const asccomm_launch_kernel_cfg* cfg, void* args, CcuKernelHandle& kernelHandle) | ||
| 116 | +{ | ||
| 117 | + CcuResult ret = HcommCcuKernelRegisterStart(cfg->ccu_ins); | ||
| 118 | + if (ret != CCU_SUCCESS) { | ||
| 119 | + return ret; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + const uint32_t dieId = GetDieIdByMask(cfg->ccu_schd.phy_die_mask); | ||
| 123 | + VoidKernelRegisterCtx registerCtx{ | ||
| 124 | + kernelFunc, | ||
| 125 | + args, | ||
| 126 | + }; | ||
| 127 | + | ||
| 128 | + const void* kernelArgs[] = {®isterCtx}; | ||
| 129 | + | ||
| 130 | + // kernelFunc do not support func that return void , only support return CcuResult | ||
| 131 | + ret = HcommCcuKernelRegister( | ||
| 132 | + cfg->ccu_ins, dieId, nullptr, reinterpret_cast<const void*>(VoidKernelTrampoline), kernelArgs, 1, | ||
| 133 | + &kernelHandle); | ||
| 134 | + if (ret != CCU_SUCCESS) { | ||
| 135 | + (void)HcommCcuKernelRegisterEnd(cfg->ccu_ins); | ||
| 136 | + return ret; | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + return HcommCcuKernelRegisterEnd(cfg->ccu_ins); | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | +class KernelHandleCache { | ||
| 143 | +public: | ||
| 144 | + CcuResult Match( | ||
| 145 | + const void* kernelFunc, const asccomm_launch_kernel_cfg* cfg, void* args, CcuKernelHandle& kernelHandle, | ||
| 146 | + uint32_t& taskArgsNum) | ||
| 147 | + { | ||
| 148 | + const uint64_t cacheTag = cfg->ccu_schd.binary_cache_tag; | ||
| 149 | + if (cacheTag == 0U) { | ||
| 150 | + return RegisterAndGetTaskArgsNum(kernelFunc, cfg, args, kernelHandle, taskArgsNum); | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 154 | + auto iter = cache_.find(cacheTag); | ||
| 155 | + if (iter != cache_.end()) { | ||
| 156 | + kernelHandle = iter->second; | ||
| 157 | + return HcommCcuGetTaskArgsNum(kernelHandle, &taskArgsNum); | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + CcuResult ret = RegisterAndGetTaskArgsNum(kernelFunc, cfg, args, kernelHandle, taskArgsNum); | ||
| 161 | + if (ret != CCU_SUCCESS) { | ||
| 162 | + return ret; | ||
| 163 | + } | ||
| 164 | + cache_[cacheTag] = kernelHandle; | ||
| 165 | + return CCU_SUCCESS; | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | +private: | ||
| 169 | + CcuResult RegisterAndGetTaskArgsNum( | ||
| 170 | + const void* kernelFunc, const asccomm_launch_kernel_cfg* cfg, void* args, CcuKernelHandle& kernelHandle, | ||
| 171 | + uint32_t& taskArgsNum) | ||
| 172 | + { | ||
| 173 | + CcuResult ret = RegisterCcuKernel(kernelFunc, cfg, args, kernelHandle); | ||
| 174 | + if (ret != CCU_SUCCESS) { | ||
| 175 | + return ret; | ||
| 176 | + } | ||
| 177 | + ret = HcommCcuGetTaskArgsNum(kernelHandle, &taskArgsNum); | ||
| 178 | + if (ret != CCU_SUCCESS) { | ||
| 179 | + return ret; | ||
| 180 | + } | ||
| 181 | + return CCU_SUCCESS; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + std::mutex mutex_; | ||
| 185 | + std::unordered_map<uint64_t, CcuKernelHandle> cache_; | ||
| 186 | +}; | ||
| 187 | + | ||
| 188 | +KernelHandleCache& GetKernelHandleCache() | ||
| 189 | +{ | ||
| 190 | + static KernelHandleCache cache; | ||
| 191 | + return cache; | ||
| 192 | +} | ||
| 193 | + | ||
| 194 | +CcuResult VoidKernelTrampoline(CcuKernelArg arg) | ||
| 195 | +{ | ||
| 196 | + auto* ctx = static_cast<VoidKernelRegisterCtx*>(arg); | ||
| 197 | + if (ctx == nullptr || ctx->kernelFunc == nullptr || ctx->packedArgs == nullptr) { | ||
| 198 | + return CCU_E_PTR; | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | + auto fn = reinterpret_cast<VoidPackedCcuKernel>(const_cast<void*>(ctx->kernelFunc)); | ||
| 202 | + fn(ctx->packedArgs); | ||
| 203 | + return CCU_SUCCESS; | ||
| 204 | +} | ||
| 205 | + | ||
| 206 | +CcuResult GetSingleTaskParam( | ||
| 207 | + CcuKernelHandle kernelHandle, const void* taskArgs, uint32_t argNum, hcomm::CcuTaskParam& taskParam) | ||
| 208 | +{ | ||
| 209 | + if (kernelHandle == 0) { | ||
| 210 | + return CCU_E_PARA; | ||
| 211 | + } | ||
| 212 | + if (argNum > hcomm::CCU_SQE_ARGS_LEN) { | ||
| 213 | + return CCU_E_NOT_SUPPORT; | ||
| 214 | + } | ||
| 215 | + if (argNum > 0 && taskArgs == nullptr) { | ||
| 216 | + return CCU_E_PTR; | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + try { | ||
| 220 | + const uint32_t devLogicId = static_cast<uint32_t>(HcclGetThreadDeviceId()); | ||
| 221 | + auto& kernelMgr = hcomm::CcuKernelMgr::GetInstance(devLogicId); | ||
| 222 | + auto* kernel = kernelMgr.GetKernel(kernelHandle); | ||
| 223 | + if (kernel == nullptr) { | ||
| 224 | + return CCU_E_PTR; | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + std::vector<hcomm::CcuTaskParam> taskParams{}; | ||
| 228 | + CcuResult ret = kernel->GeneTaskParams(static_cast<const uint64_t*>(taskArgs), argNum, taskParams); | ||
| 229 | + if (ret != CCU_SUCCESS) { | ||
| 230 | + return ret; | ||
| 231 | + } | ||
| 232 | + if (taskParams.size() != 1) { | ||
| 233 | + return CCU_E_NOT_SUPPORT; | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + taskParam = taskParams.front(); | ||
| 237 | + } catch (...) { | ||
| 238 | + return CCU_E_INTERNAL; | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + return CCU_SUCCESS; | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +CcuResult LaunchSingleCcuTask(const hcomm::CcuTaskParam& param, aclrtStream stream) | ||
| 245 | +{ | ||
| 246 | + if (stream == nullptr) { | ||
| 247 | + return CCU_E_PTR; | ||
| 248 | + } | ||
| 249 | + | ||
| 250 | + rtCcuTaskInfo_t taskInfo{}; | ||
| 251 | + taskInfo.dieId = param.dieId; | ||
| 252 | + taskInfo.missionId = param.missionId; | ||
| 253 | + taskInfo.instStartId = param.instStartId; | ||
| 254 | + taskInfo.instCnt = param.instCnt; | ||
| 255 | + taskInfo.key = param.key; | ||
| 256 | + taskInfo.argSize = param.argSize; | ||
| 257 | + taskInfo.timeout = NOTIFY_DEFAULT_WAIT_TIME; | ||
| 258 | + std::copy(std::begin(param.args), std::end(param.args), std::begin(taskInfo.args)); | ||
| 259 | + | ||
| 260 | + auto rtRet = rtCCULaunch(&taskInfo, stream); | ||
| 261 | + if (rtRet != RT_ERROR_NONE) { | ||
| 262 | + return CCU_E_RUNTIME; | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + return CCU_SUCCESS; | ||
| 266 | +} | ||
| 267 | + | ||
| 268 | +} // namespace | ||
| 269 | + | ||
| 270 | +extern "C" uint64_t asccomm_ccu_get_launch_hash_tag(const char* tag) | ||
| 271 | +{ | ||
| 272 | + if (tag == nullptr) { | ||
| 273 | + return 0; | ||
| 274 | + } | ||
| 275 | + return static_cast<uint64_t>(XXH3_64bits(tag, std::strlen(tag))); | ||
| 276 | +} | ||
| 277 | + | ||
| 278 | +extern "C" ccu_result asccomm_ccu_host_kernel_launch( | ||
| 279 | + const void* kernel_func, const asccomm_launch_kernel_cfg* cfg, void* args) | ||
| 280 | +{ | ||
| 281 | + if (kernel_func == nullptr || cfg == nullptr || args == nullptr) { | ||
| 282 | + return CCU_E_PTR; | ||
| 283 | + } | ||
| 284 | + CcuResult ret = ValidateLaunchCfg(cfg); | ||
| 285 | + if (ret != CCU_SUCCESS) { | ||
| 286 | + return ret; | ||
| 287 | + } | ||
| 288 | + if (!IsCcuKernelLaunchApiAvailable()) { | ||
| 289 | + return CCU_E_NOT_SUPPORT; | ||
| 290 | + } | ||
| 291 | + | ||
| 292 | + CcuKernelHandle kernelHandle = 0; | ||
| 293 | + uint32_t taskArgsNum = 0; | ||
| 294 | + ret = GetKernelHandleCache().Match(kernel_func, cfg, args, kernelHandle, taskArgsNum); | ||
| 295 | + if (ret != CCU_SUCCESS) { | ||
| 296 | + return ret; | ||
| 297 | + } | ||
| 298 | + | ||
| 299 | + hcomm::CcuTaskParam taskParam{}; | ||
| 300 | + ret = GetSingleTaskParam(kernelHandle, args, taskArgsNum, taskParam); | ||
| 301 | + if (ret != CCU_SUCCESS) { | ||
| 302 | + return ret; | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | + return LaunchSingleCcuTask(taskParam, cfg->stream); | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +extern "C" CcuResult HcommCcuHostKernelLaunch(const void* kernel_func, const HcommLaunchKernelCfg* cfg, void* args) | ||
| 309 | +{ | ||
| 310 | + if (cfg == nullptr) { | ||
| 311 | + return asccomm_ccu_host_kernel_launch(kernel_func, nullptr, args); | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + asccomm_launch_kernel_cfg asccommCfg{}; | ||
| 315 | + asccommCfg.ccu_schd.num_blocks = cfg->ccuSchd.numBlocks; | ||
| 316 | + asccommCfg.ccu_schd.reserved = cfg->ccuSchd.reserved; | ||
| 317 | + asccommCfg.ccu_schd.phy_die_mask = cfg->ccuSchd.phyDieMask; | ||
| 318 | + asccommCfg.ccu_schd.binary_cache_tag = cfg->ccuSchd.binaryCacheTag; | ||
| 319 | + asccommCfg.ccu_ins = cfg->ccuIns; | ||
| 320 | + asccommCfg.stream = cfg->stream; | ||
| 321 | + asccommCfg.attrs = cfg->attrs; | ||
| 322 | + return asccomm_ccu_host_kernel_launch(kernel_func, &asccommCfg, args); | ||
| 323 | +} | ||
| 324 | + | ||
| 325 | +extern "C" uint64_t HcommCcuGetLaunchHashTag(const char* tag) { return asccomm_ccu_get_launch_hash_tag(tag); } | ||
| @@ -0,0 +1,333 @@ | |||
| 1 | +/* | ||
| 2 | + * xxHash - Extremely Fast Hash algorithm | ||
| 3 | + * Copyright (C) 2012-2023 Yann Collet | ||
| 4 | + * | ||
| 5 | + * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) | ||
| 6 | + * | ||
| 7 | + * Redistribution and use in source and binary forms, with or without | ||
| 8 | + * modification, are permitted provided that the following conditions are | ||
| 9 | + * met: | ||
| 10 | + * | ||
| 11 | + * * Redistributions of source code must retain the above copyright | ||
| 12 | + * notice, this list of conditions and the following disclaimer. | ||
| 13 | + * * Redistributions in binary form must reproduce the above | ||
| 14 | + * copyright notice, this list of conditions and the following disclaimer | ||
| 15 | + * in the documentation and/or other materials provided with the | ||
| 16 | + * distribution. | ||
| 17 | + * | ||
| 18 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 19 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 20 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, OR FITNESS FOR | ||
| 21 | + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 22 | + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 23 | + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 24 | + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 25 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 26 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 27 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 28 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 29 | + */ | ||
| 30 | + | ||
| 31 | +// Trimmed internal implementation for XXH3_64bits(input, length) only. | ||
| 32 | + | ||
| 33 | +#include <cstddef> | ||
| 34 | +#include <cstdint> | ||
| 35 | +#include <cstring> | ||
| 36 | + | ||
| 37 | +namespace asccomm_xxh3_detail { | ||
| 38 | +constexpr std::size_t XXH3_SECRETSIZE_MIN = 136; | ||
| 39 | +constexpr std::size_t XXH_SECRET_DEFAULT_SIZE = 192; | ||
| 40 | +constexpr std::size_t XXH_STRIPE_LEN = 64; | ||
| 41 | +constexpr std::size_t XXH_SECRET_CONSUME_RATE = 8; | ||
| 42 | +constexpr std::size_t XXH_ACC_NB = XXH_STRIPE_LEN / sizeof(uint64_t); | ||
| 43 | +constexpr std::size_t XXH3_MIDSIZE_MAX = 240; | ||
| 44 | +constexpr std::size_t XXH3_MIDSIZE_STARTOFFSET = 3; | ||
| 45 | +constexpr std::size_t XXH3_MIDSIZE_LASTOFFSET = 17; | ||
| 46 | +constexpr std::size_t XXH_SECRET_LASTACC_START = 7; | ||
| 47 | +constexpr std::size_t XXH_SECRET_MERGEACCS_START = 11; | ||
| 48 | + | ||
| 49 | +constexpr uint32_t PRIME32_1 = 0x9E3779B1U; | ||
| 50 | +constexpr uint32_t PRIME32_2 = 0x85EBCA77U; | ||
| 51 | +constexpr uint32_t PRIME32_3 = 0xC2B2AE3DU; | ||
| 52 | +constexpr uint64_t PRIME64_1 = 11400714785074694791ULL; | ||
| 53 | +constexpr uint64_t PRIME64_2 = 14029467366897019727ULL; | ||
| 54 | +constexpr uint64_t PRIME64_3 = 1609587929392839161ULL; | ||
| 55 | +constexpr uint64_t PRIME64_4 = 9650029242287828579ULL; | ||
| 56 | +constexpr uint64_t PRIME64_5 = 2870177450012600261ULL; | ||
| 57 | +constexpr uint64_t PRIME_MX1 = 0x165667919E3779F9ULL; | ||
| 58 | +constexpr uint64_t PRIME_MX2 = 0x9FB21C651E98DF25ULL; | ||
| 59 | + | ||
| 60 | +constexpr uint8_t XXH3_K_SECRET[XXH_SECRET_DEFAULT_SIZE] = { | ||
| 61 | + 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, | ||
| 62 | + 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, | ||
| 63 | + 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, | ||
| 64 | + 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, | ||
| 65 | + 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, | ||
| 66 | + 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, | ||
| 67 | + 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, | ||
| 68 | + 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, | ||
| 69 | + 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, | ||
| 70 | + 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, | ||
| 71 | + 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, | ||
| 72 | + 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, | ||
| 73 | +}; | ||
| 74 | + | ||
| 75 | +static inline uint64_t Bswap64(uint64_t value) | ||
| 76 | +{ | ||
| 77 | +#if defined(__GNUC__) || defined(__clang__) | ||
| 78 | + return __builtin_bswap64(value); | ||
| 79 | +#else | ||
| 80 | + return ((value & 0x00000000000000ffULL) << 56) | ((value & 0x000000000000ff00ULL) << 40) | | ||
| 81 | + ((value & 0x0000000000ff0000ULL) << 24) | ((value & 0x00000000ff000000ULL) << 8) | | ||
| 82 | + ((value & 0x000000ff00000000ULL) >> 8) | ((value & 0x0000ff0000000000ULL) >> 24) | | ||
| 83 | + ((value & 0x00ff000000000000ULL) >> 40) | ((value & 0xff00000000000000ULL) >> 56); | ||
| 84 | +#endif | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +static inline uint32_t Bswap32(uint32_t value) | ||
| 88 | +{ | ||
| 89 | +#if defined(__GNUC__) || defined(__clang__) | ||
| 90 | + return __builtin_bswap32(value); | ||
| 91 | +#else | ||
| 92 | + return ((value & 0x000000ffU) << 24) | ((value & 0x0000ff00U) << 8) | | ||
| 93 | + ((value & 0x00ff0000U) >> 8) | ((value & 0xff000000U) >> 24); | ||
| 94 | +#endif | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +static inline uint64_t Read64LE(const void *ptr) | ||
| 98 | +{ | ||
| 99 | + uint64_t value; | ||
| 100 | + std::memcpy(&value, ptr, sizeof(value)); | ||
| 101 | +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) | ||
| 102 | + value = Bswap64(value); | ||
| 103 | +#endif | ||
| 104 | + return value; | ||
| 105 | +} | ||
| 106 | + | ||
| 107 | +static inline uint32_t Read32LE(const void *ptr) | ||
| 108 | +{ | ||
| 109 | + uint32_t value; | ||
| 110 | + std::memcpy(&value, ptr, sizeof(value)); | ||
| 111 | +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) | ||
| 112 | + value = Bswap32(value); | ||
| 113 | +#endif | ||
| 114 | + return value; | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +static inline uint64_t Rotl64(uint64_t value, uint32_t shift) | ||
| 118 | +{ | ||
| 119 | + return (value << shift) | (value >> (64U - shift)); | ||
| 120 | +} | ||
| 121 | + | ||
| 122 | +static inline uint64_t XXH64Avalanche(uint64_t hash) | ||
| 123 | +{ | ||
| 124 | + hash ^= hash >> 33; | ||
| 125 | + hash *= PRIME64_2; | ||
| 126 | + hash ^= hash >> 29; | ||
| 127 | + hash *= PRIME64_3; | ||
| 128 | + hash ^= hash >> 32; | ||
| 129 | + return hash; | ||
| 130 | +} | ||
| 131 | + | ||
| 132 | +static inline uint64_t Mul128Fold64(uint64_t lhs, uint64_t rhs) | ||
| 133 | +{ | ||
| 134 | +#if defined(__SIZEOF_INT128__) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) | ||
| 135 | + __uint128_t product = static_cast<__uint128_t>(lhs) * static_cast<__uint128_t>(rhs); | ||
| 136 | + return static_cast<uint64_t>(product) ^ static_cast<uint64_t>(product >> 64); | ||
| 137 | +#else | ||
| 138 | + const uint64_t loLo = (lhs & 0xFFFFFFFFULL) * (rhs & 0xFFFFFFFFULL); | ||
| 139 | + const uint64_t hiLo = (lhs >> 32) * (rhs & 0xFFFFFFFFULL); | ||
| 140 | + const uint64_t loHi = (lhs & 0xFFFFFFFFULL) * (rhs >> 32); | ||
| 141 | + const uint64_t hiHi = (lhs >> 32) * (rhs >> 32); | ||
| 142 | + const uint64_t cross = (loLo >> 32) + (hiLo & 0xFFFFFFFFULL) + loHi; | ||
| 143 | + const uint64_t upper = (hiLo >> 32) + (cross >> 32) + hiHi; | ||
| 144 | + const uint64_t lower = (cross << 32) | (loLo & 0xFFFFFFFFULL); | ||
| 145 | + return upper ^ lower; | ||
| 146 | +#endif | ||
| 147 | +} | ||
| 148 | + | ||
| 149 | +static inline uint64_t XXH3Avalanche(uint64_t hash) | ||
| 150 | +{ | ||
| 151 | + hash ^= hash >> 37; | ||
| 152 | + hash *= PRIME_MX1; | ||
| 153 | + hash ^= hash >> 32; | ||
| 154 | + return hash; | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +static inline uint64_t Len1To3(const uint8_t *input, std::size_t len, const uint8_t *secret) | ||
| 158 | +{ | ||
| 159 | + const uint8_t c1 = input[0]; | ||
| 160 | + const uint8_t c2 = input[len >> 1]; | ||
| 161 | + const uint8_t c3 = input[len - 1]; | ||
| 162 | + const uint32_t combined = (static_cast<uint32_t>(c1) << 16) | | ||
| 163 | + (static_cast<uint32_t>(c2) << 24) | static_cast<uint32_t>(c3) | | ||
| 164 | + (static_cast<uint32_t>(len) << 8); | ||
| 165 | + const uint64_t bitflip = static_cast<uint64_t>(Read32LE(secret) ^ Read32LE(secret + 4)); | ||
| 166 | + return XXH64Avalanche(static_cast<uint64_t>(combined) ^ bitflip); | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +static inline uint64_t Len4To8(const uint8_t *input, std::size_t len, const uint8_t *secret) | ||
| 170 | +{ | ||
| 171 | + const uint32_t input1 = Read32LE(input); | ||
| 172 | + const uint32_t input2 = Read32LE(input + len - 4); | ||
| 173 | + uint64_t acc = Read64LE(secret + 8) ^ Read64LE(secret + 16); | ||
| 174 | + const uint64_t input64 = static_cast<uint64_t>(input2) | (static_cast<uint64_t>(input1) << 32); | ||
| 175 | + acc ^= input64; | ||
| 176 | + acc ^= Rotl64(acc, 49) ^ Rotl64(acc, 24); | ||
| 177 | + acc *= PRIME_MX2; | ||
| 178 | + acc ^= (acc >> 35) + static_cast<uint64_t>(len); | ||
| 179 | + acc *= PRIME_MX2; | ||
| 180 | + return acc ^ (acc >> 28); | ||
| 181 | +} | ||
| 182 | + | ||
| 183 | +static inline uint64_t Len9To16(const uint8_t *input, std::size_t len, const uint8_t *secret) | ||
| 184 | +{ | ||
| 185 | + uint64_t inputLo = Read64LE(secret + 24) ^ Read64LE(secret + 32); | ||
| 186 | + uint64_t inputHi = Read64LE(secret + 40) ^ Read64LE(secret + 48); | ||
| 187 | + inputLo ^= Read64LE(input); | ||
| 188 | + inputHi ^= Read64LE(input + len - 8); | ||
| 189 | + const uint64_t acc = static_cast<uint64_t>(len) + Bswap64(inputLo) + inputHi + | ||
| 190 | + Mul128Fold64(inputLo, inputHi); | ||
| 191 | + return XXH3Avalanche(acc); | ||
| 192 | +} | ||
| 193 | + | ||
| 194 | +static inline uint64_t Len0To16(const uint8_t *input, std::size_t len, const uint8_t *secret) | ||
| 195 | +{ | ||
| 196 | + if (len > 8) { | ||
| 197 | + return Len9To16(input, len, secret); | ||
| 198 | + } | ||
| 199 | + if (len >= 4) { | ||
| 200 | + return Len4To8(input, len, secret); | ||
| 201 | + } | ||
| 202 | + if (len != 0) { | ||
| 203 | + return Len1To3(input, len, secret); | ||
| 204 | + } | ||
| 205 | + return XXH64Avalanche(Read64LE(secret + 56) ^ Read64LE(secret + 64)); | ||
| 206 | +} | ||
| 207 | + | ||
| 208 | +static inline uint64_t Mix16B(const uint8_t *input, const uint8_t *secret) | ||
| 209 | +{ | ||
| 210 | + const uint64_t lhs = Read64LE(secret) ^ Read64LE(input); | ||
| 211 | + const uint64_t rhs = Read64LE(secret + 8) ^ Read64LE(input + 8); | ||
| 212 | + return Mul128Fold64(lhs, rhs); | ||
| 213 | +} | ||
| 214 | + | ||
| 215 | +static inline uint64_t Len17To128(const uint8_t *input, std::size_t len, const uint8_t *secret) | ||
| 216 | +{ | ||
| 217 | + uint64_t acc = len * PRIME64_1; | ||
| 218 | + uint64_t accResult = Mix16B(input + len - 16, secret + 16); | ||
| 219 | + acc += Mix16B(input, secret); | ||
| 220 | + if (len > 32) { | ||
| 221 | + acc += Mix16B(input + 16, secret + 32); | ||
| 222 | + accResult += Mix16B(input + len - 32, secret + 48); | ||
| 223 | + if (len > 64) { | ||
| 224 | + acc += Mix16B(input + 32, secret + 64); | ||
| 225 | + accResult += Mix16B(input + len - 48, secret + 80); | ||
| 226 | + if (len > 96) { | ||
| 227 | + acc += Mix16B(input + 48, secret + 96); | ||
| 228 | + accResult += Mix16B(input + len - 64, secret + 112); | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + return XXH3Avalanche(acc + accResult); | ||
| 233 | +} | ||
| 234 | + | ||
| 235 | +static inline uint64_t Len129To240(const uint8_t *input, std::size_t len, const uint8_t *secret) | ||
| 236 | +{ | ||
| 237 | + uint64_t acc = static_cast<uint64_t>(len) * PRIME64_1; | ||
| 238 | + const std::size_t nbRounds = len / 16; | ||
| 239 | + for (std::size_t i = 0; i < 8; ++i) { | ||
| 240 | + acc += Mix16B(input + (16 * i), secret + (16 * i)); | ||
| 241 | + } | ||
| 242 | + acc = XXH3Avalanche(acc); | ||
| 243 | + for (std::size_t i = 8; i < nbRounds; ++i) { | ||
| 244 | + acc += Mix16B(input + (16 * i), secret + (16 * (i - 8)) + XXH3_MIDSIZE_STARTOFFSET); | ||
| 245 | + } | ||
| 246 | + acc += Mix16B(input + len - 16, secret + XXH3_SECRETSIZE_MIN - XXH3_MIDSIZE_LASTOFFSET); | ||
| 247 | + return XXH3Avalanche(acc); | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +static inline void Accumulate512(uint64_t *acc, const uint8_t *input, const uint8_t *secret) | ||
| 251 | +{ | ||
| 252 | + for (std::size_t i = 0; i < XXH_ACC_NB; ++i) { | ||
| 253 | + const uint64_t dataVal = Read64LE(input + (8 * i)); | ||
| 254 | + const uint64_t dataKey = dataVal ^ Read64LE(secret + (8 * i)); | ||
| 255 | + acc[i ^ 1] += dataVal; | ||
| 256 | + acc[i] += static_cast<uint32_t>(dataKey) * (dataKey >> 32); | ||
| 257 | + } | ||
| 258 | +} | ||
| 259 | + | ||
| 260 | +static inline void ScrambleAcc(uint64_t *acc, const uint8_t *secret) | ||
| 261 | +{ | ||
| 262 | + for (std::size_t i = 0; i < XXH_ACC_NB; ++i) { | ||
| 263 | + acc[i] ^= acc[i] >> 47; | ||
| 264 | + acc[i] ^= Read64LE(secret + (8 * i)); | ||
| 265 | + acc[i] *= PRIME32_1; | ||
| 266 | + } | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +static inline void Accumulate(uint64_t *acc, const uint8_t *input, const uint8_t *secret, | ||
| 270 | + std::size_t nbStripes) | ||
| 271 | +{ | ||
| 272 | + for (std::size_t n = 0; n < nbStripes; ++n) { | ||
| 273 | + Accumulate512(acc, input + (n * XXH_STRIPE_LEN), secret + (n * XXH_SECRET_CONSUME_RATE)); | ||
| 274 | + } | ||
| 275 | +} | ||
| 276 | + | ||
| 277 | +static inline uint64_t Mix2Accs(const uint64_t *acc, const uint8_t *secret) | ||
| 278 | +{ | ||
| 279 | + return Mul128Fold64(acc[0] ^ Read64LE(secret), acc[1] ^ Read64LE(secret + 8)); | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +static inline uint64_t MergeAccs(const uint64_t *acc, const uint8_t *secret, uint64_t start) | ||
| 283 | +{ | ||
| 284 | + uint64_t result = start; | ||
| 285 | + for (std::size_t i = 0; i < 4; ++i) { | ||
| 286 | + result += Mix2Accs(acc + (2 * i), secret + (16 * i)); | ||
| 287 | + } | ||
| 288 | + return XXH3Avalanche(result); | ||
| 289 | +} | ||
| 290 | + | ||
| 291 | +static inline uint64_t HashLong(const uint8_t *input, std::size_t len, const uint8_t *secret, | ||
| 292 | + std::size_t secretSize) | ||
| 293 | +{ | ||
| 294 | + const std::size_t nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; | ||
| 295 | + const std::size_t blockLen = XXH_STRIPE_LEN * nbStripesPerBlock; | ||
| 296 | + const std::size_t nbBlocks = (len - 1) / blockLen; | ||
| 297 | + alignas(16) uint64_t acc[XXH_ACC_NB] = { | ||
| 298 | + PRIME32_3, PRIME64_1, PRIME64_2, PRIME64_3, | ||
| 299 | + PRIME64_4, PRIME32_2, PRIME64_5, PRIME32_1, | ||
| 300 | + }; | ||
| 301 | + | ||
| 302 | + for (std::size_t n = 0; n < nbBlocks; ++n) { | ||
| 303 | + Accumulate(acc, input + (n * blockLen), secret, nbStripesPerBlock); | ||
| 304 | + ScrambleAcc(acc, secret + secretSize - XXH_STRIPE_LEN); | ||
| 305 | + } | ||
| 306 | + | ||
| 307 | + const std::size_t nbStripes = (len - 1 - (blockLen * nbBlocks)) / XXH_STRIPE_LEN; | ||
| 308 | + Accumulate(acc, input + (nbBlocks * blockLen), secret, nbStripes); | ||
| 309 | + Accumulate512(acc, input + len - XXH_STRIPE_LEN, | ||
| 310 | + secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); | ||
| 311 | + return MergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, static_cast<uint64_t>(len) * PRIME64_1); | ||
| 312 | +} | ||
| 313 | + | ||
| 314 | +static inline uint64_t XXH3_64bitsImpl(const void *input, std::size_t length) | ||
| 315 | +{ | ||
| 316 | + const uint8_t *data = static_cast<const uint8_t *>(input); | ||
| 317 | + if (length <= 16) { | ||
| 318 | + return Len0To16(data, length, XXH3_K_SECRET); | ||
| 319 | + } | ||
| 320 | + if (length <= 128) { | ||
| 321 | + return Len17To128(data, length, XXH3_K_SECRET); | ||
| 322 | + } | ||
| 323 | + if (length <= XXH3_MIDSIZE_MAX) { | ||
| 324 | + return Len129To240(data, length, XXH3_K_SECRET); | ||
| 325 | + } | ||
| 326 | + return HashLong(data, length, XXH3_K_SECRET, sizeof(XXH3_K_SECRET)); | ||
| 327 | +} | ||
| 328 | +} // namespace asccomm_xxh3_detail | ||
| 329 | + | ||
| 330 | +static inline uint64_t XXH3_64bits(const void *input, std::size_t length) | ||
| 331 | +{ | ||
| 332 | + return asccomm_xxh3_detail::XXH3_64bitsImpl(input, length); | ||
| 333 | +} | ||
| @@ -164,6 +164,8 @@ add_custom_target(prepare_asccomm_ut_header_layout | |||
| 164 | DEPENDS ${ASCCOMM_UT_STAGE_STAMP} | 164 | DEPENDS ${ASCCOMM_UT_STAGE_STAMP} |
| 165 | ) | 165 | ) |
| 166 | 166 | ||
| 167 | +set(ASCCOMM_COVERAGE_SCRIPT ${ASCCOMM_ROOT}/scripts/generate_cpp_cov.sh) | ||
| 168 | + | ||
| 167 | function(run_llt_test) | 169 | function(run_llt_test) |
| 168 | cmake_parse_arguments(LLT "" "TARGET;TASK_NUM;ENV_FILE" "FILTERS;RUNTIME_DIRS" ${ARGN}) | 170 | cmake_parse_arguments(LLT "" "TARGET;TASK_NUM;ENV_FILE" "FILTERS;RUNTIME_DIRS" ${ARGN}) |
| 169 | 171 | ||
| @@ -224,7 +226,53 @@ function(run_llt_test) | |||
| 224 | ) | 226 | ) |
| 225 | endfunction() | 227 | endfunction() |
| 226 | 228 | ||
| 227 | -set(ASCCOMM_COVERAGE_SCRIPT ${ASCCOMM_ROOT}/scripts/generate_cpp_cov.sh) | 229 | +add_library(asccomm_ccu_host_launch STATIC |
| 230 | + ${ASCCOMM_ROOT}/src/ccu/ccu_host_launch.cpp | ||
| 231 | +) | ||
| 232 | +target_include_directories(asccomm_ccu_host_launch | ||
| 233 | + PUBLIC | ||
| 234 | + ${ASCCOMM_ROOT}/include | ||
| 235 | + PRIVATE | ||
| 236 | + ${ASCEND_CANN_ARCH_DIR}/include | ||
| 237 | + ${ASCEND_CANN_ARCH_DIR}/include/hcomm/ccu | ||
| 238 | + ${ASCEND_CANN_ARCH_DIR}/include/hccl | ||
| 239 | + ${ASCEND_CANN_ARCH_DIR}/pkg_inc | ||
| 240 | + ${ASCEND_CANN_ARCH_DIR}/pkg_inc/runtime | ||
| 241 | +) | ||
| 242 | +target_compile_features(asccomm_ccu_host_launch PUBLIC cxx_std_17) | ||
| 243 | +target_compile_options(asccomm_ccu_host_launch PRIVATE | ||
| 244 | + -fPIC | ||
| 245 | + -Wall | ||
| 246 | + -Werror | ||
| 247 | +) | ||
| 248 | + | ||
| 249 | +add_executable(asccomm_ut_ccu_host_launch | ||
| 250 | + ${ASCCOMM_UT_ROOT}/ccu/test_ccu_host_launch.cpp | ||
| 251 | +) | ||
| 252 | +target_include_directories(asccomm_ut_ccu_host_launch PRIVATE | ||
| 253 | + ${ASCCOMM_ROOT}/include | ||
| 254 | + ${ASCEND_CANN_ARCH_DIR}/include | ||
| 255 | + ${ASCEND_CANN_ARCH_DIR}/include/hcomm/ccu | ||
| 256 | + ${ASCEND_CANN_ARCH_DIR}/include/hccl | ||
| 257 | + ${ASCEND_CANN_ARCH_DIR}/pkg_inc | ||
| 258 | + ${ASCEND_CANN_ARCH_DIR}/pkg_inc/runtime | ||
| 259 | +) | ||
| 260 | +target_compile_features(asccomm_ut_ccu_host_launch PRIVATE cxx_std_17) | ||
| 261 | +target_compile_options(asccomm_ut_ccu_host_launch PRIVATE | ||
| 262 | + -fPIC | ||
| 263 | + -Wall | ||
| 264 | + -Werror | ||
| 265 | +) | ||
| 266 | +target_link_libraries(asccomm_ut_ccu_host_launch PRIVATE | ||
| 267 | + intf_llt_pub_basic | ||
| 268 | + asccomm_ccu_host_launch | ||
| 269 | +) | ||
| 270 | + | ||
| 271 | +run_llt_test( | ||
| 272 | + TARGET asccomm_ut_ccu_host_launch | ||
| 273 | + TASK_NUM 1 | ||
| 274 | + FILTERS TestCcuHostLaunch.* | ||
| 275 | +) | ||
| 228 | 276 | ||
| 229 | function(asccomm_add_product_definitions target_name product_type) | 277 | function(asccomm_add_product_definitions target_name product_type) |
| 230 | target_compile_definitions(${target_name} PRIVATE | 278 | target_compile_definitions(${target_name} PRIVATE |
| @@ -0,0 +1,142 @@ | |||
| 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 | +namespace { | ||
| 18 | +constexpr uint32_t CCU_SQE_ARGS_LEN = 13; | ||
| 19 | + | ||
| 20 | +void DummyKernel(void*) {} | ||
| 21 | + | ||
| 22 | +asccomm_launch_kernel_cfg MakeLaunchCfg() | ||
| 23 | +{ | ||
| 24 | + asccomm_launch_kernel_cfg cfg{}; | ||
| 25 | + cfg.ccu_schd = {1, 0, 0x01, 0}; | ||
| 26 | + cfg.ccu_ins = 0x11; | ||
| 27 | + cfg.stream = reinterpret_cast<aclrtStream>(0x22); | ||
| 28 | + cfg.attrs = nullptr; | ||
| 29 | + return cfg; | ||
| 30 | +} | ||
| 31 | +} // namespace | ||
| 32 | + | ||
| 33 | +int32_t HcclGetThreadDeviceId() { return 0; } | ||
| 34 | + | ||
| 35 | +extern "C" int rtCCULaunch(void*, void* const) { return 0; } | ||
| 36 | + | ||
| 37 | +namespace hcomm { | ||
| 38 | +struct CcuTaskParam { | ||
| 39 | + uint8_t dieId; | ||
| 40 | + uint8_t missionId; | ||
| 41 | + uint16_t timeout; | ||
| 42 | + uint32_t instStartId; | ||
| 43 | + uint32_t instCnt; | ||
| 44 | + uint32_t key; | ||
| 45 | + uint32_t argSize; | ||
| 46 | + uint64_t args[CCU_SQE_ARGS_LEN]; | ||
| 47 | +}; | ||
| 48 | + | ||
| 49 | +class CcuKernel { | ||
| 50 | +public: | ||
| 51 | + CcuResult GeneTaskParams(const uint64_t*, uint32_t, std::vector<CcuTaskParam>& taskParams); | ||
| 52 | +}; | ||
| 53 | + | ||
| 54 | +class CcuKernelMgr { | ||
| 55 | +public: | ||
| 56 | + static CcuKernelMgr& GetInstance(int32_t); | ||
| 57 | + | ||
| 58 | + CcuKernel* GetKernel(CcuKernelHandle); | ||
| 59 | +}; | ||
| 60 | + | ||
| 61 | +CcuResult CcuKernel::GeneTaskParams(const uint64_t*, uint32_t, std::vector<CcuTaskParam>& taskParams) | ||
| 62 | +{ | ||
| 63 | + taskParams.push_back({}); | ||
| 64 | + return CCU_SUCCESS; | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +CcuKernelMgr& CcuKernelMgr::GetInstance(int32_t) | ||
| 68 | +{ | ||
| 69 | + static CcuKernelMgr mgr; | ||
| 70 | + return mgr; | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +CcuKernel* CcuKernelMgr::GetKernel(CcuKernelHandle) | ||
| 74 | +{ | ||
| 75 | + static CcuKernel kernel; | ||
| 76 | + return &kernel; | ||
| 77 | +} | ||
| 78 | +} // namespace hcomm | ||
| 79 | + | ||
| 80 | +class TestCcuHostLaunch : public testing::Test {}; | ||
| 81 | + | ||
| 82 | +TEST_F(TestCcuHostLaunch, NullArgumentsReturnPtr) | ||
| 83 | +{ | ||
| 84 | + asccomm_launch_kernel_cfg cfg = MakeLaunchCfg(); | ||
| 85 | + uint64_t args[] = {1, 2, 3}; | ||
| 86 | + | ||
| 87 | + EXPECT_EQ(asccomm_ccu_host_kernel_launch(nullptr, &cfg, args), CCU_E_PTR); | ||
| 88 | + EXPECT_EQ(asccomm_ccu_host_kernel_launch(reinterpret_cast<const void*>(DummyKernel), nullptr, args), CCU_E_PTR); | ||
| 89 | + EXPECT_EQ(asccomm_ccu_host_kernel_launch(reinterpret_cast<const void*>(DummyKernel), &cfg, nullptr), CCU_E_PTR); | ||
| 90 | + EXPECT_EQ(HcommCcuHostKernelLaunch(reinterpret_cast<const void*>(DummyKernel), nullptr, args), CCU_E_PTR); | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +TEST_F(TestCcuHostLaunch, UnsupportedDieMaskReturnsPara) | ||
| 94 | +{ | ||
| 95 | + asccomm_launch_kernel_cfg cfg = MakeLaunchCfg(); | ||
| 96 | + uint64_t args[] = {1, 2, 3}; | ||
| 97 | + | ||
| 98 | + cfg.ccu_schd.phy_die_mask = 0; | ||
| 99 | + EXPECT_EQ(asccomm_ccu_host_kernel_launch(reinterpret_cast<const void*>(DummyKernel), &cfg, args), CCU_E_PARA); | ||
| 100 | + | ||
| 101 | + cfg.ccu_schd.phy_die_mask = 0x03; | ||
| 102 | + EXPECT_EQ(asccomm_ccu_host_kernel_launch(reinterpret_cast<const void*>(DummyKernel), &cfg, args), CCU_E_PARA); | ||
| 103 | + | ||
| 104 | + HcommLaunchKernelCfg hcommCfg{}; | ||
| 105 | + hcommCfg.ccuSchd.numBlocks = cfg.ccu_schd.num_blocks; | ||
| 106 | + hcommCfg.ccuSchd.reserved = cfg.ccu_schd.reserved; | ||
| 107 | + hcommCfg.ccuSchd.phyDieMask = cfg.ccu_schd.phy_die_mask; | ||
| 108 | + hcommCfg.ccuSchd.binaryCacheTag = cfg.ccu_schd.binary_cache_tag; | ||
| 109 | + hcommCfg.ccuIns = cfg.ccu_ins; | ||
| 110 | + hcommCfg.stream = cfg.stream; | ||
| 111 | + hcommCfg.attrs = cfg.attrs; | ||
| 112 | + EXPECT_EQ(HcommCcuHostKernelLaunch(reinterpret_cast<const void*>(DummyKernel), &hcommCfg, args), CCU_E_PARA); | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +TEST_F(TestCcuHostLaunch, UnsupportedNumBlocksReturnsPara) | ||
| 116 | +{ | ||
| 117 | + asccomm_launch_kernel_cfg cfg = MakeLaunchCfg(); | ||
| 118 | + uint64_t args[] = {1, 2, 3}; | ||
| 119 | + | ||
| 120 | + cfg.ccu_schd.num_blocks = 0; | ||
| 121 | + EXPECT_EQ(asccomm_ccu_host_kernel_launch(reinterpret_cast<const void*>(DummyKernel), &cfg, args), CCU_E_PARA); | ||
| 122 | + | ||
| 123 | + cfg.ccu_schd.num_blocks = 2; | ||
| 124 | + EXPECT_EQ(asccomm_ccu_host_kernel_launch(reinterpret_cast<const void*>(DummyKernel), &cfg, args), CCU_E_PARA); | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +TEST_F(TestCcuHostLaunch, LaunchHashTagReturnsStableNonZeroValue) | ||
| 128 | +{ | ||
| 129 | + const uint64_t tag = asccomm_ccu_get_launch_hash_tag("CcuAllGatherMesh1DMem2MemKernel"); | ||
| 130 | + | ||
| 131 | + EXPECT_EQ(asccomm_ccu_get_launch_hash_tag(nullptr), 0U); | ||
| 132 | + EXPECT_NE(tag, 0U); | ||
| 133 | + EXPECT_EQ(tag, asccomm_ccu_get_launch_hash_tag("CcuAllGatherMesh1DMem2MemKernel")); | ||
| 134 | + EXPECT_NE(tag, asccomm_ccu_get_launch_hash_tag("CcuAllGatherMesh1DMem2MemKernel_rank_1")); | ||
| 135 | + EXPECT_EQ(tag, HcommCcuGetLaunchHashTag("CcuAllGatherMesh1DMem2MemKernel")); | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +int main(int argc, char** argv) | ||
| 139 | +{ | ||
| 140 | + testing::InitGoogleTest(&argc, argv); | ||
| 141 | + return RUN_ALL_TESTS(); | ||
| 142 | +} | ||


这里是跟ci同事对过的吗?这个相当于是白名单了。确认下是屏蔽还是改这里?