已合并
mc2 ccu适配:reducescatter & allgather #4645
jiachengtang创建于 7月27日
mc2 ccu适配:reducescatter & allgather #4645
已合并
共 173 个文件变更+14337-1989
| @@ -8,17 +8,20 @@ | |||
| 8 | # See LICENSE in the root of the software repository for the full text of the License. | 8 | # See LICENSE in the root of the software repository for the full text of the License. |
| 9 | # ---------------------------------------------------------------------------------------------------------- | 9 | # ---------------------------------------------------------------------------------------------------------- |
| 10 | set(OPS_BASE_DIR ${HCCL_CC_DIR}) | 10 | set(OPS_BASE_DIR ${HCCL_CC_DIR}) |
| 11 | -option(MC2_CLIENT_ENABLE_CCU "Build CCU algorithm implementations into mc2_client" OFF) | 11 | +option(MC2_CLIENT_ENABLE_CCU "Build CCU algorithm implementations into mc2_client" ON) |
| 12 | 12 | ||
| 13 | set(INCLUDE_LIST | 13 | set(INCLUDE_LIST |
| 14 | ${HCCL_CC_INCLUDE_DIR} | 14 | ${HCCL_CC_INCLUDE_DIR} |
| 15 | ${HCCL_CC_INCLUDE_DIR}/hcomm | 15 | ${HCCL_CC_INCLUDE_DIR}/hcomm |
| 16 | + ${HCCL_CC_INCLUDE_DIR}/hcomm/types | ||
| 16 | ${HCCL_CC_INCLUDE_DIR}/hcomm/hccl | 17 | ${HCCL_CC_INCLUDE_DIR}/hcomm/hccl |
| 17 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc/hccl | 18 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc/hccl |
| 19 | + ${HCCL_CC_INCLUDE_DIR}/hcomm/ccu | ||
| 18 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc/hcomm/ccu | 20 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc/hcomm/ccu |
| 19 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc | 21 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc |
| 20 | ${CMAKE_CURRENT_SOURCE_DIR}/common | 22 | ${CMAKE_CURRENT_SOURCE_DIR}/common |
| 21 | ${CMAKE_CURRENT_SOURCE_DIR}/common/hcomm_dlsym | 23 | ${CMAKE_CURRENT_SOURCE_DIR}/common/hcomm_dlsym |
| 24 | + ${CMAKE_CURRENT_SOURCE_DIR}/common/hcomm_dlsym/ccu | ||
| 22 | 25 | ||
| 23 | ${CMAKE_CURRENT_SOURCE_DIR}/ops | 26 | ${CMAKE_CURRENT_SOURCE_DIR}/ops |
| 24 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/op_common | 27 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/op_common |
| @@ -47,7 +50,6 @@ set(INCLUDE_LIST | |||
| 47 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/selector | 50 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/selector |
| 48 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template | 51 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template |
| 49 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/aicpu | 52 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/aicpu |
| 50 | - ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/aiv | ||
| 51 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/ccu | 53 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/ccu |
| 52 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/ccu/kernel | 54 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/ccu/kernel |
| 53 | 55 | ||
| @@ -56,11 +58,49 @@ set(INCLUDE_LIST | |||
| 56 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/selector | 58 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/selector |
| 57 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template | 59 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template |
| 58 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aicpu | 60 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aicpu |
| 59 | - ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aiv | ||
| 60 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/ccu | 61 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/ccu |
| 61 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/ccu/kernel | 62 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/ccu/kernel |
| 63 | + | ||
| 64 | + ${CMAKE_CURRENT_SOURCE_DIR}/ops/kfc_server | ||
| 65 | + ${CMAKE_CURRENT_SOURCE_DIR}/ops/kfc_server/executor | ||
| 66 | + ${CMAKE_CURRENT_SOURCE_DIR}/ops/kfc_server/selector | ||
| 67 | + ${CMAKE_CURRENT_SOURCE_DIR}/ops/kfc_server/template | ||
| 68 | + ${CMAKE_CURRENT_SOURCE_DIR}/ops/kfc_server/template/ccu | ||
| 69 | + ${CMAKE_CURRENT_SOURCE_DIR}/ops/kfc_server/template/ccu/kernel | ||
| 62 | ) | 70 | ) |
| 63 | 71 | ||
| 72 | +list(APPEND INCLUDE_LIST | ||
| 73 | + ${ASCEND_CANN_PACKAGE_PATH}/include | ||
| 74 | + ${ASCEND_CANN_PACKAGE_PATH}/include/acl | ||
| 75 | + | ||
| 76 | + # hcomm头文件 | ||
| 77 | + ${ASCEND_CANN_PACKAGE_PATH}/include/ccu | ||
| 78 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hccl | ||
| 79 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm | ||
| 80 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm/ccu | ||
| 81 | + | ||
| 82 | + # runtime头文件 | ||
| 83 | + ${ASCEND_CANN_PACKAGE_PATH}/include/base/ | ||
| 84 | + ${ASCEND_CANN_PACKAGE_PATH}/include/driver/ | ||
| 85 | + ${ASCEND_CANN_PACKAGE_PATH}/include/dump/ | ||
| 86 | + ${ASCEND_CANN_PACKAGE_PATH}/include/external/ | ||
| 87 | + ${ASCEND_CANN_PACKAGE_PATH}/include/platform/ | ||
| 88 | + | ||
| 89 | + # mmpa头文件 | ||
| 90 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/mmpa/ | ||
| 91 | + | ||
| 92 | + # 包间接口 | ||
| 93 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/ | ||
| 94 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/hccl | ||
| 95 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/hcomm/ccu | ||
| 96 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/runtime/ | ||
| 97 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/aicpu/ | ||
| 98 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/runtime/runtime/ | ||
| 99 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/profiling/ | ||
| 100 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/base/ | ||
| 101 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/dump/ | ||
| 102 | + ${ASCEND_CANN_PACKAGE_PATH}/pkg_inc/trace/ | ||
| 103 | +) | ||
| 64 | 104 | ||
| 65 | if(PRODUCT_SIDE STREQUAL "device") | 105 | if(PRODUCT_SIDE STREQUAL "device") |
| 66 | add_library(mc2_server SHARED | 106 | add_library(mc2_server SHARED |
| @@ -99,6 +139,7 @@ if(PRODUCT_SIDE STREQUAL "device") | |||
| 99 | 139 | ||
| 100 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_v2_reduce_scatter_sole_executor.cc | 140 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_v2_reduce_scatter_sole_executor.cc |
| 101 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_reduce_scatter_parallel_executor.cc | 141 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_reduce_scatter_parallel_executor.cc |
| 142 | + ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_reduce_scatter_concurrent_executor.cc | ||
| 102 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_v2_reduce_scatter_sequence_executor_aicpu.cc | 143 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_v2_reduce_scatter_sequence_executor_aicpu.cc |
| 103 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_v2_reduce_scatter_sequence_executor.cc | 144 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/executor/ins_v2_reduce_scatter_sequence_executor.cc |
| 104 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/aicpu/ins_temp_reduce_scatter_mesh_1D.cc | 145 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/reduce_scatter/template/aicpu/ins_temp_reduce_scatter_mesh_1D.cc |
| @@ -110,6 +151,7 @@ if(PRODUCT_SIDE STREQUAL "device") | |||
| 110 | 151 | ||
| 111 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/executor/ins_v2_all_gather_sole_executor.cc | 152 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/executor/ins_v2_all_gather_sole_executor.cc |
| 112 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/executor/ins_v2_all_gather_parallel_executor.cc | 153 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/executor/ins_v2_all_gather_parallel_executor.cc |
| 154 | + ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/executor/ins_v2_all_gather_concurrent_executor.cc | ||
| 113 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aicpu/ins_temp_all_gather_mesh_1D.cc | 155 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aicpu/ins_temp_all_gather_mesh_1D.cc |
| 114 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aicpu/ins_temp_all_gather_mesh_1D_Z_axis_detour.cc | 156 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aicpu/ins_temp_all_gather_mesh_1D_Z_axis_detour.cc |
| 115 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aicpu/ins_temp_all_gather_nhr.cc | 157 | ${CMAKE_CURRENT_SOURCE_DIR}/ops/all_gather/template/aicpu/ins_temp_all_gather_nhr.cc |
| @@ -147,7 +189,6 @@ if(PRODUCT_SIDE STREQUAL "device") | |||
| 147 | target_link_libraries(mc2_server PRIVATE | 189 | target_link_libraries(mc2_server PRIVATE |
| 148 | -Wl,--no-as-needed | 190 | -Wl,--no-as-needed |
| 149 | mc2_kernel_compat | 191 | mc2_kernel_compat |
| 150 | - -Wl,--no-as-needed | ||
| 151 | mmpa | 192 | mmpa |
| 152 | $<BUILD_INTERFACE:acl_rt_headers> | 193 | $<BUILD_INTERFACE:acl_rt_headers> |
| 153 | $<BUILD_INTERFACE:error_manager_headers> | 194 | $<BUILD_INTERFACE:error_manager_headers> |
| @@ -207,7 +248,6 @@ if(NOT KERNEL_MODE AND PRODUCT_SIDE STREQUAL "host") | |||
| 207 | -Wl,-z,relro | 248 | -Wl,-z,relro |
| 208 | -Wl,-z,now | 249 | -Wl,-z,now |
| 209 | -Wl,-z,noexecstack | 250 | -Wl,-z,noexecstack |
| 210 | - -Wl,-Bsymbolic-functions | ||
| 211 | $<$<CONFIG:Release>:-s> | 251 | $<$<CONFIG:Release>:-s> |
| 212 | ) | 252 | ) |
| 213 | 253 | ||
| @@ -43,7 +43,9 @@ target_include_directories(ccl_kernel_decoupler_open BEFORE PRIVATE | |||
| 43 | ${OPEN_HCCL_SRC_ROOT}/ops/op_common/inc | 43 | ${OPEN_HCCL_SRC_ROOT}/ops/op_common/inc |
| 44 | ${OPEN_HCCL_SRC_ROOT}/common | 44 | ${OPEN_HCCL_SRC_ROOT}/common |
| 45 | ${OPEN_HCCL_SRC_ROOT}/common/hcomm_dlsym | 45 | ${OPEN_HCCL_SRC_ROOT}/common/hcomm_dlsym |
| 46 | + ${HCCL_HCOMM_HEADER_DIR}/ccu | ||
| 46 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu | 47 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu |
| 48 | + ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu_new | ||
| 47 | 49 | ||
| 48 | ${MC2_SERVER_CCL_INCLUDE_LIST} | 50 | ${MC2_SERVER_CCL_INCLUDE_LIST} |
| 49 | ${MC2_SERVER_ORION_HEAD_LIST} | 51 | ${MC2_SERVER_ORION_HEAD_LIST} |
| @@ -95,7 +97,9 @@ target_include_directories(ccl_kernel_decoupler_open_exec BEFORE PRIVATE | |||
| 95 | ${HCCL_BASE_DIR}/pub_inc | 97 | ${HCCL_BASE_DIR}/pub_inc |
| 96 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc | 98 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc |
| 97 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hccl | 99 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hccl |
| 100 | + ${HCCL_HCOMM_HEADER_DIR}/ccu | ||
| 98 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu | 101 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu |
| 102 | + ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu_new | ||
| 99 | ) | 103 | ) |
| 100 | 104 | ||
| 101 | target_link_libraries(ccl_kernel_decoupler_open_exec PRIVATE | 105 | target_link_libraries(ccl_kernel_decoupler_open_exec PRIVATE |
| @@ -118,10 +122,15 @@ if(TARGET mc2_server) | |||
| 118 | $<TARGET_PROPERTY:asc_ccl_kernel,INTERFACE_COMPILE_OPTIONS> | 122 | $<TARGET_PROPERTY:asc_ccl_kernel,INTERFACE_COMPILE_OPTIONS> |
| 119 | ) | 123 | ) |
| 120 | 124 | ||
| 121 | - target_include_directories(mc2_server_decoupler PRIVATE | 125 | + target_include_directories(mc2_server_decoupler BEFORE PRIVATE |
| 126 | + ${HCCL_BASE_DIR}/pub_inc | ||
| 122 | ${HCCL_HCOMM_HEADER_DIR}/../ | 127 | ${HCCL_HCOMM_HEADER_DIR}/../ |
| 123 | ${OPEN_HCCL_SRC_ROOT}/ops/op_common/inc | 128 | ${OPEN_HCCL_SRC_ROOT}/ops/op_common/inc |
| 129 | + ${OPEN_HCCL_SRC_ROOT}/common/hcomm_dlsym | ||
| 130 | + ${OPEN_HCCL_SRC_ROOT}/common/hcomm_dlsym/ccu | ||
| 131 | + ${HCCL_HCOMM_HEADER_DIR}/ccu | ||
| 124 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu | 132 | ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu |
| 133 | + ${HCCL_HCOMM_HEADER_DIR}/pkg_inc/hcomm/ccu_new | ||
| 125 | ${HCCL_BASE_DIR}/legacy/unified_platform/resource/stream/aicpu | 134 | ${HCCL_BASE_DIR}/legacy/unified_platform/resource/stream/aicpu |
| 126 | 135 | ||
| 127 | ${MC2_SERVER_CCL_INCLUDE_LIST} | 136 | ${MC2_SERVER_CCL_INCLUDE_LIST} |
Mimpl/adv_api/detail/hccl/cc/src/aicpu_kfc/framework/device/aicpu_kfc/mc2_server_kernel_entry.cc+2-0
| @@ -19,6 +19,7 @@ using namespace HcclApi; | |||
| 19 | 19 | ||
| 20 | extern "C" __attribute__((visibility("default"))) uint32_t Mc2ServerKernel(void* args[]) | 20 | extern "C" __attribute__((visibility("default"))) uint32_t Mc2ServerKernel(void* args[]) |
| 21 | { | 21 | { |
| 22 | + HCCL_INFO("[Mc2ServerKernel]Start Mc2ServerKernel."); | ||
| 22 | if (args == nullptr) { | 23 | if (args == nullptr) { |
| 23 | HCCL_ERROR("args is null."); | 24 | HCCL_ERROR("args is null."); |
| 24 | return HCCL_E_PARA; | 25 | return HCCL_E_PARA; |
| @@ -28,5 +29,6 @@ extern "C" __attribute__((visibility("default"))) uint32_t Mc2ServerKernel(void* | |||
| 28 | uint64_t descValue = reinterpret_cast<uint64_t>(args[DESC_POS]); | 29 | uint64_t descValue = reinterpret_cast<uint64_t>(args[DESC_POS]); |
| 29 | auto* desc = reinterpret_cast<CommKfcParamDesc*>(&descValue); | 30 | auto* desc = reinterpret_cast<CommKfcParamDesc*>(&descValue); |
| 30 | AicpuKfcUtils::PrintHcclCommParamDesc(*desc); | 31 | AicpuKfcUtils::PrintHcclCommParamDesc(*desc); |
| 32 | + HCCL_INFO("[Mc2ServerKernel]Finish Mc2ServerKernel."); | ||
| 31 | return CommKfcDispatcher::Run(&(args[1]), desc->itemNum); | 33 | return CommKfcDispatcher::Run(&(args[1]), desc->itemNum); |
| 32 | } | 34 | } |
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | + | ||
| 15 | 16 | ||
| 16 | 17 | ||
| 17 | 18 | ||
| @@ -23,7 +24,7 @@ class BinaryStream { | |||
| 23 | public: | 24 | public: |
| 24 | static constexpr std::ios_base::openmode DEFAULT_IOS_MODE = std::ios_base::in | std::ios_base::out; | 25 | static constexpr std::ios_base::openmode DEFAULT_IOS_MODE = std::ios_base::in | std::ios_base::out; |
| 25 | 26 | ||
| 26 | - explicit BinaryStream(std::ios_base::openmode mode = DEFAULT_IOS_MODE) : stream(mode | std::ios_base::binary){}; | 27 | + explicit BinaryStream(std::ios_base::openmode mode = DEFAULT_IOS_MODE) : stream(mode | std::ios_base::binary) {}; |
| 27 | 28 | ||
| 28 | explicit BinaryStream(std::vector<char>& buf, std::ios_base::openmode mode = DEFAULT_IOS_MODE) | 29 | explicit BinaryStream(std::vector<char>& buf, std::ios_base::openmode mode = DEFAULT_IOS_MODE) |
| 29 | : stream(mode | std::ios_base::binary) | 30 | : stream(mode | std::ios_base::binary) |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | -#include "binary_stream.h" | 16 | +#include "../../../common/binary_stream.h" |
| 17 | namespace Hccl { | 17 | namespace Hccl { |
| 18 | 18 | ||
| 19 | constexpr u32 MODULE_NAME_LEN = 128; | 19 | constexpr u32 MODULE_NAME_LEN = 128; |
| @@ -0,0 +1,168 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +namespace mc2_ops_hccl { | ||
| 17 | + | ||
| 18 | +// HCCL通信算法类型 | ||
| 19 | +enum class HcclAlgoType { | ||
| 20 | + HCCL_ALGO_TYPE_DEFAULT = 0, // 默认算法,配置为此时,使用HCCL内藏算法选择逻辑 | ||
| 21 | + HCCL_ALGO_TYPE_RING, | ||
| 22 | + HCCL_ALGO_TYPE_PIPELINE, | ||
| 23 | + HCCL_ALGO_TYPE_FULLMESH, | ||
| 24 | + HCCL_ALGO_TYPE_HDR, | ||
| 25 | + HCCL_ALGO_TYPE_PAIRWISE, | ||
| 26 | + HCCL_ALGO_TYPE_NHR, | ||
| 27 | + HCCL_ALGO_TYPE_NHR_V1, | ||
| 28 | + HCCL_ALGO_TYPE_NB, | ||
| 29 | + HCCL_ALGO_TYPE_NULL, | ||
| 30 | + HCCL_ALGO_TYPE_NA, | ||
| 31 | + HCCL_ALGO_TYPE_AHC, | ||
| 32 | + HCCL_ALGO_TYPE_AHC_BROKE | ||
| 33 | +}; | ||
| 34 | + | ||
| 35 | +// 对内拓扑算法枚举 | ||
| 36 | +enum class AlgTypeLevel0 { | ||
| 37 | + ALG_LEVEL0_WHOLE_RING = 0, // 单层拓扑, 所有level均为Whole ring时,组成一个大环 | ||
| 38 | + ALG_LEVEL0_8P_RING, // 拓扑组合0层, Ring 节点内4个固定stream | ||
| 39 | + ALG_LEVEL0_4P_MESH, // 拓扑组合0层, Mesh 节点内3个固定stream | ||
| 40 | + ALG_LEVEL0_2P_MESH, // 拓扑组合0层, Mesh | ||
| 41 | + ALG_LEVEL0_1P_MESH, // 拓扑组合0层, Mesh | ||
| 42 | + ALG_LEVEL0_4P_RING, // 拓扑组合0层, Ring | ||
| 43 | + ALG_LEVEL0_NP_SINGLE_RING, // 拓扑组合0层, Ring | ||
| 44 | + ALG_LEVEL0_NP_DOUBLE_RING, // 拓扑组合0层, double Ring | ||
| 45 | + ALG_LEVEL0_NP_MESH, // 拓扑组合0层, 服务器内3~8p rank组成MESH | ||
| 46 | + ALG_LEVEL0_NP_HD, // 拓扑组合0层, HD | ||
| 47 | + ALG_LEVEL0_NP_STAR, | ||
| 48 | + ALG_LEVEL0_PAIRWISE, | ||
| 49 | + ALG_LEVEL0_RESERVED | ||
| 50 | +}; | ||
| 51 | + | ||
| 52 | +enum class AlgTypeLevel1 { | ||
| 53 | + ALG_LEVEL1_WHOLE_RING = 0, // 单层拓扑, 所有level均为Whole ring时,组成一个大环 | ||
| 54 | + ALG_LEVEL1_HD, // 拓扑组合1层, HDR | ||
| 55 | + ALG_LEVEL1_RING, // 拓扑组合1层, Ring | ||
| 56 | + ALG_LEVEL1_PIPELINE, // 拓扑组合1层, Pipeline | ||
| 57 | + ALG_LEVEL1_STAR, | ||
| 58 | + ALG_LEVEL1_NHR, // 拓扑组合1层,NHR | ||
| 59 | + ALG_LEVEL1_NHR_V1, // 拓扑组合1层,NHR_V1 | ||
| 60 | + ALG_LEVEL1_NB, // 拓扑组合1层,NB | ||
| 61 | + ALG_LEVEL1_AHC, // 拓扑组合1层,AHC | ||
| 62 | + ALG_LEVEL1_AHC_BROKE, // 拓扑组合1层,AHC_BROKE | ||
| 63 | + ALG_LEVEL1_RESERVED | ||
| 64 | +}; | ||
| 65 | + | ||
| 66 | +enum class AlgTypeLevel2 { | ||
| 67 | + ALG_LEVEL2_WHOLE_RING = 0, // 单层拓扑, 所有leve2均为Whole ring时,组成一个大环 | ||
| 68 | + ALG_LEVEL2_HD, // 拓扑组合2层, HDR | ||
| 69 | + ALG_LEVEL2_RING, // 拓扑组合2层, Ring | ||
| 70 | + ALG_LEVEL2_NHR, // 拓扑组合2层, NHR | ||
| 71 | + ALG_LEVEL2_NB, // 拓扑组合2层, NB | ||
| 72 | + ALG_LEVEL2_RESERVED | ||
| 73 | +}; | ||
| 74 | + | ||
| 75 | +using AlgType = struct TagAlgType { | ||
| 76 | + AlgTypeLevel0 algoLevel0; | ||
| 77 | + AlgTypeLevel1 algoLevel1; | ||
| 78 | + AlgTypeLevel2 algoLevel2; | ||
| 79 | + TagAlgType() | ||
| 80 | + : algoLevel0(AlgTypeLevel0::ALG_LEVEL0_WHOLE_RING), | ||
| 81 | + algoLevel1(AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING), | ||
| 82 | + algoLevel2(AlgTypeLevel2::ALG_LEVEL2_WHOLE_RING) | ||
| 83 | + {} | ||
| 84 | + | ||
| 85 | + explicit TagAlgType(AlgTypeLevel0 algoLevel0) | ||
| 86 | + : algoLevel0(algoLevel0), | ||
| 87 | + algoLevel1(AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING), | ||
| 88 | + algoLevel2(AlgTypeLevel2::ALG_LEVEL2_WHOLE_RING) | ||
| 89 | + {} | ||
| 90 | + TagAlgType(AlgTypeLevel0 algoLevel0, AlgTypeLevel1 algoLevel1) | ||
| 91 | + : algoLevel0(algoLevel0), algoLevel1(algoLevel1), algoLevel2(AlgTypeLevel2::ALG_LEVEL2_WHOLE_RING) | ||
| 92 | + {} | ||
| 93 | + | ||
| 94 | + TagAlgType(AlgTypeLevel0 algoLevel0, AlgTypeLevel2 algoLevel2) | ||
| 95 | + : algoLevel0(algoLevel0), algoLevel1(AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING), algoLevel2(algoLevel2) | ||
| 96 | + {} | ||
| 97 | + | ||
| 98 | + TagAlgType(AlgTypeLevel0 algoLevel0, AlgTypeLevel1 algoLevel1, AlgTypeLevel2 algoLevel2) | ||
| 99 | + : algoLevel0(algoLevel0), algoLevel1(algoLevel1), algoLevel2(algoLevel2) | ||
| 100 | + {} | ||
| 101 | + explicit TagAlgType(AlgTypeLevel1 algoLevel1) | ||
| 102 | + : algoLevel0(AlgTypeLevel0::ALG_LEVEL0_WHOLE_RING), | ||
| 103 | + algoLevel1(algoLevel1), | ||
| 104 | + algoLevel2(AlgTypeLevel2::ALG_LEVEL2_WHOLE_RING) | ||
| 105 | + {} | ||
| 106 | + | ||
| 107 | + TagAlgType(AlgTypeLevel1 algoLevel1, AlgTypeLevel2 algoLevel2) | ||
| 108 | + : algoLevel0(AlgTypeLevel0::ALG_LEVEL0_WHOLE_RING), algoLevel1(algoLevel1), algoLevel2(algoLevel2) | ||
| 109 | + {} | ||
| 110 | + | ||
| 111 | + explicit TagAlgType(AlgTypeLevel2 algoLevel2) | ||
| 112 | + : algoLevel0(AlgTypeLevel0::ALG_LEVEL0_WHOLE_RING), | ||
| 113 | + algoLevel1(AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING), | ||
| 114 | + algoLevel2(algoLevel2) | ||
| 115 | + {} | ||
| 116 | + | ||
| 117 | + static TagAlgType Reserved() | ||
| 118 | + { | ||
| 119 | + return TagAlgType( | ||
| 120 | + AlgTypeLevel0::ALG_LEVEL0_RESERVED, AlgTypeLevel1::ALG_LEVEL1_RESERVED, AlgTypeLevel2::ALG_LEVEL2_RESERVED); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + TagAlgType(const TagAlgType& that) | ||
| 124 | + : algoLevel0(that.algoLevel0), algoLevel1(that.algoLevel1), algoLevel2(that.algoLevel2) | ||
| 125 | + {} | ||
| 126 | + | ||
| 127 | + TagAlgType& operator=(const TagAlgType& that) | ||
| 128 | + { | ||
| 129 | + if (&that != this) { | ||
| 130 | + algoLevel0 = that.algoLevel0; | ||
| 131 | + algoLevel1 = that.algoLevel1; | ||
| 132 | + algoLevel2 = that.algoLevel2; | ||
| 133 | + } | ||
| 134 | + return *this; | ||
| 135 | + } | ||
| 136 | +}; | ||
| 137 | + | ||
| 138 | +const std::map<AlgTypeLevel0, std::string> HCCL_ALGO_LEVEL0_NAME_MAP = { | ||
| 139 | + {AlgTypeLevel0::ALG_LEVEL0_NP_DOUBLE_RING, "ring"}, {AlgTypeLevel0::ALG_LEVEL0_WHOLE_RING, "ring"}, | ||
| 140 | + {AlgTypeLevel0::ALG_LEVEL0_8P_RING, "ring"}, {AlgTypeLevel0::ALG_LEVEL0_4P_MESH, "fullmesh"}, | ||
| 141 | + {AlgTypeLevel0::ALG_LEVEL0_2P_MESH, "fullmesh"}, {AlgTypeLevel0::ALG_LEVEL0_1P_MESH, "fullmesh"}, | ||
| 142 | + {AlgTypeLevel0::ALG_LEVEL0_4P_RING, "ring"}, {AlgTypeLevel0::ALG_LEVEL0_NP_SINGLE_RING, "ring"}, | ||
| 143 | + {AlgTypeLevel0::ALG_LEVEL0_NP_MESH, "fullmesh"}, {AlgTypeLevel0::ALG_LEVEL0_NP_HD, "HD"}, | ||
| 144 | + {AlgTypeLevel0::ALG_LEVEL0_NP_STAR, "star"}, {AlgTypeLevel0::ALG_LEVEL0_RESERVED, "null"}, | ||
| 145 | +}; | ||
| 146 | + | ||
| 147 | +const std::map<AlgTypeLevel1, std::string> HCCL_ALGO_LEVEL1_NAME_MAP = { | ||
| 148 | + {AlgTypeLevel1::ALG_LEVEL1_WHOLE_RING, "ring"}, {AlgTypeLevel1::ALG_LEVEL1_HD, "H-D"}, | ||
| 149 | + {AlgTypeLevel1::ALG_LEVEL1_RING, "ring"}, {AlgTypeLevel1::ALG_LEVEL1_PIPELINE, "pipeline"}, | ||
| 150 | + {AlgTypeLevel1::ALG_LEVEL1_NHR, "NHR"}, {AlgTypeLevel1::ALG_LEVEL1_NHR_V1, "NHR_V1"}, | ||
| 151 | + {AlgTypeLevel1::ALG_LEVEL1_AHC, "AHC"}, {AlgTypeLevel1::ALG_LEVEL1_AHC_BROKE, "AHC_BROKE"}, | ||
| 152 | + {AlgTypeLevel1::ALG_LEVEL1_NB, "NB"}, {AlgTypeLevel1::ALG_LEVEL1_RESERVED, "null"}, | ||
| 153 | +}; | ||
| 154 | + | ||
| 155 | +const std::map<AlgTypeLevel2, std::string> HCCL_ALGO_LEVEL2_NAME_MAP = { | ||
| 156 | + {AlgTypeLevel2::ALG_LEVEL2_WHOLE_RING, "ring"}, {AlgTypeLevel2::ALG_LEVEL2_HD, "H-D"}, | ||
| 157 | + {AlgTypeLevel2::ALG_LEVEL2_RING, "ring"}, {AlgTypeLevel2::ALG_LEVEL2_NHR, "NHR"}, | ||
| 158 | + {AlgTypeLevel2::ALG_LEVEL2_NB, "NB"}, {AlgTypeLevel2::ALG_LEVEL2_RESERVED, "null"}, | ||
| 159 | +}; | ||
| 160 | + | ||
| 161 | +std::string AlgTypeToStr(const AlgType algType); | ||
| 162 | + | ||
| 163 | +std::string TransferAlgTypeStr(AlgType algType); | ||
| 164 | + | ||
| 165 | +std::string TransferAlgType(AlgType algType); | ||
| 166 | +} // namespace mc2_ops_hccl | ||
| 167 | + | ||
| 168 | + | ||
| @@ -0,0 +1,165 @@ | |||
| 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 | +namespace mc2_ops_hccl { | ||
| 22 | + | ||
| 23 | +class BinaryStream { | ||
| 24 | +public: | ||
| 25 | + static constexpr std::ios_base::openmode DEFAULT_IOS_MODE = std::ios_base::in | std::ios_base::out; | ||
| 26 | + | ||
| 27 | + explicit BinaryStream(std::ios_base::openmode mode = DEFAULT_IOS_MODE) : stream(mode | std::ios_base::binary) {}; | ||
| 28 | + | ||
| 29 | + explicit BinaryStream(std::vector<char>& buf, std::ios_base::openmode mode = DEFAULT_IOS_MODE) | ||
| 30 | + : stream(mode | std::ios_base::binary) | ||
| 31 | + { | ||
| 32 | + stream.rdbuf()->pubsetbuf(buf.data(), buf.size()); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + template <typename T> | ||
| 36 | + BinaryStream& operator<<(const T& t) | ||
| 37 | + { | ||
| 38 | + stream.write(reinterpret_cast<const char*>(&t), sizeof(T)); | ||
| 39 | + return *this; | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + // 多级vector递归序列化 | ||
| 43 | + template <typename T> | ||
| 44 | + BinaryStream& operator<<(const std::vector<T>& vec) | ||
| 45 | + { | ||
| 46 | + size_t size = vec.size(); | ||
| 47 | + *this << size; | ||
| 48 | + for (const auto& elem : vec) { | ||
| 49 | + *this << elem; | ||
| 50 | + } | ||
| 51 | + return *this; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + // 对string的输入函数 | ||
| 55 | + BinaryStream& operator<<(const std::string& s) | ||
| 56 | + { | ||
| 57 | + size_t size = s.size(); | ||
| 58 | + stream.write(reinterpret_cast<const char*>(&size), sizeof(size_t)); // 写入长度 | ||
| 59 | + stream.write(s.data(), size); // 写入字符数据 | ||
| 60 | + return *this; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + template <typename T> | ||
| 64 | + BinaryStream& operator>>(T& t) | ||
| 65 | + { | ||
| 66 | + stream.read(reinterpret_cast<char*>(&t), sizeof(T)); | ||
| 67 | + return *this; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + // 对string的读取函数 | ||
| 71 | + BinaryStream& operator>>(std::string& s) | ||
| 72 | + { | ||
| 73 | + size_t size; | ||
| 74 | + stream.read(reinterpret_cast<char*>(&size), sizeof(size)); // 先从流中读取字符串长度 | ||
| 75 | + s.resize(size); // 为string分配足够空间 | ||
| 76 | + stream.read(&s[0], size); // 直接读取数据到string的缓冲区中,无需再分配内存 | ||
| 77 | + return *this; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + // 多级vector递归反序列化 | ||
| 81 | + template <typename T> | ||
| 82 | + BinaryStream& operator>>(std::vector<T>& vec) | ||
| 83 | + { | ||
| 84 | + size_t size; | ||
| 85 | + *this >> size; | ||
| 86 | + vec.resize(size); | ||
| 87 | + for (auto& elem : vec) { | ||
| 88 | + *this >> elem; | ||
| 89 | + } | ||
| 90 | + return *this; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + // map序列化 | ||
| 94 | + template <typename T1, typename T2> | ||
| 95 | + BinaryStream& operator<<(const std::map<T1, T2>& m) | ||
| 96 | + { | ||
| 97 | + size_t size = m.size(); | ||
| 98 | + *this << size; | ||
| 99 | + for (const auto& elem : m) { | ||
| 100 | + *this << elem.first; | ||
| 101 | + *this << elem.second; | ||
| 102 | + } | ||
| 103 | + return *this; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + // map反序列化 | ||
| 107 | + template <typename T1, typename T2> | ||
| 108 | + BinaryStream& operator>>(std::map<T1, T2>& m) | ||
| 109 | + { | ||
| 110 | + size_t size; | ||
| 111 | + *this >> size; | ||
| 112 | + for (size_t i = 0; i < size; i++) { | ||
| 113 | + T1 key; | ||
| 114 | + *this >> key; | ||
| 115 | + T2 value; | ||
| 116 | + *this >> value; | ||
| 117 | + m[key] = value; | ||
| 118 | + } | ||
| 119 | + return *this; | ||
| 120 | + } | ||
| 121 | + | ||
| 122 | + void Dump(std::vector<char>& vec) | ||
| 123 | + { | ||
| 124 | + std::for_each(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>(), [&vec](const char c) { | ||
| 125 | + vec.push_back(c); | ||
| 126 | + }); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + void DumpWithRevert(std::vector<char>& vec) | ||
| 130 | + { | ||
| 131 | + std::streampos originalPos = stream.tellg(); // 保存原始位置 | ||
| 132 | + std::for_each(std::istreambuf_iterator<char>(stream), std::istreambuf_iterator<char>(), [&vec](const char c) { | ||
| 133 | + vec.push_back(c); | ||
| 134 | + }); | ||
| 135 | + stream.seekg(originalPos); // 恢复原始位置 | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + std::uint64_t GetSize() { return stream.str().size(); } | ||
| 139 | + | ||
| 140 | + std::string GetString() { return stream.str(); } | ||
| 141 | + | ||
| 142 | + std::string SplictStream(u64& start, u64& end) | ||
| 143 | + { | ||
| 144 | + std::string temp = stream.str(); | ||
| 145 | + if (start >= temp.length()) { | ||
| 146 | + HCCL_ERROR("[SplictStream]start[%llu] is bigger than stream length[%llu]", start, temp.length()); | ||
| 147 | + return ""; | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + // 截取子串 | ||
| 151 | + std::string result = temp.substr(start, end - start); | ||
| 152 | + | ||
| 153 | + // 返回新的 string | ||
| 154 | + return result; | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + void Clear() { stream.clear(); } | ||
| 158 | + | ||
| 159 | +private: | ||
| 160 | + std::stringstream stream; | ||
| 161 | +}; | ||
| 162 | + | ||
| 163 | +} // namespace mc2_ops_hccl | ||
| 164 | + | ||
| 165 | + | ||
| @@ -20,6 +20,7 @@ if(PRODUCT_SIDE STREQUAL "host") | |||
| 20 | ${CMAKE_CURRENT_SOURCE_DIR}/log.cc | 20 | ${CMAKE_CURRENT_SOURCE_DIR}/log.cc |
| 21 | ${CMAKE_CURRENT_SOURCE_DIR}/sal.cc | 21 | ${CMAKE_CURRENT_SOURCE_DIR}/sal.cc |
| 22 | ${CMAKE_CURRENT_SOURCE_DIR}/hccl_mc2.cc | 22 | ${CMAKE_CURRENT_SOURCE_DIR}/hccl_mc2.cc |
| 23 | + ${CMAKE_CURRENT_SOURCE_DIR}/hccl_alloc_ctx_res.cc | ||
| 23 | ${CMAKE_CURRENT_SOURCE_DIR}/compat.cc | 24 | ${CMAKE_CURRENT_SOURCE_DIR}/compat.cc |
| 24 | ) | 25 | ) |
| 25 | 26 | ||
| @@ -8,13 +8,12 @@ | |||
| 8 | * See LICENSE in the root of the software repository for the full text of the License. | 8 | * See LICENSE in the root of the software repository for the full text of the License. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | + | ||
| 11 | 12 | ||
| 12 | 13 | ||
| 13 | namespace mc2_ops_hccl { | 14 | namespace mc2_ops_hccl { |
| 14 | -void CompatSymInit(void) | 15 | + |
| 15 | -{ | 16 | +void CompatSymInit(void) { HcommDlInit(); } |
| 16 | - HcommDlInit(); // 增加强制依赖 | ||
| 17 | -} | ||
| 18 | 17 | ||
| 19 | __attribute__((constructor)) void InitCompat() | 18 | __attribute__((constructor)) void InitCompat() |
| 20 | { | 19 | { |
| @@ -0,0 +1,1010 @@ | |||
| 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 | +using namespace mc2_ops_hccl; | ||
| 13 | +using namespace hcomm::CcuRep; | ||
| 14 | + | ||
| 15 | +std::unordered_map<HcclCMDType, OpParamPrepareFunc> opParamPrepareFuncMap = { | ||
| 16 | + {HcclCMDType::HCCL_CMD_ALLGATHER, PrepareParamForAllGather}, | ||
| 17 | + {HcclCMDType::HCCL_CMD_ALLREDUCE, PrepareParamForAllReduce}, | ||
| 18 | + {HcclCMDType::HCCL_CMD_REDUCE_SCATTER, PrepareParamForReduceScatter}, | ||
| 19 | + {HcclCMDType::HCCL_CMD_ALLTOALL, PrepareParamForAlltoAll}, | ||
| 20 | + {HcclCMDType::HCCL_CMD_ALLTOALLV, PrepareParamForAlltoAllV}, | ||
| 21 | +}; | ||
| 22 | + | ||
| 23 | +CommEngine OpExecuteConfigToCommEngine(uint8_t commEngine) | ||
| 24 | +{ | ||
| 25 | + if (static_cast<OpExecuteConfig>(commEngine) == OpExecuteConfig::AICPU_TS) { | ||
| 26 | + return COMM_ENGINE_AICPU; | ||
| 27 | + } else if (static_cast<OpExecuteConfig>(commEngine) == OpExecuteConfig::CCU_SCHED) { | ||
| 28 | + return COMM_ENGINE_CCU; | ||
| 29 | + } | ||
| 30 | + return COMM_ENGINE_RESERVED; | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +HcclResult CheckInputParam(const HcclComm comm, const void* mc2Tiling, const aclrtStream stream) | ||
| 34 | +{ | ||
| 35 | + // 检查comm是否为空指针 | ||
| 36 | + RPT_INPUT_ERR( | ||
| 37 | + comm == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}), | ||
| 38 | + std::vector<std::string>({"HcclAllocComResourceByTiling", "nullptr", "comm", "non-null pointer"})); | ||
| 39 | + CHK_PTR_NULL(comm); | ||
| 40 | + | ||
| 41 | + // 检查sendBuf是否为空指针 | ||
| 42 | + RPT_INPUT_ERR( | ||
| 43 | + mc2Tiling == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}), | ||
| 44 | + std::vector<std::string>({"HcclAllocComResourceByTiling", "nullptr", "mc2Tiling", "non-null pointer"})); | ||
| 45 | + CHK_PTR_NULL(mc2Tiling); | ||
| 46 | + | ||
| 47 | + // 检查stream是否为空指针 | ||
| 48 | + RPT_INPUT_ERR( | ||
| 49 | + stream == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}), | ||
| 50 | + std::vector<std::string>({"HcclAllocComResourceByTiling", "nullptr", "stream", "non-null pointer"})); | ||
| 51 | + CHK_PTR_NULL(stream); | ||
| 52 | + | ||
| 53 | + return HCCL_SUCCESS; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +HcclResult HcclGetTilingList(const void* mc2Tiling, const void* p[], uint32_t& cnt) | ||
| 57 | +{ | ||
| 58 | + const u32* versionPtr = static_cast<const u32*>(mc2Tiling); | ||
| 59 | + const u32 version = *(versionPtr++); | ||
| 60 | + CHK_PRT_RET(version < MC2_TILING_VERSION, HCCL_ERROR("Invalid tiling version %u.", version), HCCL_E_PARA); | ||
| 61 | + | ||
| 62 | + cnt = *(versionPtr++); | ||
| 63 | + CHK_PRT_RET(cnt > MAX_HCOM_NUM, HCCL_ERROR("Invalid hcom tiling number %u.", cnt), HCCL_E_PARA); | ||
| 64 | + | ||
| 65 | + u64 serverCfgAddr = reinterpret_cast<u64>(versionPtr) + sizeof(Mc2ServerCfg); | ||
| 66 | + for (uint32_t i = 0U; i < MAX_CC_TILING_NUM; ++i) { | ||
| 67 | + p[i] = reinterpret_cast<const void*>(reinterpret_cast<const u8*>(mc2Tiling) + versionPtr[i]); | ||
| 68 | + } | ||
| 69 | + HCCL_INFO("HcclGetTilingList version[%u] cnt[%u]", version, cnt); | ||
| 70 | + return HCCL_SUCCESS; | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +HcclResult CheckIsReduce(const Mc2CcTilingInner* ccTiling, bool* isReduce) | ||
| 74 | +{ | ||
| 75 | + if (ccTiling->opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER || ccTiling->opType == HcclCMDType::HCCL_CMD_REDUCE || | ||
| 76 | + ccTiling->opType == HcclCMDType::HCCL_CMD_ALLREDUCE) { | ||
| 77 | + *isReduce = true; | ||
| 78 | + } else { | ||
| 79 | + *isReduce = false; | ||
| 80 | + } | ||
| 81 | + return HCCL_SUCCESS; | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +HcclResult CheckCommEngine(const void* ccTilingList[], uint32_t tilingNum) | ||
| 85 | +{ | ||
| 86 | + for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 87 | + const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 88 | + if (ccTiling->commEngine != static_cast<uint8_t>(COMM_ENGINE_AICPU) && | ||
| 89 | + ccTiling->commEngine != static_cast<uint8_t>(COMM_ENGINE_CPU)) { | ||
| 90 | + HCCL_ERROR("Invalid commEngine %u.", ccTiling->commEngine); | ||
| 91 | + return HCCL_E_NOT_SUPPORT; | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | + return HCCL_SUCCESS; | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +HcclResult ObtainCommEngine(const void* ccTilingList[], uint32_t tilingNum, uint8_t& commEngine) | ||
| 98 | +{ | ||
| 99 | + commEngine = static_cast<uint8_t>(OpExecuteConfig::DEFAULT); | ||
| 100 | + for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 101 | + const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 102 | + if (commEngine == static_cast<uint8_t>(OpExecuteConfig::DEFAULT)) { | ||
| 103 | + commEngine = ccTiling->commEngine; | ||
| 104 | + } | ||
| 105 | + if (ccTiling->commEngine != commEngine) { | ||
| 106 | + HCCL_ERROR("Invalid commEngine %u.", ccTiling->commEngine); | ||
| 107 | + return HCCL_E_NOT_SUPPORT; | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + if (commEngine != static_cast<uint8_t>(OpExecuteConfig::AICPU_TS) && | ||
| 112 | + commEngine != static_cast<uint8_t>(OpExecuteConfig::CCU_SCHED)) { | ||
| 113 | + HCCL_ERROR("Invalid commEngine %u.", commEngine); | ||
| 114 | + return HCCL_E_NOT_SUPPORT; | ||
| 115 | + } | ||
| 116 | + return HCCL_SUCCESS; | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +namespace { | ||
| 120 | +bool IsCcuKfcSupportedOp(uint32_t opType) | ||
| 121 | +{ | ||
| 122 | + return opType == static_cast<uint32_t>(HcclCMDType::HCCL_CMD_ALLGATHER) || | ||
| 123 | + opType == static_cast<uint32_t>(HcclCMDType::HCCL_CMD_REDUCE_SCATTER); | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +HcclResult GetOrCreateCcuCtx(HcclComm comm, const std::string& tag, uint64_t ctxSize, void** ctx) | ||
| 127 | +{ | ||
| 128 | + uint64_t actualSize = ctxSize; | ||
| 129 | + if (HcclEngineCtxGet(comm, tag.c_str(), COMM_ENGINE_AIV, ctx, &actualSize) == HCCL_SUCCESS) { | ||
| 130 | + HCCL_INFO( | ||
| 131 | + "[AllocCcuOpResCtx] HcclEngineCtxGet success, tag[%s], ctxAddr[%p], ctxSize[%llu]", tag.c_str(), *ctx, | ||
| 132 | + static_cast<unsigned long long>(actualSize)); | ||
| 133 | + return HCCL_SUCCESS; | ||
| 134 | + } | ||
| 135 | + return HcclEngineCtxCreate(comm, tag.c_str(), COMM_ENGINE_AIV, ctxSize, ctx); | ||
| 136 | +} | ||
| 137 | +} // namespace | ||
| 138 | + | ||
| 139 | +HcclResult CheckCcuKfcFlow(const void* mc2Tiling, const void* ccTilingList[], uint32_t tilingNum) | ||
| 140 | +{ | ||
| 141 | + CHK_PTR_NULL(mc2Tiling); | ||
| 142 | + CHK_PTR_NULL(ccTilingList); | ||
| 143 | + const auto* initTiling = static_cast<const Mc2InitTilingInner*>(mc2Tiling); | ||
| 144 | + if (initTiling->version != INIT_TILING_CCU_NEW_VERSION) { | ||
| 145 | + HCCL_ERROR("Invalid CCU KFC tiling version %u, expected %u.", initTiling->version, INIT_TILING_CCU_NEW_VERSION); | ||
| 146 | + return HCCL_E_NOT_SUPPORT; | ||
| 147 | + } | ||
| 148 | + if (tilingNum == 0U || tilingNum > MAX_CC_TILING_NUM || tilingNum != initTiling->mc2HcommCnt) { | ||
| 149 | + HCCL_ERROR("Invalid CCU KFC tiling number %u, init tiling number %u.", tilingNum, initTiling->mc2HcommCnt); | ||
| 150 | + return HCCL_E_NOT_SUPPORT; | ||
| 151 | + } | ||
| 152 | + uint32_t expectedOpType = static_cast<uint32_t>(HcclCMDType::HCCL_CMD_INVALID); | ||
| 153 | + for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 154 | + const auto* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 155 | + CHK_PTR_NULL(ccTiling); | ||
| 156 | + if (expectedOpType == static_cast<uint32_t>(HcclCMDType::HCCL_CMD_INVALID)) { | ||
| 157 | + expectedOpType = ccTiling->opType; | ||
| 158 | + } | ||
| 159 | + if (!IsCcuKfcSupportedOp(ccTiling->opType) || | ||
| 160 | + ccTiling->commEngine != static_cast<uint8_t>(OpExecuteConfig::CCU_SCHED) || | ||
| 161 | + ccTiling->opType != expectedOpType) { | ||
| 162 | + HCCL_ERROR( | ||
| 163 | + "Unsupported CCU KFC tiling at index %u, opType %u, commEngine %u.", i, ccTiling->opType, | ||
| 164 | + ccTiling->commEngine); | ||
| 165 | + return HCCL_E_NOT_SUPPORT; | ||
| 166 | + } | ||
| 167 | + } | ||
| 168 | + return HCCL_SUCCESS; | ||
| 169 | +} | ||
| 170 | + | ||
| 171 | +// 构建 opResCtx 基础字段 | ||
| 172 | +HcclResult AllocCcuOpResCtx(HcclComm comm, const std::string& ctxTag, u32 rankSize, u32 userRank, OpResCtx& opResCtx) | ||
| 173 | +{ | ||
| 174 | + // 1. 分配workspace、scratch、comParam(XN)、comSync(CKE) | ||
| 175 | + constexpr uint32_t comSyncNum = 2; | ||
| 176 | + constexpr uint64_t scratchSize = Hccl::MC2_WORKSPACE_SIZE; | ||
| 177 | + uint64_t comParamBufSize = Hccl::CCU_TASK_NUM_MAX * Hccl::CCU_PARAM_NUM_MAX * Hccl::CCU_ONE_PARAM_SIZE; | ||
| 178 | + uint64_t comSyncBufSize = Hccl::CCU_TASK_NUM_MAX * comSyncNum * Hccl::CCU_ONE_PARAM_SIZE; | ||
| 179 | + | ||
| 180 | + std::string tagWorkspace = ctxTag + "_ccu_workspace"; | ||
| 181 | + std::string tagScratch = ctxTag + "_ccu_scratch"; | ||
| 182 | + std::string tagComParam = ctxTag + "_ccu_comParam"; | ||
| 183 | + std::string tagComSync = ctxTag + "_ccu_comSync"; | ||
| 184 | + | ||
| 185 | + void* workspacePtr = nullptr; | ||
| 186 | + void* scratchPtr = nullptr; | ||
| 187 | + void* comParamPtr = nullptr; | ||
| 188 | + void* comSyncPtr = nullptr; | ||
| 189 | + | ||
| 190 | + CHK_RET(GetOrCreateCcuCtx(comm, tagWorkspace, Hccl::MC2_WORKSPACE_SIZE, &workspacePtr)); | ||
| 191 | + CHK_RET(GetOrCreateCcuCtx(comm, tagScratch, scratchSize, &scratchPtr)); | ||
| 192 | + CHK_RET(GetOrCreateCcuCtx(comm, tagComParam, comParamBufSize, &comParamPtr)); | ||
| 193 | + CHK_RET(GetOrCreateCcuCtx(comm, tagComSync, comSyncBufSize, &comSyncPtr)); | ||
| 194 | + | ||
| 195 | + uint64_t ckeTokenInfo = hcomm::CcuRep::GetTokenInfo(reinterpret_cast<uint64_t>(comSyncPtr), comSyncBufSize); | ||
| 196 | + HCCL_INFO( | ||
| 197 | + "[CcuTokenTrace][ComSync] ckeAddr[0x%llx], size[%llu], token[0x%llx]", | ||
| 198 | + reinterpret_cast<unsigned long long>(comSyncPtr), static_cast<unsigned long long>(comSyncBufSize), | ||
| 199 | + static_cast<unsigned long long>(ckeTokenInfo)); | ||
| 200 | + | ||
| 201 | + opResCtx.workSpace = reinterpret_cast<uint64_t>(workspacePtr); | ||
| 202 | + opResCtx.workSpaceSize = Hccl::MC2_WORKSPACE_SIZE; | ||
| 203 | + opResCtx.rankId = userRank; | ||
| 204 | + opResCtx.rankSize = rankSize; | ||
| 205 | + opResCtx.xnAddr = reinterpret_cast<uint64_t>(comParamPtr); | ||
| 206 | + opResCtx.ckeAddr = reinterpret_cast<uint64_t>(comSyncPtr); | ||
| 207 | + // ReduceScatter KFC follows pr_4523 and partitions this fixed 16 MiB buffer as rankSize * sliceSize. | ||
| 208 | + opResCtx.res[0] = reinterpret_cast<uint64_t>(scratchPtr); | ||
| 209 | + | ||
| 210 | + HCCL_INFO( | ||
| 211 | + "[AllocCcuOpResCtx] workspace[%p], workspaceSize[%llu], scratch[%p], scratchSize[%llu], " | ||
| 212 | + "comParam[%p], comParamBufSize[%llu], comSync[%p], comSyncBufSize[%llu], " | ||
| 213 | + "rankId[%u], rankSize[%u], xnAddr[0x%llx], ckeAddr[0x%llx]", | ||
| 214 | + workspacePtr, Hccl::MC2_WORKSPACE_SIZE, scratchPtr, scratchSize, comParamPtr, comParamBufSize, comSyncPtr, | ||
| 215 | + comSyncBufSize, userRank, rankSize, static_cast<unsigned long long>(opResCtx.xnAddr), | ||
| 216 | + static_cast<unsigned long long>(opResCtx.ckeAddr)); | ||
| 217 | + | ||
| 218 | + return HCCL_SUCCESS; | ||
| 219 | +} | ||
| 220 | + | ||
| 221 | +namespace { | ||
| 222 | +HcclResult AllocOpParamMemory( | ||
| 223 | + HcclComm comm, const std::string& ctxTag, const std::vector<OpParam>& opParamVec, | ||
| 224 | + const Mc2InitTilingInner* initTiling, const void* ccTilingList[], OpResCtx& resCtx) | ||
| 225 | +{ | ||
| 226 | + std::vector<uint64_t> opParamAddr(opParamVec.size()); | ||
| 227 | + uint64_t opParamSize = sizeof(OpParam); | ||
| 228 | + for (uint32_t i = 0U; i < opParamVec.size(); ++i) { | ||
| 229 | + std::string tagParam = ctxTag + "_" + std::to_string(i); | ||
| 230 | + void* opParamPtr = nullptr; | ||
| 231 | + const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 232 | + if (HcclEngineCtxGet( | ||
| 233 | + comm, tagParam.c_str(), OpExecuteConfigToCommEngine(ccTiling->commEngine), &opParamPtr, &opParamSize) == | ||
| 234 | + HCCL_SUCCESS) { | ||
| 235 | + HCCL_INFO( | ||
| 236 | + "HcclEngineCtxGet success, tagParam[%s], opParamAddr[%p], opParamSize[%u]", tagParam.c_str(), | ||
| 237 | + opParamPtr, opParamSize); | ||
| 238 | + opParamAddr[i] = reinterpret_cast<uint64_t>(opParamPtr); | ||
| 239 | + } else { | ||
| 240 | + CHK_RET(HcclEngineCtxCreate( | ||
| 241 | + comm, tagParam.c_str(), OpExecuteConfigToCommEngine(ccTiling->commEngine), opParamSize, &opParamPtr)); | ||
| 242 | + opParamAddr[i] = reinterpret_cast<uint64_t>(opParamPtr); | ||
| 243 | + } | ||
| 244 | + HCCL_INFO( | ||
| 245 | + "HcclAllocOpResCtx the %dth opParam: opParamAddr[%u], opParamSize[%u]", i, opParamAddr[i], opParamSize); | ||
| 246 | + | ||
| 247 | + aclError aclRet = aclrtMemcpy( | ||
| 248 | + reinterpret_cast<void*>(opParamAddr[i]), opParamSize, &opParamVec[i], opParamSize, aclrtMemcpyKind(1)); | ||
| 249 | + CHK_RET(aclRet == ACL_ERROR_NONE ? HCCL_SUCCESS : HCCL_E_RUNTIME); | ||
| 250 | + resCtx.algInfo[i].opParam = opParamAddr[i]; | ||
| 251 | + resCtx.algInfo[i].offset = initTiling->offset[i]; | ||
| 252 | + } | ||
| 253 | + return HCCL_SUCCESS; | ||
| 254 | +} | ||
| 255 | + | ||
| 256 | +HcclResult AllocWorkspaceMemory( | ||
| 257 | + HcclComm comm, const std::string& ctxTag, const Mc2CcTilingInner* ccTiling, OpResCtx& resCtx) | ||
| 258 | +{ | ||
| 259 | + uint64_t memSize = 20 * 1024 * 1024; | ||
| 260 | + resCtx.workSpaceSize = memSize; | ||
| 261 | + std::string tagWorkSpace = ctxTag + "_workSpace"; | ||
| 262 | + void* workSpacePtr = nullptr; | ||
| 263 | + if (HcclEngineCtxGet( | ||
| 264 | + comm, tagWorkSpace.c_str(), OpExecuteConfigToCommEngine(ccTiling->commEngine), &workSpacePtr, &memSize) == | ||
| 265 | + HCCL_SUCCESS) { | ||
| 266 | + HCCL_INFO( | ||
| 267 | + "HcclEngineCtxGet success, tagWorkSpace[%s], workSpaceAddr[%p], workSpaceSize[%u]", tagWorkSpace.c_str(), | ||
| 268 | + workSpacePtr, memSize); | ||
| 269 | + resCtx.workSpace = reinterpret_cast<uint64_t>(workSpacePtr); | ||
| 270 | + } else { | ||
| 271 | + CHK_RET(HcclEngineCtxCreate( | ||
| 272 | + comm, tagWorkSpace.c_str(), OpExecuteConfigToCommEngine(ccTiling->commEngine), memSize, &workSpacePtr)); | ||
| 273 | + resCtx.workSpace = reinterpret_cast<uint64_t>(workSpacePtr); | ||
| 274 | + } | ||
| 275 | + HCCL_INFO("HcclAllocOpResCtx the workSpace: workSpaceAddr[%u], workSpaceSize[%u]", resCtx.workSpace, memSize); | ||
| 276 | + return HCCL_SUCCESS; | ||
| 277 | +} | ||
| 278 | + | ||
| 279 | +HcclResult FillRankInfo(HcclComm comm, OpResCtx& resCtx) | ||
| 280 | +{ | ||
| 281 | + uint32_t rankSize = 0U; | ||
| 282 | + uint32_t rankId = 0U; | ||
| 283 | + CHK_RET(HcclGetRankSize(comm, &rankSize)); | ||
| 284 | + CHK_RET(HcclGetRankId(comm, &rankId)); | ||
| 285 | + resCtx.rankSize = rankSize; | ||
| 286 | + resCtx.rankId = rankId; | ||
| 287 | + return HCCL_SUCCESS; | ||
| 288 | +} | ||
| 289 | + | ||
| 290 | +HcclResult AllocAndCopyOpResCtx( | ||
| 291 | + HcclComm comm, const std::string& ctxTag, const Mc2CcTilingInner* ccTiling, const OpResCtx& resCtx, | ||
| 292 | + void** opResCtxPtr) | ||
| 293 | +{ | ||
| 294 | + std::string tagOpResCtx = ctxTag + "_opResCtx"; | ||
| 295 | + uint64_t opResCtxSize = sizeof(OpResCtx); | ||
| 296 | + if (HcclEngineCtxGet( | ||
| 297 | + comm, tagOpResCtx.c_str(), OpExecuteConfigToCommEngine(ccTiling->commEngine), opResCtxPtr, &opResCtxSize) == | ||
| 298 | + HCCL_SUCCESS) { | ||
| 299 | + HCCL_INFO( | ||
| 300 | + "HcclEngineCtxGet success, tagOpResCtx[%s], opResCtxAddr[%p], opResCtxSize[%u]", tagOpResCtx.c_str(), | ||
| 301 | + opResCtxPtr, opResCtxSize); | ||
| 302 | + } else { | ||
| 303 | + CHK_RET(HcclEngineCtxCreate( | ||
| 304 | + comm, tagOpResCtx.c_str(), OpExecuteConfigToCommEngine(ccTiling->commEngine), opResCtxSize, opResCtxPtr)); | ||
| 305 | + } | ||
| 306 | + | ||
| 307 | + HCCL_INFO("HcclAllocOpResCtx the opResCtx: opResCtxAddr[%u], opResCtxSize[%u]", opResCtxPtr, opResCtxSize); | ||
| 308 | + | ||
| 309 | + aclError aclRet = aclrtMemcpy(*opResCtxPtr, opResCtxSize, &resCtx, opResCtxSize, aclrtMemcpyKind(1)); | ||
| 310 | + CHK_RET(aclRet == ACL_ERROR_NONE ? HCCL_SUCCESS : HCCL_E_RUNTIME); | ||
| 311 | + return HCCL_SUCCESS; | ||
| 312 | +} | ||
| 313 | +} // namespace | ||
| 314 | + | ||
| 315 | +HcclResult HcclAllocOpResCtx( | ||
| 316 | + HcclComm comm, const std::string& ctxTag, const std::vector<OpParam>& opParamVec, void* mc2Tiling, | ||
| 317 | + const void* ccTilingList[], void** opResCtxPtr) | ||
| 318 | +{ | ||
| 319 | + CHK_PTR_NULL(opResCtxPtr); | ||
| 320 | + OpResCtx resCtx{}; | ||
| 321 | + const auto* initTiling = static_cast<const Mc2InitTilingInner*>(mc2Tiling); | ||
| 322 | + const auto* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[0]); | ||
| 323 | + | ||
| 324 | + CHK_RET(AllocOpParamMemory(comm, ctxTag, opParamVec, initTiling, ccTilingList, resCtx)); | ||
| 325 | + CHK_RET(AllocWorkspaceMemory(comm, ctxTag, ccTiling, resCtx)); | ||
| 326 | + CHK_RET(FillRankInfo(comm, resCtx)); | ||
| 327 | + return AllocAndCopyOpResCtx(comm, ctxTag, ccTiling, resCtx, opResCtxPtr); | ||
| 328 | +} | ||
| 329 | + | ||
| 330 | +// AllToAll适配AllToAllV | ||
| 331 | +HcclResult ConvertAlltoAllParam( | ||
| 332 | + const u64 recvCount, const u32 rankSize, std::vector<u64>& sdispls, std::vector<u64>& rdispls) | ||
| 333 | +{ | ||
| 334 | + u64 dataCountOffset = 0; | ||
| 335 | + for (u64 i = 0; i < rankSize; i++) { | ||
| 336 | + sdispls[i] = dataCountOffset; | ||
| 337 | + rdispls[i] = dataCountOffset; | ||
| 338 | + dataCountOffset += recvCount; | ||
| 339 | + } | ||
| 340 | + return HCCL_SUCCESS; | ||
| 341 | +} | ||
| 342 | + | ||
| 343 | +HcclResult PrepareOpsCommParam(const std::string& tag, OpParam& param) | ||
| 344 | +{ | ||
| 345 | + param.opMode = OpMode::OPBASE; | ||
| 346 | + DevType deviceType = DevType::DEV_TYPE_COUNT; | ||
| 347 | + CHK_RET(hrtGetDeviceType(deviceType)); | ||
| 348 | + | ||
| 349 | + // topoInfo的tag,所有相同的算子可以共享 | ||
| 350 | + int ret = sprintf_s(param.tag, sizeof(param.tag), "%s", tag.c_str()); | ||
| 351 | + if (ret <= 0) { | ||
| 352 | + HCCL_ERROR("failed to fill param.tag"); | ||
| 353 | + return HCCL_E_INTERNAL; | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + param.inputPtr = nullptr; | ||
| 357 | + param.outputPtr = nullptr; | ||
| 358 | + param.inputSize = 0; | ||
| 359 | + param.outputSize = 0; | ||
| 360 | + param.enableDetour = false; | ||
| 361 | + param.deviceType = deviceType; | ||
| 362 | + | ||
| 363 | + return HCCL_SUCCESS; | ||
| 364 | +} | ||
| 365 | + | ||
| 366 | +HcclResult PrintOpsCommParam(OpParam& param) | ||
| 367 | +{ | ||
| 368 | + HCCL_INFO("commName: %s", param.commName); | ||
| 369 | + HCCL_INFO("tag:%s", param.tag); | ||
| 370 | + HCCL_INFO("stream: %p", param.stream); | ||
| 371 | + HCCL_INFO("inputPtr %p", param.inputPtr); | ||
| 372 | + HCCL_INFO("outputPtr %p", param.outputPtr); | ||
| 373 | + HCCL_INFO("inputSize %lu", param.inputSize); | ||
| 374 | + HCCL_INFO("outputSize %lu", param.outputSize); | ||
| 375 | + HCCL_INFO("opMode %u", static_cast<uint32_t>(param.opMode)); | ||
| 376 | + HCCL_INFO("deviceType %u", static_cast<uint32_t>(param.deviceType)); | ||
| 377 | + return HCCL_SUCCESS; | ||
| 378 | +} | ||
| 379 | + | ||
| 380 | +HcclResult PrepareParamForAllGather( | ||
| 381 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 382 | +{ | ||
| 383 | + HCCL_INFO("PrepareParamForAllGather, ccTiling[%p]", ccTiling); | ||
| 384 | + u32 userRankSize; | ||
| 385 | + CHK_RET(HcclGetRankSize(comm, &userRankSize)); // 加上,后面计算outputSize可能使用 | ||
| 386 | + | ||
| 387 | + HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 388 | + if (ret != HCCL_SUCCESS) { | ||
| 389 | + HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + param.opType = HcclCMDType::HCCL_CMD_ALLGATHER; | ||
| 393 | + param.reduceType = HcclReduceOp::HCCL_REDUCE_SUM; | ||
| 394 | + param.DataDes.dataType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 395 | + param.DataDes.count = 0; | ||
| 396 | + | ||
| 397 | + HCCL_INFO("Print PrepareParamForAllGather."); | ||
| 398 | + CHK_RET(PrintOpsCommParam(param)); | ||
| 399 | + HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 400 | + HCCL_INFO("DataDes.dataType %u", static_cast<uint32_t>(param.DataDes.dataType)); | ||
| 401 | + HCCL_INFO("DataDes.count %lu", param.DataDes.count); | ||
| 402 | + HCCL_INFO("Execute PrepareParamForAllGather success."); | ||
| 403 | + return HCCL_SUCCESS; | ||
| 404 | +} | ||
| 405 | + | ||
| 406 | +HcclResult PrepareParamForAllReduce( | ||
| 407 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 408 | +{ | ||
| 409 | + HCCL_INFO("PrepareParamForAllReduce, ccTiling[%p]", ccTiling); | ||
| 410 | + u32 userRankSize; | ||
| 411 | + CHK_RET(HcclGetRankSize(comm, &userRankSize)); // 加上,后面计算outputSize可能使用 | ||
| 412 | + | ||
| 413 | + HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 414 | + if (ret != HCCL_SUCCESS) { | ||
| 415 | + HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + param.opType = HcclCMDType::HCCL_CMD_ALLREDUCE; | ||
| 419 | + param.reduceType = static_cast<HcclReduceOp>(ccTiling->reduceType); | ||
| 420 | + param.DataDes.dataType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 421 | + param.DataDes.outputType = param.DataDes.dataType; | ||
| 422 | + param.DataDes.count = 0; | ||
| 423 | + | ||
| 424 | + HCCL_INFO("Print PrepareParamForAllReduce."); | ||
| 425 | + CHK_RET(PrintOpsCommParam(param)); | ||
| 426 | + HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 427 | + HCCL_INFO("reduceType %u", static_cast<uint32_t>(param.reduceType)); | ||
| 428 | + HCCL_INFO("DataDes.dataType %u", static_cast<uint32_t>(param.DataDes.dataType)); | ||
| 429 | + HCCL_INFO("DataDes.outputType %u", static_cast<uint32_t>(param.DataDes.outputType)); | ||
| 430 | + HCCL_INFO("DataDes.count %lu", param.DataDes.count); | ||
| 431 | + HCCL_INFO("Execute PrepareParamForAllReduce success."); | ||
| 432 | + return HCCL_SUCCESS; | ||
| 433 | +} | ||
| 434 | + | ||
| 435 | +HcclResult PrepareParamForReduceScatter( | ||
| 436 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 437 | +{ | ||
| 438 | + HCCL_INFO("PrepareParamForReduceScatter, ccTiling[%p]", ccTiling); | ||
| 439 | + u32 userRankSize; | ||
| 440 | + CHK_RET(HcclGetRankSize(comm, &userRankSize)); // 加上,后面计算outputSize可能使用 | ||
| 441 | + | ||
| 442 | + HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 443 | + if (ret != HCCL_SUCCESS) { | ||
| 444 | + HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 445 | + } | ||
| 446 | + | ||
| 447 | + param.opType = HcclCMDType::HCCL_CMD_REDUCE_SCATTER; | ||
| 448 | + param.reduceType = static_cast<HcclReduceOp>(ccTiling->reduceType); | ||
| 449 | + param.DataDes.dataType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 450 | + param.DataDes.count = 0; | ||
| 451 | + | ||
| 452 | + HCCL_INFO("Print PrepareParamForReduceScatter."); | ||
| 453 | + CHK_RET(PrintOpsCommParam(param)); | ||
| 454 | + HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 455 | + HCCL_INFO("reduceType %u", static_cast<uint32_t>(param.reduceType)); | ||
| 456 | + HCCL_INFO("DataDes.dataType %u", static_cast<uint32_t>(param.DataDes.dataType)); | ||
| 457 | + HCCL_INFO("DataDes.count %lu", param.DataDes.count); | ||
| 458 | + HCCL_INFO("Execute PrepareParamForReduceScatter success."); | ||
| 459 | + return HCCL_SUCCESS; | ||
| 460 | +} | ||
| 461 | + | ||
| 462 | +HcclResult PrepareParamForAlltoAll( | ||
| 463 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 464 | +{ | ||
| 465 | + HCCL_INFO("PrepareParamForAlltoAll, ccTiling[%p]", ccTiling); | ||
| 466 | + u32 userRankSize; | ||
| 467 | + CHK_RET(HcclGetRankSize(comm, &userRankSize)); | ||
| 468 | + | ||
| 469 | + HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 470 | + if (ret != HCCL_SUCCESS) { | ||
| 471 | + HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 472 | + } | ||
| 473 | + | ||
| 474 | + u64 varMemSize = ALL_TO_ALL_V_VECTOR_NUM * userRankSize * sizeof(u64); | ||
| 475 | + param.varMemSize = varMemSize; | ||
| 476 | + param.opType = HcclCMDType::HCCL_CMD_ALLTOALL; | ||
| 477 | + param.all2AllVDataDes.sendType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 478 | + param.all2AllVDataDes.recvType = static_cast<HcclDataType>(ccTiling->dstDataType); | ||
| 479 | + param.all2AllVDataDes.sendCounts = nullptr; | ||
| 480 | + param.all2AllVDataDes.recvCounts = nullptr; | ||
| 481 | + param.all2AllVDataDes.sdispls = nullptr; | ||
| 482 | + param.all2AllVDataDes.rdispls = nullptr; | ||
| 483 | + | ||
| 484 | + HCCL_INFO("Print PrepareParamForAlltoAll."); | ||
| 485 | + CHK_RET(PrintOpsCommParam(param)); | ||
| 486 | + HCCL_INFO("varMemSize %lu", param.varMemSize); | ||
| 487 | + HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 488 | + HCCL_INFO("all2AllVDataDes.sendType %u", static_cast<uint32_t>(param.all2AllVDataDes.sendType)); | ||
| 489 | + HCCL_INFO("all2AllVDataDes.recvType %u", static_cast<uint32_t>(param.all2AllVDataDes.recvType)); | ||
| 490 | + HCCL_INFO("Execute PrepareParamForAlltoAll success."); | ||
| 491 | + return HCCL_SUCCESS; | ||
| 492 | +} | ||
| 493 | + | ||
| 494 | +HcclResult PrepareParamForAlltoAllV( | ||
| 495 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 496 | +{ | ||
| 497 | + HCCL_INFO("PrepareParamForAlltoAllV, ccTiling[%p]", ccTiling); | ||
| 498 | + u32 userRankSize; | ||
| 499 | + CHK_RET(HcclGetRankSize(comm, &userRankSize)); | ||
| 500 | + | ||
| 501 | + HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 502 | + if (ret != HCCL_SUCCESS) { | ||
| 503 | + HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 504 | + } | ||
| 505 | + | ||
| 506 | + u64 varMemSize = ALL_TO_ALL_V_VECTOR_NUM * userRankSize * sizeof(u64); | ||
| 507 | + param.varMemSize = varMemSize; | ||
| 508 | + param.opType = HcclCMDType::HCCL_CMD_ALLTOALLV; | ||
| 509 | + param.all2AllVDataDes.sendType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 510 | + param.all2AllVDataDes.recvType = static_cast<HcclDataType>(ccTiling->dstDataType); | ||
| 511 | + param.all2AllVDataDes.sendCounts = nullptr; | ||
| 512 | + param.all2AllVDataDes.recvCounts = nullptr; | ||
| 513 | + param.all2AllVDataDes.sdispls = nullptr; | ||
| 514 | + param.all2AllVDataDes.rdispls = nullptr; | ||
| 515 | + | ||
| 516 | + HCCL_INFO("Print PrepareParamForAlltoAllV."); | ||
| 517 | + CHK_RET(PrintOpsCommParam(param)); | ||
| 518 | + HCCL_INFO("varMemSize %lu", param.varMemSize); | ||
| 519 | + HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 520 | + HCCL_INFO("all2AllVDataDes.sendType %u", static_cast<uint32_t>(param.all2AllVDataDes.sendType)); | ||
| 521 | + HCCL_INFO("all2AllVDataDes.recvType %u", static_cast<uint32_t>(param.all2AllVDataDes.recvType)); | ||
| 522 | + return HCCL_SUCCESS; | ||
| 523 | +} | ||
| 524 | + | ||
| 525 | +HcclResult PrepareOpParams(HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam) | ||
| 526 | +{ | ||
| 527 | + auto it = opParamPrepareFuncMap.find(static_cast<HcclCMDType>(ccTiling->opType)); | ||
| 528 | + if (it != opParamPrepareFuncMap.end()) { | ||
| 529 | + return it->second(comm, tag, ccTiling, opParam); | ||
| 530 | + } | ||
| 531 | + HCCL_ERROR("PrepareOpParams error, opType[%d] not found", ccTiling->opType); | ||
| 532 | + return HCCL_E_INTERNAL; | ||
| 533 | +} | ||
| 534 | + | ||
| 535 | +HcclResult InitOpParamByTiling( | ||
| 536 | + HcclComm comm, void* stream, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam) | ||
| 537 | +{ | ||
| 538 | + opParam.opType = static_cast<HcclCMDType>(ccTiling->opType); | ||
| 539 | + opParam.stream = reinterpret_cast<aclrtStream>(stream); | ||
| 540 | + opParam.engine = OpExecuteConfigToCommEngine(ccTiling->commEngine); | ||
| 541 | + CHK_RET(HcclGetCommName(comm, opParam.commName)); | ||
| 542 | + CHK_RET(PrepareOpParams(comm, tag, ccTiling, opParam)); | ||
| 543 | + if (opParam.opType == HcclCMDType::HCCL_CMD_ALLTOALL) { | ||
| 544 | + opParam.all2AllVDataDes.sendType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 545 | + // sendCounts指向的host侧数组由调用方(GetOpParam)持有并填充,此处保持nullptr, | ||
| 546 | + // 避免将数值当作指针使用导致后续解引用非法地址。 | ||
| 547 | + } | ||
| 548 | + return HCCL_SUCCESS; | ||
| 549 | +} | ||
| 550 | + | ||
| 551 | +HcclResult PrepareTopoInfoForOp(HcclComm comm, OpParam& opParam, std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo) | ||
| 552 | +{ | ||
| 553 | + HCCL_INFO("[SelectAlgAndPrepareEngine]start SelectAlgAndPrepareEngine!"); | ||
| 554 | + opParam.hcclComm = comm; | ||
| 555 | + CHK_RET(HcclGetOpExpansionMode(comm, opParam)); | ||
| 556 | + HCCL_INFO("[SelectAlgAndPrepareEngine] successfully!"); | ||
| 557 | + CHK_RET(HcclCalcTopoInfo(comm, opParam, topoInfo)); | ||
| 558 | + HCCL_INFO("[SelectAlgAndPrepareEngine]HcclCalcTopoInfo successfully!"); | ||
| 559 | + return HCCL_SUCCESS; | ||
| 560 | +} | ||
| 561 | + | ||
| 562 | +HcclResult PrepareEngineForAlg(OpParam& opParam, const std::string& algName) | ||
| 563 | +{ | ||
| 564 | + CHK_RET(SetCommEngine(opParam)); | ||
| 565 | + if (GetExternalInputHcclAivOnlyMode() && opParam.engine != COMM_ENGINE_AIV) { | ||
| 566 | + HCCL_ERROR( | ||
| 567 | + "[HcclExecOp] opType[%d] currently do not select aiv mode, aiv only not support.", | ||
| 568 | + static_cast<int>(opParam.opType)); | ||
| 569 | + return HCCL_E_NOT_SUPPORT; | ||
| 570 | + } | ||
| 571 | + if ((opParam.engine == COMM_ENGINE_AICPU_TS) || (opParam.engine == COMM_ENGINE_CPU)) { | ||
| 572 | + HCCL_DEBUG("[Selector] is aicpu mode"); | ||
| 573 | + CHK_RET(LoadAICPUKernel()); | ||
| 574 | + } | ||
| 575 | + CHK_RET(SetOpParamAlgTag(opParam, algName)); | ||
| 576 | + return HCCL_SUCCESS; | ||
| 577 | +} | ||
| 578 | + | ||
| 579 | +std::unique_ptr<InsCollAlgBase> GetAlgExecutorForOp(const OpParam& opParam, const std::string& algName) | ||
| 580 | +{ | ||
| 581 | + if (UseCannBridge(opParam)) { | ||
| 582 | + return GetAlgExecViaCann(opParam.opType, algName); | ||
| 583 | + } | ||
| 584 | + return CollAlgExecRegistryV2::Instance().GetAlgExec(opParam.opType, algName); | ||
| 585 | +} | ||
| 586 | + | ||
| 587 | +HcclResult CheckForcedAlgResource( | ||
| 588 | + HcclComm comm, const OpParam& opParam, TopoInfoWithNetLayerDetails* topoInfo, const std::string& algName) | ||
| 589 | +{ | ||
| 590 | + std::unique_ptr<InsCollAlgBase> executor = GetAlgExecutorForOp(opParam, algName); | ||
| 591 | + CHK_PRT_RET( | ||
| 592 | + executor == nullptr, | ||
| 593 | + HCCL_WARNING( | ||
| 594 | + "[MC2_FORCE_ALG] fallback, algName[%s] is not registered for opType[%u].", algName.c_str(), | ||
| 595 | + static_cast<u32>(opParam.opType)), | ||
| 596 | + HCCL_E_NOT_SUPPORT); | ||
| 597 | + | ||
| 598 | + AlgHierarchyInfoForAllLevel algHierarchyInfo; | ||
| 599 | + HcclResult ret = executor->CalcAlgHierarchyInfo(comm, topoInfo, algHierarchyInfo); | ||
| 600 | + CHK_PRT_RET( | ||
| 601 | + ret != HCCL_SUCCESS, | ||
| 602 | + HCCL_WARNING( | ||
| 603 | + "[MC2_FORCE_ALG] fallback, CalcAlgHierarchyInfo failed, algName[%s], ret[%d].", algName.c_str(), | ||
| 604 | + static_cast<int>(ret)), | ||
| 605 | + HCCL_E_NOT_SUPPORT); | ||
| 606 | + | ||
| 607 | + AlgResourceRequest resRequest; | ||
| 608 | + ret = executor->CalcRes(comm, opParam, topoInfo, algHierarchyInfo, resRequest); | ||
| 609 | + CHK_PRT_RET( | ||
| 610 | + ret != HCCL_SUCCESS, | ||
| 611 | + HCCL_WARNING( | ||
| 612 | + "[MC2_FORCE_ALG] fallback, CalcRes failed, algName[%s], ret[%d].", algName.c_str(), static_cast<int>(ret)), | ||
| 613 | + HCCL_E_NOT_SUPPORT); | ||
| 614 | + return HCCL_SUCCESS; | ||
| 615 | +} | ||
| 616 | + | ||
| 617 | +bool GetForcedAlgName(const Mc2CcTilingInner* ccTiling, std::string& algName) | ||
| 618 | +{ | ||
| 619 | + if (ccTiling == nullptr || ccTiling->algConfig[0] == '\0') { | ||
| 620 | + return false; | ||
| 621 | + } | ||
| 622 | + | ||
| 623 | + std::string algConfig(ccTiling->algConfig); | ||
| 624 | + if (algConfig.find('=') != std::string::npos) { | ||
| 625 | + HCCL_INFO("[MC2_FORCE_ALG] legacy algConfig[%s], use default selector.", algConfig.c_str()); | ||
| 626 | + return false; | ||
| 627 | + } | ||
| 628 | + | ||
| 629 | + algName = algConfig; | ||
| 630 | + return true; | ||
| 631 | +} | ||
| 632 | + | ||
| 633 | +HcclResult TryForcedAlgAndPrepareEngine( | ||
| 634 | + HcclComm comm, const Mc2CcTilingInner* ccTiling, OpParam& opParam, std::string& algName, | ||
| 635 | + std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo, bool& forcedAlgAccepted) | ||
| 636 | +{ | ||
| 637 | + forcedAlgAccepted = false; | ||
| 638 | + std::string forcedAlgName; | ||
| 639 | + if (!GetForcedAlgName(ccTiling, forcedAlgName)) { | ||
| 640 | + return HCCL_SUCCESS; | ||
| 641 | + } | ||
| 642 | + | ||
| 643 | + OpParam opParamBackup = opParam; | ||
| 644 | + CHK_RET(PrepareTopoInfoForOp(comm, opParam, topoInfo)); | ||
| 645 | + HcclResult ret = PrepareEngineForAlg(opParam, forcedAlgName); | ||
| 646 | + if (ret != HCCL_SUCCESS) { | ||
| 647 | + opParam = opParamBackup; | ||
| 648 | + HCCL_ERROR( | ||
| 649 | + "[MC2_FORCE_ALG] prepare engine failed, algName[%s], ret[%d].", forcedAlgName.c_str(), | ||
| 650 | + static_cast<int>(ret)); | ||
| 651 | + return ret; | ||
| 652 | + } | ||
| 653 | + | ||
| 654 | + ret = CheckForcedAlgResource(comm, opParam, topoInfo.get(), forcedAlgName); | ||
| 655 | + if (ret != HCCL_SUCCESS) { | ||
| 656 | + opParam = opParamBackup; | ||
| 657 | + topoInfo = std::make_unique<TopoInfoWithNetLayerDetails>(); | ||
| 658 | + algName.clear(); | ||
| 659 | + forcedAlgAccepted = false; | ||
| 660 | + HCCL_WARNING( | ||
| 661 | + "[MC2_FORCE_ALG] fallback to default selector, opType[%u], algConfig[%s].", | ||
| 662 | + static_cast<u32>(opParam.opType), forcedAlgName.c_str()); | ||
| 663 | + return HCCL_SUCCESS; | ||
| 664 | + } | ||
| 665 | + | ||
| 666 | + algName = forcedAlgName; | ||
| 667 | + forcedAlgAccepted = true; | ||
| 668 | + HCCL_INFO("[MC2_FORCE_ALG] accepted, opType[%u], algName[%s].", static_cast<u32>(opParam.opType), algName.c_str()); | ||
| 669 | + return HCCL_SUCCESS; | ||
| 670 | +} | ||
| 671 | + | ||
| 672 | +HcclResult SelectAlgAndPrepareEngine( | ||
| 673 | + HcclComm comm, OpParam& opParam, std::string& algName, std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo) | ||
| 674 | +{ | ||
| 675 | + CHK_RET(PrepareTopoInfoForOp(comm, opParam, topoInfo)); | ||
| 676 | + | ||
| 677 | + std::shared_ptr<ExecuteSelector> collAlgSelector = std::make_shared<ExecuteSelector>(ExecuteSelector()); | ||
| 678 | + CHK_RET(collAlgSelector->Run(opParam, topoInfo.get(), algName)); | ||
| 679 | + if (algName.empty()) { | ||
| 680 | + HCCL_ERROR("[Selector] select algname fail!"); | ||
| 681 | + return HCCL_E_PTR; | ||
| 682 | + } | ||
| 683 | + | ||
| 684 | + CHK_RET(PrepareEngineForAlg(opParam, algName)); | ||
| 685 | + return HCCL_SUCCESS; | ||
| 686 | +} | ||
| 687 | + | ||
| 688 | +HcclResult FillOpParamAlgName(OpParam& opParam, const std::string& algName) | ||
| 689 | +{ | ||
| 690 | + int result = sprintf_s(opParam.algName, sizeof(opParam.algName), "%s", algName.c_str()); | ||
| 691 | + CHK_PRT_RET(result <= 0, HCCL_ERROR("failed to fill opParam.algName"), HCCL_E_INTERNAL); | ||
| 692 | + HCCL_INFO( | ||
| 693 | + "[GetOpParam] prepared opParam, opType[%u], algName[%s], algTag[%s].", static_cast<u32>(opParam.opType), | ||
| 694 | + opParam.algName, opParam.algTag); | ||
| 695 | + return HCCL_SUCCESS; | ||
| 696 | +} | ||
| 697 | + | ||
| 698 | +HcclResult HandleSingleRankAndCommMode(HcclComm comm, OpParam& opParam, bool& skipGetRes) | ||
| 699 | +{ | ||
| 700 | + uint32_t userRankSize = 0; | ||
| 701 | + CHK_RET(HcclGetRankSize(comm, &userRankSize)); | ||
| 702 | + if (userRankSize == 1) { | ||
| 703 | + HCCL_WARNING("[%s] ranksize == 1, enter SingleRankProc", __func__); | ||
| 704 | + CHK_RET(SingleRankProc(opParam)); | ||
| 705 | + skipGetRes = true; | ||
| 706 | + return HCCL_SUCCESS; | ||
| 707 | + } | ||
| 708 | + | ||
| 709 | + bool isOpBase = true; | ||
| 710 | + const char* opModeStr = isOpBase ? "_opbase" : "_offload"; | ||
| 711 | + auto ret = sprintf_s(opParam.commModeTag, sizeof(opParam.commModeTag), "%s_%s", opParam.commName, opModeStr); | ||
| 712 | + if (ret <= 0) { | ||
| 713 | + HCCL_ERROR("[%s] failed to fill opParam.commModeTag", __func__); | ||
| 714 | + return HCCL_E_INTERNAL; | ||
| 715 | + } | ||
| 716 | + skipGetRes = false; | ||
| 717 | + return HCCL_SUCCESS; | ||
| 718 | +} | ||
| 719 | + | ||
| 720 | +static HcclResult AcquireAlgResources( | ||
| 721 | + HcclComm comm, OpParam& opParam, std::unique_ptr<InsCollAlgBase>& executor, TopoInfoWithNetLayerDetails* topoInfo, | ||
| 722 | + std::unique_ptr<AlgResourceCtxSerializable>& resCtxHost, OpResCtx& opResCtx, void** resCtxOut) | ||
| 723 | +{ | ||
| 724 | + HCCL_INFO("[AcquireAlgResources]start AcquireAlgResources!"); | ||
| 725 | + bool isResourceReused = false; | ||
| 726 | + ThreadHandle cpuTsThread{0}; | ||
| 727 | + ThreadHandle exportedAicpuTsThread{0}; | ||
| 728 | + if ((opParam.engine == COMM_ENGINE_AICPU_TS) || (opParam.engine == COMM_ENGINE_CPU)) { | ||
| 729 | + CHK_RET(HcclThreadAcquireWithStream(comm, COMM_ENGINE_CPU_TS, opParam.stream, 1, &cpuTsThread)); | ||
| 730 | + CHK_RET(HcclThreadExportToCommEngine(comm, 1, &cpuTsThread, COMM_ENGINE_AICPU_TS, &exportedAicpuTsThread)); | ||
| 731 | + } | ||
| 732 | + if (opParam.engine == COMM_ENGINE_CCU) { | ||
| 733 | + // 填充 kfcServerArgs 的所有6个字段(最后一个为 token 占位符,后续更新) | ||
| 734 | + resCtxHost->kfcServerArgs = { | ||
| 735 | + opResCtx.xnAddr, opResCtx.ckeAddr, | ||
| 736 | + static_cast<uint64_t>(1), // dieNum | ||
| 737 | + static_cast<uint64_t>(1), // missionNum | ||
| 738 | + static_cast<uint64_t>(0), // missionIndex | ||
| 739 | + static_cast<uint64_t>(0), // token 占位符,后续在 GetAlgResCcu 中更新 | ||
| 740 | + }; | ||
| 741 | + resCtxHost->kfcServerArgSize = 6; | ||
| 742 | + HCCL_INFO( | ||
| 743 | + "[AcquireAlgResources] kfcServerArgs generated: " | ||
| 744 | + "argSize[%u], xnAddr[0x%llx], ckeAddr[0x%llx], dieNum[%llu], " | ||
| 745 | + "missionNum[%llu], missionIndex[%llu], token[%llu]", | ||
| 746 | + resCtxHost->kfcServerArgSize, static_cast<unsigned long long>(resCtxHost->kfcServerArgs[0]), | ||
| 747 | + static_cast<unsigned long long>(resCtxHost->kfcServerArgs[1]), | ||
| 748 | + static_cast<unsigned long long>(resCtxHost->kfcServerArgs[2]), | ||
| 749 | + static_cast<unsigned long long>(resCtxHost->kfcServerArgs[3]), | ||
| 750 | + static_cast<unsigned long long>(resCtxHost->kfcServerArgs[4]), | ||
| 751 | + static_cast<unsigned long long>(resCtxHost->kfcServerArgs[5])); | ||
| 752 | + | ||
| 753 | + CHK_RET(HcclGetAlgRes(comm, opParam, executor, topoInfo, resCtxHost, resCtxOut, isResourceReused)); | ||
| 754 | + opParam.resCtx = *resCtxOut; | ||
| 755 | + } else { | ||
| 756 | + CHK_RET(HcclGetAlgRes(comm, opParam, executor, topoInfo, resCtxHost, resCtxOut, isResourceReused)); | ||
| 757 | + opParam.resCtx = *resCtxOut; | ||
| 758 | + } | ||
| 759 | + HCCL_INFO("[AcquireAlgResources]end AcquireAlgResources!"); | ||
| 760 | + return HCCL_SUCCESS; | ||
| 761 | +} | ||
| 762 | + | ||
| 763 | +HcclResult GetOpParamResCtx( | ||
| 764 | + HcclComm comm, const std::string& algName, OpParam& opParam, TopoInfoWithNetLayerDetails* topoInfo, | ||
| 765 | + void** resCtxOut) | ||
| 766 | +{ | ||
| 767 | + bool useCannResCtx = UseCannBridge(opParam); | ||
| 768 | + std::unique_ptr<InsCollAlgBase> executor = nullptr; | ||
| 769 | + if (useCannResCtx) { | ||
| 770 | + executor = GetAlgExecViaCann(opParam.opType, algName); | ||
| 771 | + } else { | ||
| 772 | + executor = CollAlgExecRegistryV2::Instance().GetAlgExec(opParam.opType, algName); | ||
| 773 | + } | ||
| 774 | + CHK_PRT_RET( | ||
| 775 | + executor.get() == nullptr, HCCL_ERROR("Fail to find executor for algName[%s]", algName.c_str()), HCCL_E_PARA); | ||
| 776 | + std::unique_ptr<AlgResourceCtxSerializable> resCtxHost = std::make_unique<AlgResourceCtxSerializable>(); | ||
| 777 | + resCtxHost->isHcommBatchTransferOnThreadSupported = HcommIsSupportHcommBatchTransferOnThread(); | ||
| 778 | + HCCL_DEBUG( | ||
| 779 | + "[MC2_BATCH_TRANSFER][HostSupport] opType[%u], algName[%s], supported[%d].", | ||
| 780 | + static_cast<uint32_t>(opParam.opType), algName.c_str(), | ||
| 781 | + static_cast<int>(resCtxHost->isHcommBatchTransferOnThreadSupported)); | ||
| 782 | + bool isResourceReused = false; | ||
| 783 | + | ||
| 784 | + ThreadHandle cpuTsThread{0}; | ||
| 785 | + ThreadHandle exportedAicpuTsThread{0}; | ||
| 786 | + if ((opParam.engine == COMM_ENGINE_AICPU_TS) || (opParam.engine == COMM_ENGINE_CPU)) { | ||
| 787 | + CHK_RET(HcclThreadAcquireWithStream(comm, COMM_ENGINE_CPU_TS, opParam.stream, 1, &cpuTsThread)); | ||
| 788 | + CHK_RET(HcclThreadExportToCommEngine(comm, 1, &cpuTsThread, COMM_ENGINE_AICPU_TS, &exportedAicpuTsThread)); | ||
| 789 | + } | ||
| 790 | + CHK_RET(HcclGetAlgRes(comm, opParam, executor, topoInfo, resCtxHost, resCtxOut, isResourceReused)); | ||
| 791 | + opParam.cacheValid = isResourceReused; | ||
| 792 | + opParam.resCtx = *resCtxOut; | ||
| 793 | + return HCCL_SUCCESS; | ||
| 794 | +} | ||
| 795 | + | ||
| 796 | +HcclResult GetCcuOpParamResCtx( | ||
| 797 | + HcclComm comm, const std::string& algName, OpParam& opParam, TopoInfoWithNetLayerDetails* topoInfo, | ||
| 798 | + OpResCtx& opResCtx, void** resCtxOut) | ||
| 799 | +{ | ||
| 800 | + HCCL_INFO("[GetCcuOpParamResCtx]start GetCcuOpParamResCtx!"); | ||
| 801 | + HCCL_INFO( | ||
| 802 | + "[GetCcuOpParamResCtx]received: workspace[%p], size[%llu]", (void*)opResCtx.workSpace, opResCtx.workSpaceSize); | ||
| 803 | + std::unique_ptr<InsCollAlgBase> executor = CollAlgExecRegistryV2::Instance().GetAlgExec(opParam.opType, algName); | ||
| 804 | + HCCL_INFO("[GetCcuOpParamResCtx]Generate executor successfully!"); | ||
| 805 | + CHK_PRT_RET( | ||
| 806 | + executor.get() == nullptr, HCCL_ERROR("Fail to find executor for algName[%s]", algName.c_str()), HCCL_E_PARA); | ||
| 807 | + std::unique_ptr<AlgResourceCtxSerializable> resCtxHost = std::make_unique<AlgResourceCtxSerializable>(); | ||
| 808 | + return AcquireAlgResources(comm, opParam, executor, topoInfo, resCtxHost, opResCtx, resCtxOut); | ||
| 809 | +} | ||
| 810 | + | ||
| 811 | +HcclResult GetOpParam( | ||
| 812 | + HcclComm comm, void* stream, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam) | ||
| 813 | +{ | ||
| 814 | + CHK_RET(InitOpParamByTiling(comm, stream, tag, ccTiling, opParam)); | ||
| 815 | + | ||
| 816 | + // ALLTOALL场景下sendCounts需指向host侧真实数组,且必须在整个GetOpParam调用链 | ||
| 817 | + // (含SelectAlgAndPrepareEngine、GetOpParamResCtx中的GetAlgExecViaCann)期间保持存活。 | ||
| 818 | + // 该数组持有在本函数栈帧,覆盖opParam的全部使用范围。 | ||
| 819 | + constexpr uint64_t ALLTOALL_DEFAULT_SEND_COUNTS = 200ULL * 1024 * 1024; | ||
| 820 | + std::vector<uint64_t> sendCounts; | ||
| 821 | + void* origSendCounts = opParam.all2AllVDataDes.sendCounts; | ||
| 822 | + if (opParam.opType == HcclCMDType::HCCL_CMD_ALLTOALL) { | ||
| 823 | + uint32_t userRankSize = 0; | ||
| 824 | + CHK_RET(HcclGetRankSize(comm, &userRankSize)); | ||
| 825 | + sendCounts.assign(userRankSize, ALLTOALL_DEFAULT_SEND_COUNTS); | ||
| 826 | + opParam.all2AllVDataDes.sendCounts = reinterpret_cast<void*>(sendCounts.data()); | ||
| 827 | + } | ||
| 828 | + | ||
| 829 | + std::string algName; | ||
| 830 | + std::unique_ptr<TopoInfoWithNetLayerDetails> topoInfo = std::make_unique<TopoInfoWithNetLayerDetails>(); | ||
| 831 | + bool forcedAlgAccepted = false; | ||
| 832 | + OpParam opParamBeforeAlg = opParam; | ||
| 833 | + CHK_RET(TryForcedAlgAndPrepareEngine(comm, ccTiling, opParam, algName, topoInfo, forcedAlgAccepted)); | ||
| 834 | + if (!forcedAlgAccepted) { | ||
| 835 | + CHK_RET(SelectAlgAndPrepareEngine(comm, opParam, algName, topoInfo)); | ||
| 836 | + } | ||
| 837 | + CHK_RET(FillOpParamAlgName(opParam, algName)); | ||
| 838 | + | ||
| 839 | + bool skipGetRes = false; | ||
| 840 | + CHK_RET(HandleSingleRankAndCommMode(comm, opParam, skipGetRes)); | ||
| 841 | + if (skipGetRes) { | ||
| 842 | + opParam.all2AllVDataDes.sendCounts = origSendCounts; | ||
| 843 | + return HCCL_SUCCESS; | ||
| 844 | + } | ||
| 845 | + | ||
| 846 | + void* resCtxSequence = nullptr; | ||
| 847 | + HcclResult resRet = GetOpParamResCtx(comm, algName, opParam, topoInfo.get(), &resCtxSequence); | ||
| 848 | + if (resRet != HCCL_SUCCESS && forcedAlgAccepted && resCtxSequence == nullptr) { | ||
| 849 | + HCCL_WARNING( | ||
| 850 | + "[MC2_FORCE_ALG] fallback to default selector after resource failure, algName[%s], ret[%d].", | ||
| 851 | + algName.c_str(), static_cast<int>(resRet)); | ||
| 852 | + opParam = opParamBeforeAlg; | ||
| 853 | + algName.clear(); | ||
| 854 | + topoInfo = std::make_unique<TopoInfoWithNetLayerDetails>(); | ||
| 855 | + CHK_RET(SelectAlgAndPrepareEngine(comm, opParam, algName, topoInfo)); | ||
| 856 | + CHK_RET(FillOpParamAlgName(opParam, algName)); | ||
| 857 | + CHK_RET(HandleSingleRankAndCommMode(comm, opParam, skipGetRes)); | ||
| 858 | + if (skipGetRes) { | ||
| 859 | + opParam.all2AllVDataDes.sendCounts = origSendCounts; | ||
| 860 | + return HCCL_SUCCESS; | ||
| 861 | + } | ||
| 862 | + CHK_RET(GetOpParamResCtx(comm, algName, opParam, topoInfo.get(), &resCtxSequence)); | ||
| 863 | + } else { | ||
| 864 | + CHK_RET(resRet); | ||
| 865 | + } | ||
| 866 | + // GetOpParamResCtx执行结束,sendCounts的临时host数组已不再需要, | ||
| 867 | + // 将指向恢复为原值(大概率为nullptr),避免遗留指向本函数栈内vector的悬空指针。 | ||
| 868 | + opParam.all2AllVDataDes.sendCounts = origSendCounts; | ||
| 869 | + return HCCL_SUCCESS; | ||
| 870 | +} | ||
| 871 | + | ||
| 872 | +HcclResult CcuSelectAlgCheck(const Mc2CcTilingInner* ccTiling, uint32_t tilingIndex) | ||
| 873 | +{ | ||
| 874 | + HCCL_DEBUG("[CcuSelectAlgCheck] Default function."); | ||
| 875 | + return HCCL_SUCCESS; | ||
| 876 | +} | ||
| 877 | + | ||
| 878 | +namespace { | ||
| 879 | +void RunCcuSelectAlgCheck(const Mc2CcTilingInner* ccTiling, uint32_t tilingIndex) | ||
| 880 | +{ | ||
| 881 | + if (CcuSelectAlgCheck(ccTiling, tilingIndex) != HCCL_SUCCESS) { | ||
| 882 | + HCCL_WARNING( | ||
| 883 | + "[CcuSelectAlg] CcuSelectAlgCheck failed for ccTiling[%u], opType[%u]. " | ||
| 884 | + "CCU execution condition not satisfied.", | ||
| 885 | + tilingIndex, ccTiling->opType); | ||
| 886 | + } | ||
| 887 | + HCCL_INFO("[CcuSelectAlg]CcuSelectAlgCheck[%u] successfully!", tilingIndex); | ||
| 888 | +} | ||
| 889 | + | ||
| 890 | +HcclResult SelectCcuAlgorithm( | ||
| 891 | + HcclComm comm, void* stream, const std::string& topoTag, const Mc2CcTilingInner* ccTiling, uint32_t tilingIndex, | ||
| 892 | + OpParam& opParam, std::string& algName, std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo, | ||
| 893 | + AlgorithmType& algorithmType) | ||
| 894 | +{ | ||
| 895 | + CHK_RET(InitOpParamByTiling(comm, stream, topoTag, ccTiling, opParam)); | ||
| 896 | + HCCL_INFO("[CcuSelectAlg]InitOpParamByTiling[%u] successfully!", tilingIndex); | ||
| 897 | + | ||
| 898 | + CHK_RET(SelectAlgAndPrepareEngine(comm, opParam, algName, topoInfo)); | ||
| 899 | + HCCL_INFO( | ||
| 900 | + "[CcuSelectAlg]SelectAlgAndPrepareEngine[%u] successfully, algName = [%s]!", tilingIndex, algName.c_str()); | ||
| 901 | + | ||
| 902 | + auto it = algorithmMap.find(algName); | ||
| 903 | + if (it == algorithmMap.end()) { | ||
| 904 | + HCCL_ERROR( | ||
| 905 | + "[CcuSelectAlg] ccTiling[%u] selected nonCCU algorithm[%s] for opType[%u].", tilingIndex, algName.c_str(), | ||
| 906 | + ccTiling->opType); | ||
| 907 | + return HCCL_E_NOT_SUPPORT; | ||
| 908 | + } | ||
| 909 | + algorithmType = it->second; | ||
| 910 | + | ||
| 911 | + int result = sprintf_s(opParam.algName, sizeof(opParam.algName), "%s", algName.c_str()); | ||
| 912 | + CHK_PRT_RET(result <= 0, HCCL_ERROR("failed to fill opParam.algName"), HCCL_E_INTERNAL); | ||
| 913 | + HCCL_INFO( | ||
| 914 | + "[CcuSelectAlg] prepared opParam, opType[%u], algName[%s], algTag[%s].", static_cast<u32>(opParam.opType), | ||
| 915 | + opParam.algName, opParam.algTag); | ||
| 916 | + return HCCL_SUCCESS; | ||
| 917 | +} | ||
| 918 | + | ||
| 919 | +void FillCcuAlgorithmInfo( | ||
| 920 | + uint32_t tilingIndex, const Mc2CcTilingInner* ccTiling, const std::string& algName, AlgorithmType algorithmType, | ||
| 921 | + OpParam& opParam, OpResCtx& opResCtx) | ||
| 922 | +{ | ||
| 923 | + opResCtx.opType[tilingIndex] = ccTiling->opType; | ||
| 924 | + opResCtx.algorithmType[tilingIndex] = algorithmType; | ||
| 925 | + opResCtx.isKfc[tilingIndex] = true; | ||
| 926 | + opParam.isKfc = true; | ||
| 927 | + | ||
| 928 | + HCCL_INFO( | ||
| 929 | + "[CcuSelectAlg] ccTiling[%u]: opType[%u], algName[%s], algorithmType[%u]", tilingIndex, | ||
| 930 | + opResCtx.opType[tilingIndex], algName.c_str(), opResCtx.algorithmType[tilingIndex]); | ||
| 931 | +} | ||
| 932 | + | ||
| 933 | +HcclResult PrepareCcuAlgorithmResource( | ||
| 934 | + HcclComm comm, uint32_t tilingIndex, const std::string& algName, OpParam& opParam, | ||
| 935 | + TopoInfoWithNetLayerDetails* topoInfo, OpResCtx& opResCtx, bool& skipGetRes) | ||
| 936 | +{ | ||
| 937 | + CHK_RET(HandleSingleRankAndCommMode(comm, opParam, skipGetRes)); | ||
| 938 | + if (skipGetRes) { | ||
| 939 | + return HCCL_SUCCESS; | ||
| 940 | + } | ||
| 941 | + HCCL_INFO("[CcuSelectAlg]HandleSingleRankAndCommMode[%u] successfully!", tilingIndex); | ||
| 942 | + | ||
| 943 | + void* resCtxSequence = nullptr; | ||
| 944 | + CHK_RET(GetCcuOpParamResCtx(comm, algName, opParam, topoInfo, opResCtx, &resCtxSequence)); | ||
| 945 | + HCCL_INFO("[CcuSelectAlg]GetCcuOpParamResCtx[%u] successfully!", tilingIndex); | ||
| 946 | + return HCCL_SUCCESS; | ||
| 947 | +} | ||
| 948 | + | ||
| 949 | +HcclResult CopyCcuOpParamToDevice( | ||
| 950 | + HcclComm comm, uint32_t tilingIndex, const Mc2InitTilingInner* initTiling, const OpParam& opParam, | ||
| 951 | + OpResCtx& opResCtx) | ||
| 952 | +{ | ||
| 953 | + std::string tagParam = std::to_string(tilingIndex) + "_" + std::string(opParam.algTag); | ||
| 954 | + void* opParamPtr = nullptr; | ||
| 955 | + uint64_t opParamSize = sizeof(OpParam); | ||
| 956 | + if (HcclEngineCtxGet(comm, tagParam.c_str(), COMM_ENGINE_AIV, &opParamPtr, &opParamSize) == HCCL_SUCCESS) { | ||
| 957 | + HCCL_INFO( | ||
| 958 | + "HcclEngineCtxGet success, tagParam[%s], opParamAddr[%p], opParamSize[%llu]", tagParam.c_str(), opParamPtr, | ||
| 959 | + opParamSize); | ||
| 960 | + } else { | ||
| 961 | + CHK_RET(HcclEngineCtxCreate(comm, tagParam.c_str(), COMM_ENGINE_AIV, opParamSize, &opParamPtr)); | ||
| 962 | + } | ||
| 963 | + aclError aclRet = aclrtMemcpy(opParamPtr, opParamSize, &opParam, opParamSize, ACL_MEMCPY_HOST_TO_DEVICE); | ||
| 964 | + CHK_RET(aclRet == ACL_ERROR_NONE ? HCCL_SUCCESS : HCCL_E_RUNTIME); | ||
| 965 | + opResCtx.algInfo[tilingIndex].opParam = reinterpret_cast<uint64_t>(opParamPtr); | ||
| 966 | + opResCtx.algInfo[tilingIndex].offset = initTiling->offset[tilingIndex]; | ||
| 967 | + HCCL_INFO( | ||
| 968 | + "[CcuSelectAlg] ccTiling[%u]: opParamAddr[%llu], offset[%u]", tilingIndex, | ||
| 969 | + opResCtx.algInfo[tilingIndex].opParam, opResCtx.algInfo[tilingIndex].offset); | ||
| 970 | + return HCCL_SUCCESS; | ||
| 971 | +} | ||
| 972 | + | ||
| 973 | +HcclResult ProcessCcuTiling( | ||
| 974 | + HcclComm comm, void* stream, const std::string& topoTag, const Mc2CcTilingInner* ccTiling, uint32_t tilingIndex, | ||
| 975 | + const Mc2InitTilingInner* initTiling, OpResCtx& opResCtx) | ||
| 976 | +{ | ||
| 977 | + RunCcuSelectAlgCheck(ccTiling, tilingIndex); | ||
| 978 | + | ||
| 979 | + OpParam opParam{}; | ||
| 980 | + std::string algName; | ||
| 981 | + auto topoInfo = std::make_unique<TopoInfoWithNetLayerDetails>(); | ||
| 982 | + AlgorithmType algorithmType; | ||
| 983 | + CHK_RET( | ||
| 984 | + SelectCcuAlgorithm(comm, stream, topoTag, ccTiling, tilingIndex, opParam, algName, topoInfo, algorithmType)); | ||
| 985 | + FillCcuAlgorithmInfo(tilingIndex, ccTiling, algName, algorithmType, opParam, opResCtx); | ||
| 986 | + | ||
| 987 | + bool skipGetRes = false; | ||
| 988 | + CHK_RET(PrepareCcuAlgorithmResource(comm, tilingIndex, algName, opParam, topoInfo.get(), opResCtx, skipGetRes)); | ||
| 989 | + if (skipGetRes) { | ||
| 990 | + return HCCL_SUCCESS; | ||
| 991 | + } | ||
| 992 | + return CopyCcuOpParamToDevice(comm, tilingIndex, initTiling, opParam, opResCtx); | ||
| 993 | +} | ||
| 994 | +} // namespace | ||
| 995 | + | ||
| 996 | +// CCU路径逐算子:算法选择 + 资源准备(参照GetOpParam形式) | ||
| 997 | +HcclResult CcuSelectAlg( | ||
| 998 | + HcclComm comm, void* stream, const std::string topoTag[], const void* ccTilingList[], uint32_t tilingNum, | ||
| 999 | + void* mc2Tiling, OpResCtx& opResCtx) | ||
| 1000 | +{ | ||
| 1001 | + HCCL_INFO("[CcuSelectAlg]start CcuSelectAlg!"); | ||
| 1002 | + HCCL_INFO("[CcuSelectAlg]received: workspace[%p], size[%llu]", (void*)opResCtx.workSpace, opResCtx.workSpaceSize); | ||
| 1003 | + Mc2InitTilingInner* initTiling = static_cast<Mc2InitTilingInner*>(mc2Tiling); | ||
| 1004 | + for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 1005 | + const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 1006 | + CHK_RET(ProcessCcuTiling(comm, stream, topoTag[i], ccTiling, i, initTiling, opResCtx)); | ||
| 1007 | + } | ||
| 1008 | + | ||
| 1009 | + return HCCL_SUCCESS; | ||
| 1010 | +} | ||
| @@ -20,6 +20,8 @@ | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | + | ||
| 24 | + | ||
| 23 | 25 | ||
| 24 | 26 | ||
| 25 | 27 | ||
| @@ -41,6 +43,7 @@ constexpr uint32_t MC2_TILING_VERSION = 2U; | |||
| 41 | constexpr uint32_t MAX_HCOM_NUM = 3U; | 43 | constexpr uint32_t MAX_HCOM_NUM = 3U; |
| 42 | 44 | ||
| 43 | constexpr uint32_t INIT_TILING_VERSION = 100U; | 45 | constexpr uint32_t INIT_TILING_VERSION = 100U; |
| 46 | +constexpr uint32_t INIT_TILING_CCU_NEW_VERSION = 101U; | ||
| 44 | constexpr uint32_t MAX_CC_TILING_NUM = 8U; | 47 | constexpr uint32_t MAX_CC_TILING_NUM = 8U; |
| 45 | 48 | ||
| 46 | struct Mc2ServerCfg { | 49 | struct Mc2ServerCfg { |
| @@ -53,7 +56,7 @@ struct Mc2ServerCfg { | |||
| 53 | }; | 56 | }; |
| 54 | 57 | ||
| 55 | struct Mc2InitTilingInner { | 58 | struct Mc2InitTilingInner { |
| 56 | - uint32_t version; | 59 | + uint32_t version; // ccu & alltoall (暂定version 为 原本的version + 1) |
| 57 | uint32_t mc2HcommCnt; | 60 | uint32_t mc2HcommCnt; |
| 58 | uint32_t offset[MAX_CC_TILING_NUM]; | 61 | uint32_t offset[MAX_CC_TILING_NUM]; |
| 59 | uint8_t debugMode; | 62 | uint8_t debugMode; |
| @@ -93,650 +96,126 @@ struct OpResCtx { | |||
| 93 | uint64_t rankId; | 96 | uint64_t rankId; |
| 94 | uint64_t rankSize; | 97 | uint64_t rankSize; |
| 95 | AlgInfo algInfo[MAX_CC_TILING_NUM]; | 98 | AlgInfo algInfo[MAX_CC_TILING_NUM]; |
| 99 | + | ||
| 100 | + // for ccu | ||
| 101 | + uint64_t xnAddr; // xn寄存器起始地址 | ||
| 102 | + uint64_t ckeAddr; // cke寄存器起始地址 | ||
| 103 | + uint64_t sprAddr; // spr寄存器起始地址 | ||
| 104 | + uint64_t res[Hccl::MC2_MAX_OP_NUM]; // MS地址,预留 | ||
| 105 | + uint64_t resCtx; // 资源地址,用于资源下发时的处理 | ||
| 106 | + uint32_t opType[Hccl::MC2_MAX_OP_NUM]; | ||
| 107 | + uint32_t algorithmType[Hccl::MC2_MAX_OP_NUM]; | ||
| 108 | + bool isKfc[Hccl::MC2_MAX_OP_NUM]; // 用于标记是否走kfcServer | ||
| 96 | }; | 109 | }; |
| 97 | 110 | ||
| 98 | -HcclResult CheckInputParam(const HcclComm comm, const void* mc2Tiling, const aclrtStream stream) | 111 | +enum AlgorithmType { |
| 99 | -{ | 112 | + CcuAllGatherMesh1D = 0, |
| 100 | - // 检查comm是否为空指针 | 113 | + CcuAllGatherMeshMem2Mem1D, |
| 101 | - RPT_INPUT_ERR( | 114 | + CcuAllGatherMesh2D, |
| 102 | - comm == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}), | 115 | + CcuReduceScatterMesh1D = 50, |
| 103 | - std::vector<std::string>({"HcclAllocComResourceByTiling", "nullptr", "comm", "non-null pointer"})); | 116 | + CcuReduceScatterMeshMem2Mem1D, |
| 104 | - CHK_PTR_NULL(comm); | 117 | + CcuReduceScatterMesh2D, |
| 118 | + CcuAllReduceMesh1D = 100, | ||
| 119 | + CcuAllReduceMeshMem2Mem1D, | ||
| 120 | + CcuAllReduceMesh2DOneShot | ||
| 121 | +}; | ||
| 105 | 122 | ||
| 106 | - // 检查sendBuf是否为空指针 | 123 | +static const std::unordered_map<std::string, AlgorithmType> algorithmMap = { |
| 107 | - RPT_INPUT_ERR( | 124 | + {"CcuAllGatherMesh1DMem2Mem", CcuAllGatherMeshMem2Mem1D}, |
| 108 | - mc2Tiling == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}), | 125 | + {"CcuAllGatherMeshMem2Mem1D", CcuAllGatherMeshMem2Mem1D}, |
| 109 | - std::vector<std::string>({"HcclAllocComResourceByTiling", "nullptr", "mc2Tiling", "non-null pointer"})); | 126 | + {"CcuKfcReduceScatterMesh1DMem2Mem", CcuReduceScatterMeshMem2Mem1D}}; |
| 110 | - CHK_PTR_NULL(mc2Tiling); | ||
| 111 | - | ||
| 112 | - // 检查stream是否为空指针 | ||
| 113 | - RPT_INPUT_ERR( | ||
| 114 | - stream == nullptr, "EI0003", std::vector<std::string>({"ccl_op", "value", "parameter", "expect"}), | ||
| 115 | - std::vector<std::string>({"HcclAllocComResourceByTiling", "nullptr", "stream", "non-null pointer"})); | ||
| 116 | - CHK_PTR_NULL(stream); | ||
| 117 | - | ||
| 118 | - return HCCL_SUCCESS; | ||
| 119 | -} | ||
| 120 | - | ||
| 121 | -HcclResult HcclGetTilingList(const void* mc2Tiling, const void* p[], uint32_t& cnt) | ||
| 122 | -{ | ||
| 123 | - const u32* versionPtr = static_cast<const u32*>(mc2Tiling); | ||
| 124 | - const u32 version = *(versionPtr++); | ||
| 125 | - CHK_PRT_RET(version < MC2_TILING_VERSION, HCCL_ERROR("Invalid tiling version %u.", version), HCCL_E_PARA); | ||
| 126 | - | ||
| 127 | - cnt = *(versionPtr++); | ||
| 128 | - CHK_PRT_RET(cnt > MAX_HCOM_NUM, HCCL_ERROR("Invalid hcom tiling number %u.", cnt), HCCL_E_PARA); | ||
| 129 | - | ||
| 130 | - u64 serverCfgAddr = reinterpret_cast<u64>(versionPtr) + sizeof(Mc2ServerCfg); | ||
| 131 | - for (uint32_t i = 0U; i < MAX_CC_TILING_NUM; ++i) { | ||
| 132 | - p[i] = reinterpret_cast<const void*>(reinterpret_cast<const u8*>(mc2Tiling) + versionPtr[i]); | ||
| 133 | - } | ||
| 134 | - HCCL_INFO("HcclGetTilingList version[%u] cnt[%u]", version, cnt); | ||
| 135 | - return HCCL_SUCCESS; | ||
| 136 | -} | ||
| 137 | - | ||
| 138 | -HcclResult CheckIsReduce(const Mc2CcTilingInner* ccTiling, bool* isReduce) | ||
| 139 | -{ | ||
| 140 | - if (ccTiling->opType == HcclCMDType::HCCL_CMD_REDUCE_SCATTER || ccTiling->opType == HcclCMDType::HCCL_CMD_REDUCE || | ||
| 141 | - ccTiling->opType == HcclCMDType::HCCL_CMD_ALLREDUCE) { | ||
| 142 | - *isReduce = true; | ||
| 143 | - } else { | ||
| 144 | - *isReduce = false; | ||
| 145 | - } | ||
| 146 | - return HCCL_SUCCESS; | ||
| 147 | -} | ||
| 148 | - | ||
| 149 | -HcclResult CheckCommEngine(const void* ccTilingList[], uint32_t tilingNum) | ||
| 150 | -{ | ||
| 151 | - for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 152 | - const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 153 | - if (ccTiling->commEngine != static_cast<uint8_t>(COMM_ENGINE_AICPU) && | ||
| 154 | - ccTiling->commEngine != static_cast<uint8_t>(COMM_ENGINE_CPU)) { | ||
| 155 | - HCCL_ERROR("Invalid commEngine %u.", ccTiling->commEngine); | ||
| 156 | - return HCCL_E_NOT_SUPPORT; | ||
| 157 | - } | ||
| 158 | - } | ||
| 159 | - return HCCL_SUCCESS; | ||
| 160 | -} | ||
| 161 | - | ||
| 162 | -HcclResult HcclAllocOpResCtx( | ||
| 163 | - HcclComm comm, const std::string& ctxTag, const std::vector<OpParam>& opParamVec, void* mc2Tiling, | ||
| 164 | - const void* ccTilingList[], void** opResCtxPtr) | ||
| 165 | -{ | ||
| 166 | - CHK_PTR_NULL(opResCtxPtr); | ||
| 167 | - OpResCtx resCtx{}; | ||
| 168 | - Mc2InitTilingInner* initTiling = static_cast<Mc2InitTilingInner*>(mc2Tiling); | ||
| 169 | - | ||
| 170 | - // 1. 申请存放OpParam的内存空间 | ||
| 171 | - std::vector<uint64_t> opParamAddr(opParamVec.size()); | ||
| 172 | - uint64_t opParamSize = sizeof(OpParam); | ||
| 173 | - for (uint32_t i = 0U; i < opParamVec.size(); ++i) { | ||
| 174 | - // 申请硬件内存 | ||
| 175 | - std::string tagParam = ctxTag + "_" + std::to_string(i); | ||
| 176 | - void* opParamPtr = nullptr; | ||
| 177 | - const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 178 | - // 当 commEngine 为 0 (默认值)时,设置为aicpu模式 | ||
| 179 | - CommEngine commEngine = | ||
| 180 | - (ccTiling->commEngine == 0) ? CommEngine::COMM_ENGINE_AICPU : static_cast<CommEngine>(ccTiling->commEngine); | ||
| 181 | - if (HcclEngineCtxGet(comm, tagParam.c_str(), commEngine, &opParamPtr, &opParamSize) == HCCL_SUCCESS) { | ||
| 182 | - HCCL_INFO( | ||
| 183 | - "HcclEngineCtxGet success, tagParam[%s], opParamAddr[%p], opParamSize[%u]", tagParam.c_str(), | ||
| 184 | - opParamPtr, opParamSize); | ||
| 185 | - opParamAddr[i] = reinterpret_cast<uint64_t>(opParamPtr); | ||
| 186 | - } else { | ||
| 187 | - CHK_RET(HcclEngineCtxCreate(comm, tagParam.c_str(), commEngine, opParamSize, &opParamPtr)); | ||
| 188 | - opParamAddr[i] = reinterpret_cast<uint64_t>(opParamPtr); | ||
| 189 | - } | ||
| 190 | - HCCL_INFO( | ||
| 191 | - "HcclAllocOpResCtx the %dth opParam: opParamAddr[%u], opParamSize[%u]", i, opParamAddr[i], opParamSize); | ||
| 192 | - | ||
| 193 | - // 复制数据到硬件内存 | ||
| 194 | - aclError aclRet = aclrtMemcpy( | ||
| 195 | - reinterpret_cast<void*>(opParamAddr[i]), opParamSize, &opParamVec[i], opParamSize, aclrtMemcpyKind(1)); | ||
| 196 | - CHK_RET(aclRet == ACL_ERROR_NONE ? HCCL_SUCCESS : HCCL_E_RUNTIME); | ||
| 197 | - // 记录OpParam的地址 | ||
| 198 | - resCtx.algInfo[i].opParam = opParamAddr[i]; | ||
| 199 | - // 记录OpParam的偏移量 | ||
| 200 | - resCtx.algInfo[i].offset = initTiling->offset[i]; | ||
| 201 | - } | ||
| 202 | - | ||
| 203 | - // 2. 申请WorkSpace的内存空间 | ||
| 204 | - uint64_t memSize = 20 * 1024 * 1024; | ||
| 205 | - resCtx.workSpaceSize = memSize; | ||
| 206 | - // 申请硬件内存 | ||
| 207 | - std::string tagWorkSpace = ctxTag + "_workSpace"; | ||
| 208 | - void* workSpacePtr = nullptr; | ||
| 209 | - const Mc2CcTilingInner* ccTiling0 = static_cast<const Mc2CcTilingInner*>(ccTilingList[0]); | ||
| 210 | - CommEngine commEngine = | ||
| 211 | - (ccTiling0->commEngine == 0) ? CommEngine::COMM_ENGINE_AICPU : static_cast<CommEngine>(ccTiling0->commEngine); | ||
| 212 | - if (HcclEngineCtxGet(comm, tagWorkSpace.c_str(), commEngine, &workSpacePtr, &memSize) == HCCL_SUCCESS) { | ||
| 213 | - HCCL_INFO( | ||
| 214 | - "HcclEngineCtxGet success, tagWorkSpace[%s], workSpaceAddr[%p], workSpaceSize[%u]", tagWorkSpace.c_str(), | ||
| 215 | - workSpacePtr, memSize); | ||
| 216 | - resCtx.workSpace = reinterpret_cast<uint64_t>(workSpacePtr); | ||
| 217 | - } else { | ||
| 218 | - CHK_RET(HcclEngineCtxCreate(comm, tagWorkSpace.c_str(), commEngine, memSize, &workSpacePtr)); | ||
| 219 | - resCtx.workSpace = reinterpret_cast<uint64_t>(workSpacePtr); | ||
| 220 | - } | ||
| 221 | - HCCL_INFO("HcclAllocOpResCtx the workSpace: workSpaceAddr[%u], workSpaceSize[%u]", resCtx.workSpace, memSize); | ||
| 222 | - | ||
| 223 | - // 3. 获取rankID和ranksize | ||
| 224 | - uint32_t rankSize = 0U; | ||
| 225 | - uint32_t rankId = 0U; | ||
| 226 | - CHK_RET(HcclGetRankSize(comm, &rankSize)); | ||
| 227 | - CHK_RET(HcclGetRankId(comm, &rankId)); | ||
| 228 | - resCtx.rankSize = rankSize; | ||
| 229 | - resCtx.rankId = rankId; | ||
| 230 | - | ||
| 231 | - // 4. 申请OpResCtx的内存空间 | ||
| 232 | - std::string tagOpResCtx = ctxTag + "_opResCtx"; | ||
| 233 | - uint64_t opResCtxSize = sizeof(OpResCtx); | ||
| 234 | - if (HcclEngineCtxGet(comm, tagOpResCtx.c_str(), commEngine, opResCtxPtr, &opResCtxSize) == HCCL_SUCCESS) { | ||
| 235 | - HCCL_INFO( | ||
| 236 | - "HcclEngineCtxGet success, tagOpResCtx[%s], opResCtxAddr[%p], opResCtxSize[%u]", tagOpResCtx.c_str(), | ||
| 237 | - opResCtxPtr, opResCtxSize); | ||
| 238 | - } else { | ||
| 239 | - CHK_RET(HcclEngineCtxCreate(comm, tagOpResCtx.c_str(), commEngine, opResCtxSize, opResCtxPtr)); | ||
| 240 | - } | ||
| 241 | - | ||
| 242 | - HCCL_INFO("HcclAllocOpResCtx the opResCtx: opResCtxAddr[%u], opResCtxSize[%u]", opResCtxPtr, opResCtxSize); | ||
| 243 | - | ||
| 244 | - // 5. 复制OpResCtx到硬件内存 | ||
| 245 | - aclError aclRet = aclrtMemcpy(*opResCtxPtr, opResCtxSize, &resCtx, opResCtxSize, aclrtMemcpyKind(1)); | ||
| 246 | - CHK_RET(aclRet == ACL_ERROR_NONE ? HCCL_SUCCESS : HCCL_E_RUNTIME); | ||
| 247 | - | ||
| 248 | - return HCCL_SUCCESS; | ||
| 249 | -} | ||
| 250 | - | ||
| 251 | -// AllToAll适配AllToAllV | ||
| 252 | -HcclResult ConvertAlltoAllParam( | ||
| 253 | - const u64 recvCount, const u32 rankSize, std::vector<u64>& sdispls, std::vector<u64>& rdispls) | ||
| 254 | -{ | ||
| 255 | - u64 dataCountOffset = 0; | ||
| 256 | - for (u64 i = 0; i < rankSize; i++) { | ||
| 257 | - sdispls[i] = dataCountOffset; | ||
| 258 | - rdispls[i] = dataCountOffset; | ||
| 259 | - dataCountOffset += recvCount; | ||
| 260 | - } | ||
| 261 | - return HCCL_SUCCESS; | ||
| 262 | -} | ||
| 263 | - | ||
| 264 | -HcclResult PrepareOpsCommParam(const std::string& tag, OpParam& param) | ||
| 265 | -{ | ||
| 266 | - param.opMode = OpMode::OPBASE; | ||
| 267 | - DevType deviceType = DevType::DEV_TYPE_COUNT; | ||
| 268 | - CHK_RET(hrtGetDeviceType(deviceType)); | ||
| 269 | - | ||
| 270 | - // topoInfo的tag,所有相同的算子可以共享 | ||
| 271 | - int ret = sprintf_s(param.tag, sizeof(param.tag), "%s", tag.c_str()); | ||
| 272 | - if (ret <= 0) { | ||
| 273 | - HCCL_ERROR("failed to fill param.tag"); | ||
| 274 | - return HCCL_E_INTERNAL; | ||
| 275 | - } | ||
| 276 | - | ||
| 277 | - param.inputPtr = nullptr; | ||
| 278 | - param.outputPtr = nullptr; | ||
| 279 | - param.inputSize = 0; | ||
| 280 | - param.outputSize = 0; | ||
| 281 | - param.enableDetour = false; | ||
| 282 | - param.deviceType = deviceType; | ||
| 283 | - | ||
| 284 | - return HCCL_SUCCESS; | ||
| 285 | -} | ||
| 286 | - | ||
| 287 | -HcclResult PrintOpsCommParam(OpParam& param) | ||
| 288 | -{ | ||
| 289 | - HCCL_INFO("commName: %s", param.commName); | ||
| 290 | - HCCL_INFO("tag:%s", param.tag); | ||
| 291 | - HCCL_INFO("stream: %p", param.stream); | ||
| 292 | - HCCL_INFO("inputPtr %p", param.inputPtr); | ||
| 293 | - HCCL_INFO("outputPtr %p", param.outputPtr); | ||
| 294 | - HCCL_INFO("inputSize %lu", param.inputSize); | ||
| 295 | - HCCL_INFO("outputSize %lu", param.outputSize); | ||
| 296 | - HCCL_INFO("opMode %u", static_cast<uint32_t>(param.opMode)); | ||
| 297 | - HCCL_INFO("deviceType %u", static_cast<uint32_t>(param.deviceType)); | ||
| 298 | - return HCCL_SUCCESS; | ||
| 299 | -} | ||
| 300 | - | ||
| 301 | -HcclResult PrepareParamForAllGather( | ||
| 302 | - HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 303 | -{ | ||
| 304 | - HCCL_INFO("PrepareParamForAllGather, ccTiling[%p]", ccTiling); | ||
| 305 | - u32 userRankSize; | ||
| 306 | - CHK_RET(HcclGetRankSize(comm, &userRankSize)); // 加上,后面计算outputSize可能使用 | ||
| 307 | - | ||
| 308 | - HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 309 | - if (ret != HCCL_SUCCESS) { | ||
| 310 | - HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 311 | - } | ||
| 312 | - | ||
| 313 | - param.opType = HcclCMDType::HCCL_CMD_ALLGATHER; | ||
| 314 | - param.DataDes.dataType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 315 | - param.DataDes.count = 0; | ||
| 316 | - | ||
| 317 | - HCCL_INFO("Print PrepareParamForAllGather."); | ||
| 318 | - CHK_RET(PrintOpsCommParam(param)); | ||
| 319 | - HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 320 | - HCCL_INFO("DataDes.dataType %u", static_cast<uint32_t>(param.DataDes.dataType)); | ||
| 321 | - HCCL_INFO("DataDes.count %lu", param.DataDes.count); | ||
| 322 | - HCCL_INFO("Execute PrepareParamForAllGather success."); | ||
| 323 | - return HCCL_SUCCESS; | ||
| 324 | -} | ||
| 325 | - | ||
| 326 | -HcclResult PrepareParamForAllReduce( | ||
| 327 | - HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 328 | -{ | ||
| 329 | - HCCL_INFO("PrepareParamForAllReduce, ccTiling[%p]", ccTiling); | ||
| 330 | - u32 userRankSize; | ||
| 331 | - CHK_RET(HcclGetRankSize(comm, &userRankSize)); // 加上,后面计算outputSize可能使用 | ||
| 332 | - | ||
| 333 | - HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 334 | - if (ret != HCCL_SUCCESS) { | ||
| 335 | - HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 336 | - } | ||
| 337 | - | ||
| 338 | - param.opType = HcclCMDType::HCCL_CMD_ALLREDUCE; | ||
| 339 | - param.reduceType = static_cast<HcclReduceOp>(ccTiling->reduceType); | ||
| 340 | - param.DataDes.dataType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 341 | - param.DataDes.count = 0; | ||
| 342 | - | ||
| 343 | - HCCL_INFO("Print PrepareParamForAllReduce."); | ||
| 344 | - CHK_RET(PrintOpsCommParam(param)); | ||
| 345 | - HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 346 | - HCCL_INFO("reduceType %u", static_cast<uint32_t>(param.reduceType)); | ||
| 347 | - HCCL_INFO("DataDes.dataType %u", static_cast<uint32_t>(param.DataDes.dataType)); | ||
| 348 | - HCCL_INFO("DataDes.count %lu", param.DataDes.count); | ||
| 349 | - HCCL_INFO("Execute PrepareParamForAllReduce success."); | ||
| 350 | - return HCCL_SUCCESS; | ||
| 351 | -} | ||
| 352 | - | ||
| 353 | -HcclResult PrepareParamForReduceScatter( | ||
| 354 | - HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 355 | -{ | ||
| 356 | - HCCL_INFO("PrepareParamForReduceScatter, ccTiling[%p]", ccTiling); | ||
| 357 | - u32 userRankSize; | ||
| 358 | - CHK_RET(HcclGetRankSize(comm, &userRankSize)); // 加上,后面计算outputSize可能使用 | ||
| 359 | - | ||
| 360 | - HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 361 | - if (ret != HCCL_SUCCESS) { | ||
| 362 | - HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 363 | - } | ||
| 364 | - | ||
| 365 | - param.opType = HcclCMDType::HCCL_CMD_REDUCE_SCATTER; | ||
| 366 | - param.reduceType = static_cast<HcclReduceOp>(ccTiling->reduceType); | ||
| 367 | - param.DataDes.dataType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 368 | - param.DataDes.count = 0; | ||
| 369 | - | ||
| 370 | - HCCL_INFO("Print PrepareParamForReduceScatter."); | ||
| 371 | - CHK_RET(PrintOpsCommParam(param)); | ||
| 372 | - HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 373 | - HCCL_INFO("reduceType %u", static_cast<uint32_t>(param.reduceType)); | ||
| 374 | - HCCL_INFO("DataDes.dataType %u", static_cast<uint32_t>(param.DataDes.dataType)); | ||
| 375 | - HCCL_INFO("DataDes.count %lu", param.DataDes.count); | ||
| 376 | - HCCL_INFO("Execute PrepareParamForReduceScatter success."); | ||
| 377 | - return HCCL_SUCCESS; | ||
| 378 | -} | ||
| 379 | - | ||
| 380 | -HcclResult PrepareParamForAlltoAll( | ||
| 381 | - HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 382 | -{ | ||
| 383 | - HCCL_INFO("PrepareParamForAlltoAll, ccTiling[%p]", ccTiling); | ||
| 384 | - u32 userRankSize; | ||
| 385 | - CHK_RET(HcclGetRankSize(comm, &userRankSize)); | ||
| 386 | - | ||
| 387 | - HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 388 | - if (ret != HCCL_SUCCESS) { | ||
| 389 | - HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 390 | - } | ||
| 391 | - | ||
| 392 | - u64 varMemSize = ALL_TO_ALL_V_VECTOR_NUM * userRankSize * sizeof(u64); | ||
| 393 | - param.varMemSize = varMemSize; | ||
| 394 | - param.opType = HcclCMDType::HCCL_CMD_ALLTOALL; | ||
| 395 | - param.all2AllVDataDes.sendType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 396 | - param.all2AllVDataDes.recvType = static_cast<HcclDataType>(ccTiling->dstDataType); | ||
| 397 | - param.all2AllVDataDes.sendCounts = nullptr; | ||
| 398 | - param.all2AllVDataDes.recvCounts = nullptr; | ||
| 399 | - param.all2AllVDataDes.sdispls = nullptr; | ||
| 400 | - param.all2AllVDataDes.rdispls = nullptr; | ||
| 401 | - | ||
| 402 | - HCCL_INFO("Print PrepareParamForAlltoAll."); | ||
| 403 | - CHK_RET(PrintOpsCommParam(param)); | ||
| 404 | - HCCL_INFO("varMemSize %lu", param.varMemSize); | ||
| 405 | - HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 406 | - HCCL_INFO("all2AllVDataDes.sendType %u", static_cast<uint32_t>(param.all2AllVDataDes.sendType)); | ||
| 407 | - HCCL_INFO("all2AllVDataDes.recvType %u", static_cast<uint32_t>(param.all2AllVDataDes.recvType)); | ||
| 408 | - HCCL_INFO("Execute PrepareParamForAlltoAll success."); | ||
| 409 | - return HCCL_SUCCESS; | ||
| 410 | -} | ||
| 411 | - | ||
| 412 | -HcclResult PrepareParamForAlltoAllV( | ||
| 413 | - HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param) | ||
| 414 | -{ | ||
| 415 | - HCCL_INFO("PrepareParamForAlltoAllV, ccTiling[%p]", ccTiling); | ||
| 416 | - u32 userRankSize; | ||
| 417 | - CHK_RET(HcclGetRankSize(comm, &userRankSize)); | ||
| 418 | - | ||
| 419 | - HcclResult ret = PrepareOpsCommParam(tag, param); | ||
| 420 | - if (ret != HCCL_SUCCESS) { | ||
| 421 | - HCCL_ERROR("failed to fill OpsCommParam"); | ||
| 422 | - } | ||
| 423 | - | ||
| 424 | - u64 varMemSize = ALL_TO_ALL_V_VECTOR_NUM * userRankSize * sizeof(u64); | ||
| 425 | - param.varMemSize = varMemSize; | ||
| 426 | - param.opType = HcclCMDType::HCCL_CMD_ALLTOALLV; | ||
| 427 | - param.all2AllVDataDes.sendType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 428 | - param.all2AllVDataDes.recvType = static_cast<HcclDataType>(ccTiling->dstDataType); | ||
| 429 | - param.all2AllVDataDes.sendCounts = nullptr; | ||
| 430 | - param.all2AllVDataDes.recvCounts = nullptr; | ||
| 431 | - param.all2AllVDataDes.sdispls = nullptr; | ||
| 432 | - param.all2AllVDataDes.rdispls = nullptr; | ||
| 433 | - | ||
| 434 | - HCCL_INFO("Print PrepareParamForAlltoAllV."); | ||
| 435 | - CHK_RET(PrintOpsCommParam(param)); | ||
| 436 | - HCCL_INFO("varMemSize %lu", param.varMemSize); | ||
| 437 | - HCCL_INFO("opType %u", static_cast<uint32_t>(param.opType)); | ||
| 438 | - HCCL_INFO("all2AllVDataDes.sendType %u", static_cast<uint32_t>(param.all2AllVDataDes.sendType)); | ||
| 439 | - HCCL_INFO("all2AllVDataDes.recvType %u", static_cast<uint32_t>(param.all2AllVDataDes.recvType)); | ||
| 440 | - return HCCL_SUCCESS; | ||
| 441 | -} | ||
| 442 | 127 | ||
| 443 | typedef HcclResult (*OpParamPrepareFunc)( | 128 | typedef HcclResult (*OpParamPrepareFunc)( |
| 444 | HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param); | 129 | HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param); |
| 445 | 130 | ||
| 446 | -std::unordered_map<HcclCMDType, OpParamPrepareFunc> opParamPrepareFuncMap = { | 131 | +CommEngine OpExecuteConfigToCommEngine(uint8_t commEngine); |
| 447 | - {HcclCMDType::HCCL_CMD_ALLGATHER, PrepareParamForAllGather}, | ||
| 448 | - {HcclCMDType::HCCL_CMD_ALLREDUCE, PrepareParamForAllReduce}, | ||
| 449 | - {HcclCMDType::HCCL_CMD_REDUCE_SCATTER, PrepareParamForReduceScatter}, | ||
| 450 | - {HcclCMDType::HCCL_CMD_ALLTOALL, PrepareParamForAlltoAll}, | ||
| 451 | - {HcclCMDType::HCCL_CMD_ALLTOALLV, PrepareParamForAlltoAllV}, | ||
| 452 | -}; | ||
| 453 | 132 | ||
| 454 | -HcclResult PrepareOpParams(HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam) | 133 | +HcclResult CheckInputParam(const HcclComm comm, const void* mc2Tiling, const aclrtStream stream); |
| 455 | -{ | 134 | + |
| 456 | - auto it = opParamPrepareFuncMap.find(static_cast<HcclCMDType>(ccTiling->opType)); | 135 | +HcclResult HcclGetTilingList(const void* mc2Tiling, const void* p[], uint32_t& cnt); |
| 457 | - if (it != opParamPrepareFuncMap.end()) { | 136 | + |
| 458 | - return it->second(comm, tag, ccTiling, opParam); | 137 | +HcclResult CheckIsReduce(const Mc2CcTilingInner* ccTiling, bool* isReduce); |
| 459 | - } | 138 | + |
| 460 | - HCCL_ERROR("PrepareOpParams error, opType[%d] not found", ccTiling->opType); | 139 | +HcclResult CheckCommEngine(const void* ccTilingList[], uint32_t tilingNum); |
| 461 | - return HCCL_E_INTERNAL; | 140 | + |
| 462 | -} | 141 | +HcclResult ObtainCommEngine(const void* ccTilingList[], uint32_t tilingNum, uint8_t& commEngine); |
| 142 | + | ||
| 143 | +HcclResult CheckCcuKfcFlow(const void* mc2Tiling, const void* ccTilingList[], uint32_t tilingNum); | ||
| 144 | + | ||
| 145 | +// 构建 opResCtx 基础字段 | ||
| 146 | +HcclResult AllocCcuOpResCtx(HcclComm comm, const std::string& ctxTag, u32 rankSize, u32 userRank, OpResCtx& opResCtx); | ||
| 147 | + | ||
| 148 | +HcclResult HcclAllocOpResCtx( | ||
| 149 | + HcclComm comm, const std::string& ctxTag, const std::vector<OpParam>& opParamVec, void* mc2Tiling, | ||
| 150 | + const void* ccTilingList[], void** opResCtxPtr); | ||
| 151 | + | ||
| 152 | +// AllToAll适配AllToAllV | ||
| 153 | +HcclResult ConvertAlltoAllParam( | ||
| 154 | + const u64 recvCount, const u32 rankSize, std::vector<u64>& sdispls, std::vector<u64>& rdispls); | ||
| 155 | + | ||
| 156 | +HcclResult PrepareOpsCommParam(const std::string& tag, OpParam& param); | ||
| 157 | + | ||
| 158 | +HcclResult PrintOpsCommParam(OpParam& param); | ||
| 159 | + | ||
| 160 | +HcclResult PrepareParamForAllGather( | ||
| 161 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param); | ||
| 162 | + | ||
| 163 | +HcclResult PrepareParamForAllReduce( | ||
| 164 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param); | ||
| 165 | + | ||
| 166 | +HcclResult PrepareParamForReduceScatter( | ||
| 167 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param); | ||
| 168 | + | ||
| 169 | +HcclResult PrepareParamForAlltoAll( | ||
| 170 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param); | ||
| 171 | + | ||
| 172 | +HcclResult PrepareParamForAlltoAllV( | ||
| 173 | + HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& param); | ||
| 174 | + | ||
| 175 | +HcclResult PrepareOpParams(HcclComm comm, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam); | ||
| 463 | 176 | ||
| 464 | HcclResult InitOpParamByTiling( | 177 | HcclResult InitOpParamByTiling( |
| 465 | - HcclComm comm, void* stream, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam) | 178 | + HcclComm comm, void* stream, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam); |
| 466 | -{ | ||
| 467 | - opParam.opType = static_cast<HcclCMDType>(ccTiling->opType); | ||
| 468 | - opParam.stream = reinterpret_cast<aclrtStream>(stream); | ||
| 469 | - opParam.engine = static_cast<CommEngine>(ccTiling->commEngine); | ||
| 470 | - CHK_RET(HcclGetCommName(comm, opParam.commName)); | ||
| 471 | - CHK_RET(PrepareOpParams(comm, tag, ccTiling, opParam)); | ||
| 472 | - if (opParam.opType == HcclCMDType::HCCL_CMD_ALLTOALL) { | ||
| 473 | - opParam.all2AllVDataDes.sendType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 474 | - // sendCounts指向的host侧数组由调用方(GetOpParam)持有并填充,此处保持nullptr, | ||
| 475 | - // 避免将数值当作指针使用导致后续解引用非法地址。 | ||
| 476 | - } | ||
| 477 | - return HCCL_SUCCESS; | ||
| 478 | -} | ||
| 479 | 179 | ||
| 480 | -HcclResult PrepareTopoInfoForOp(HcclComm comm, OpParam& opParam, std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo) | 180 | +HcclResult PrepareTopoInfoForOp( |
| 481 | -{ | 181 | + HcclComm comm, OpParam& opParam, std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo); |
| 482 | - opParam.hcclComm = comm; | ||
| 483 | - CHK_RET(HcclGetOpExpansionMode(comm, opParam)); | ||
| 484 | - CHK_RET(HcclCalcTopoInfo(comm, opParam, topoInfo)); | ||
| 485 | - return HCCL_SUCCESS; | ||
| 486 | -} | ||
| 487 | 182 | ||
| 488 | -HcclResult PrepareEngineForAlg(OpParam& opParam, const std::string& algName) | 183 | +HcclResult PrepareEngineForAlg(OpParam& opParam, const std::string& algName); |
| 489 | -{ | ||
| 490 | - CHK_RET(SetCommEngine(opParam)); | ||
| 491 | - if (GetExternalInputHcclAivOnlyMode() && opParam.engine != COMM_ENGINE_AIV) { | ||
| 492 | - HCCL_ERROR( | ||
| 493 | - "[HcclExecOp] opType[%d] currently do not select aiv mode, aiv only not support.", | ||
| 494 | - static_cast<int>(opParam.opType)); | ||
| 495 | - return HCCL_E_NOT_SUPPORT; | ||
| 496 | - } | ||
| 497 | - if ((opParam.engine == COMM_ENGINE_AICPU_TS) || (opParam.engine == COMM_ENGINE_CPU)) { | ||
| 498 | - HCCL_DEBUG("[Selector] is aicpu mode"); | ||
| 499 | - CHK_RET(LoadAICPUKernel()); | ||
| 500 | - } | ||
| 501 | - CHK_RET(SetOpParamAlgTag(opParam, algName)); | ||
| 502 | - return HCCL_SUCCESS; | ||
| 503 | -} | ||
| 504 | 184 | ||
| 505 | -std::unique_ptr<InsCollAlgBase> GetAlgExecutorForOp(const OpParam& opParam, const std::string& algName) | 185 | +std::unique_ptr<InsCollAlgBase> GetAlgExecutorForOp(const OpParam& opParam, const std::string& algName); |
| 506 | -{ | ||
| 507 | - if (UseCannBridge(opParam)) { | ||
| 508 | - return GetAlgExecViaCann(opParam.opType, algName); | ||
| 509 | - } | ||
| 510 | - return CollAlgExecRegistryV2::Instance().GetAlgExec(opParam.opType, algName); | ||
| 511 | -} | ||
| 512 | 186 | ||
| 513 | HcclResult CheckForcedAlgResource( | 187 | HcclResult CheckForcedAlgResource( |
| 514 | - HcclComm comm, const OpParam& opParam, TopoInfoWithNetLayerDetails* topoInfo, const std::string& algName) | 188 | + HcclComm comm, const OpParam& opParam, TopoInfoWithNetLayerDetails* topoInfo, const std::string& algName); |
| 515 | -{ | ||
| 516 | - std::unique_ptr<InsCollAlgBase> executor = GetAlgExecutorForOp(opParam, algName); | ||
| 517 | - CHK_PRT_RET( | ||
| 518 | - executor == nullptr, | ||
| 519 | - HCCL_WARNING( | ||
| 520 | - "[MC2_FORCE_ALG] fallback, algName[%s] is not registered for opType[%u].", algName.c_str(), | ||
| 521 | - static_cast<u32>(opParam.opType)), | ||
| 522 | - HCCL_E_NOT_SUPPORT); | ||
| 523 | 189 | ||
| 524 | - AlgHierarchyInfoForAllLevel algHierarchyInfo; | 190 | +bool GetForcedAlgName(const Mc2CcTilingInner* ccTiling, std::string& algName); |
| 525 | - HcclResult ret = executor->CalcAlgHierarchyInfo(comm, topoInfo, algHierarchyInfo); | ||
| 526 | - CHK_PRT_RET( | ||
| 527 | - ret != HCCL_SUCCESS, | ||
| 528 | - HCCL_WARNING( | ||
| 529 | - "[MC2_FORCE_ALG] fallback, CalcAlgHierarchyInfo failed, algName[%s], ret[%d].", algName.c_str(), | ||
| 530 | - static_cast<int>(ret)), | ||
| 531 | - HCCL_E_NOT_SUPPORT); | ||
| 532 | - | ||
| 533 | - AlgResourceRequest resRequest; | ||
| 534 | - ret = executor->CalcRes(comm, opParam, topoInfo, algHierarchyInfo, resRequest); | ||
| 535 | - CHK_PRT_RET( | ||
| 536 | - ret != HCCL_SUCCESS, | ||
| 537 | - HCCL_WARNING( | ||
| 538 | - "[MC2_FORCE_ALG] fallback, CalcRes failed, algName[%s], ret[%d].", algName.c_str(), static_cast<int>(ret)), | ||
| 539 | - HCCL_E_NOT_SUPPORT); | ||
| 540 | - return HCCL_SUCCESS; | ||
| 541 | -} | ||
| 542 | - | ||
| 543 | -bool GetForcedAlgName(const Mc2CcTilingInner* ccTiling, std::string& algName) | ||
| 544 | -{ | ||
| 545 | - if (ccTiling == nullptr || ccTiling->algConfig[0] == '\0') { | ||
| 546 | - return false; | ||
| 547 | - } | ||
| 548 | - | ||
| 549 | - std::string algConfig(ccTiling->algConfig); | ||
| 550 | - if (algConfig.find('=') != std::string::npos) { | ||
| 551 | - HCCL_INFO("[MC2_FORCE_ALG] legacy algConfig[%s], use default selector.", algConfig.c_str()); | ||
| 552 | - return false; | ||
| 553 | - } | ||
| 554 | - | ||
| 555 | - algName = algConfig; | ||
| 556 | - return true; | ||
| 557 | -} | ||
| 558 | 191 | ||
| 559 | HcclResult TryForcedAlgAndPrepareEngine( | 192 | HcclResult TryForcedAlgAndPrepareEngine( |
| 560 | HcclComm comm, const Mc2CcTilingInner* ccTiling, OpParam& opParam, std::string& algName, | 193 | HcclComm comm, const Mc2CcTilingInner* ccTiling, OpParam& opParam, std::string& algName, |
| 561 | - std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo, bool& forcedAlgAccepted) | 194 | + std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo, bool& forcedAlgAccepted); |
| 562 | -{ | ||
| 563 | - forcedAlgAccepted = false; | ||
| 564 | - std::string forcedAlgName; | ||
| 565 | - if (!GetForcedAlgName(ccTiling, forcedAlgName)) { | ||
| 566 | - return HCCL_SUCCESS; | ||
| 567 | - } | ||
| 568 | - | ||
| 569 | - OpParam opParamBackup = opParam; | ||
| 570 | - CHK_RET(PrepareTopoInfoForOp(comm, opParam, topoInfo)); | ||
| 571 | - HcclResult ret = PrepareEngineForAlg(opParam, forcedAlgName); | ||
| 572 | - if (ret != HCCL_SUCCESS) { | ||
| 573 | - opParam = opParamBackup; | ||
| 574 | - HCCL_ERROR( | ||
| 575 | - "[MC2_FORCE_ALG] prepare engine failed, algName[%s], ret[%d].", forcedAlgName.c_str(), | ||
| 576 | - static_cast<int>(ret)); | ||
| 577 | - return ret; | ||
| 578 | - } | ||
| 579 | - | ||
| 580 | - ret = CheckForcedAlgResource(comm, opParam, topoInfo.get(), forcedAlgName); | ||
| 581 | - if (ret != HCCL_SUCCESS) { | ||
| 582 | - opParam = opParamBackup; | ||
| 583 | - topoInfo = std::make_unique<TopoInfoWithNetLayerDetails>(); | ||
| 584 | - algName.clear(); | ||
| 585 | - forcedAlgAccepted = false; | ||
| 586 | - HCCL_WARNING( | ||
| 587 | - "[MC2_FORCE_ALG] fallback to default selector, opType[%u], algConfig[%s].", | ||
| 588 | - static_cast<u32>(opParam.opType), forcedAlgName.c_str()); | ||
| 589 | - return HCCL_SUCCESS; | ||
| 590 | - } | ||
| 591 | - | ||
| 592 | - algName = forcedAlgName; | ||
| 593 | - forcedAlgAccepted = true; | ||
| 594 | - HCCL_INFO("[MC2_FORCE_ALG] accepted, opType[%u], algName[%s].", static_cast<u32>(opParam.opType), algName.c_str()); | ||
| 595 | - return HCCL_SUCCESS; | ||
| 596 | -} | ||
| 597 | 195 | ||
| 598 | HcclResult SelectAlgAndPrepareEngine( | 196 | HcclResult SelectAlgAndPrepareEngine( |
| 599 | - HcclComm comm, OpParam& opParam, std::string& algName, std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo) | 197 | + HcclComm comm, OpParam& opParam, std::string& algName, std::unique_ptr<TopoInfoWithNetLayerDetails>& topoInfo); |
| 600 | -{ | ||
| 601 | - CHK_RET(PrepareTopoInfoForOp(comm, opParam, topoInfo)); | ||
| 602 | 198 | ||
| 603 | - std::shared_ptr<ExecuteSelector> collAlgSelector = std::make_shared<ExecuteSelector>(ExecuteSelector()); | 199 | +HcclResult FillOpParamAlgName(OpParam& opParam, const std::string& algName); |
| 604 | - CHK_RET(collAlgSelector->Run(opParam, topoInfo.get(), algName)); | ||
| 605 | - if (algName.empty()) { | ||
| 606 | - HCCL_ERROR("[Selector] select algname fail!"); | ||
| 607 | - return HCCL_E_PTR; | ||
| 608 | - } | ||
| 609 | 200 | ||
| 610 | - CHK_RET(PrepareEngineForAlg(opParam, algName)); | 201 | +HcclResult HandleSingleRankAndCommMode(HcclComm comm, OpParam& opParam, bool& skipGetRes); |
| 611 | - return HCCL_SUCCESS; | ||
| 612 | -} | ||
| 613 | - | ||
| 614 | -HcclResult FillOpParamAlgName(OpParam& opParam, const std::string& algName) | ||
| 615 | -{ | ||
| 616 | - int result = sprintf_s(opParam.algName, sizeof(opParam.algName), "%s", algName.c_str()); | ||
| 617 | - CHK_PRT_RET(result <= 0, HCCL_ERROR("failed to fill opParam.algName"), HCCL_E_INTERNAL); | ||
| 618 | - HCCL_INFO( | ||
| 619 | - "[GetOpParam] prepared opParam, opType[%u], algName[%s], algTag[%s].", static_cast<u32>(opParam.opType), | ||
| 620 | - opParam.algName, opParam.algTag); | ||
| 621 | - return HCCL_SUCCESS; | ||
| 622 | -} | ||
| 623 | - | ||
| 624 | -HcclResult HandleSingleRankAndCommMode(HcclComm comm, OpParam& opParam, bool& skipGetRes) | ||
| 625 | -{ | ||
| 626 | - uint32_t userRankSize = 0; | ||
| 627 | - CHK_RET(HcclGetRankSize(comm, &userRankSize)); | ||
| 628 | - if (userRankSize == 1) { | ||
| 629 | - HCCL_WARNING("[%s] ranksize == 1, enter SingleRankProc", __func__); | ||
| 630 | - CHK_RET(SingleRankProc(opParam)); | ||
| 631 | - skipGetRes = true; | ||
| 632 | - return HCCL_SUCCESS; | ||
| 633 | - } | ||
| 634 | - | ||
| 635 | - bool isOpBase = true; | ||
| 636 | - const char* opModeStr = isOpBase ? "_opbase" : "_offload"; | ||
| 637 | - auto ret = sprintf_s(opParam.commModeTag, sizeof(opParam.commModeTag), "%s_%s", opParam.commName, opModeStr); | ||
| 638 | - if (ret <= 0) { | ||
| 639 | - HCCL_ERROR("[%s] failed to fill opParam.commModeTag", __func__); | ||
| 640 | - return HCCL_E_INTERNAL; | ||
| 641 | - } | ||
| 642 | - skipGetRes = false; | ||
| 643 | - return HCCL_SUCCESS; | ||
| 644 | -} | ||
| 645 | 202 | ||
| 646 | HcclResult GetOpParamResCtx( | 203 | HcclResult GetOpParamResCtx( |
| 647 | HcclComm comm, const std::string& algName, OpParam& opParam, TopoInfoWithNetLayerDetails* topoInfo, | 204 | HcclComm comm, const std::string& algName, OpParam& opParam, TopoInfoWithNetLayerDetails* topoInfo, |
| 648 | - void** resCtxOut) | 205 | + void** resCtxOut); |
| 649 | -{ | ||
| 650 | - bool useCannResCtx = UseCannBridge(opParam); | ||
| 651 | 206 | ||
| 652 | - std::unique_ptr<InsCollAlgBase> executor = nullptr; | 207 | +HcclResult GetCcuOpParamResCtx( |
| 653 | - if (useCannResCtx) { | 208 | + HcclComm comm, const std::string& algName, OpParam& opParam, TopoInfoWithNetLayerDetails* topoInfo, |
| 654 | - executor = GetAlgExecViaCann(opParam.opType, algName); | 209 | + OpResCtx& opResCtx, void** resCtxOut); |
| 655 | - } else { | ||
| 656 | - executor = CollAlgExecRegistryV2::Instance().GetAlgExec(opParam.opType, algName); | ||
| 657 | - } | ||
| 658 | - CHK_PRT_RET( | ||
| 659 | - executor.get() == nullptr, HCCL_ERROR("Fail to find executor for algName[%s]", algName.c_str()), HCCL_E_PARA); | ||
| 660 | - | ||
| 661 | - std::unique_ptr<AlgResourceCtxSerializable> resCtxHost = std::make_unique<AlgResourceCtxSerializable>(); | ||
| 662 | - resCtxHost->isHcommBatchTransferOnThreadSupported = HcommIsSupportHcommBatchTransferOnThread(); | ||
| 663 | - HCCL_DEBUG( | ||
| 664 | - "[MC2_BATCH_TRANSFER][HostSupport] opType[%u], algName[%s], supported[%d].", | ||
| 665 | - static_cast<uint32_t>(opParam.opType), algName.c_str(), | ||
| 666 | - static_cast<int>(resCtxHost->isHcommBatchTransferOnThreadSupported)); | ||
| 667 | - bool isResourceReused = false; | ||
| 668 | - | ||
| 669 | - ThreadHandle cpuTsThread{0}; | ||
| 670 | - ThreadHandle exportedAicpuTsThread{0}; | ||
| 671 | - if ((opParam.engine == COMM_ENGINE_AICPU_TS) || (opParam.engine == COMM_ENGINE_CPU)) { | ||
| 672 | - CHK_RET(HcclThreadAcquireWithStream(comm, COMM_ENGINE_CPU_TS, opParam.stream, 1, &cpuTsThread)); | ||
| 673 | - CHK_RET(HcclThreadExportToCommEngine(comm, 1, &cpuTsThread, COMM_ENGINE_AICPU_TS, &exportedAicpuTsThread)); | ||
| 674 | - } | ||
| 675 | - CHK_RET(HcclGetAlgRes(comm, opParam, executor, topoInfo, resCtxHost, resCtxOut, isResourceReused)); | ||
| 676 | - opParam.cacheValid = isResourceReused; | ||
| 677 | - opParam.resCtx = *resCtxOut; | ||
| 678 | - return HCCL_SUCCESS; | ||
| 679 | -} | ||
| 680 | 210 | ||
| 681 | HcclResult GetOpParam( | 211 | HcclResult GetOpParam( |
| 682 | - HcclComm comm, void* stream, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam) | 212 | + HcclComm comm, void* stream, const std::string& tag, const Mc2CcTilingInner* ccTiling, OpParam& opParam); |
| 683 | -{ | ||
| 684 | - CHK_RET(InitOpParamByTiling(comm, stream, tag, ccTiling, opParam)); | ||
| 685 | 213 | ||
| 686 | - // ALLTOALL场景下sendCounts需指向host侧真实数组,且必须在整个GetOpParam调用链 | 214 | +HcclResult CcuSelectAlgCheck(const Mc2CcTilingInner* ccTiling, uint32_t tilingIndex); |
| 687 | - // (含SelectAlgAndPrepareEngine、GetOpParamResCtx中的GetAlgExecViaCann)期间保持存活。 | ||
| 688 | - // 该数组持有在本函数栈帧,覆盖opParam的全部使用范围。 | ||
| 689 | - constexpr uint64_t ALLTOALL_DEFAULT_SEND_COUNTS = 200ULL * 1024 * 1024; | ||
| 690 | - std::vector<uint64_t> sendCounts; | ||
| 691 | - void* origSendCounts = opParam.all2AllVDataDes.sendCounts; | ||
| 692 | - if (opParam.opType == HcclCMDType::HCCL_CMD_ALLTOALL) { | ||
| 693 | - uint32_t userRankSize = 0; | ||
| 694 | - CHK_RET(HcclGetRankSize(comm, &userRankSize)); | ||
| 695 | - sendCounts.assign(userRankSize, ALLTOALL_DEFAULT_SEND_COUNTS); | ||
| 696 | - opParam.all2AllVDataDes.sendCounts = reinterpret_cast<void*>(sendCounts.data()); | ||
| 697 | - } | ||
| 698 | 215 | ||
| 699 | - std::string algName; | 216 | +// CCU路径逐算子:算法选择 + 资源准备(参照GetOpParam形式) |
| 700 | - std::unique_ptr<TopoInfoWithNetLayerDetails> topoInfo = std::make_unique<TopoInfoWithNetLayerDetails>(); | 217 | +HcclResult CcuSelectAlg( |
| 701 | - bool forcedAlgAccepted = false; | 218 | + HcclComm comm, void* stream, const std::string topoTag[], const void* ccTilingList[], uint32_t tilingNum, |
| 702 | - OpParam opParamBeforeAlg = opParam; | 219 | + void* mc2Tiling, OpResCtx& opResCtx); |
| 703 | - CHK_RET(TryForcedAlgAndPrepareEngine(comm, ccTiling, opParam, algName, topoInfo, forcedAlgAccepted)); | ||
| 704 | - if (!forcedAlgAccepted) { | ||
| 705 | - CHK_RET(SelectAlgAndPrepareEngine(comm, opParam, algName, topoInfo)); | ||
| 706 | - } | ||
| 707 | - CHK_RET(FillOpParamAlgName(opParam, algName)); | ||
| 708 | - | ||
| 709 | - bool skipGetRes = false; | ||
| 710 | - CHK_RET(HandleSingleRankAndCommMode(comm, opParam, skipGetRes)); | ||
| 711 | - if (skipGetRes) { | ||
| 712 | - opParam.all2AllVDataDes.sendCounts = origSendCounts; | ||
| 713 | - return HCCL_SUCCESS; | ||
| 714 | - } | ||
| 715 | - | ||
| 716 | - void* resCtxSequence = nullptr; | ||
| 717 | - HcclResult resRet = GetOpParamResCtx(comm, algName, opParam, topoInfo.get(), &resCtxSequence); | ||
| 718 | - if (resRet != HCCL_SUCCESS && forcedAlgAccepted && resCtxSequence == nullptr) { | ||
| 719 | - HCCL_WARNING( | ||
| 720 | - "[MC2_FORCE_ALG] fallback to default selector after resource failure, algName[%s], ret[%d].", | ||
| 721 | - algName.c_str(), static_cast<int>(resRet)); | ||
| 722 | - opParam = opParamBeforeAlg; | ||
| 723 | - algName.clear(); | ||
| 724 | - topoInfo = std::make_unique<TopoInfoWithNetLayerDetails>(); | ||
| 725 | - CHK_RET(SelectAlgAndPrepareEngine(comm, opParam, algName, topoInfo)); | ||
| 726 | - CHK_RET(FillOpParamAlgName(opParam, algName)); | ||
| 727 | - CHK_RET(HandleSingleRankAndCommMode(comm, opParam, skipGetRes)); | ||
| 728 | - if (skipGetRes) { | ||
| 729 | - opParam.all2AllVDataDes.sendCounts = origSendCounts; | ||
| 730 | - return HCCL_SUCCESS; | ||
| 731 | - } | ||
| 732 | - CHK_RET(GetOpParamResCtx(comm, algName, opParam, topoInfo.get(), &resCtxSequence)); | ||
| 733 | - } else { | ||
| 734 | - CHK_RET(resRet); | ||
| 735 | - } | ||
| 736 | - // GetOpParamResCtx执行结束,sendCounts的临时host数组已不再需要, | ||
| 737 | - // 将指向恢复为原值(大概率为nullptr),避免遗留指向本函数栈内vector的悬空指针。 | ||
| 738 | - opParam.all2AllVDataDes.sendCounts = origSendCounts; | ||
| 739 | - return HCCL_SUCCESS; | ||
| 740 | -} | ||
| 741 | 220 | ||
| 742 | 221 | ||
| @@ -15,6 +15,9 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 18 | 21 | ||
| 19 | using namespace mc2_ops_hccl; | 22 | using namespace mc2_ops_hccl; |
| 20 | 23 | ||
| @@ -188,14 +191,116 @@ HcclResult HcclCreateOpResCtx(HcclComm comm, uint8_t opType, void* opArgs, void* | |||
| 188 | return HCCL_SUCCESS; | 191 | return HCCL_SUCCESS; |
| 189 | } | 192 | } |
| 190 | 193 | ||
| 191 | -HcclResult __attribute__((visibility("default"))) HcclAllocComResourceByTiling( | 194 | +// 公共逻辑:构造topoTag/ctxTag并校验ccTiling参数 |
| 192 | - HcclComm comm, void* stream, void* mc2Tiling, void** opResCtx) | 195 | +HcclResult BuildTagsAndValidate( |
| 196 | + const void* ccTilingList[], uint32_t tilingNum, const char* commName, u32 rankSize, u32 userRank, | ||
| 197 | + std::string topoTag[], std::string& ctxTag) | ||
| 198 | +{ | ||
| 199 | + for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 200 | + const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 201 | + topoTag[i] = std::to_string(ccTiling->opType) + "_" + std::to_string(ccTiling->srcDataType) + "_" + | ||
| 202 | + std::string(commName); | ||
| 203 | + CHK_RET(HcclCheckTag(topoTag[i].c_str())); | ||
| 204 | + bool isReduce; | ||
| 205 | + CHK_RET(CheckIsReduce(ccTiling, &isReduce)); | ||
| 206 | + CHK_RET(CheckDataType(static_cast<HcclDataType>(ccTiling->srcDataType), isReduce)); | ||
| 207 | + | ||
| 208 | + if (i == 0) { | ||
| 209 | + ctxTag = std::string(ccTiling->groupName) + "_" + std::to_string(ccTiling->opType) + "_" + | ||
| 210 | + std::string(ccTiling->algConfig) + "_" + std::to_string(ccTiling->commEngine); | ||
| 211 | + } else { | ||
| 212 | + ctxTag += "_" + std::to_string(ccTiling->opType) + "_" + std::string(ccTiling->algConfig) + "_" + | ||
| 213 | + std::to_string(ccTiling->commEngine); | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + CHK_RET(HcomCheckUserRank(rankSize, userRank)); | ||
| 217 | + return HCCL_SUCCESS; | ||
| 218 | +} | ||
| 219 | + | ||
| 220 | +// AICPU引擎资源分配流程 | ||
| 221 | +HcclResult AllocComResourceByTilingAicpu( | ||
| 222 | + HcclComm comm, void* stream, void* mc2Tiling, const void* ccTilingList[], uint32_t tilingNum, const char* commName, | ||
| 223 | + u32 rankSize, u32 userRank, void** opResCtx, std::string& ctxTag) | ||
| 224 | +{ | ||
| 225 | + std::string topoTag[Hccl::MC2_MAX_OP_NUM]; | ||
| 226 | + CHK_RET(BuildTagsAndValidate(ccTilingList, tilingNum, commName, rankSize, userRank, topoTag, ctxTag)); | ||
| 227 | + | ||
| 228 | + std::vector<OpParam> opParamVec(tilingNum); | ||
| 229 | + for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 230 | + CHK_RET( | ||
| 231 | + GetOpParam(comm, stream, topoTag[i], static_cast<const Mc2CcTilingInner*>(ccTilingList[i]), opParamVec[i])); | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + CHK_RET(HcclAllocOpResCtx(comm, ctxTag, opParamVec, mc2Tiling, ccTilingList, opResCtx)); | ||
| 235 | + | ||
| 236 | + for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 237 | + const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 238 | + const OpParam& opParam = opParamVec[i]; | ||
| 239 | + const HcclDataType srcDataType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 240 | + const HcclDataType dstDataType = static_cast<HcclDataType>(ccTiling->dstDataType); | ||
| 241 | + const std::string srcDataTypeName = GetDataTypeEnumStr(srcDataType); | ||
| 242 | + const std::string dstDataTypeName = GetDataTypeEnumStr(dstDataType); | ||
| 243 | + HCCL_RUN_INFO( | ||
| 244 | + "[MC2_ALG_INFO] rank[%u], group[%s], opType[%s](%u), algName[%s], " | ||
| 245 | + "srcDataType[%s](%u), dstDataType[%s](%u), engine[%u].", | ||
| 246 | + userRank, ccTiling->groupName, GetMc2OpTypeName(opParam.opType), static_cast<uint32_t>(opParam.opType), | ||
| 247 | + opParam.algName, srcDataTypeName.c_str(), static_cast<uint32_t>(srcDataType), dstDataTypeName.c_str(), | ||
| 248 | + static_cast<uint32_t>(dstDataType), static_cast<uint32_t>(opParam.engine)); | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + return HCCL_SUCCESS; | ||
| 252 | +} | ||
| 253 | + | ||
| 254 | +// CCU引擎资源分配流程 | ||
| 255 | +HcclResult AllocComResourceByTilingCcu( | ||
| 256 | + HcclComm comm, void* stream, void* mc2Tiling, const void* ccTilingList[], uint32_t tilingNum, const char* commName, | ||
| 257 | + u32 rankSize, u32 userRank, void** opResCtx, std::string& ctxTag) | ||
| 258 | +{ | ||
| 259 | + HCCL_INFO("[AllocComResourceByTilingCcu]start AllocComResourceByTilingCcu!"); | ||
| 260 | + std::string topoTag[Hccl::MC2_MAX_OP_NUM]; | ||
| 261 | + CHK_RET(BuildTagsAndValidate(ccTilingList, tilingNum, commName, rankSize, userRank, topoTag, ctxTag)); | ||
| 262 | + HCCL_INFO("[AllocComResourceByTilingCcu]BuildTagsAndValidate successfully!"); | ||
| 263 | + | ||
| 264 | + // 构建 OpResCtx 基础字段(workspace、XN、CKE等) | ||
| 265 | + OpResCtx resCtx{}; | ||
| 266 | + CHK_RET(AllocCcuOpResCtx(comm, ctxTag, rankSize, userRank, resCtx)); | ||
| 267 | + HCCL_INFO("[AllocComResourceByTilingCcu]AllocCcuOpResCtx successfully!"); | ||
| 268 | + HCCL_INFO( | ||
| 269 | + "[AllocComResourceByTilingCcu]allocated: workspace[%p], size[%llu]", (void*)resCtx.workSpace, | ||
| 270 | + resCtx.workSpaceSize); | ||
| 271 | + | ||
| 272 | + // 逐算子选择算法 + 资源准备(executor->CalcRes + GetAlgResCcu) | ||
| 273 | + CHK_RET(CcuSelectAlg(comm, stream, topoTag, ccTilingList, tilingNum, mc2Tiling, resCtx)); | ||
| 274 | + HCCL_INFO("[AllocComResourceByTilingCcu]CcuSelectAlg successfully!"); | ||
| 275 | + | ||
| 276 | + // 申请OpResCtx硬件内存并写入 | ||
| 277 | + std::string tagOpResCtx = ctxTag + "_opResCtx"; | ||
| 278 | + uint64_t opResCtxSize = sizeof(OpResCtx); | ||
| 279 | + if (HcclEngineCtxGet(comm, tagOpResCtx.c_str(), COMM_ENGINE_AIV, opResCtx, &opResCtxSize) == HCCL_SUCCESS) { | ||
| 280 | + HCCL_INFO( | ||
| 281 | + "HcclEngineCtxGet success, tagOpResCtx[%s], opResCtxAddr[%p], opResCtxSize[%u]", tagOpResCtx.c_str(), | ||
| 282 | + *opResCtx, opResCtxSize); | ||
| 283 | + } else { | ||
| 284 | + CHK_RET(HcclEngineCtxCreate(comm, tagOpResCtx.c_str(), COMM_ENGINE_AIV, opResCtxSize, opResCtx)); | ||
| 285 | + } | ||
| 286 | + aclError aclRet = aclrtMemcpy(*opResCtx, opResCtxSize, &resCtx, opResCtxSize, ACL_MEMCPY_HOST_TO_DEVICE); | ||
| 287 | + HCCL_INFO( | ||
| 288 | + "[CCU_DEBUG] opResCtxPtr=%p, *opResCtx=%p, size=%llu ws=0x%llx wsSize=0x%llx xn=0x%llx cke=0x%llx rankId=%llu " | ||
| 289 | + "rankSize=%llu", | ||
| 290 | + opResCtx, *opResCtx, opResCtxSize, resCtx.workSpace, resCtx.workSpaceSize, resCtx.xnAddr, resCtx.ckeAddr, | ||
| 291 | + resCtx.rankId, resCtx.rankSize); | ||
| 292 | + CHK_RET(aclRet == ACL_ERROR_NONE ? HCCL_SUCCESS : HCCL_E_RUNTIME); | ||
| 293 | + HCCL_INFO("[AllocComResourceByTilingCcu]end AllocComResourceByTilingCcu!"); | ||
| 294 | + return HCCL_SUCCESS; | ||
| 295 | +} | ||
| 296 | + | ||
| 297 | +namespace { | ||
| 298 | +HcclResult HcclAllocComResourceByTilingImpl(HcclComm comm, void* stream, void* mc2Tiling, void** opResCtx) | ||
| 193 | { | 299 | { |
| 194 | HCCL_RUN_INFO( | 300 | HCCL_RUN_INFO( |
| 195 | - "[MC2_CLIENT_A5_AICPU] enter asc-devkit common HcclAllocComResourceByTiling, " | 301 | + "[MC2_CLIENT_A5] enter asc-devkit common HcclAllocComResourceByTiling, " |
| 196 | "comm[%p], stream[%p], tiling[%p].", | 302 | "comm[%p], stream[%p], tiling[%p].", |
| 197 | comm, stream, mc2Tiling); | 303 | comm, stream, mc2Tiling); |
| 198 | - HCCL_INFO("Start to run execute HcclAllocComResourceByTiling"); | ||
| 199 | // 记录开始时间,用于性能统计 | 304 | // 记录开始时间,用于性能统计 |
| 200 | HcclUs startut = TIME_NOW(); | 305 | HcclUs startut = TIME_NOW(); |
| 201 | // 获取设备类型 | 306 | // 获取设备类型 |
| @@ -227,78 +332,41 @@ HcclResult __attribute__((visibility("default"))) HcclAllocComResourceByTiling( | |||
| 227 | char commName[COMM_INDENTIFIER_MAX_LENGTH]; | 332 | char commName[COMM_INDENTIFIER_MAX_LENGTH]; |
| 228 | CHK_RET(HcclGetCommName(comm, commName)); | 333 | CHK_RET(HcclGetCommName(comm, commName)); |
| 229 | 334 | ||
| 230 | - const void* ccTilingList[MAX_CC_TILING_NUM]; | 335 | + const void* ccTilingList[Hccl::MC2_MAX_OP_NUM]; |
| 231 | uint32_t tilingNum; | 336 | uint32_t tilingNum; |
| 232 | CHK_RET(HcclGetTilingList(mc2Tiling, ccTilingList, tilingNum)); | 337 | CHK_RET(HcclGetTilingList(mc2Tiling, ccTilingList, tilingNum)); |
| 233 | 338 | ||
| 234 | // 校验commengine | 339 | // 校验commengine |
| 235 | - CHK_RET(CheckCommEngine(ccTilingList, tilingNum)); | 340 | + uint8_t commEngine; |
| 341 | + CHK_RET(ObtainCommEngine(ccTilingList, tilingNum, commEngine)); | ||
| 236 | 342 | ||
| 237 | - // 构造操作标签,用于日志、错误追踪、topo资源管理 | 343 | + // 根据commEngine类型分发到对应的资源分配流程 |
| 238 | - // topoTag = ccTilingList->opType + commName | ||
| 239 | - // ctxTag = ccTilingList->groupName + "_" + ccTilingList[0]->opType + "_" + ccTilingList[0]->algConfig + "_" + | ||
| 240 | - // ccTilingList[0]->commEngine | ||
| 241 | - // ctxTag不再统一管理资源,而是根据每个资源opParam、WorkSpace、OpResCtx继续组成tag申请资源 | ||
| 242 | - std::string topoTag[MAX_CC_TILING_NUM]; | ||
| 243 | std::string ctxTag; | 344 | std::string ctxTag; |
| 244 | - for (uint32_t i = 0U; i < tilingNum; ++i) { | 345 | + if (commEngine == static_cast<uint8_t>(OpExecuteConfig::AICPU_TS)) { |
| 245 | - const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | 346 | + HCCL_INFO("[HcclAllocComResourceByTiling]commEngine == AICPU_TS!"); |
| 246 | - topoTag[i] = std::to_string(ccTiling->opType) + "_" + std::to_string(ccTiling->srcDataType) + "_" + | 347 | + CHK_RET(AllocComResourceByTilingAicpu( |
| 247 | - std::string(commName); | 348 | + comm, stream, mc2Tiling, ccTilingList, tilingNum, commName, rankSize, userRank, opResCtx, ctxTag)); |
| 248 | - // 检查标签的合法性 | 349 | + } else if (commEngine == static_cast<uint8_t>(OpExecuteConfig::CCU_SCHED)) { |
| 249 | - CHK_RET(HcclCheckTag(topoTag[i].c_str())); | 350 | + HCCL_INFO("[HcclAllocComResourceByTiling]commEngine == CCU_SCHED!"); |
| 250 | - // 检查是否为reduce类型 | 351 | + CHK_RET(CheckCcuKfcFlow(mc2Tiling, ccTilingList, tilingNum)); |
| 251 | - bool isReduce; | 352 | + CHK_RET(AllocComResourceByTilingCcu( |
| 252 | - CHK_RET(CheckIsReduce(ccTiling, &isReduce)); | 353 | + comm, stream, mc2Tiling, ccTilingList, tilingNum, commName, rankSize, userRank, opResCtx, ctxTag)); |
| 253 | - // 检查数据类型的合法性 | 354 | + } else { |
| 254 | - CHK_RET(CheckDataType(static_cast<HcclDataType>(ccTiling->srcDataType), isReduce)); | 355 | + HCCL_ERROR("[%s] unsupported commEngine[%u]", __func__, commEngine); |
| 255 | - | 356 | + return HCCL_E_NOT_SUPPORT; |
| 256 | - if (i == 0) { | ||
| 257 | - ctxTag = std::string(ccTiling->groupName) + "_" + std::to_string(ccTiling->opType) + "_" + | ||
| 258 | - std::string(ccTiling->algConfig) + "_" + std::to_string(ccTiling->commEngine); | ||
| 259 | - } else { | ||
| 260 | - ctxTag += "_" + std::to_string(ccTiling->opType) + "_" + std::string(ccTiling->algConfig) + "_" + | ||
| 261 | - std::to_string(ccTiling->commEngine); | ||
| 262 | - } | ||
| 263 | } | 357 | } |
| 264 | 358 | ||
| 265 | - // TODO:记录接口入口日志,包含所有关键参数信息 | ||
| 266 | - | ||
| 267 | - // 检查userRank是否在有效范围内 | ||
| 268 | - CHK_RET(HcomCheckUserRank(rankSize, userRank)); | ||
| 269 | - | ||
| 270 | - std::vector<OpParam> opParamVec(tilingNum); | ||
| 271 | - for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 272 | - // TODO: 根据topoTag[i] 获取opParam[i]的参数 | ||
| 273 | - CHK_RET( | ||
| 274 | - GetOpParam(comm, stream, topoTag[i], static_cast<const Mc2CcTilingInner*>(ccTilingList[i]), opParamVec[i])); | ||
| 275 | - } | ||
| 276 | - | ||
| 277 | - // TODO: 根据ctxTag 申请通信资源 ,并返回OpResCtx的地址 | ||
| 278 | - CHK_RET(HcclAllocOpResCtx(comm, ctxTag, opParamVec, mc2Tiling, ccTilingList, opResCtx)); | ||
| 279 | - | ||
| 280 | // 记录退出日志和性能统计信息 | 359 | // 记录退出日志和性能统计信息 |
| 281 | CHK_RET(LogHcclExit("HcclAllocComResourceByTiling", ctxTag.c_str(), startut)); | 360 | CHK_RET(LogHcclExit("HcclAllocComResourceByTiling", ctxTag.c_str(), startut)); |
| 282 | - | ||
| 283 | - for (uint32_t i = 0U; i < tilingNum; ++i) { | ||
| 284 | - const Mc2CcTilingInner* ccTiling = static_cast<const Mc2CcTilingInner*>(ccTilingList[i]); | ||
| 285 | - const OpParam& opParam = opParamVec[i]; | ||
| 286 | - const HcclDataType srcDataType = static_cast<HcclDataType>(ccTiling->srcDataType); | ||
| 287 | - const HcclDataType dstDataType = static_cast<HcclDataType>(ccTiling->dstDataType); | ||
| 288 | - const std::string srcDataTypeName = GetDataTypeEnumStr(srcDataType); | ||
| 289 | - const std::string dstDataTypeName = GetDataTypeEnumStr(dstDataType); | ||
| 290 | - HCCL_RUN_INFO( | ||
| 291 | - "[MC2_ALG_INFO] rank[%u], group[%s], opType[%s](%u), algName[%s], " | ||
| 292 | - "srcDataType[%s](%u), dstDataType[%s](%u), engine[%u].", | ||
| 293 | - userRank, ccTiling->groupName, GetMc2OpTypeName(opParam.opType), static_cast<uint32_t>(opParam.opType), | ||
| 294 | - opParam.algName, srcDataTypeName.c_str(), static_cast<uint32_t>(srcDataType), dstDataTypeName.c_str(), | ||
| 295 | - static_cast<uint32_t>(dstDataType), static_cast<uint32_t>(opParam.engine)); | ||
| 296 | - } | ||
| 297 | - | ||
| 298 | - HCCL_INFO("End to run execute HcclAllocComResourceByTiling"); | ||
| 299 | - | ||
| 300 | return HCCL_SUCCESS; | 361 | return HCCL_SUCCESS; |
| 301 | } | 362 | } |
| 363 | +} // namespace | ||
| 364 | + | ||
| 365 | +HcclResult __attribute__((visibility("default"))) HcclAllocComResourceByTiling( | ||
| 366 | + HcclComm comm, void* stream, void* mc2Tiling, void** opResCtx) | ||
| 367 | +{ | ||
| 368 | + return HcclAllocComResourceByTilingImpl(comm, stream, mc2Tiling, opResCtx); | ||
| 369 | +} | ||
| 302 | 370 | ||
| 303 | extern "C" HcclResult __attribute__((visibility("default"))) HcclAllocComResourceByTilingA5Mc2( | 371 | extern "C" HcclResult __attribute__((visibility("default"))) HcclAllocComResourceByTilingA5Mc2( |
| 304 | HcclComm comm, void* stream, void* mc2Tiling, void** opResCtx) | 372 | HcclComm comm, void* stream, void* mc2Tiling, void** opResCtx) |
| @@ -307,5 +375,144 @@ extern "C" HcclResult __attribute__((visibility("default"))) HcclAllocComResourc | |||
| 307 | "[MC2_CLIENT_A5_AICPU] enter asc-devkit explicit A5 MC2 resource allocator, " | 375 | "[MC2_CLIENT_A5_AICPU] enter asc-devkit explicit A5 MC2 resource allocator, " |
| 308 | "comm[%p], stream[%p], tiling[%p].", | 376 | "comm[%p], stream[%p], tiling[%p].", |
| 309 | comm, stream, mc2Tiling); | 377 | comm, stream, mc2Tiling); |
| 310 | - return HcclAllocComResourceByTiling(comm, stream, mc2Tiling, opResCtx); | 378 | + return HcclAllocComResourceByTilingImpl(comm, stream, mc2Tiling, opResCtx); |
| 379 | +} | ||
| 380 | + | ||
| 381 | +namespace { | ||
| 382 | +CcuResult CopyOpResCtxToHost(void* opResCtx, OpResCtx& opResHost) | ||
| 383 | +{ | ||
| 384 | + HCCL_INFO("[CcuKernelLaunch]Obtain OpResCtx."); | ||
| 385 | + aclError aclRet = aclrtMemcpy(&opResHost, sizeof(OpResCtx), opResCtx, sizeof(OpResCtx), ACL_MEMCPY_DEVICE_TO_HOST); | ||
| 386 | + CHK_PRT_RET( | ||
| 387 | + aclRet != ACL_SUCCESS, | ||
| 388 | + HCCL_ERROR( | ||
| 389 | + "[CcuKernelLaunch] aclrtMemcpy D2H opResCtx failed, ret[%d], src[%p], size[%zu].", aclRet, opResCtx, | ||
| 390 | + sizeof(OpResCtx)), | ||
| 391 | + CCU_E_INTERNAL); | ||
| 392 | + CHK_PRT_RET( | ||
| 393 | + opResHost.algInfo[0].opParam == 0U, | ||
| 394 | + HCCL_ERROR("invalid ccu op resource ctx, opParam[%llu].", opResHost.algInfo[0].opParam), CCU_E_PARA); | ||
| 395 | + CHK_PRT_RET( | ||
| 396 | + opResHost.workSpace == 0U || opResHost.workSpaceSize == 0U, | ||
| 397 | + HCCL_ERROR( | ||
| 398 | + "invalid ccu op resource ctx, workSpace[%llu], workSpaceSize[%llu].", opResHost.workSpace, | ||
| 399 | + opResHost.workSpaceSize), | ||
| 400 | + CCU_E_PARA); | ||
| 401 | + return CCU_SUCCESS; | ||
| 402 | +} | ||
| 403 | + | ||
| 404 | +CcuResult CopyOpParamToHost(const OpResCtx& opResHost, OpParam& opParamHost) | ||
| 405 | +{ | ||
| 406 | + HCCL_INFO("[CcuKernelLaunch]Obtain OpParam."); | ||
| 407 | + void* opParamDev = reinterpret_cast<void*>(opResHost.algInfo[0].opParam); | ||
| 408 | + aclError aclRet = | ||
| 409 | + aclrtMemcpy(&opParamHost, sizeof(OpParam), opParamDev, sizeof(OpParam), ACL_MEMCPY_DEVICE_TO_HOST); | ||
| 410 | + CHK_PRT_RET( | ||
| 411 | + aclRet != ACL_SUCCESS, | ||
| 412 | + HCCL_ERROR( | ||
| 413 | + "[CcuKernelLaunch] aclrtMemcpy D2H OpParam failed, ret[%d], src[%p], size[%zu].", aclRet, opParamDev, | ||
| 414 | + sizeof(OpParam)), | ||
| 415 | + CCU_E_INTERNAL); | ||
| 416 | + CHK_PRT_RET( | ||
| 417 | + opParamHost.resCtx == nullptr || opParamHost.ctxSize == 0U, | ||
| 418 | + HCCL_ERROR("invalid ccu op resource ctx, resCtx[%p], ctxSize[%llu].", opParamHost.resCtx, opParamHost.ctxSize), | ||
| 419 | + CCU_E_PARA); | ||
| 420 | + return CCU_SUCCESS; | ||
| 421 | +} | ||
| 422 | + | ||
| 423 | +CcuResult LoadResourceCtx(const OpParam& opParamHost, AlgResourceCtxSerializable& resourceCtx) | ||
| 424 | +{ | ||
| 425 | + HCCL_INFO("[CcuKernelLaunch]Obtain resCtx."); | ||
| 426 | + auto* resCtx = static_cast<char*>(opParamHost.resCtx); | ||
| 427 | + std::vector<char> seq(opParamHost.ctxSize); | ||
| 428 | + HCCL_INFO("[CcuKernelLaunch]Start aclrtMemcpy D2H."); | ||
| 429 | + aclError aclRet = | ||
| 430 | + aclrtMemcpy(seq.data(), opParamHost.ctxSize, resCtx, opParamHost.ctxSize, ACL_MEMCPY_DEVICE_TO_HOST); | ||
| 431 | + CHK_PRT_RET( | ||
| 432 | + aclRet != ACL_SUCCESS, | ||
| 433 | + HCCL_ERROR( | ||
| 434 | + "[CcuKernelLaunch] aclrtMemcpy D2H failed, ret[%d], dst[%p], src[%p], size[%llu].", aclRet, seq.data(), | ||
| 435 | + resCtx, opParamHost.ctxSize), | ||
| 436 | + CCU_E_INTERNAL); | ||
| 437 | + HCCL_INFO("[CcuKernelLaunch]Start resourceCtx DeSerialize."); | ||
| 438 | + resourceCtx.DeSerialize(seq); | ||
| 439 | + return CCU_SUCCESS; | ||
| 440 | +} | ||
| 441 | + | ||
| 442 | +CcuResult GetLaunchHandles( | ||
| 443 | + const AlgResourceCtxSerializable& resourceCtx, ThreadHandle& threadHandle, CcuKernelHandle& kernelHandle) | ||
| 444 | +{ | ||
| 445 | + CHK_PRT_RET(resourceCtx.threads.empty(), HCCL_ERROR("empty ccu threads"), CCU_E_PARA); | ||
| 446 | + CHK_PRT_RET(resourceCtx.ccuKernels.empty(), HCCL_ERROR("empty ccu kernels"), CCU_E_PARA); | ||
| 447 | + | ||
| 448 | + threadHandle = resourceCtx.threads[0]; | ||
| 449 | + CHK_PRT_RET(threadHandle == 0, HCCL_ERROR("invalid threadHandle"), CCU_E_PARA); | ||
| 450 | + | ||
| 451 | + // HcclGetCcuKernel 已根据 isKfc 过滤,isKfc=true 时 ccuKernels[0] 即为 CcuKfcServerKernel | ||
| 452 | + kernelHandle = resourceCtx.ccuKernels[0]; | ||
| 453 | + CHK_PRT_RET(kernelHandle == 0, HCCL_ERROR("invalid kernelHandle"), CCU_E_PARA); | ||
| 454 | + CHK_PRT_RET( | ||
| 455 | + resourceCtx.kfcServerArgSize != 0U && resourceCtx.kfcServerArgs.empty(), | ||
| 456 | + HCCL_ERROR("invalid kfcServerArgs, kfcServerArgSize[%u].", resourceCtx.kfcServerArgSize), CCU_E_PTR); | ||
| 457 | + return CCU_SUCCESS; | ||
| 458 | +} | ||
| 459 | + | ||
| 460 | +void LogKernelLaunchArgs( | ||
| 461 | + const AlgResourceCtxSerializable& resourceCtx, ThreadHandle threadHandle, CcuKernelHandle kernelHandle) | ||
| 462 | +{ | ||
| 463 | + if (resourceCtx.kfcServerArgs.size() >= 6U) { | ||
| 464 | + HCCL_INFO( | ||
| 465 | + "[CcuKernelLaunch] HcommCcuKernelLaunch args: " | ||
| 466 | + "threadHandle[0x%llx], kernelHandle[0x%llx], argSize[%u], " | ||
| 467 | + "xnAddr[0x%llx], ckeAddr[0x%llx], dieNum[%llu], missionNum[%llu], " | ||
| 468 | + "missionIndex[%llu], token[%llu]", | ||
| 469 | + static_cast<unsigned long long>(threadHandle), static_cast<unsigned long long>(kernelHandle), | ||
| 470 | + resourceCtx.kfcServerArgSize, static_cast<unsigned long long>(resourceCtx.kfcServerArgs[0]), | ||
| 471 | + static_cast<unsigned long long>(resourceCtx.kfcServerArgs[1]), | ||
| 472 | + static_cast<unsigned long long>(resourceCtx.kfcServerArgs[2]), | ||
| 473 | + static_cast<unsigned long long>(resourceCtx.kfcServerArgs[3]), | ||
| 474 | + static_cast<unsigned long long>(resourceCtx.kfcServerArgs[4]), | ||
| 475 | + static_cast<unsigned long long>(resourceCtx.kfcServerArgs[5])); | ||
| 476 | + } else { | ||
| 477 | + HCCL_INFO( | ||
| 478 | + "[CcuKernelLaunch] HcommCcuKernelLaunch args: " | ||
| 479 | + "threadHandle[0x%llx], kernelHandle[0x%llx], argSize[%u], kfcServerArgsSize[%zu]", | ||
| 480 | + static_cast<unsigned long long>(threadHandle), static_cast<unsigned long long>(kernelHandle), | ||
| 481 | + resourceCtx.kfcServerArgSize, resourceCtx.kfcServerArgs.size()); | ||
| 482 | + } | ||
| 483 | +} | ||
| 484 | +} // namespace | ||
| 485 | + | ||
| 486 | +CcuResult CcuKernelLaunch(HcclComm comm, void* opResCtx) | ||
| 487 | +{ | ||
| 488 | + CHK_PRT_RET(comm == nullptr, HCCL_ERROR("[%s] comm is nullptr.", __func__), CCU_E_PTR); | ||
| 489 | + CHK_PRT_RET(opResCtx == nullptr, HCCL_ERROR("[%s] opResCtx is nullptr.", __func__), CCU_E_PTR); | ||
| 490 | + | ||
| 491 | + // HcclEngineCtxCreate分配的OpResCtx、OpParam和序列化资源均位于device,需逐层拷贝到host。 | ||
| 492 | + OpResCtx opResHost{}; | ||
| 493 | + CcuResult ret = CopyOpResCtxToHost(opResCtx, opResHost); | ||
| 494 | + if (ret != CCU_SUCCESS) { | ||
| 495 | + return ret; | ||
| 496 | + } | ||
| 497 | + OpParam opParamHost{}; | ||
| 498 | + ret = CopyOpParamToHost(opResHost, opParamHost); | ||
| 499 | + if (ret != CCU_SUCCESS) { | ||
| 500 | + return ret; | ||
| 501 | + } | ||
| 502 | + AlgResourceCtxSerializable resourceCtx; | ||
| 503 | + ret = LoadResourceCtx(opParamHost, resourceCtx); | ||
| 504 | + if (ret != CCU_SUCCESS) { | ||
| 505 | + return ret; | ||
| 506 | + } | ||
| 507 | + ThreadHandle threadHandle = 0; | ||
| 508 | + CcuKernelHandle kernelHandle = 0; | ||
| 509 | + ret = GetLaunchHandles(resourceCtx, threadHandle, kernelHandle); | ||
| 510 | + if (ret != CCU_SUCCESS) { | ||
| 511 | + return ret; | ||
| 512 | + } | ||
| 513 | + LogKernelLaunchArgs(resourceCtx, threadHandle, kernelHandle); | ||
| 514 | + HCCL_INFO("[CcuKernelLaunch]Start HcommCcuKernelLaunch."); | ||
| 515 | + const void* kfcArgs = | ||
| 516 | + resourceCtx.kfcServerArgs.empty() ? nullptr : static_cast<const void*>(resourceCtx.kfcServerArgs.data()); | ||
| 517 | + return HcommCcuKernelLaunch(threadHandle, kernelHandle, kfcArgs, resourceCtx.kfcServerArgSize); | ||
| 311 | } | 518 | } |
| @@ -12,10 +12,17 @@ if(BUILD_OPEN_PROJECT) | |||
| 12 | ${HCCL_LOCAL_HEADER_DIRS} | 12 | ${HCCL_LOCAL_HEADER_DIRS} |
| 13 | ${HCCL_CC_INCLUDE_DIR}/hcomm | 13 | ${HCCL_CC_INCLUDE_DIR}/hcomm |
| 14 | ${HCCL_CC_INCLUDE_DIR}/hcomm/hccl | 14 | ${HCCL_CC_INCLUDE_DIR}/hcomm/hccl |
| 15 | + ${HCCL_CC_INCLUDE_DIR}/hcomm/ccu | ||
| 15 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc/hccl | 16 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc/hccl |
| 17 | + ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc/hcomm/ccu | ||
| 16 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc | 18 | ${HCCL_CC_INCLUDE_DIR}/hcomm/pkg_inc |
| 17 | ${CMAKE_CURRENT_SOURCE_DIR}/.. | 19 | ${CMAKE_CURRENT_SOURCE_DIR}/.. |
| 20 | + ${CMAKE_CURRENT_SOURCE_DIR}/ccu | ||
| 18 | 21 | ||
| 22 | + # hcomm头文件 | ||
| 23 | + ${ASCEND_CANN_PACKAGE_PATH}/include/ccu | ||
| 24 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm | ||
| 25 | + ${ASCEND_CANN_PACKAGE_PATH}/include/hcomm/ccu | ||
| 19 | ) | 26 | ) |
| 20 | else() | 27 | else() |
| 21 | set(INCLUDE_LIST | 28 | set(INCLUDE_LIST |
| @@ -53,6 +60,7 @@ else() | |||
| 53 | ${TOP_DIR}/hcomm/inc/hccl | 60 | ${TOP_DIR}/hcomm/inc/hccl |
| 54 | ${TOP_DIR}/hcomm/pkg_inc | 61 | ${TOP_DIR}/hcomm/pkg_inc |
| 55 | ${TOP_DIR}/hcomm/pkg_inc/hccl | 62 | ${TOP_DIR}/hcomm/pkg_inc/hccl |
| 63 | + ${TOP_DIR}/hcomm/ccu | ||
| 56 | ${TOP_DIR}/hcomm/pkg_inc/hcomm/ccu | 64 | ${TOP_DIR}/hcomm/pkg_inc/hcomm/ccu |
| 57 | ${TOP_DIR}/hcomm/include | 65 | ${TOP_DIR}/hcomm/include |
| 58 | ${TOP_DIR}/hcomm/include/hccl | 66 | ${TOP_DIR}/hcomm/include/hccl |
| @@ -124,6 +132,12 @@ if(PRODUCT_SIDE STREQUAL "host") | |||
| 124 | hcomm_dlsym.cc | 132 | hcomm_dlsym.cc |
| 125 | hccl_inner_dl.cc | 133 | hccl_inner_dl.cc |
| 126 | hcomm_host_profiling_dl.cc | 134 | hcomm_host_profiling_dl.cc |
| 135 | + ccu_primitives_impl_dl.cc | ||
| 136 | + ccu_res_dl.cc | ||
| 137 | + hccl_ccu_res_dl.cc | ||
| 138 | + hccl_res_expt_dl.cc | ||
| 139 | + hccl_host_comm_dl.cc | ||
| 140 | + ccu_launch_dl.cc | ||
| 127 | ) | 141 | ) |
| 128 | endif() | 142 | endif() |
| 129 | 143 | ||
| @@ -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 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +namespace AscendC { | ||
| 26 | +namespace ccu { | ||
| 27 | + | ||
| 28 | +class LocalAddr; | ||
| 29 | +class RemoteAddr; | ||
| 30 | +template <typename U> | ||
| 31 | +class Array; | ||
| 32 | + | ||
| 33 | +class Address final { | ||
| 34 | +public: | ||
| 35 | + Address() { CCU_THROW_IF_FAILED(CcuAddressAlloc(&this->handle), "CcuAddressAlloc: failed"); } | ||
| 36 | + | ||
| 37 | + Address(const Address& other) { this->handle = other.handle; } | ||
| 38 | + | ||
| 39 | + Address(Address&& other) noexcept { this->handle = other.handle; } | ||
| 40 | + | ||
| 41 | + void operator=(const Address& other) const | ||
| 42 | + { | ||
| 43 | + CCU_THROW_IF_FAILED( | ||
| 44 | + CcuAddressAssignAddr(this->handle, other.handle), | ||
| 45 | + "Address::operator=(Address): CcuAddressAssignAddr failed"); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + void operator=(Address&& other) { this->handle = other.handle; } | ||
| 49 | + | ||
| 50 | + void operator=(uint64_t immediate) const | ||
| 51 | + { | ||
| 52 | + CCU_THROW_IF_FAILED( | ||
| 53 | + CcuAddressAssignImm(this->handle, immediate), "Address::operator=(uint64_t): CcuAddressAssignImm failed"); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + void operator=(const Variable& var) const | ||
| 57 | + { | ||
| 58 | + CCU_THROW_IF_FAILED( | ||
| 59 | + CcuAddressAssignVar(this->handle, var.handle), "Address::operator=(Variable): CcuAddressAssignVar failed"); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + void operator=(detail::CcuArithmeticOperator<Address, Address> op) const | ||
| 63 | + { | ||
| 64 | + CCU_THROW_IF_FAILED( | ||
| 65 | + CcuAddressAddAddrToAddr(this->handle, op.lhs.handle, op.rhs.handle), | ||
| 66 | + "Address::operator=(Addr+Addr): CcuAddressAddAddrToAddr failed"); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + void operator=(detail::CcuArithmeticOperator<Address, Variable> op) const | ||
| 70 | + { | ||
| 71 | + CCU_THROW_IF_FAILED( | ||
| 72 | + CcuAddressAddVarToAddr(this->handle, op.lhs.handle, op.rhs.handle), | ||
| 73 | + "Address::operator=(Addr+Var): CcuAddressAddVarToAddr failed"); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + void operator=(detail::CcuArithmeticOperator<Variable, Address> op) const | ||
| 77 | + { | ||
| 78 | + CCU_THROW_IF_FAILED( | ||
| 79 | + CcuAddressAddVarToAddr(this->handle, op.rhs.handle, op.lhs.handle), | ||
| 80 | + "Address::operator=(Var+Addr): CcuAddressAddVarToAddr failed"); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + // addr + addr | ||
| 84 | + detail::CcuArithmeticOperator<Address, Address> operator+(const Address& that) const | ||
| 85 | + { | ||
| 86 | + return detail::CcuArithmeticOperator<Address, Address>( | ||
| 87 | + *this, that, detail::CcuArithmeticOperatorType::ADDITION); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + // addr + variable | ||
| 91 | + detail::CcuArithmeticOperator<Address, Variable> operator+(const Variable& var) const | ||
| 92 | + { | ||
| 93 | + return detail::CcuArithmeticOperator<Address, Variable>( | ||
| 94 | + *this, var, detail::CcuArithmeticOperatorType::ADDITION); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + void operator+=(const Variable& var) const | ||
| 98 | + { | ||
| 99 | + CCU_THROW_IF_FAILED( | ||
| 100 | + CcuAddressAddAssignVar(this->handle, var.handle), | ||
| 101 | + "Address::operator+=(Variable): CcuAddressAddAssignVar failed"); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + // addr += addr | ||
| 105 | + void operator+=(const Address& other) const | ||
| 106 | + { | ||
| 107 | + CCU_THROW_IF_FAILED( | ||
| 108 | + CcuAddressAddAddrToAddr(this->handle, this->handle, other.handle), | ||
| 109 | + "Address::operator+=(Address): CcuAddressAddAddrToAddr failed"); | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + CcuAddressHandle handle{0}; | ||
| 113 | + | ||
| 114 | +private: | ||
| 115 | + explicit Address(detail::NoAllocTag) {} | ||
| 116 | + template <typename U> | ||
| 117 | + friend class Array; | ||
| 118 | + friend class LocalAddr; | ||
| 119 | + friend class RemoteAddr; | ||
| 120 | +}; | ||
| 121 | + | ||
| 122 | +// variable + addr(交换律) | ||
| 123 | +inline detail::CcuArithmeticOperator<Variable, Address> operator+(const Variable& var, const Address& addr) | ||
| 124 | +{ | ||
| 125 | + return detail::CcuArithmeticOperator<Variable, Address>(var, addr, detail::CcuArithmeticOperatorType::ADDITION); | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +} // namespace ccu | ||
| 129 | +} // namespace AscendC | ||
| 130 | + | ||
| 131 | +template <> | ||
| 132 | +inline void AscendC::ccu::detail::CcuArithmeticOperator<AscendC::ccu::Address, AscendC::ccu::Address>::Check() const | ||
| 133 | +{} | ||
| 134 | +template <> | ||
| 135 | +inline void AscendC::ccu::detail::CcuArithmeticOperator<AscendC::ccu::Address, AscendC::ccu::Variable>::Check() const | ||
| 136 | +{} | ||
| 137 | +template <> | ||
| 138 | +inline void AscendC::ccu::detail::CcuArithmeticOperator<AscendC::ccu::Variable, AscendC::ccu::Address>::Check() const | ||
| 139 | +{} | ||
| 140 | + | ||
| 141 | + | ||
| 142 | + | ||
| @@ -0,0 +1,136 @@ | |||
| 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 | +namespace AscendC { | ||
| 29 | +namespace ccu { | ||
| 30 | + | ||
| 31 | +// 主模板未实现:未特化的资源类型实例化 Array<T> 时编译失败, | ||
| 32 | +// 当前期次仅 Variable / Event / Buffer 提供底层 CcuBlock*Alloc C 接口。 | ||
| 33 | +template <typename T> | ||
| 34 | +struct CcuArrayTraits; | ||
| 35 | + | ||
| 36 | +template <> | ||
| 37 | +struct CcuArrayTraits<Variable> { | ||
| 38 | + using Handle = CcuVariableHandle; | ||
| 39 | + static CcuResult BlockAlloc(Handle* h, uint32_t n) { return CcuBlockVariableAlloc(h, n); } | ||
| 40 | + static void SetHandle(Variable& v, Handle h) { v.handle = h; } | ||
| 41 | +}; | ||
| 42 | + | ||
| 43 | +template <> | ||
| 44 | +struct CcuArrayTraits<Event> { | ||
| 45 | + using Handle = CcuEventHandle; | ||
| 46 | + static CcuResult BlockAlloc(Handle* h, uint32_t n) { return CcuBlockEventAlloc(h, n); } | ||
| 47 | + static void SetHandle(Event& e, Handle h) { e.handle = h; } | ||
| 48 | +}; | ||
| 49 | + | ||
| 50 | +template <> | ||
| 51 | +struct CcuArrayTraits<CcuBuffer> { | ||
| 52 | + using Handle = CcuBufferHandle; | ||
| 53 | + static CcuResult BlockAlloc(Handle* h, uint32_t n) { return CcuBlockBufferAlloc(h, n); } | ||
| 54 | + static void SetHandle(CcuBuffer& b, Handle h) { b.handle = h; } | ||
| 55 | +}; | ||
| 56 | + | ||
| 57 | +// 连续资源容器:在构造时一次性 BlockAlloc 出 count 个底层句柄并填充给占位元素。 | ||
| 58 | +// 元素本身通过 NoAllocTag 私有构造跳过单元 Alloc,避免与 BlockAlloc 双重分配。 | ||
| 59 | +template <typename T> | ||
| 60 | +class Array final { | ||
| 61 | +public: | ||
| 62 | + explicit Array(uint32_t count) : count_(count) | ||
| 63 | + { | ||
| 64 | + if (count == 0) { | ||
| 65 | + return; | ||
| 66 | + } | ||
| 67 | + using H = typename CcuArrayTraits<T>::Handle; | ||
| 68 | + std::vector<H> handles(count); | ||
| 69 | + elems_ = static_cast<T*>(::operator new(sizeof(T) * count)); | ||
| 70 | + for (uint32_t i = 0; i < count; ++i) { | ||
| 71 | + ::new (static_cast<void*>(&elems_[i])) T(detail::NoAllocTag{}); | ||
| 72 | + } | ||
| 73 | + auto ret = CcuArrayTraits<T>::BlockAlloc(handles.data(), count); | ||
| 74 | + if (ret != CcuResult::CCU_SUCCESS) { | ||
| 75 | + for (uint32_t i = 0; i < count; ++i) { | ||
| 76 | + elems_[i].~T(); | ||
| 77 | + } | ||
| 78 | + ::operator delete(elems_); | ||
| 79 | + elems_ = nullptr; | ||
| 80 | + count_ = 0; | ||
| 81 | + throw ::AscendC::ccu::detail::CcuException(ret, "Array BlockAlloc: failed"); | ||
| 82 | + } | ||
| 83 | + for (uint32_t i = 0; i < count; ++i) { | ||
| 84 | + CcuArrayTraits<T>::SetHandle(elems_[i], handles[i]); | ||
| 85 | + } | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + ~Array() | ||
| 89 | + { | ||
| 90 | + if (elems_ == nullptr) { | ||
| 91 | + return; | ||
| 92 | + } | ||
| 93 | + for (uint32_t i = 0; i < count_; ++i) { | ||
| 94 | + elems_[i].~T(); | ||
| 95 | + } | ||
| 96 | + ::operator delete(elems_); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + Array(const Array&) = delete; | ||
| 100 | + Array& operator=(const Array&) = delete; | ||
| 101 | + | ||
| 102 | + Array(Array&& other) noexcept : elems_(other.elems_), count_(other.count_) | ||
| 103 | + { | ||
| 104 | + other.elems_ = nullptr; | ||
| 105 | + other.count_ = 0; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + Array& operator=(Array&& other) noexcept | ||
| 109 | + { | ||
| 110 | + if (this != &other) { | ||
| 111 | + this->~Array(); | ||
| 112 | + elems_ = other.elems_; | ||
| 113 | + count_ = other.count_; | ||
| 114 | + other.elems_ = nullptr; | ||
| 115 | + other.count_ = 0; | ||
| 116 | + } | ||
| 117 | + return *this; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + T& operator[](uint32_t i) { return elems_[i]; } | ||
| 121 | + const T& operator[](uint32_t i) const { return elems_[i]; } | ||
| 122 | + T* data() { return elems_; } | ||
| 123 | + const T* data() const { return elems_; } | ||
| 124 | + uint32_t size() const { return count_; } | ||
| 125 | + | ||
| 126 | +private: | ||
| 127 | + T* elems_{nullptr}; | ||
| 128 | + uint32_t count_{0}; | ||
| 129 | +}; | ||
| 130 | + | ||
| 131 | +} // namespace ccu | ||
| 132 | +} // namespace AscendC | ||
| 133 | + | ||
| 134 | + | ||
| 135 | + | ||
| 136 | + | ||
| @@ -0,0 +1,52 @@ | |||
| 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 | +namespace AscendC { | ||
| 24 | +namespace ccu { | ||
| 25 | + | ||
| 26 | +template <typename U> | ||
| 27 | +class Array; | ||
| 28 | + | ||
| 29 | +class CcuBuffer final { | ||
| 30 | +public: | ||
| 31 | + CcuBuffer() { CCU_THROW_IF_FAILED(CcuBufferAlloc(&this->handle), "CcuBufferAlloc: failed"); } | ||
| 32 | + | ||
| 33 | + CcuBuffer(const CcuBuffer& other) { this->handle = other.handle; } | ||
| 34 | + | ||
| 35 | + CcuBuffer(CcuBuffer&& other) noexcept { this->handle = other.handle; } | ||
| 36 | + | ||
| 37 | + void operator=(CcuBuffer&& other) { this->handle = other.handle; } | ||
| 38 | + | ||
| 39 | + CcuBufferHandle handle{0}; | ||
| 40 | + | ||
| 41 | +private: | ||
| 42 | + explicit CcuBuffer(detail::NoAllocTag) {} | ||
| 43 | + template <typename U> | ||
| 44 | + friend class Array; | ||
| 45 | +}; | ||
| 46 | + | ||
| 47 | +} // namespace ccu | ||
| 48 | +} // namespace AscendC | ||
| 49 | + | ||
| 50 | + | ||
| 51 | + | ||
| 52 | + | ||
| @@ -0,0 +1,77 @@ | |||
| 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 | + | ||
| 31 | + | ||
| 32 | + for (::AscendC::ccu::CondExpr uid##_ce = (expr), *uid##_p = &uid##_ce; uid##_p != nullptr; uid##_p = nullptr) \ | ||
| 33 | + for (const char *uid##_dwLbl = _CcuDoWhileStackPopForWhile(), *uid##_sen = (const char*)1; \ | ||
| 34 | + uid##_sen != nullptr; uid##_sen = nullptr) \ | ||
| 35 | + for (int uid##_rc = \ | ||
| 36 | + (uid##_dwLbl != nullptr) ? \ | ||
| 37 | + (int)CCU_SUCCESS : \ | ||
| 38 | + (int)CcuWhileBegin(uid##_ce.var->handle, uid##_ce.imm, uid##_ce.cond, CCU_LABEL(uid)), \ | ||
| 39 | + uid##_done = 0; \ | ||
| 40 | + uid##_rc == (int)CCU_SUCCESS && !uid##_done; \ | ||
| 41 | + uid##_done = 1, uid##_rc = (uid##_dwLbl != nullptr) ? \ | ||
| 42 | + (int)CcuDoWhileEnd( \ | ||
| 43 | + uid##_ce.var->handle, uid##_ce.imm, uid##_ce.cond, uid##_dwLbl) : \ | ||
| 44 | + (int)CcuWhileEnd(CCU_LABEL(uid))) | ||
| 45 | + | ||
| 46 | + | ||
| 47 | + | ||
| 48 | + | ||
| 49 | + | ||
| 50 | + | ||
| 51 | + for (::AscendC::ccu::CondExpr uid##_ce = (expr), *uid##_p = &uid##_ce; uid##_p != nullptr; uid##_p = nullptr) \ | ||
| 52 | + for (int uid##_rc = (int)CcuIfBegin(uid##_ce.var->handle, uid##_ce.imm, uid##_ce.cond, CCU_LABEL(uid)), \ | ||
| 53 | + uid##_done = (_CcuIfStackPush(CCU_LABEL(uid)), 0); \ | ||
| 54 | + uid##_rc == (int)CCU_SUCCESS && uid##_done == 0; \ | ||
| 55 | + uid##_done = 1, ((void)CcuFlushPendingIfs(), _CcuIfStackMarkBodyDone(), (void)0)) | ||
| 56 | + | ||
| 57 | + | ||
| 58 | + | ||
| 59 | + | ||
| 60 | + | ||
| 61 | + | ||
| 62 | + for (const char *uid##_lbl = _CcuIfStackPopForElse(), *uid##_sen = uid##_lbl; uid##_sen != nullptr; \ | ||
| 63 | + uid##_sen = nullptr) \ | ||
| 64 | + for (int uid##_rc = (int)CcuIfElse(uid##_lbl), uid##_done = 0; uid##_rc == (int)CCU_SUCCESS && !uid##_done; \ | ||
| 65 | + uid##_done = 1, uid##_rc = (int)CcuIfEnd(uid##_lbl)) | ||
| 66 | + | ||
| 67 | + | ||
| 68 | + | ||
| 69 | + | ||
| 70 | + | ||
| 71 | + | ||
| 72 | + for (int uid##_rc = (int)CcuDoWhileBegin(CCU_LABEL(uid)), uid##_done = 0; \ | ||
| 73 | + uid##_rc == (int)CCU_SUCCESS && !uid##_done; uid##_done = 1, _CcuDoWhileStackPush(CCU_LABEL(uid))) | ||
| 74 | + | ||
| 75 | + | ||
| 76 | + | ||
| 77 | + | ||
| @@ -0,0 +1,55 @@ | |||
| 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 | +namespace AscendC { | ||
| 25 | +namespace ccu { | ||
| 26 | + | ||
| 27 | +template <typename U> | ||
| 28 | +class Array; | ||
| 29 | + | ||
| 30 | +// Event 退化为纯 handle 持有者:mask 已与 Event 解耦, | ||
| 31 | +// 由调用方在每个 EventRecord/Wait/LocalCopy/Read/Write/... API 上独立传入。 | ||
| 32 | +// 旧的 EventMask 代理类、Event::mask 字段、Event::setMask 接口已废弃删除。 | ||
| 33 | +class Event final { | ||
| 34 | +public: | ||
| 35 | + Event() { CCU_THROW_IF_FAILED(CcuEventAlloc(&this->handle), "CcuEventAlloc: failed"); } | ||
| 36 | + | ||
| 37 | + Event(const Event& other) : handle(other.handle) {} | ||
| 38 | + | ||
| 39 | + Event(Event&& other) noexcept : handle(other.handle) {} | ||
| 40 | + | ||
| 41 | + void operator=(Event&& other) { this->handle = other.handle; } | ||
| 42 | + | ||
| 43 | + CcuEventHandle handle{0}; | ||
| 44 | + | ||
| 45 | +private: | ||
| 46 | + explicit Event(detail::NoAllocTag) {} | ||
| 47 | + template <typename U> | ||
| 48 | + friend class Array; | ||
| 49 | +}; | ||
| 50 | + | ||
| 51 | +} // namespace ccu | ||
| 52 | +} // namespace AscendC | ||
| 53 | + | ||
| 54 | + | ||
| 55 | + | ||