选择分支名或 Tag 名,也可以输入一个 commit 的 ID,点击对比按钮。
| ... | @@ -1,22 +1,47 @@ |
| 2 | ## 描述 |
| 3 | <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> |
| 4 | |
| 5 | +## 变更类型 |
| 6 | +请选择本次引入的变更类型: |
| 7 | +<!-- [x] 表示选中 --> |
| 8 | +- [ ] 🐛 Bug修复 |
| 9 | +- [ ] ✨ 新特性 |
| 10 | +- [ ] 🚀 性能优化 |
| 11 | +- [ ] 📝 文档更新 |
| 12 | +- [ ] 📋 其他,请描述: |
| 13 | + |
| 14 | ## 关联的Issue |
| 15 | <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。--> |
| 16 | <!-- 如果这个PR不涉及Issue,可填写"NA"。--> |
| 17 | |
| 18 | ## 测试 |
| 19 | <!--描述进行了哪些测试来验证你的改动。包括但不限于构造对应xx测试用例、二级冒烟、算子泛化等。--> |
| 20 | +已完成的测试用例和场景: |
| 21 | +1. |
| 22 | +2. |
| 23 | + |
| 24 | +补充的UT用例: |
| 25 | |
| 26 | ## 文档更新 |
| 27 | <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> |
| 28 | |
| 29 | -## 类型标签 |
| 30 | +## 合入检查 |
| 31 | +<!-- 在正式合入前,请做好必要的代码测试,用例补充,软件代码风格检查等。提高合入效率。--> |
| 32 | <!-- [x] 表示选中 --> |
| 33 | -- [ ] Bug修复 |
| 34 | -- [ ] 新特性 |
| 35 | -- [ ] 性能优化 |
| 36 | -- [ ] 文档更新 |
| 37 | -- [ ] 其他,请描述: |
| 38 | - |
| 39 | - |
| 40 | +- [ ] 🧐 已经详细阅读了贡献指南(CONTRIBUTING.md),并遵守了其中的所有规定,包括但不限于commit message的格式、无效commit的合并等 |
| 41 | +- [ ] 🔍 邀请 committer评论`/lgtm`前的必要检查 |
| 42 | + - [ ] 🏷️ 标题中使用了合适的类型标签(如:`[feat]`, `[fix]`) |
| 43 | + - [ ] 📄 代码修改内容已简要描述,相关文档已更新 |
| 44 | + - [ ] 📝 代码注释已更新,代码遵循项目整体代码风格 |
| 45 | + - [ ] 🧪 代码UT测试已更新,覆盖率已达标 |
| 46 | + - [ ] 🔬 验证方法已更新到"测试"部分 |
| 47 | + - [ ] 🛠️ 代码已通过静态分析工具检查,无错误 |
| 48 | + - [ ] 👥 代码检视/code review/同行评议和必要的代码串讲,确保代码质量 |
| 49 | + - [ ] ✅ 代码检视意见已处理或答复,无未处理的检视意见 |
| 50 | +- [ ] 🚀 预约 前冒烟 用例前的必要检查 |
| 51 | + - [ ] ✔️ 代码已有committer的`/lgtm` 和 模块committer的`/lgtm`评论 |
| 52 | + - [ ] 🔧 代码已通过compile,编译无错误,无告警 |
| 53 | + - [ ] 🖥️ 代码已通过基本功能本地测试或者在线测试,确保基本功能正常 |
| 54 | +- [ ] 🎯 预约 approver评论`/approve`,正式合入前的必要检查 |
| 55 | + - [ ] 📊 前冒烟 用例已全量通过 |
| 56 | + - [ ] 📦 新增功能已同步补充基本功能测试用例到前冒烟里 |
| 57 | \ No newline at end of file |
| 58 |
| ... | @@ -13,12 +13,6 @@ message(STATUS "DEVICE_MODE=${DEVICE_MODE}") |
| 2 | message(STATUS "BUILD_OPEN_PROJECT=${BUILD_OPEN_PROJECT}") |
| 3 | message(STATUS "AARCH_MODE=${AARCH_MODE}") |
| 4 | |
| 5 | -find_program(CCACHE_PROGRAM ccache) |
| 6 | -if(CCACHE_PROGRAM) |
| 7 | - set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) |
| 8 | - set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) |
| 9 | -endif() |
| 10 | - |
| 11 | if((BUILD_OPEN_PROJECT AND DEVICE_MODE) OR AARCH_MODE) |
| 12 | # need to switch |
| 13 | set(CMAKE_SYSTEM_NAME Linux) |
| ... | @@ -44,18 +38,20 @@ execute_process( |
| 15 | OUTPUT_STRIP_TRAILING_WHITESPACE |
| 16 | ) |
| 17 | message(STATUS "当前系统架构: ${SYSTEM_ARCH}") |
| 18 | + |
| 19 | +# 引入CANN/cmake库 |
| 20 | +include(cmake/fetch_cann_cmake.cmake) |
| 21 | + |
| 22 | project(hcomm) |
| 23 | |
| 24 | +# 引入CANN/cmake库,初始化 |
| 25 | +init_cann_project() |
| 26 | + |
| 27 | +set(CMAKE_CXX_STANDARD 14) |
| 28 | +set(CMAKE_CXX_STANDARD_REQUIRED ON) |
| 29 | set(CMAKE_C_FLAGS_RELEASE "") |
| 30 | set(CMAKE_CXX_FLAGS_RELEASE "") |
| 31 | |
| 32 | -set(CMAKE_CXX_COMPILE_OBJECT |
| 33 | - "<CMAKE_CXX_COMPILER> <DEFINES> -D__FILE__='\"$(notdir $(abspath <SOURCE>))\"' -Wno-builtin-macro-redefined <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>" |
| 34 | -) |
| 35 | -set(CMAKE_C_COMPILE_OBJECT |
| 36 | - "<CMAKE_C_COMPILER> <DEFINES> -D__FILE__='\"$(notdir $(abspath <SOURCE>))\"' -Wno-builtin-macro-redefined <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>" |
| 37 | -) |
| 38 | - |
| 39 | # 获取 CPU 核心数 |
| 40 | if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") |
| 41 | execute_process( |
| ... | @@ -104,7 +100,7 @@ elseif(BUILD_OPEN_PROJECT) |
| 43 | include(cmake/func.cmake) |
| 44 | include(version.cmake) |
| 45 | if(ENABLE_OPEN_SRC) |
| 46 | - check_pkg_build_deps("hcomm") |
| 47 | + check_pkg_build_deps("hcomm") |
| 48 | endif() |
| 49 | add_version_info_targets() |
| 50 | pack_built_in() |
| ... | @@ -213,25 +209,29 @@ elseif(BUILD_OPEN_PROJECT) |
| 52 | ) |
| 53 | install(FILES ${BUILD_DEVICE_DIR}/signatures/cann-hcomm-compat.tar.gz |
| 54 | DESTINATION ${INSTALL_DEVICE_TAR_DIR} OPTIONAL |
| 55 | + PERMISSIONS OWNER_READ GROUP_READ |
| 56 | + OPTIONAL |
| 57 | ) |
| 58 | install(FILES ${BUILD_DEVICE_DIR}/signatures/aicpu_hcomm.tar.gz |
| 59 | - DESTINATION ${INSTALL_DEVICE_TAR_DIR} OPTIONAL |
| 60 | + DESTINATION ${INSTALL_CCL_KERNEL_JSON_DIR}/kernel OPTIONAL |
| 61 | ) |
| 62 | install(FILES ${BUILD_HCCD_DIR}/signatures/cann-hccd-compat.tar.gz |
| 63 | DESTINATION ${INSTALL_DEVICE_TAR_DIR} OPTIONAL |
| 64 | + PERMISSIONS OWNER_READ GROUP_READ |
| 65 | + OPTIONAL |
| 66 | ) |
| 67 | install(FILES ${BUILD_DEVICE_DIR}/src/framework/libaicpu_custom.so |
| 68 | - DESTINATION ${INSTALL_CCL_KERNEL_JSON_DIR} OPTIONAL |
| 69 | + DESTINATION ${INSTALL_CCL_KERNEL_JSON_DIR}/kernel OPTIONAL |
| 70 | ) |
| 71 | install(FILES ${BUILD_DEVICE_DIR}/src/framework/libaicpu_custom.json |
| 72 | - DESTINATION ${INSTALL_CCL_KERNEL_JSON_DIR} OPTIONAL |
| 73 | + DESTINATION ${INSTALL_CCL_KERNEL_JSON_DIR}/kernel OPTIONAL |
| 74 | ) |
| 75 | |
| 76 | add_custom_target(install_ccl_kernel DEPENDS |
| 77 | ${BUILD_DEVICE_DIR}/src/framework/libccl_kernel.so |
| 78 | ) |
| 79 | install(FILES ${BUILD_DEVICE_DIR}/src/framework/libccl_kernel.so |
| 80 | - DESTINATION ${INSTALL_LIBRARY_DIR} OPTIONAL |
| 81 | + DESTINATION ${CMAKE_SYSTEM_PROCESSOR}-linux/devlib/device OPTIONAL |
| 82 | ) |
| 83 | add_dependencies(install_tar hcomm) |
| 84 | add_dependencies(install_ccl_kernel hcomm) |
| ... | @@ -242,10 +242,12 @@ elseif(BUILD_OPEN_PROJECT) |
| 86 | ${HCCL_JSON} |
| 87 | DESTINATION ${INSTALL_INCLUDE_DIR}/hccl/ OPTIONAL |
| 88 | ) |
| 89 | - install(FILES |
| 90 | - ${HCOMM_HEAD} |
| 91 | - DESTINATION ${INSTALL_INCLUDE_DIR}/ OPTIONAL |
| 92 | - ) |
| 93 | + if(NOT BUILD_OPEN_PROJECT) |
| 94 | + install(FILES |
| 95 | + ${HCOMM_HEAD} |
| 96 | + DESTINATION ${INSTALL_INCLUDE_DIR}/ OPTIONAL |
| 97 | + ) |
| 98 | + endif() |
| 99 | install(FILES |
| 100 | include/hcomm_primitives.h |
| 101 | DESTINATION ${INSTALL_INCLUDE_DIR}/hcomm/ OPTIONAL |
| ... | @@ -255,15 +257,6 @@ elseif(BUILD_OPEN_PROJECT) |
| 103 | include/hcomm_res_defs.h |
| 104 | DESTINATION ${INSTALL_INCLUDE_DIR}/hcomm/ OPTIONAL |
| 105 | ) |
| 106 | - install(CODE [[ |
| 107 | -file(MAKE_DIRECTORY "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/hcomm/include/hccl") |
| 108 | -file(REMOVE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/hcomm/include/hcomm_primitives.h") |
| 109 | -file(REMOVE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/hcomm/include/hccl/hcomm_primitives.h") |
| 110 | -file(CREATE_LINK "../hcomm/hcomm_primitives.h" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/hcomm/include/hccl/hcomm_primitives.h" SYMBOLIC) |
| 111 | -file(REMOVE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/hcomm/include/hcomm_res_defs.h") |
| 112 | -file(REMOVE "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/hcomm/include/hccl/hcomm_res_defs.h") |
| 113 | -file(CREATE_LINK "../hcomm/hcomm_res_defs.h" "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/hcomm/include/hccl/hcomm_res_defs.h" SYMBOLIC) |
| 114 | -]]) |
| 115 | |
| 116 | set(HCCL_PKG_HEAD |
| 117 | pkg_inc/hccl/base.h |
| 118 |
| ... | @@ -17,62 +17,108 @@ |
| 2 | 请遵从[CANN 社区编码规范](https://gitcode.com/cann/community/tree/master/contributor/coding-standards)。 |
| 3 | |
| 4 | ### PR规范 |
| 5 | -1. 提交 PR 时,请按照 PR 模板仔细填写本次 PR 的业务背景、目的、方案等信息。 |
| 6 | -2. 使用 Git 提交代码前,请参考 [pre-commit工具使用指导](./docs/dev_guide/pre-commit-guide.md),以保持代码风格一致且符合合规规范。 |
| 7 | -3. 若您的修改不是简单的 bug 修复,而是涉及到新增特性、新增接口、新增配置参数或者修改代码流程等,请务必先通过 Issue 进行方案讨论,以避免您的代码被拒绝合入。若您不确定本次修改是否可被归为“简单的 bug 修复”,亦可通过提交 Issue 进行方案讨论。 |
| 8 | + |
| 9 | +1. 提交 PR 时,请按照 PR 模板仔细填写本次 PR 的业务背景、目的、方案等信息; |
| 10 | +2. **所有PR都必须关联Issue**,请在PR描述中引用对应的Issue编号; |
| 11 | +3. 使用 Git 提交代码前,请参考 [pre-commit工具使用指导](./docs/dev_guide/pre-commit-guide.md),以保持代码风格一致且符合合规规范。 |
| 12 | +4. 若您的修改不是简单的 bug 修复,而是涉及到新增特性、新增接口、新增配置参数或者修改代码流程等,请务必先通过 Issue 进行方案讨论,以避免您的代码被拒绝合入。若您不确定本次修改是否可被归为"简单的 bug 修复",亦可通过提交 Issue 进行方案讨论。 |
| 13 | |
| 14 | ## 贡献流程 |
| 15 | |
| 16 | -### 问题修复或简单代码更改 |
| 17 | +贡献可以分为两类: |
| 18 | |
| 19 | -1. 认领Issue,可在Issue中讨论修复方案; |
| 20 | -2. 发起PR,确保包含触发该Bug的回归测试; |
| 21 | -3. 对PR进行审核、批准并合入。 |
| 22 | +- 简单问题处理:Bug修复、简单代码修改、文档修改等; |
| 23 | +- 新功能或新特性:增加新功能、新特性、新接口,或者支持新业务场景的贡献。 |
| 24 | |
| 25 | -### 新功能或新特性 |
| 26 | +**整体流程** |
| 27 | |
| 28 | -1. 记录Issue |
| 29 | +```mermaid |
| 30 | +flowchart TD |
| 31 | + A1[开始贡献] --> A2{类型?} |
| 32 | + A2 -->|简单问题| A3[查询Issue列表] |
| 33 | + A2 -->|新功能/特性| A4[提交Requirement类型Issue] |
| 34 | |
| 35 | -发起Requirement类型的Issue,按照模板描述您想贡献的新功能与使用场景,在社区发起讨论。 |
| 36 | + A3 --> A5{已有Issue?} |
| 37 | + A5 -->|有| A6[认领该Issue] |
| 38 | + A5 -->|无| A7[创建Issue并认领] |
| 39 | + A7 --> A6 |
| 40 | + A6 --> A19 |
| 41 | |
| 42 | -2. 需求评审 |
| 43 | + A4 --> A10{SIG组决策} |
| 44 | + A10 -->|拒绝| A11[关闭Issue] |
| 45 | + A10 -->|接纳| A12[添加accepted标签] |
| 46 | + A12 --> A13[设计系统方案] |
| 47 | + A13 --> A14[编写/修改RFC] |
| 48 | + A14 --> A15[提交包含RFC的PR] |
| 49 | + A15 --> A16{Maintainer评审} |
| 50 | + A16 -->|提出意见| A14 |
| 51 | + A16 -->|通过| A17[合入RFC] |
| 52 | + A17 --> A19[修改/实现代码,提交PR] |
| 53 | |
| 54 | -- 议题申报:在[SIG双周例会](https://etherpad-cann.meeting.osinfra.cn/p/sig-hccl)申报议题进行评审。 |
| 55 | -- 评审内容: |
| 56 | - - 需求的应用场景与业务价值; |
| 57 | - - 需求的紧迫性与重要性; |
| 58 | - - 是否符合社区当前的技术路线与愿景。 |
| 59 | + A19 --> A20{Committer检视} |
| 60 | + A20 -->|检视意见| A21[修改] |
| 61 | + A21 --> A20 |
| 62 | + A20 -->|通过| A24[合入PR] |
| 63 | +``` |
| 64 | + |
| 65 | +### 简单问题处理 |
| 66 | + |
| 67 | +1. 查询并认领Issue |
| 68 | + |
| 69 | + - 现在Issue列表中查询该问题是否有对应的Issue; |
| 70 | + - **如有对应Issue**:直接认领该Issue; |
| 71 | + - **如无对应Issue**:创建新的Issue并认领。 |
| 72 | + |
| 73 | +2. 修改代码并提交PR |
| 74 | + |
| 75 | + - 需要满足编码规范与PR规范; |
| 76 | + - 确保包含触发Bug的回归测试。 |
| 77 | + |
| 78 | +3. 代码评审与合入 |
| 79 | + |
| 80 | + - 负责对应模块或组件的Committer检视代码并反馈检视意见,请根据意见修改;没有问题后,添加`/lgtm`和`/approve`标签并合入。 |
| 81 | + |
| 82 | + |
| 83 | +### 增加新功能或新特性 |
| 84 | + |
| 85 | + |
| 86 | +1. 提交Requirement类型Issue |
| 87 | + |
| 88 | + - 在代码仓提交Requirement类型的Issue; |
| 89 | + - 详细描述:使用场景、业务价值、大致技术方案; |
| 90 | + - 在社区发起讨论,SIG组决策是否接纳该需求;如果接纳,添加`accepted`标签。 |
| 91 | + |
| 92 | +2. 系统方案设计 |
| 93 | + |
| 94 | + - 需求被接纳后,设计详细的系统方案; |
| 95 | + - 在 `docs/rfcs` 目录下创建markdown格式的RFC文件,并按RFC模板撰写系统方案; |
| 96 | + - 提交PR。 |
| 97 | |
| 98 | 3. 系统方案评审 |
| 99 | |
| 100 | -- 议题申报:在[SIG双周例会](https://etherpad-cann.meeting.osinfra.cn/p/sig-hccl)申报议题进行评审。 |
| 101 | -- 评审内容: |
| 102 | - - 技术可行性; |
| 103 | - - 系统整体架构的合理性; |
| 104 | - - 潜在的技术风险与问题识别。 |
| 105 | - |
| 106 | -4. 软件方案设计 |
| 107 | - |
| 108 | -您需要将系统方案转化为可执行的软件设计方案,同时包含完善的测试与验证方案,保障功能完善且不影响已有功能。 |
| 109 | - |
| 110 | -- 设计原则: |
| 111 | - - 需详细阐述模块划分、数据流向及关键逻辑,确保模块职责单一,模块间解耦; |
| 112 | - - 需要包含特性开关设计,确保新功能可以通过配置开关进行隔离,便于灰度发布与回滚。 |
| 113 | - |
| 114 | -5. 软件方案评审 |
| 115 | - |
| 116 | -在评审前,请确保在相应Requirement Issue中进行过充分讨论。 |
| 117 | - |
| 118 | -- 议题申报:在[SIG双周例会](https://etherpad-cann.meeting.osinfra.cn/p/sig-hccl)申报议题进行评审。 |
| 119 | - |
| 120 | -6. 提交PR |
| 121 | - |
| 122 | -开发者准备本地代码并提交PR;提交PR时,请按照 PR 模板仔细填写本次 PR 的业务背景、目的、方案等信息。 |
| 123 | - |
| 124 | -7. 社区版本特性规划 |
| 125 | - |
| 126 | -Roadmap规划时,根据新功能是否成熟、稳定以及优先级,决定是否加入到具体的社区版本。 |
| 127 | - |
| 128 | -*注:本文档有社区维护,如有变更建议,请在Issue中提出。* |
| 129 | + - 详细设计方案通过包含RFC的PR进行评审; |
| 130 | + - 过程中请针对评审意见进行方案修改; |
| 131 | |
| 132 | |
| 133 | +4. RFC合入 |
| 134 | + |
| 135 | + - 所有Maintainer对方案均无异议后,由Maintainer添加`/lgtm`和`/approve`标签合入; |
| 136 | + - 合入的RFC方案作为后续代码实施的合约,代码实现需要遵循RFC方案。 |
| 137 | + |
| 138 | +5. 软件实现 |
| 139 | + |
| 140 | + - 按照RFC方案实现代码,并提交PR; |
| 141 | + - 必须包含对应的测试代码(包含单元测试与系统测试)。 |
| 142 | + |
| 143 | +6. 代码评审与合入 |
| 144 | + |
| 145 | + - 负责对应模块或组件的Committer检视代码并反馈检视意见,请根据意见修改;没有问题后,添加`/lgtm`和`/approve`标签并合入。 |
| 146 | + |
| 147 | +--- |
| 148 | + |
| 149 | +## 争议处理 |
| 150 | + |
| 151 | +存在争议的Issue、PR或RFC可以在[SIG工作会议](https://etherpad-cann.meeting.osinfra.cn/p/sig-hccl)上申报议题,由SIG组决策。 |
| 152 | + |
| 153 | + |
| 154 | +*本文档由社区维护,如有变更建议,请在Issue中提出。* |
| 155 |
| ... | @@ -96,6 +96,7 @@ HCOMM通信基础库采用分层解耦的设计思路,将通信能力划分为 |
| 2 | ## 📖 学习教程 |
| 3 | |
| 4 | HCCL提供了使用指南、通信算子开发指南、技术文章、培训视频,详细可参见 [HCCL 参考资料](./docs/README.md)。 |
| 5 | +此外,HCCL还提供了QuickStart指南、常见FAQ等wiki,详细可参见 [WIKI](https://gitcode.com/cann/hcomm/wiki)。 |
| 6 | |
| 7 | ## 📝 相关信息 |
| 8 | |
| 9 |
| ... | @@ -16,8 +16,12 @@ src/framework/next/comms/endpoint_pairs/channels/channel_process.cc |
| 2 | src/framework/next/comms/endpoint_pairs/channels/aicpu/device/aicpu_channel_process.cc |
| 3 | src/legacy/framework/dfx/aicpu/profiling/profiling_command_handle_lite.cc |
| 4 | src/framework/next/coll_comms/api_c_adpt/dev/dev_coll_comm_c_adpt.cc |
| 5 | -src/framework/hcom/hcom.cc |
| 6 | -src/framework/communicator/impl/zero_copy/zero_copy_memory_agent.cc |
| 7 | -src/framework/next/comms/endpoint_pairs/channels/aicpu/device/aicpu_ts_urma_channel_kernel.cc |
| 8 | -src/framework/next/coll_comms/dfx/taskException/aicpu/hcclCommTaskExceptionLite.cc |
| 9 | - |
| 10 | +src/legacy/unified_platform/resource/transport/aicpu/p2p_transport_lite_impl.cc |
| 11 | +src/legacy/unified_platform/resource/transport/aicpu/ub_transport_lite_impl.cc |
| 12 | +src/legacy/unified_platform/resource/transport/p2p_transport.cc |
| 13 | +src/legacy/unified_platform/resource/stream/stream.cc |
| 14 | +src/legacy/unified_platform/resource/notify/ipc_remote_notify.cc |
| 15 | +src/legacy/interface/rank_graph_interface.cc |
| 16 | +src/framework/next/comms/endpoint_pairs/channels/aicpu/aicpu_ts_p2p_channel.cc |
| 17 | +src/framework/next/comms/endpoint_pairs/channels/channel.cc |
| 18 | +src/framework/next/comms/common/orion_adpt_utils.cc |
| 19 |
| ... | @@ -37,7 +37,9 @@ BUILD_CB_TEST="false" |
| 2 | |
| 3 | ENABLE_UT="off" |
| 4 | ENABLE_ST="off" |
| 5 | +ST_TASKS=() |
| 6 | ENABLE_GCOV="off" |
| 7 | +ENABLE_NO_EXEC="off" |
| 8 | CMAKE_BUILD_TYPE="Debug" |
| 9 | |
| 10 | if [ "${USER_ID}" != "0" ]; then |
| ... | @@ -82,9 +84,8 @@ function rmdir() |
| 12 | |
| 13 | function cmake_config() |
| 14 | { |
| 15 | - local extra_option="$1" |
| 16 | - log "Info: cmake config ${CUSTOM_OPTION} ${extra_option} ." |
| 17 | - cmake .. ${CUSTOM_OPTION} ${extra_option} |
| 18 | + log "Info: cmake config ${CUSTOM_OPTION} $*" |
| 19 | + cmake .. ${CUSTOM_OPTION} "$@" |
| 20 | } |
| 21 | |
| 22 | function build() |
| ... | @@ -128,100 +129,74 @@ function build_cb_test_verify(){ |
| 24 | bash build.sh |
| 25 | } |
| 26 | |
| 27 | -function build_test() { |
| 28 | - ENABLE_ST="on" |
| 29 | - cmake_config -DENABLE_ST=${ENABLE_ST} |
| 30 | - |
| 31 | - LIBRARY_DIR="${BUILD_DIR}/test:${ASCEND_HOME_PATH}/lib64:" |
| 32 | - # 每日构建sdk包安装路径 |
| 33 | - if [ -d "${ASCEND_HOME_PATH}/opensdk" ];then |
| 34 | - LIBRARY_DIR="${LIBRARY_DIR}${ASCEND_HOME_PATH}/opensdk/opensdk/gtest_shared/lib64:" |
| 35 | +function run_ctest() { |
| 36 | + # 设置 --noexec 选项,则跳过执行测试用例 |
| 37 | + if [[ "$ENABLE_NO_EXEC" = "on" ]]; then |
| 38 | + log "Info: Skip executing tests" |
| 39 | + return 0 |
| 40 | fi |
| 41 | |
| 42 | - # 社区sdk包安装路径 |
| 43 | - if [ -d "${ASCEND_HOME_PATH}/../../latest/opensdk" ];then |
| 44 | - LIBRARY_DIR="${LIBRARY_DIR}${ASCEND_HOME_PATH}/../../latest/opensdk/opensdk/gtest_shared/lib64:" |
| 45 | + local suite_name="$1" # "ut" or "st" |
| 46 | + local log_dir="${OUTPUT_PATH}/logs/${suite_name}" |
| 47 | + local ctest_log="${log_dir}/ctest_output.log" |
| 48 | + local ctest_summary="${log_dir}/ctest_summary.log" |
| 49 | + |
| 50 | + # 创建日志目录 |
| 51 | + mk_dir "${log_dir}" |
| 52 | + |
| 53 | + # CTest 执行用例 |
| 54 | + ctest ${JOB_NUM} \ |
| 55 | + --build-nocmake \ |
| 56 | + --timeout 200 \ |
| 57 | + --output-on-failure \ |
| 58 | + --stop-on-failure \ |
| 59 | + --test-output-size-failed 10000000 \ |
| 60 | + -O "${ctest_log}" \ |
| 61 | + 2>&1 | tee "${ctest_summary}" |
| 62 | + |
| 63 | + # 超时时间:200s |
| 64 | + local ctest_ret=${PIPESTATUS[0]} |
| 65 | + if [ "${ctest_ret}" -eq 137 ]; then |
| 66 | + log "Error: ctest timeout: execute more than 200s killed" |
| 67 | + exit 1 |
| 68 | fi |
| 69 | |
| 70 | - GCC_MAJOR=`gcc -dumpversion | cut -d. -f1` |
| 71 | - if [ "${ASAN}" == "true" ];then |
| 72 | - ARCH=$(uname -m) |
| 73 | - if [[ $ARCH == "x86_64" || $ARCH == "i386" || $ARCH == "i686" ]]; then |
| 74 | - PRELOAD="/usr/lib/gcc/x86_64-linux-gnu/${GCC_MAJOR}/libasan.so:/usr/lib/gcc/x86_64-linux-gnu/${GCC_MAJOR}/libstdc++.so" |
| 75 | - elif [[ $ARCH == "aarch64" || $ARCH == "armv8l" || $ARCH == "armv7l" ]]; then |
| 76 | - PRELOAD="/usr/lib/gcc/aarch64-linux-gnu/${GCC_MAJOR}/libasan.so:/usr/lib/gcc/aarch64-linux-gnu/${GCC_MAJOR}/libstdc++.so" |
| 77 | - else |
| 78 | - echo "未知架构: $ARCH" |
| 79 | - fi |
| 80 | - echo "PRELOAD is ${PRELOAD}" |
| 81 | - ASAN_OPT="detect_leaks=0" |
| 82 | + return ${ctest_ret} |
| 83 | +} |
| 84 | + |
| 85 | +function build_st() { |
| 86 | + log "Info: build_st" |
| 87 | + mk_dir "${BUILD_DIR}" |
| 88 | + cd "${BUILD_DIR}" |
| 89 | + |
| 90 | + # 配置 ST 用例代码 |
| 91 | + local st_tasks=$(printf '%s;' "${ST_TASKS[@]}" | sed 's/;$//') |
| 92 | + log "Info: build_st: ST_TASKS=${st_tasks}" |
| 93 | + cmake_config -DPRODUCT_SIDE=host \ |
| 94 | + -DENABLE_GCOV=${ENABLE_GCOV} \ |
| 95 | + -DENABLE_TEST=${ENABLE_TEST} \ |
| 96 | + -DENABLE_ST=${ENABLE_ST} \ |
| 97 | + -DST_TASKS=${st_tasks} |
| 98 | + if [ $? -ne 0 ]; then |
| 99 | + log "Error: build_st: cmake config failed" |
| 100 | + exit 1 |
| 101 | fi |
| 102 | |
| 103 | - if [ "${TEST_TASK_NAME}" == "open_hccl_test" ] || [ "$TEST" = "all" ];then |
| 104 | - build open_hccl_test |
| 105 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 106 | - && ${BUILD_DIR}/test/st/algorithm/testcase/testcase/open_hccl_test |
| 107 | + # 编译 ST 用例代码 |
| 108 | + cmake --build . ${JOB_NUM} |
| 109 | + if [ $? -ne 0 ]; then |
| 110 | + log "Error: build_st: cmake build failed" |
| 111 | + exit 1 |
| 112 | fi |
| 113 | |
| 114 | - if [ "${TEST_TASK_NAME}" == "executor_hccl_test" ] || [ "$TEST" = "all" ];then |
| 115 | - build executor_hccl_test |
| 116 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 117 | - && ${BUILD_DIR}/test/st/algorithm/testcase/executor_testcase_generalization/executor_hccl_test |
| 118 | + # CTest 运行用例 |
| 119 | + run_ctest "st" |
| 120 | + if [ $? -ne 0 ]; then |
| 121 | + log "Error: build_st: ctest execution failed" |
| 122 | + exit 1 |
| 123 | fi |
| 124 | |
| 125 | - if [ "${TEST_TASK_NAME}" == "executor_reduce_hccl_test" ] || [ "$TEST" = "all" ];then |
| 126 | - build executor_reduce_hccl_test |
| 127 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 128 | - && ${BUILD_DIR}/test/st/algorithm/testcase/executor_reduce_testcase_generalization/executor_reduce_hccl_test |
| 129 | - fi |
| 130 | - |
| 131 | - if [ "${TEST_TASK_NAME}" == "executor_pipeline_hccl_test" ] || [ "$TEST" = "all" ];then |
| 132 | - build executor_pipeline_hccl_test |
| 133 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 134 | - && ${BUILD_DIR}/test/st/algorithm/testcase/executor_alltoall_A3_pipeline_testcase/executor_pipeline_hccl_test |
| 135 | - fi |
| 136 | - |
| 137 | - if [ "${TEST_TASK_NAME}" == "legacy_aicpu_2d_testcase" ] || [ "${TEST_TASK_NAME}" == "legacy_all_testcase" ] || [ "$TEST" = "all" ];then |
| 138 | - build legacy_alg_aicpu_2d_testcase |
| 139 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 140 | - && ${BUILD_DIR}/test/legacy/st/algorithm/testcase/aicpu_2d_testcase/legacy_alg_aicpu_2d_testcase |
| 141 | - fi |
| 142 | - |
| 143 | - if [ "${TEST_TASK_NAME}" == "legacy_ccu_1d_hf16p_testcase" ] || [ "${TEST_TASK_NAME}" == "legacy_all_testcase" ] || [ "$TEST" = "all" ];then |
| 144 | - build legacy_alg_ccu_1d_hf16p_testcase |
| 145 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 146 | - && ${BUILD_DIR}/test/legacy/st/algorithm/testcase/ccu_1d_hf16p_testcase/legacy_alg_ccu_1d_hf16p_testcase |
| 147 | - fi |
| 148 | - |
| 149 | - if [ "${TEST_TASK_NAME}" == "legacy_ccu_1d_testcase_part1" ] || [ "${TEST_TASK_NAME}" == "legacy_all_testcase" ] || [ "$TEST" = "all" ];then |
| 150 | - build legacy_alg_ccu_1d_testcase_part1 |
| 151 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 152 | - && ${BUILD_DIR}/test/legacy/st/algorithm/testcase/ccu_1d_testcase_part1/legacy_alg_ccu_1d_testcase_part1 |
| 153 | - fi |
| 154 | - |
| 155 | - if [ "${TEST_TASK_NAME}" == "legacy_ccu_1d_testcase_part2" ] || [ "${TEST_TASK_NAME}" == "legacy_all_testcase" ] || [ "$TEST" = "all" ];then |
| 156 | - build legacy_alg_ccu_1d_testcase_part2 |
| 157 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 158 | - && ${BUILD_DIR}/test/legacy/st/algorithm/testcase/ccu_1d_testcase_part2/legacy_alg_ccu_1d_testcase_part2 |
| 159 | - fi |
| 160 | - |
| 161 | - if [ "${TEST_TASK_NAME}" == "legacy_alg_ccu_reduce" ] || [ "${TEST_TASK_NAME}" == "legacy_all_testcase" ] || [ "$TEST" = "all" ];then |
| 162 | - build legacy_alg_ccu_reduce |
| 163 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 164 | - && ${BUILD_DIR}/test/legacy/st/algorithm/testcase/ccu_reduce_testcase/legacy_alg_ccu_reduce |
| 165 | - fi |
| 166 | - |
| 167 | - if [ "${TEST_TASK_NAME}" == "legacy_function_ut_testcase" ] || [ "${TEST_TASK_NAME}" == "legacy_all_testcase" ] || [ "$TEST" = "all" ];then |
| 168 | - build legacy_alg_function_ut_testcase |
| 169 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 170 | - && ${BUILD_DIR}/test/legacy/st/algorithm/testcase/function_ut_testcase/legacy_alg_function_ut_testcase |
| 171 | - fi |
| 172 | - |
| 173 | - if [ "${TEST_TASK_NAME}" == "legacy_alg_testcase" ] || [ "${TEST_TASK_NAME}" == "legacy_all_testcase" ] || [ "$TEST" = "all" ];then |
| 174 | - build legacy_alg_testcase |
| 175 | - export LD_LIBRARY_PATH=${LIBRARY_DIR}${LD_LIBRARY_PATH} && export LD_PRELOAD=${PRELOAD} && export ASAN_OPTIONS=${ASAN_OPT} \ |
| 176 | - && ${BUILD_DIR}/test/legacy/st/algorithm/testcase/legacy_alg_testcase/legacy_alg_testcase |
| 177 | - fi |
| 178 | + log "Info: Build and tests completed successfully!" |
| 179 | } |
| 180 | |
| 181 | function build_kernel() { |
| ... | @@ -236,85 +211,39 @@ function mk_dir() { |
| 183 | echo "created ${create_dir}" |
| 184 | } |
| 185 | |
| 186 | -# create build path |
| 187 | function build_ut() { |
| 188 | - echo "create build directory and build"; |
| 189 | - mk_dir ${OUTPUT_PATH} |
| 190 | - mk_dir "${BUILD_DIR}" |
| 191 | - local report_dir="${OUTPUT_PATH}/report/ut" && mk_dir "${report_dir}" |
| 192 | - local log_dir="${OUTPUT_PATH}/ut_logs" && mk_dir "${log_dir}" |
| 193 | - cd "${BUILD_DIR}" |
| 194 | - unset LD_LIBRARY_PATH |
| 195 | + log "Info: build_ut" |
| 196 | + mk_dir "${BUILD_DIR}" |
| 197 | + cd "${BUILD_DIR}" |
| 198 | |
| 199 | - local BUILD_JOBS |
| 200 | - if [ "${CPU_NUM}" -ge 8 ]; then |
| 201 | - BUILD_JOBS=$((CPU_NUM-1)) |
| 202 | - else |
| 203 | - BUILD_JOBS=8 |
| 204 | - fi |
| 205 | + # 避免加载系统库 |
| 206 | + unset LD_LIBRARY_PATH |
| 207 | |
| 208 | - local LLT_KILL_TIME=200 |
| 209 | - CMAKE_ARGS="-DPRODUCT_SIDE=host \ |
| 210 | - -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \ |
| 211 | - -DCMAKE_INSTALL_PREFIX=${BUILD_OUTPUT_DIR} \ |
| 212 | - -DASCEND_INSTALL_PATH=${ASCEND_INSTALL_PATH} \ |
| 213 | - -DCANN_3RD_LIB_PATH=${CANN_3RD_LIB_PATH} \ |
| 214 | - -DENABLE_GCOV=${ENABLE_GCOV} \ |
| 215 | - -DENABLE_TEST=${ENABLE_TEST} \ |
| 216 | - -DENABLE_UT=${ENABLE_UT} \ |
| 217 | - -DOUTPUT_PATH=${OUTPUT_PATH} \ |
| 218 | - -DLLT_KILL_TIME=${LLT_KILL_TIME}" |
| 219 | + # 配置 UT 用例代码 |
| 220 | + cmake_config -DPRODUCT_SIDE=host \ |
| 221 | + -DENABLE_TEST=${ENABLE_TEST} \ |
| 222 | + -DENABLE_UT=${ENABLE_UT} \ |
| 223 | + -DENABLE_GCOV=${ENABLE_GCOV} |
| 224 | + if [ $? -ne 0 ]; then |
| 225 | + log "Error: build_ut: cmake config failed" |
| 226 | + exit 1 |
| 227 | + fi |
| 228 | |
| 229 | - echo "CMAKE_ARGS=${CMAKE_ARGS}" |
| 230 | - cmake ${CMAKE_ARGS} .. |
| 231 | - if [ $? -ne 0 ]; then |
| 232 | - echo "execute command: cmake ${CMAKE_ARGS} .. failed." |
| 233 | - return 1 |
| 234 | - fi |
| 235 | + # 编译 UT 用例代码 |
| 236 | + cmake --build . ${JOB_NUM} |
| 237 | + if [ $? -ne 0 ]; then |
| 238 | + log "Error: build_ut: cmake build failed" |
| 239 | + exit 1 |
| 240 | + fi |
| 241 | |
| 242 | - echo "Building all test targets..." |
| 243 | - cmake --build . -j${BUILD_JOBS} |
| 244 | - run_ret=${PIPESTATUS[0]} |
| 245 | - echo "exit code: ${run_ret}" |
| 246 | - if [ "${run_ret}" -eq 137 ] |
| 247 | - then |
| 248 | - echo "timeout: execute more than ${LLT_KILL_TIME}s killed" |
| 249 | - exit 1 |
| 250 | - fi |
| 251 | - if [ "${run_ret}" -ne 0 ]; then |
| 252 | - echo "execute command: cmake --build . -j${BUILD_JOBS} failed." |
| 253 | - return 1 |
| 254 | - fi |
| 255 | - echo "build success!" |
| 256 | + # CTest 运行用例 |
| 257 | + run_ctest "ut" |
| 258 | + if [ $? -ne 0 ]; then |
| 259 | + log "Error: build_ut: ctest execution failed" |
| 260 | + exit 1 |
| 261 | + fi |
| 262 | |
| 263 | - echo "Running tests with CTest (parallel jobs: ${BUILD_JOBS})..." |
| 264 | - |
| 265 | - local ctest_log="${log_dir}/ctest_output.log" |
| 266 | - local ctest_summary="${log_dir}/ctest_summary.log" |
| 267 | - |
| 268 | - ctest -j ${BUILD_JOBS} \ |
| 269 | - --build-nocmake \ |
| 270 | - --timeout ${LLT_KILL_TIME} \ |
| 271 | - --output-on-failure \ |
| 272 | - --stop-on-failure \ |
| 273 | - --test-output-size-failed 10000000 \ |
| 274 | - -O "${ctest_log}" \ |
| 275 | - 2>&1 | tee "${ctest_summary}" |
| 276 | - |
| 277 | - local ctest_ret=${PIPESTATUS[0]} |
| 278 | - |
| 279 | - if [ "${ctest_ret}" -eq 137 ]; then |
| 280 | - echo "timeout: execute more than ${LLT_KILL_TIME}s killed" |
| 281 | - exit 1 |
| 282 | - fi |
| 283 | - |
| 284 | - if [ "${ctest_ret}" -ne 0 ]; then |
| 285 | - echo "CTest execution failed. See logs in ${log_dir}" |
| 286 | - return 1 |
| 287 | - fi |
| 288 | - |
| 289 | - echo "Build and tests completed successfully!" |
| 290 | - echo "Test logs saved in: ${log_dir}" |
| 291 | + log "Info: Build and tests completed successfully!" |
| 292 | } |
| 293 | |
| 294 | function make_ut_gov() { |
| ... | @@ -332,20 +261,6 @@ function make_ut_gov() { |
| 296 | fi |
| 297 | } |
| 298 | |
| 299 | -function run_ut() { |
| 300 | - if [[ "X$ENABLE_UT" = "Xon" ]]; then |
| 301 | - local ut_dir="${BUILD_DIR}/test" |
| 302 | - echo "ut_dir = ${ut_dir}" |
| 303 | - find "$ut_dir" -type f -executable | while read -r ut_exec; do |
| 304 | - filename=$(basename "$ut_exec") |
| 305 | - echo "Executing: $filename" |
| 306 | - ${ut_exec} |
| 307 | - done |
| 308 | - else |
| 309 | - echo "Unit tests is not enabled, sh build.sh with parameter -u or --ut to enable it" |
| 310 | - fi |
| 311 | -} |
| 312 | - |
| 313 | # print usage message |
| 314 | function usage() { |
| 315 | echo "Usage:" |
| ... | @@ -357,12 +272,12 @@ function usage() { |
| 317 | echo "Options:" |
| 318 | echo " -h, --help Print usage" |
| 319 | echo " --asan Enable AddressSanitizer" |
| 320 | - echo " -build-type=<TYPE>" |
| 321 | + echo " --build-type=<TYPE>" |
| 322 | echo " Specify build type (TYPE options: Release/Debug), Default: Release" |
| 323 | echo " -j<N> Set the number of threads used for building, default is 8" |
| 324 | echo " --cann_3rd_lib_path=<PATH>" |
| 325 | echo " Set ascend third_party package install path, default ./output/third_party" |
| 326 | - echo " -p|--package-path <PATH>" |
| 327 | + echo " -p, --package-path <PATH>" |
| 328 | echo " Set ascend package install path, default /usr/local/Ascend/cann" |
| 329 | echo " --sign-script <PATH>" |
| 330 | echo " Set sign-script's path to <PATH>" |
| ... | @@ -370,6 +285,9 @@ function usage() { |
| 332 | echo " Enable to sign" |
| 333 | echo " --version <VERSION>" |
| 334 | echo " Set sign version to <VERSION>" |
| 335 | + echo " -u, --ut Run all unit tests (UT)" |
| 336 | + echo " -s, --st Run all system tests (ST)" |
| 337 | + echo " --noexec Run build and skip executing tests" |
| 338 | echo "" |
| 339 | } |
| 340 | |
| ... | @@ -409,73 +327,97 @@ while [[ $# -gt 0 ]]; do |
| 342 | CANN_3RD_LIB_PATH="$(realpath ${OPTARG#*=})" |
| 343 | shift |
| 344 | ;; |
| 345 | + --noexec) |
| 346 | + ENABLE_NO_EXEC="on" |
| 347 | + shift |
| 348 | + ;; |
| 349 | -u|--ut) |
| 350 | ENABLE_TEST="on" |
| 351 | ENABLE_UT="on" |
| 352 | shift |
| 353 | ;; |
| 354 | -s|--st) |
| 355 | - TEST="all" |
| 356 | + ENABLE_TEST="on" |
| 357 | + ENABLE_ST="on" |
| 358 | + ST_TASKS+=("all") |
| 359 | shift |
| 360 | ;; |
| 361 | --open_hccl_test) |
| 362 | - TEST="partial" |
| 363 | - TEST_TASK_NAME="open_hccl_test" |
| 364 | + ENABLE_TEST="on" |
| 365 | + ENABLE_ST="on" |
| 366 | + ST_TASKS+=("open_hccl_test") |
| 367 | shift |
| 368 | ;; |
| 369 | --executor_hccl_test) |
| 370 | - TEST="partial" |
| 371 | - TEST_TASK_NAME="executor_hccl_test" |
| 372 | + ENABLE_TEST="on" |
| 373 | + ENABLE_ST="on" |
| 374 | + ST_TASKS+=("executor_hccl_test") |
| 375 | shift |
| 376 | ;; |
| 377 | --executor_reduce_hccl_test) |
| 378 | - TEST="partial" |
| 379 | - TEST_TASK_NAME="executor_reduce_hccl_test" |
| 380 | + ENABLE_TEST="on" |
| 381 | + ENABLE_ST="on" |
| 382 | + ST_TASKS+=("executor_reduce_hccl_test") |
| 383 | shift |
| 384 | ;; |
| 385 | --executor_pipeline_hccl_test) |
| 386 | - TEST="partial" |
| 387 | - TEST_TASK_NAME="executor_pipeline_hccl_test" |
| 388 | + ENABLE_TEST="on" |
| 389 | + ENABLE_ST="on" |
| 390 | + ST_TASKS+=("executor_pipeline_hccl_test") |
| 391 | shift |
| 392 | ;; |
| 393 | --legacy_all_testcase) |
| 394 | - TEST="partial" |
| 395 | - TEST_TASK_NAME="legacy_all_testcase" |
| 396 | + ENABLE_TEST="on" |
| 397 | + ENABLE_ST="on" |
| 398 | + ST_TASKS+=("legacy_all_testcase") |
| 399 | shift |
| 400 | ;; |
| 401 | --legacy_aicpu_2d_testcase) |
| 402 | - TEST="partial" |
| 403 | - TEST_TASK_NAME="legacy_aicpu_2d_testcase" |
| 404 | + ENABLE_TEST="on" |
| 405 | + ENABLE_ST="on" |
| 406 | + ST_TASKS+=("legacy_aicpu_2d_testcase") |
| 407 | + shift |
| 408 | + ;; |
| 409 | + --legacy_ccu_2d_testcase) |
| 410 | + ENABLE_TEST="on" |
| 411 | + ENABLE_ST="on" |
| 412 | + ST_TASKS+=("legacy_ccu_2d_testcase") |
| 413 | shift |
| 414 | ;; |
| 415 | --legacy_ccu_1d_hf16p_testcase) |
| 416 | - TEST="partial" |
| 417 | - TEST_TASK_NAME="legacy_ccu_1d_hf16p_testcase" |
| 418 | + ENABLE_TEST="on" |
| 419 | + ENABLE_ST="on" |
| 420 | + ST_TASKS+=("legacy_ccu_1d_hf16p_testcase") |
| 421 | shift |
| 422 | ;; |
| 423 | --legacy_ccu_1d_testcase_part1) |
| 424 | - TEST="partial" |
| 425 | - TEST_TASK_NAME="legacy_ccu_1d_testcase_part1" |
| 426 | + ENABLE_TEST="on" |
| 427 | + ENABLE_ST="on" |
| 428 | + ST_TASKS+=("legacy_ccu_1d_testcase_part1") |
| 429 | shift |
| 430 | ;; |
| 431 | --legacy_ccu_1d_testcase_part2) |
| 432 | - TEST="partial" |
| 433 | - TEST_TASK_NAME="legacy_ccu_1d_testcase_part2" |
| 434 | + ENABLE_TEST="on" |
| 435 | + ENABLE_ST="on" |
| 436 | + ST_TASKS+=("legacy_ccu_1d_testcase_part2") |
| 437 | shift |
| 438 | ;; |
| 439 | --legacy_alg_ccu_reduce) |
| 440 | - TEST="partial" |
| 441 | - TEST_TASK_NAME="legacy_alg_ccu_reduce" |
| 442 | + ENABLE_TEST="on" |
| 443 | + ENABLE_ST="on" |
| 444 | + ST_TASKS+=("legacy_alg_ccu_reduce") |
| 445 | shift |
| 446 | ;; |
| 447 | --legacy_function_ut_testcase) |
| 448 | - TEST="partial" |
| 449 | - TEST_TASK_NAME="legacy_function_ut_testcase" |
| 450 | + ENABLE_TEST="on" |
| 451 | + ENABLE_ST="on" |
| 452 | + ST_TASKS+=("legacy_function_ut_testcase") |
| 453 | shift |
| 454 | ;; |
| 455 | --legacy_alg_testcase) |
| 456 | - TEST="partial" |
| 457 | - TEST_TASK_NAME="legacy_alg_testcase" |
| 458 | + ENABLE_TEST="on" |
| 459 | + ENABLE_ST="on" |
| 460 | + ST_TASKS+=("legacy_alg_testcase") |
| 461 | shift |
| 462 | ;; |
| 463 | --aicpu) # 新增选项,用于只编译 ccl_kernel.so |
| ... | @@ -537,10 +479,6 @@ while [[ $# -gt 0 ]]; do |
| 465 | esac |
| 466 | done |
| 467 | |
| 468 | -if [ -n "${TEST}" ];then |
| 469 | - CUSTOM_OPTION="${CUSTOM_OPTION} -DENABLE_TEST=ON" |
| 470 | -fi |
| 471 | - |
| 472 | if [ "${KERNEL}" == "true" ];then |
| 473 | CUSTOM_OPTION="${CUSTOM_OPTION} -DKERNEL_MODE=ON -DDEVICE_MODE=ON -DPRODUCT=ascend -DPRODUCT_SIDE=device" |
| 474 | fi |
| ... | @@ -587,6 +525,7 @@ if [ -n "${third_party_nlohmann_path}" ];then |
| 476 | fi |
| 477 | |
| 478 | CUSTOM_OPTION="${CUSTOM_OPTION} -DCUSTOM_ASCEND_CANN_PACKAGE_PATH=${ASCEND_CANN_PACKAGE_PATH}" |
| 479 | +CUSTOM_OPTION="${CUSTOM_OPTION} -DASCEND_INSTALL_PATH=${ASCEND_CANN_PACKAGE_PATH}" |
| 480 | # CUSTOM_OPTION="${CUSTOM_OPTION} -DCANN_3RD_LIB_PATH=${cann_3rd_lib_path}" |
| 481 | CUSTOM_OPTION="$CUSTOM_OPTION -DCANN_3RD_LIB_PATH=${CANN_3RD_LIB_PATH} -DCANN_UTILS_LIB_PATH=${CANN_UTILS_LIB_PATH}" |
| 482 | |
| ... | @@ -605,8 +544,8 @@ cd ${BUILD_DIR} |
| 484 | if [ "${ENABLE_UT}" == "on" ]; then |
| 485 | build_ut |
| 486 | make_ut_gov |
| 487 | -elif [ -n "${TEST}" ];then |
| 488 | - build_test |
| 489 | +elif [ "${ENABLE_ST}" == "on" ]; then |
| 490 | + build_st |
| 491 | elif [ "${KERNEL}" == "true" ]; then |
| 492 | build_kernel |
| 493 | elif [ "${BUILD_FWK_HLT}" == "true" ]; then |
| 494 |
| ... | @@ -134,12 +134,6 @@ set(ASCEND_MOCKCPP_PACKAGE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) |
| 2 | # message(FATAL_ERROR "${THIRD_PARTY_NLOHMANN_PATH} does not exist, please check the setting of THIRD_PARTY_NLOHMANN_PATH.") |
| 3 | # endif() |
| 4 | |
| 5 | -set(ASCEND_SDK_PACKAGE_PATH "${ASCEND_CANN_PACKAGE_PATH}") |
| 6 | -if (NOT EXISTS "${ASCEND_CANN_PACKAGE_PATH}/opensdk") |
| 7 | - # 设置社区包sdk安装位置 |
| 8 | - set(ASCEND_SDK_PACKAGE_PATH "${ASCEND_CANN_PACKAGE_PATH}/../latest") |
| 9 | -endif() |
| 10 | - |
| 11 | #execute_process(COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/cmake/scripts/check_version_compatiable.sh |
| 12 | # ${ASCEND_CANN_PACKAGE_PATH} |
| 13 | # hccl |
| ... | @@ -164,11 +158,11 @@ set(HI_PYTHON "python3" CACHE STRING |
| 15 | message(STATUS "config.cmake KERNEL_MODE=${KERNEL_MODE} BUILD_OPEN_PROJECT=${BUILD_OPEN_PROJECT}") |
| 16 | message(STATUS "config.cmake PRODUCT=${PRODUCT} PRODUCT_SIDE=${PRODUCT_SIDE}") |
| 17 | |
| 18 | -set(INSTALL_LIBRARY_DIR hcomm/lib64) |
| 19 | -set(INSTALL_INCLUDE_DIR hcomm/include) |
| 20 | -set(INSTALL_PKG_INCLUDE_DIR hcomm/pkg_inc) |
| 21 | -set(INSTALL_CCL_KERNEL_JSON_DIR hcomm/built-in/data/op/aicpu) |
| 22 | -set(INSTALL_DPU_KERNEL_JSON_DIR hcomm/built-in/data/op/dpu) |
| 23 | -set(INSTALL_DEVICE_TAR_DIR hcomm/Ascend/aicpu) |
| 24 | +set(INSTALL_LIBRARY_DIR ${CMAKE_SYSTEM_PROCESSOR}-linux/lib64) |
| 25 | +set(INSTALL_INCLUDE_DIR ${CMAKE_SYSTEM_PROCESSOR}-linux/include) |
| 26 | +set(INSTALL_PKG_INCLUDE_DIR ${CMAKE_SYSTEM_PROCESSOR}-linux/pkg_inc) |
| 27 | +set(INSTALL_CCL_KERNEL_JSON_DIR opp/built-in/op_impl/aicpu) |
| 28 | +set(INSTALL_DPU_KERNEL_JSON_DIR opp/built-in/op_impl/dpu) |
| 29 | +set(INSTALL_DEVICE_TAR_DIR compat) |
| 30 | |
| 31 | set(CMAKE_SKIP_RPATH TRUE) |
| 32 |
| ... | @@ -0,0 +1,38 @@ |
| 2 | +# ----------------------------------------------------------------------------------------------------------- |
| 3 | +# Copyright (c) 2026 Huawei Technologies Co., Ltd. |
| 4 | +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 5 | +# CANN Open Software License Agreement Version 2.0 (the "License"). |
| 6 | +# Please refer to the License for details. You may not use this file except in compliance with the License. |
| 7 | +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, |
| 8 | +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. |
| 9 | +# See LICENSE in the root of the software repository for the full text of the License. |
| 10 | +# ----------------------------------------------------------------------------------------------------------- |
| 11 | +# 引入CANN/cmake库 |
| 12 | + |
| 13 | +if(NOT PROJECT_SOURCE_DIR) |
| 14 | + if(CANN_3RD_LIB_PATH AND IS_DIRECTORY "${CANN_3RD_LIB_PATH}/cann-cmake") |
| 15 | + include("${CANN_3RD_LIB_PATH}/cann-cmake/function/prepare.cmake") |
| 16 | + else() |
| 17 | + include(FetchContent) |
| 18 | + |
| 19 | + set(CANN_CMAKE_TAG "master-001") |
| 20 | + if(CANN_3RD_LIB_PATH AND EXISTS "${CANN_3RD_LIB_PATH}/cmake-${CANN_CMAKE_TAG}.tar.gz") |
| 21 | + FetchContent_Declare( |
| 22 | + cann-cmake |
| 23 | + URL "${CANN_3RD_LIB_PATH}/cmake-${CANN_CMAKE_TAG}.tar.gz" |
| 24 | + ) |
| 25 | + else() |
| 26 | + FetchContent_Declare( |
| 27 | + cann-cmake |
| 28 | + GIT_REPOSITORY https://gitcode.com/cann/cmake.git |
| 29 | + GIT_TAG ${CANN_CMAKE_TAG} |
| 30 | + GIT_SHALLOW TRUE |
| 31 | + ) |
| 32 | + endif() |
| 33 | + FetchContent_GetProperties(cann-cmake) |
| 34 | + if(NOT cann-cmake_POPULATED) |
| 35 | + FetchContent_Populate(cann-cmake) |
| 36 | + endif() |
| 37 | + include("${cann-cmake_SOURCE_DIR}/function/prepare.cmake") |
| 38 | + endif() |
| 39 | +endif() |
| 40 | \ No newline at end of file |
| 41 |
| ... | @@ -227,62 +227,6 @@ function(sign_file) |
| 2 | endif() |
| 3 | endfunction() |
| 4 | |
| 5 | -macro(replace_cur_major_minor_ver) |
| 6 | - string(REPLACE CUR_MAJOR_MINOR_VER "${CANN_VERSION_${CANN_VERSION_CURRENT_PACKAGE}_VERSION_MAJOR_MINOR}" depend "${depend}") |
| 7 | -endmacro() |
| 8 | - |
| 9 | -# 设置包和版本号 |
| 10 | -function(set_package name) |
| 11 | - cmake_parse_arguments(VERSION "" "VERSION" "" ${ARGN}) |
| 12 | - set(VERSION "${VERSION_VERSION}") |
| 13 | - if(NOT name) |
| 14 | - message(FATAL_ERROR "The name parameter is not set in set_package.") |
| 15 | - endif() |
| 16 | - if(NOT VERSION) |
| 17 | - message(FATAL_ERROR "The VERSION parameter is not set in set_package(${name}).") |
| 18 | - endif() |
| 19 | - string(REGEX MATCH "^([0-9]+\\.[0-9]+)" VERSION_MAJOR_MINOR "${VERSION}") |
| 20 | - list(APPEND CANN_VERSION_PACKAGES "${name}") |
| 21 | - set(CANN_VERSION_PACKAGES "${CANN_VERSION_PACKAGES}" PARENT_SCOPE) |
| 22 | - set(CANN_VERSION_CURRENT_PACKAGE "${name}" PARENT_SCOPE) |
| 23 | - set(CANN_VERSION_${name}_VERSION "${VERSION}" PARENT_SCOPE) |
| 24 | - set(CANN_VERSION_${name}_VERSION_MAJOR_MINOR "${VERSION_MAJOR_MINOR}" PARENT_SCOPE) |
| 25 | - set(CANN_VERSION_${name}_BUILD_DEPS PARENT_SCOPE) |
| 26 | - set(CANN_VERSION_${name}_RUN_DEPS PARENT_SCOPE) |
| 27 | -endfunction() |
| 28 | - |
| 29 | -# 设置构建依赖 |
| 30 | -function(set_build_dependencies pkg_name depend) |
| 31 | - if(NOT CANN_VERSION_CURRENT_PACKAGE) |
| 32 | - message(FATAL_ERROR "The set_package must be invoked first.") |
| 33 | - endif() |
| 34 | - if(NOT pkg_name) |
| 35 | - message(FATAL_ERROR "The pkg_name parameter is not set in set_build_dependencies.") |
| 36 | - endif() |
| 37 | - if(NOT depend) |
| 38 | - message(FATAL_ERROR "The depend parameter is not set in set_build_dependencies.") |
| 39 | - endif() |
| 40 | - replace_cur_major_minor_ver() |
| 41 | - list(APPEND CANN_VERSION_${CANN_VERSION_CURRENT_PACKAGE}_BUILD_DEPS "${pkg_name}" "${depend}") |
| 42 | - set(CANN_VERSION_${CANN_VERSION_CURRENT_PACKAGE}_BUILD_DEPS "${CANN_VERSION_${CANN_VERSION_CURRENT_PACKAGE}_BUILD_DEPS}" PARENT_SCOPE) |
| 43 | -endfunction() |
| 44 | - |
| 45 | -# 设置运行依赖 |
| 46 | -function(set_run_dependencies pkg_name depend) |
| 47 | - if(NOT CANN_VERSION_CURRENT_PACKAGE) |
| 48 | - message(FATAL_ERROR "The set_package must be invoked first.") |
| 49 | - endif() |
| 50 | - if(NOT pkg_name) |
| 51 | - message(FATAL_ERROR "The pkg_name parameter is not set in set_run_dependencies.") |
| 52 | - endif() |
| 53 | - if(NOT depend) |
| 54 | - message(FATAL_ERROR "The depend parameter is not set in set_run_dependencies.") |
| 55 | - endif() |
| 56 | - replace_cur_major_minor_ver() |
| 57 | - list(APPEND CANN_VERSION_${CANN_VERSION_CURRENT_PACKAGE}_RUN_DEPS "${pkg_name}" "${depend}") |
| 58 | - set(CANN_VERSION_${CANN_VERSION_CURRENT_PACKAGE}_RUN_DEPS "${CANN_VERSION_${CANN_VERSION_CURRENT_PACKAGE}_RUN_DEPS}" PARENT_SCOPE) |
| 59 | -endfunction() |
| 60 | - |
| 61 | # 检查构建依赖 |
| 62 | function(check_pkg_build_deps pkg_name) |
| 63 | execute_process( |
| 64 |
| ... | @@ -22,7 +22,7 @@ set(HCOMM_UTILS_FILE "cann-hcomm-utils_${HCOMM_UTILS_VERSION}_linux-${HCOMM_UTIL |
| 2 | set(HCOMM_UTILS_URL "https://ascend-cann.obs.cn-north-4.myhuaweicloud.com/CANN/20260330_newest/${HCOMM_UTILS_FILE}") |
| 3 | set(HCOMM_UTILS_PKG_PATH ${CANN_3RD_LIB_PATH}/${HCOMM_UTILS_FILE}) |
| 4 | set(HCOMM_UTILS_INSTALL_PATH ${CANN_3RD_LIB_PATH}/hcomm_utils) |
| 5 | -set(INSTALL_LIBRARY_DIR hcomm/lib64) |
| 6 | +set(INSTALL_LIBRARY_DIR ${CMAKE_SYSTEM_PROCESSOR}-linux/lib64) |
| 7 | |
| 8 | # 查找目录下是否已经安装,避免重复编译安装 |
| 9 | message(STATUS "[ThirdParty] HCOMM_UTILS_INSTALL_PATH=${HCOMM_UTILS_INSTALL_PATH}") |
| 10 |
| ... | @@ -69,9 +69,33 @@ configure_file( |
| 2 | ) |
| 3 | configure_file( |
| 4 | ${NN_VERSION_OUT_PUT} |
| 5 | - ${STAGING_DIR}/share/info/hcomm/ |
| 6 | + ${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/include/version/hcomm_version.h |
| 7 | COPYONLY |
| 8 | ) |
| 9 | + |
| 10 | +# 统一修正文件权限 |
| 11 | +if(EXISTS "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/conf/path.cfg") |
| 12 | + execute_process(COMMAND chmod 440 "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/conf/path.cfg") |
| 13 | +endif() |
| 14 | +if(EXISTS "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/bin") |
| 15 | + execute_process(COMMAND find "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/bin" -type f -exec chmod 550 {} +) |
| 16 | +endif() |
| 17 | +if(EXISTS "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/lib64") |
| 18 | + execute_process(COMMAND find "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/lib64" -type f -exec chmod 440 {} +) |
| 19 | +endif() |
| 20 | +if(EXISTS "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/devlib") |
| 21 | + execute_process(COMMAND find "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/devlib" -type f -exec chmod 440 {} +) |
| 22 | +endif() |
| 23 | +if(EXISTS "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/include") |
| 24 | + execute_process(COMMAND find "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/include" -type f -exec chmod 440 {} +) |
| 25 | +endif() |
| 26 | +if(EXISTS "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/pkg_inc") |
| 27 | + execute_process(COMMAND find "${STAGING_DIR}/${CMAKE_SYSTEM_PROCESSOR}-linux/pkg_inc" -type f -exec chmod 440 {} +) |
| 28 | +endif() |
| 29 | +if(EXISTS "${STAGING_DIR}/opp/built-in/op_impl") |
| 30 | + execute_process(COMMAND find "${STAGING_DIR}/opp/built-in/op_impl" -type f -exec chmod 440 {} +) |
| 31 | +endif() |
| 32 | + |
| 33 | # makeself打包 |
| 34 | file(STRINGS ${CPACK_CMAKE_BINARY_DIR}/makeself.txt script_output) |
| 35 | string(REPLACE " " ";" makeself_param_string "${script_output}") |
| 36 |
| ... | @@ -120,17 +120,11 @@ function(pack_built_in) |
| 2 | OPTIONAL |
| 3 | ) |
| 4 | install(FILES ${CONF_FILES} |
| 5 | - DESTINATION hcomm/conf |
| 6 | + DESTINATION ${CMAKE_SYSTEM_PROCESSOR}-linux/conf |
| 7 | ) |
| 8 | install(FILES ${PACKAGE_FILES} |
| 9 | DESTINATION share/info/hcomm/script |
| 10 | ) |
| 11 | - install(FILES ${LATEST_MANGER_FILES} |
| 12 | - DESTINATION latest_manager |
| 13 | - ) |
| 14 | - install(DIRECTORY ${CMAKE_SOURCE_DIR}/scripts/package/latest_manager/scripts/ |
| 15 | - DESTINATION latest_manager |
| 16 | - ) |
| 17 | |
| 18 | string(FIND "${ASCEND_COMPUTE_UNIT}" ";" SEMICOLON_INDEX) |
| 19 | if (SEMICOLON_INDEX GREATER -1) |
| 20 |
| ... | @@ -0,0 +1,21 @@ |
| 2 | +# HCCL 架构文档 |
| 3 | + |
| 4 | +本文档描述HCCL(Huawei Collective Communication Library)的软件架构。 |
| 5 | + |
| 6 | +## 文档目录 |
| 7 | + |
| 8 | +- [系统概述](./overview.md) - 系统整体架构与模块划分 |
| 9 | +- [base_comm](./base_comm/) - 基础通信模块 |
| 10 | +- [coll_comm](./coll_comm/) - 集合通信域管理模块 |
| 11 | + |
| 12 | +## 架构原则 |
| 13 | + |
| 14 | +1. **模块化设计** - 各模块职责单一,模块间解耦 |
| 15 | +2. **平台抽象** - 屏蔽底层硬件差异,提供统一接口 |
| 16 | +3. **可扩展性** - 支持新算法、新通信原语的灵活扩展 |
| 17 | + |
| 18 | +## 相关链接 |
| 19 | + |
| 20 | +- [贡献指南](../CONTRIBUTING.md) |
| 21 | +- [RFC文档](../rfcs/) |
| 22 | +- [开发者指南](../dev_guide/) |
| 23 |
| ... | @@ -0,0 +1,11 @@ |
| 2 | +# 基础通信模块 |
| 3 | + |
| 4 | +基础通信模块,与业务无关,封装底层硬件与协议,为上层框架提供统一的通信抽象。 |
| 5 | + |
| 6 | +## 子模块 |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## 代码路径 |
| 11 | + |
| 12 | +`src/platform/` |
| 13 |
| ... | @@ -0,0 +1,15 @@ |
| 2 | +# HCCP Protocol |
| 3 | + |
| 4 | +HCCP(Huawei Collective Communication Protocol)通信协议模块。 |
| 5 | + |
| 6 | +## 职责 |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +## 协议层次 |
| 11 | + |
| 12 | + |
| 13 | + |
| 14 | +## 代码路径 |
| 15 | + |
| 16 | +`src/platform/hccp/` |
| 17 |
| ... | @@ -0,0 +1,12 @@ |
| 2 | +# 集合通信域管理模块 |
| 3 | + |
| 4 | +集合通信域管理模块。 |
| 5 | + |
| 6 | +## 子模块 |
| 7 | + |
| 8 | +- [Communicator](./communicator.md) - 通信域 |
| 9 | +- ... |
| 10 | + |
| 11 | +## 代码路径 |
| 12 | + |
| 13 | +`src/framework/` |
| 14 |
| ... | @@ -0,0 +1,22 @@ |
| 2 | +# Communicator |
| 3 | + |
| 4 | +通信器模块,管理和协调集合通信操作。 |
| 5 | + |
| 6 | +## 职责 |
| 7 | + |
| 8 | +- 通信上下文管理 |
| 9 | +- 集合操作创建与调度 |
| 10 | +- 通信域管理 |
| 11 | +- 拓扑信息维护 |
| 12 | + |
| 13 | +## 核心接口 |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | +## 数据流 |
| 18 | + |
| 19 | + |
| 20 | + |
| 21 | +## 代码路径 |
| 22 | + |
| 23 | +`src/framework/communicator/` |
| 24 |
| ... | @@ -0,0 +1,9 @@ |
| 2 | +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 837 559" width="837" height="559"><!-- svg-source:excalidraw --><metadata><!-- payload-type:application/vnd.excalidraw+json --><!-- payload-version:2 --><!-- payload-start -->eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO2cTWvcRlx1MDAxY8bv/lx1MDAxNGZzbVx1MDAxZM2M5kWBUlx1MDAxY78kgSRt40BcdTAwMGZtXHTa1dgrrJVcdTAwMTbtbGI3XHUwMDA0UighoVx1MDAxNFxcSlx0tITgnnpJ6KWXXHUwMDEw6IdpbTenfIWOtM6OdjWSJe1LlGT3sKBZWVx1MDAxYf31PPPT6JF8d2l5uSH2u7xxYbnB91q25zqhfafxUdR+m4c9N/DlTzBe7lx1MDAwNf2wXHUwMDE1r9lcdTAwMTai27tw/nzHXHUwMDBld7noenaLr9x2e33b64m+41x1MDAwNiutoHPeXHUwMDE1vNP7NPq+bnf4J92g44hwRe3kY+64XCJcYlx1MDAwN/viXHUwMDFl73Bf9OTWv5LLy8t342/5i+tEe/TsfVx1MDAxZaJ43bj1TZ9D3lx1MDAxMra/43H1055sN43h4r5cXLTU4lx1MDAxZNdcdTAwMTFt2cRcdTAwMDBcdTAwMWW2tbm701x1MDAxNrJcdTAwMTFcdTAwMTC14mCrXHUwMDE3llVLT4TBLl9cdTAwMGI82Wm563OcXHUwMDExhrfVjpt2a3cnXGb6vqPW2dxcXF+9aKl1tl3P21x1MDAxMvvxlmVBZSVcdTAwMWFj2//ytINwrD3rr+RcdTAwMGV32j7v9Ub6XHUwMDFhdO2WK6JjXHUwMDA3hmqNete94sRV/ia5XHUwMDA13zndwpuyq1x1MDAxMrPTlnuqP5w7I1x1MDAxZFRCQcZ44/XAjzWDTIhcdTAwMTAwqDlcXMH1XHUwMDFkXHUwMDFlnauGXHLU0bi9dSlcdTAwMDVcdTAwMTHvYFvKiavKhVJFV6J2v+95quhR5zdcdTAwMTLqUcfV7zr2YEuAUkKZYVBgUjD83XP93fHNeUFrV+18KXHgWkHe8uwm99KyXHUwMDE0fE/kKlx1MDAxMlx1MDAxOFgjSZiWJCqjyJaJmybNVaRcYm2/17VDWa4qqlx1MDAwNG9FlSOn6FR+SPU+8MWW+23UXHLARlo37Y7rRbtTxY7PjOzv5bW1q69+e3B08PDV/V///fvw5Pnjo2dcdTAwMDfJ0vW4XHUwMDE0yNhGo79e9dydSOuNlqwhXHUwMDBmXHUwMDFiScVcdTAwMGJXjm7DXHUwMDE1RNBtaExcdTAwMDJJlkmgXHUwMDAxgFx1MDAwMaVIXHKNS+DcXFxCgFx1MDAwNUu4ZNjckiW3Zc3CdFx1MDAwN4LQ3XF927tZsPx2X1x1MDAwNDd4b3BWR/dcdTAwMTKdlcvDXHUwMDExe4WMfmiOZ4MuuNVcZvZcblOEKtnEmsVpjCTbhp6lU/bsue348+74NU1cdTAwMTGcRVx1MDAxMVNjkFx1MDAwNJrHXGZcdTAwMDIgNJiJXHUwMDE51mFcdTAwMDTNyyCEmoROXHUwMDA3I5EkR2GRjZBxOVJWTI7ALCFHI/58XHUwMDE4XGJR9UxcIoSMtOYgZNXzbnCn3+J6asCRPyhOjY7rOMmRqIgvmEEgJaZJNLYw62qLKtzQ1HxcdTAwMDRcdTAwMTVcIuxnkMJYYVx1MDAxNOc6XHUwMDExloJcdTAwMDMkXHUwMDBiOsycXHUwMDBlqSulfDpcdTAwMTiIXHUwMDEwXHUwMDAwLItpbIDraoMzNFmUXHUwMDBlKT0u8DAhXHUwMDFl1EmsiodLtmgnx/q3hVx1MDAwNzmpwIxcdTAwMDJcdTAwMDR1fCB1NUZFPoxcdTAwMTd9anxApfhg4lx1MDAwNVx1MDAxZmbOXHUwMDA3Vs5cdTAwMDbUYphKI+j4QOtqgzM0WZRcdTAwMGYpPS74MCFcdTAwMWasyfgwuI7datlC1IFcdTAwMTFcdTAwMTZjgCBCdd5gdfVGXHUwMDE1RGTUfWqYMEthgphcdTAwMGJMzFx1MDAxY1x1MDAxMyBcdTAwMTVL5FrBhFx1MDAwNiRcdTAwMTBjnVx1MDAxNay6WuFcZk1cdTAwMTbFREqPXHUwMDBiTEyIXHSgulJ1XHUwMDFlIVx1MDAwMvn19lx1MDAxMcGA/DBkQI0vVuvqi4qziLGST4lcdTAwMGVxalxiXHUwMDBiw2EsNIRMl2OrYlTMsWGTNVv5Zjy3ur7ONkhcdTAwMTUj1j7HXHUwMDA2uiBcdTAwMWKiLFx1MDAxM1x1MDAwMFxmXHUwMDE4IVx1MDAxNGpdcHFeLlx1MDAwMFx1MDAxNiWshFx1MDAwYs7UZOUkXHUwMDFiWrNIsoFNbJb/bMX7XHUwMDAziFx0o+xkjnr09OnJ88OTg1x1MDAwN8d/XHUwMDFjXHUwMDFlPXk8lzxcdTAwMWKlMjzlXHUwMDE1Ylx1MDAxONTQ3XVam1x1MDAxYi9cdTAwMDCks+ZFoTMwk0i7Uy7RXHUwMDA2TJ2r/fjUKVx1MDAxYkxvtlHAvO/1bEOXacNMk2BcZiFcdTAwMDGE6HiyPieXXHUwMDAwXHRcdTAwMTRW5pmPfElcdTAwMTadbKTkSKxiclxcTDayWKLPtM2R1jyWjI5h85pzZLuDSXVcdTAwMTKDIN1cXHyjru6oxJCsylx1MDAxN5x6gDxLlou2XHUwMDExXVBi9pTQZdvZPoDAMlx1MDAwMNYneJt19UG+JItSXCIlx1x1MDAwNSUmpYQ+2i5Jif/++v74xUFdQGExzFxiNZnOIJfqapDqoNBcdTAwMTd/XHUwMDFhrChcdTAwMTdzY7JgxexZocu5s61AXHUwMDE5syi1XHUwMDEyVVdWuFxcVyvkS7IoK1JyXFywYlJW6GPuwqw4/uHn40c/1YVcdTAwMTJcdTAwMTBcdTAwMTDIoPbx8St1dUZcdTAwMTVI6Ks+XHUwMDA1PMR3i0FhPIzdLDY1dmSJ+59VXHUwMDEzXGZOXHUwMDFkXHUwMDA08/FgWZub1nv6Jp72VbzMt4xMXHUwMDA0oFx1MDAwNVx1MDAxMdPdcLo6r9uyJsKJXHUwMDE50ORcdTAwMDFcdTAwMDaoXHUwMDFjYJhMXHUwMDE3YGhcdTAwMTBRLsBoYlx1MDAwZT9cdTAwMTBEwFx0XHUwMDAzjKOnL05cdTAwMGXvXHUwMDBmrmvnmVukbKPewzMpRNCwdJy4Ni+LYGpZZd5WrcKJvNLPJLBollxmLMaeWsQoPb2AZOLpxdlmfZ+nXHUwMDE36culaG2Q6Vx1MDAwZWBcIoosaupcdTAwMDByfW5cdTAwMDBhOPHGw0RcdTAwMDBplkgsrDE9YpjSo9TsXG6R3jVcdTAwMDCAyDBcdGNpeUJWQp5cdTAwMWbSdFx1MDAwM05cdTAwMThgJFx1MDAwN7TBPZKv/dcvXHUwMDFmrrVt3+feP/e/u9lcdTAwMGW57Zw8e/T65aN5zUeyXHUwMDEzcoxNgDDShn+fzctKlolmPiGpeF6mMGNpllx1MDAwYj/Gn5NfXHUwMDEwZ9A6XeLowo/sf1x1MDAxZVx1MDAxMr3TXHUwMDE3vd2qTVx1MDAwMT9/XHUwMDE3iVM8/UjpXHUwMDExp6fQWj0u7mhlIWbC9GPkmvmXP49/fP7qye9zQ0m2SZBcdTAwMDUtRLVcdOFcdTAwMTd19cjEc5Z0/cshQ37Hx9Owu90tIY9mOJBJdbnOqTjgadVcdTAwMDdtgneVMOKma4HDN3y76Y1cdTAwMWZZ47bL71xczFx1MDAxZdyXTkeIyEg8XHUwMDFlRO8t3ftcdTAwMWZWtYX5In0=<!-- payload-end --></metadata><defs><style class="style-fonts"> |
| 3 | + @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAS8ABEAAAAADUwAAARkAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhxGBmAANAgKCY4uERAKgySCcwsMAAE2AiQDDgQgBYJeByAMFBviC8gGHng8q/eTtB46HXrlTodqRu6anT1nDkbPOZqx+v30y78JywgHbFxe5l9IRtgYkxd+AYC6OiJhUJhWyVoC26pKQFVhTL+VXebGoK2I3+P1RxCAGwCQEICCQABOUklFeH1NXdhRAEwToCd2OsUakf3LKK8PQWAoAPbnWc3/EUjIKMjyi+JkLCAhAWJzbDWoFvYVkrAiC8cPcyRf1OSv7WWlaTcd8mZzM8ibOXlEERd98AZIFul/QMUCSIAMxCIjwKKgQpHF3HSYJoe9+E/fKrAQi/srDShuNHC3+W8W4kTNEOZRBt60u3AjDw+VGIhiVa0JeENipMRAKjYQhZ4SA7lY9YXkHF+HP0tTdVWvn9BVnzozOhFScghvfNKkrpWpITr9ATVEl98TWqml2DsmNW1xiYGyhlap6Rq01bWztWs5fcv/SgwsxY1qSM5t87f7Q0FvSmilV0vxeNSa0INt/tCD3hSPppUYWE/J4/GBQOJ5YatbC2nJvoLo5JyONF0v1bI8sEHXU/QszTzREDD9yqbB5NVyTo0hgm3NC8EsTwquZXnkdVqKR/OWGDiKGzv9NV5k9mjC+brRsevtjAturSv0YRI5nB6hIBJRmkhjtLySIVDwb/HcbAwhlolDvDYu9AkSOZGepCAZKZpktaYiNo2QzmRA1WaE3iORM+lZCrKRo8lWay5i8wj5TAEKtQWhL5LIxfQSBaUo05SqtRz5V7woIGNHIhFhmsgAWABwAgpwFGAAlEFJuO+S5cnI3OPMvf/511/33eHUX32163Snnntm8nlFb7zRu2Dutde6z4HE09fl6j1nCpFylsuVc1e995prrqveel1BnKHxCdsf3XNm/Os9r4tZlm3KX85qBMcls6Wnd98hRNEr7bPLxOzrTqlwGctczjU9gq/CP7H09IUjPdb++Wc2507mdmwpD+/krNr2OiPSuvCiqOqo5mW3drWK0Pxd9ivqdvX/mGQ59Rw+WxO8+/HzL4iynvZWlHVRy9Dy1bENiSsKj4o8sfjrhanKovOjra/3rryyst3xJ/PLl3x019S6gkDu6JRd2jbwYH1jV7ql4Nxo66mB9qlVZ3V0LDht++x5+nXfsbfam21NPWJBe5T31aW1FcPV5zW07Wl+3DVRjvrremeSu7J3jKY5Wgtn24ZnnnnI1wY5teDEu9dcNxyx9De7S/4S4M3Lvs8G+KQo51TzU7NA+VfeAtiRZqQ/UDXltx7T/98eR+BwnGS7v2Qpq6WTaVM2i/QNeWVGypU6CTxkow8ZoTiAQt7OXYJYHndJhGO4ZErR9yr9Lgu7iRZW4+vAT4BRNrGeUQJ0soYeJtnKNgJsYiMqVZRSQQVL8DLJOJNsYAzOUqmmGJVKyv2EUfSNX9zOGraCGE2xaahSsUK53B9WMr8m1Ph01ZQwRoDtpyiq4miLheiA4TQ7Rh66dR4Xtk1sZo9vgGlm2L73mpOeqdKEn1p6kXHimZspZ2aQX6SQjlg4GxQB); } |
| 4 | + @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAARkABEAAAAADLwAAAQMAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKgkiCLAsGAAE2AiQDCAQgBYJeByAMFBttC1GUDkqb7EdibMyt6R+KmF4Uj8ktiCU1ePje+7wzk7cAs/BbqTRT2Smlv57G1KVP4EtdtoKt8uIkncsHOybgBcQMGZqTDrqbEMzrLv+/e3Nw75+tuGCli+3s+W+b6Ar1Zj2lVKAKkhCGSmlgHaMc8XxRy3M1QL2q2N9fCQJwAwAEIBEIBOBCGGGIchWq1cMJDcCyAEauV+qGmIkNJBIQvVKTSY5wmiWFA0p4IMCJb6rWqGJDSrWp3aa26mX1AtWLma00seL5/QZpk/8BHRsgAQX4oRBo1NChqUR/m9qWpdSW+dg42PDzf6QJ9qombrUa7RJiemNTWOOCcuEHcUO1bJFqIuy6Xr5zuZ2iVaqJtJuIEcksAbZTdRVXd5pAplvlu+mV3pe7a3FppPNVD2s8JOfTDzm/spdCx131AEYSkD24tsAaU6Xvav6N8Lv8JaD2ObmK3+hW3cgd2iujw0zFT2w0HMkdBtwCuyWLpK3fp70veIUl87zYIbNXIrwJm1wrJ8ZFZh2Lgb1jCISmVC1YPFfFlRDGprvXSNyhcmLtLHQYWQJpn++1ZDAwMup3QyM0QtAwuPa/ycgW3ZbhwJUcnacqJeDN+Ft8t+gTAiFExEP/x4yc0FMZGXIpU2oBYkmohBoNr/3fMnJH72UMGKVBqROIM2ERVmx89f/OyAf9lHHhli6lPuD59jSgnOdJghCWhQJAAqDlmb4KpgCNdnfpcJWk1pNLrA9Z4TrF/16DOy6TN4tRgVvyG67gPQ1cAuZXZgS6igWBC4ZG5vlzPz8b3oThZzozc5bdDT+QcEDbcxFGztx6D+tvbD05YOlw4PJ7De7x+v2GK87wN+rdvStLc/YnN1iKUfw3eB7GxqxmWbE1/PuH+fyzDdXGjkhW7p08XLsmyva6iqusKs85Yvp4mYdnLmtXYbGX9+K8dssrqejWjp4T3N2W9kv/sduDlml+m5sHeUye5RF24GSrSEch2hTGae6HbOGuLUQ32wStRXu7OkadeuUfu3tcOVxWXjhpdYo2yfJ1aHp1oX9snvM4bWxqopP3JEnqbVVY0vI0j8YtPYv9dXJVHwAerPkWC/A6JW629cZatX+qN+CEpLjkU9b+juj/f9mOwIvRGOoDNZUxKT+TwLgoZOlx7zpHmqAQmjOQzKPSLvDjnF3igWlXpDF5rTZutzEIn4yD9X3QiM60pifdaE1n6lKWBrSnD33pTE96oJNNGplkUpRytKct7elOGxzRycGuNLLICBtFqTB/pB9l6UOZ1jl6NnQydyhkhI0s8loZPd1dDqm0oTP9bpHT1a0VUTN1sNGR/jM37bMuopp70ovB7p3pSCf6rd1000N1qtGIijRE4YWzepFB1yQxRUcE/OBSJQU=); } |
| 5 | + @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAAVYABEAAAAADgwAAAT9AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAAPAgKCY4uERAKhQyEKwsIAAE2AiQDCgQgBYJeByAMFBt2DMieA+7ORpcsikGIlBTF8DGnbR6CgOyq6unZs2YP1v+BjF6OHBGICP9Y9/amEJPOr4zcCk1BpIBWyDp7B3TbO2/Q4LnVKwPwYGG+/ofzL2zVsq28/s/yhQsRUC8cS92QjMWYTyFLQi4fhQElUdm/49/hQ/QYh/TcYzrBRRa6yH9zEIAZqCkI3a3/PSbo0SOyclJyQAUV4D+AmVukvCCmwoAS9kD0R/1ebmG0SREGSBGAVUa8UFFdfD5E1OYXv5T9/wfI/sy3qcKS+9dB0Sn/AA90gAJIwA6JAJ1KAAzKAkXafQ0vbl97ZlE4CIKqDjv1R+4FEFLIkcvqLgkxuX6v+D/O43oTZGRriysHGOKBYqUYJtpCOaCQvQCDPF054BCPOCZ9c7IKRIIooold1CMOVRaVMtUXXYNPKqP14YjBWychBl8dZhH15v6hbkKCXDmQLeRqkKq1OFQlLa9yKaG/C4pMSCFOKu9XVpBZwEZlaSwii5hjjGLZ0bK6eJSlYUIIMfaSzJXXeiWT64JLsUFKlN8gVKm5lGo9Hd9Kihh2jR+vUZG4V3IBVZmR4SC8VfpmczGqbDg4CsLmPCli4yZijkmMKwchpJCQjI0BLSYh8XPXh1fynARZLq28wsgqXROhw5DpalPI4GCpgf8F781bBJtz4MqdlfcY2acHIkJEslCqMeMTQsplyOXZyheMXNIrETUaWS3VlvEdoecGjPJh5SdGnumLiBWbbJXqzhYfLQDpPa7ghPgPCZDGDDThTlVoBDUVZmeTecFKiX4KI1Y7vLlWs/VK1UwTv9mCdiD6em3VqkPpuEbddEVt1XUxujjB38wQ1iby3QBqp77K+dUVvanvLPBnGqhdDcLVmOravXz8Nr72lomkm9isrdkzNfMHzqRg1Yy7vPnKlX7XhcmVqnajE0+C0KWME2uvXonZObhndltNznWh+Yu14DedUoNUNarVVJ80Pb7Wh6z367guas6avH5b81y4on51wgGfVJb3qqr6NozaWtOYR/zmQ8TPeYVkLTQp1K+5pOOr3nnL6JplR3qL4ciIeLh3ocOiuREt0w20KpG+iuMWurtHKMrO7rVWTDiANfTzDl0Uh5klDSp0FJh+6d7Db265qV2+eREhW8aL96M+XLuDFv/kMbGGd3dFfF87o0w1bq11pZxybZZj4BtjrT2Amgy9/1jN3KozPB64o82eZXNRvewn6pVeq1BjmExq0cDrfhcXOC5xJxvh7u9iZ3TB8yw9bXL4K14uF1nBi44nBNGe5RR4ygJ6lhmaU12lcb/tSwThCv7mwF2jpU/VuqyRINNA81Y7nTngvWPilklcT5u8zURiHLjJdAnW+zLvz7bR0k+x39B1tO/kDx3uu9eCw5LldZ6rppYAIACpD0xCH0tbtUO+GpnKFwA3jt75ADx29l38/8Sg/pEDAIxQdO8PMKl+ndH8zSUEgRcXIl8QQJlBKq/xj0ESohQKcDSkAXmEalwL4lZtEdhxzKJgwV6LJIzxJ9V5i47h6IUMypeDOiSKqKeGIiSyiSaPMppoRqKeOhDRhBFJJMlkUUYJZdRSDCNEDCFaJYqI2AmRHPqohWiaIFRUor6CiNwgFhFXoojrhTzy68UQSgcSLZeIIP1iQXqoAioVtBLPbZJz6YZ6GuicK1FBJS0n1130Xg+KKCCefOQJNvofHjT30gebSGFDTINgAAAA); } |
| 6 | + @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,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); } |
| 7 | + @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,d09GMgABAAAAAATYABEAAAAADUAAAAR9AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbHhweBmAANAgKCY4uERAKg0yDDQsGAAE2AiQDCAQgBYJeByAMFBvOC1HUB8HoluxHQuamj+azuDh5oMhipVayKL8HD6R79y6Xivilokldf39bTBPMP+5zwGdbYQvbMYnNjCIywVYZWJd3bw80mqAIKa2t/+H8C//fnEb250q2QgIa1+vLf6nxNQbwCigBFbJQKMym5BQAyjmUU3rSL9Zv0N2kYP3dDwEkAgACMBAwLcRT+JuIUHjOEmIxAWYADFwt5TNxmSgwMACxN9lf0ypiwRDRSOECDrFMzXHHljO4/B3ukntn9kJ0Dy6vM8XNd+dgRBnTgNrSS2oSyEQRwTUmCsyagOXvLuFFmVulQ02IItP7kRrs2ZrEBe4dIS56WsxMEyq6SyJy7RpHI2ylRiOhQKxzNIatEbWWo5G2CgeyIrzILfOUr/yJTb4Kq23rNwVmReJufdFm32tQAYvdiApY4lrBoFfgzG32vG5HY25BzBHfU2G1fTHZ7iZsasR7RdmzVSArF7gL3eBsqCAYDHkFlqVGg/u2bnDfsMDyPEcTfUl3kj8Vyb0uxKSia0k0dgO2mLlJzvP9SrLMgmPlfoFf5lnbagFVDGY0swdlxagWZxe0V86WWQXIFbv4fb0Cyws5mjh79mJ3NFRgWZ6jiTGfax+lQFFYwBGs+HgOTcATBZCAzJNUFJkuBdjL/VvAe9NUBI2iA4PQxWdyaBaeTQA7cPDsUuUENBeCm+IBXsIjPh+H5scLCBAEIV5QqsKAFkGIUmIgTsTEl+DQFBvvCKiHBr5eqo3AtukdAUksBrmIGUgADABMIBq4BtyDJnDH6IUmBDE8DB9VLtwMcgyNSawpnJ05O5ZOy+MQcXFuYbZgK4TaTtlm4t2UmgBWN8b51OncpSUkhPpo4yeyTn1ivxNMOeOMv39Zt9F51vkie+cmTXSgkRY9C3L0VYi4rOVKy1gjkANV2QAXoU1qGMe5cxF271zWScDZ7Jlzhwi2pw046bR3wTiFYI64RzIt8RaNZQZw0w5Wvd+/cE4jl7vACsHnBq5WTkYUZhxCicE8HRfkoakVpJ42RUBH3byq4UbQCc4c5wln2XMZHDDUxujoZMHYbe4gHLuo+X8lnHixZfK6ZZmlX1e7HR4uOLKqYTAx4NSKaHVqzWso3nBouwP/CgUzKln5v4J/PrMHTLX8gARQrIPZYMnuDnuY0YW/elSR4YXD/IV2OfA6hJNaeXJT040H7h7ucLc4vTPmaMvy6H/HC56zqu0pjoa7ACAAWVjjr+mPWpvS+x+Fld8Bnnf9FQT4JFFxdeYzMXNSxgGxGAAI+Fslzf9Q/d9bEbhe1EB+x2ENw/hFFSYi1ix97lUxrEAizDiglpeFUZDJU6NBMtooqcdfNIeNURwlnUWb7wOXCOvZw07WE2ExIyxjM/s5QIQ97EbRQj1NNNFDiM1sZDO72ABrilZslm2mMXDBSHh67SAj7IdsfQZ7soqmDWKNQbaZ9gZTyc5acdhAhIOXiCi+WTdni2B2K4cmrt2/zM21e9jLMesIW9nGwcXbFz1QMQeXMZYjcZ3NRCMlTXWdhGLIhPg0dQAAAA==); } |
| 8 | + @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,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); } |
| 9 | + @font-face { font-family: Xiaolai; src: url(data:font/woff2;base64,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); } |
| 10 | + @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,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); }</style></defs><rect x="0" y="0" width="837" height="559" fill="#ffffff"></rect><g stroke-linecap="round" transform="translate(10 10) rotate(0 407.5 80)"><path d="M0 0 C195.57 0, 391.15 0, 815 0 C815 0, 815 0, 815 0 C815 40.11, 815 80.23, 815 160 C815 160, 815 160, 815 160 C594.26 160, 373.52 160, 0 160 C0 160, 0 160, 0 160 C0 114.16, 0 68.33, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#FFDAB9"></path><path d="M0 0 C163.01 0, 326.01 0, 815 0 M0 0 C280.35 0, 560.7 0, 815 0 M815 0 C815 0, 815 0, 815 0 M815 0 C815 0, 815 0, 815 0 M815 0 C815 37.6, 815 75.2, 815 160 M815 0 C815 60.65, 815 121.29, 815 160 M815 160 C815 160, 815 160, 815 160 M815 160 C815 160, 815 160, 815 160 M815 160 C626.45 160, 437.91 160, 0 160 M815 160 C626.21 160, 437.43 160, 0 160 M0 160 C0 160, 0 160, 0 160 M0 160 C0 160, 0 160, 0 160 M0 160 C0 100.22, 0 40.44, 0 0 M0 160 C0 103.55, 0 47.09, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#e8685f" stroke-width="2" fill="none"></path></g><g transform="translate(10 25) rotate(0 406 15)"><text x="406" y="19.608" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="18px" fill="#c45b47" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">HCCL集合通信算子</text></g><g stroke-linecap="round" transform="translate(45 70) rotate(0 75 35)"><path d="M0 0 C41.99 0, 83.98 0, 150 0 C150 0, 150 0, 150 0 C150 21.1, 150 42.2, 150 70 C150 70, 150 70, 150 70 C98.75 70, 47.49 70, 0 70 C0 70, 0 70, 0 70 C0 43.89, 0 17.79, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C30 0, 60.01 0, 150 0 M0 0 C43.2 0, 86.39 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 18.9, 150 37.8, 150 70 M150 0 C150 25.07, 150 50.13, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C110.6 70, 71.19 70, 0 70 M150 70 C110.51 70, 71.02 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 45.69, 0 21.39, 0 0 M0 70 C0 48.6, 0 27.21, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#c45b47" stroke-width="1" fill="none"></path></g><g transform="translate(45 98) rotate(0 75 7)"><text x="75" y="11.096" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="16px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">AllReduce</text></g><g stroke-linecap="round" transform="translate(235 70) rotate(0 75 35)"><path d="M0 0 C47.99 0, 95.97 0, 150 0 C150 0, 150 0, 150 0 C150 24.65, 150 49.3, 150 70 C150 70, 150 70, 150 70 C118.12 70, 86.24 70, 0 70 C0 70, 0 70, 0 70 C0 51.84, 0 33.68, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C30 0, 60.01 0, 150 0 M0 0 C34.79 0, 69.59 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 21.35, 150 42.7, 150 70 M150 0 C150 23.6, 150 47.2, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C105.89 70, 61.79 70, 0 70 M150 70 C105.76 70, 61.52 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 47.54, 0 25.08, 0 0 M0 70 C0 51.9, 0 33.81, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#c45b47" stroke-width="1" fill="none"></path></g><g transform="translate(235 98) rotate(0 75 7)"><text x="75" y="11.096" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="16px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">AllGather</text></g><g stroke-linecap="round" transform="translate(425 70) rotate(0 75 35)"><path d="M0 0 C53.98 0, 107.96 0, 150 0 C150 0, 150 0, 150 0 C150 14.2, 150 28.4, 150 70 C150 70, 150 70, 150 70 C107.49 70, 64.99 70, 0 70 C0 70, 0 70, 0 70 C0 45.79, 0 21.57, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C30.01 0, 60.01 0, 150 0 M0 0 C56.39 0, 112.79 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 23.8, 150 47.6, 150 70 M150 0 C150 22.13, 150 44.26, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C101.19 70, 52.39 70, 0 70 M150 70 C101.02 70, 52.03 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 49.39, 0 28.77, 0 0 M0 70 C0 55.21, 0 40.41, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#c45b47" stroke-width="1" fill="none"></path></g><g transform="translate(425 98) rotate(0 75 7)"><text x="75" y="11.096" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="16px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">ReduceScatter</text></g><g stroke-linecap="round" transform="translate(615 70) rotate(0 75 35)"><path d="M0 0 C59.98 0, 119.95 0, 150 0 C150 0, 150 0, 150 0 C150 17.75, 150 35.5, 150 70 C150 70, 150 70, 150 70 C96.87 70, 43.73 70, 0 70 C0 70, 0 70, 0 70 C0 53.73, 0 37.46, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C30.01 0, 60.01 0, 150 0 M0 0 C47.99 0, 95.98 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 26.25, 150 52.5, 150 70 M150 0 C150 20.67, 150 41.33, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C96.49 70, 42.98 70, 0 70 M150 70 C96.27 70, 42.54 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 51.23, 0 32.47, 0 0 M0 70 C0 44.51, 0 19.02, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#c45b47" stroke-width="1" fill="none"></path></g><g transform="translate(615 98) rotate(0 75 7)"><text x="75" y="11.096" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="16px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">AlltoAll</text></g><g stroke-linecap="round" transform="translate(10 200) rotate(0 408.5 80)"><path d="M0 0 C195.93 0, 391.86 0, 817 0 C817 0, 817 0, 817 0 C817 48.68, 817 97.37, 817 160 C817 160, 817 160, 817 160 C633.12 160, 449.25 160, 0 160 C0 160, 0 160, 0 160 C0 108.98, 0 57.96, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ADD8E6"></path><path d="M0 0 C163.44 0, 326.89 0, 817 0 M0 0 C215.63 0, 431.25 0, 817 0 M817 0 C817 0, 817 0, 817 0 M817 0 C817 0, 817 0, 817 0 M817 0 C817 33.6, 817 67.21, 817 160 M817 0 C817 43.88, 817 87.76, 817 160 M817 160 C817 160, 817 160, 817 160 M817 160 C817 160, 817 160, 817 160 M817 160 C499.95 160, 182.89 160, 0 160 M817 160 C498.5 160, 179.99 160, 0 160 M0 160 C0 160, 0 160, 0 160 M0 160 C0 160, 0 160, 0 160 M0 160 C0 121.33, 0 82.65, 0 0 M0 160 C0 109.28, 0 58.56, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#2b8bc0" stroke-width="2" fill="none"></path></g><g transform="translate(10 215) rotate(0 406 15)"><text x="406" y="19.608" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="18px" fill="#1a6a8f" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">集合通信域管理模块</text></g><g stroke-linecap="round" transform="translate(154 261) rotate(0 75 35)"><path d="M0 0 C41.97 0, 83.93 0, 150 0 C150 0, 150 0, 150 0 C150 24.85, 150 49.7, 150 70 C150 70, 150 70, 150 70 C105.61 70, 61.23 70, 0 70 C0 70, 0 70, 0 70 C0 55.62, 0 41.25, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C30.01 0, 60.02 0, 150 0 M0 0 C31.19 0, 62.37 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 17.15, 150 34.3, 150 70 M150 0 C150 17.73, 150 35.46, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C117.09 70, 84.18 70, 0 70 M150 70 C116.78 70, 83.55 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 54.93, 0 39.85, 0 0 M0 70 C0 51.11, 0 32.22, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#1a6a8f" stroke-width="1" fill="none"></path></g><g transform="translate(154 289) rotate(0 75 7)"><text x="75" y="10.584" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="14px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">通信域管理</text></g><g stroke-linecap="round" transform="translate(344 261) rotate(0 75 35)"><path d="M0 0 C47.96 0, 95.93 0, 150 0 C150 0, 150 0, 150 0 C150 14.4, 150 28.8, 150 70 C150 70, 150 70, 150 70 C94.99 70, 39.97 70, 0 70 C0 70, 0 70, 0 70 C0 49.57, 0 29.14, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C30.01 0, 60.02 0, 150 0 M0 0 C52.79 0, 105.57 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 19.6, 150 39.21, 150 70 M150 0 C150 16.26, 150 32.53, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C112.39 70, 74.77 70, 0 70 M150 70 C112.03 70, 74.06 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 42.77, 0 15.55, 0 0 M0 70 C0 54.41, 0 38.83, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#1a6a8f" stroke-width="1" fill="none"></path></g><g transform="translate(344 289) rotate(0 75 7)"><text x="75" y="10.584" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="14px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">通信资源管理</text></g><g stroke-linecap="round" transform="translate(534 261) rotate(0 75 35)"><path d="M0 0 C53.96 0, 107.92 0, 150 0 C150 0, 150 0, 150 0 C150 17.95, 150 35.9, 150 70 C150 70, 150 70, 150 70 C114.36 70, 78.72 70, 0 70 C0 70, 0 70, 0 70 C0 43.52, 0 17.03, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C30.01 0, 60.02 0, 150 0 M0 0 C44.38 0, 88.77 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 0, 150 0, 150 0 M150 0 C150 22.05, 150 44.11, 150 70 M150 0 C150 14.8, 150 29.6, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C150 70, 150 70, 150 70 M150 70 C107.68 70, 65.37 70, 0 70 M150 70 C107.29 70, 64.57 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 44.62, 0 19.24, 0 0 M0 70 C0 43.71, 0 17.43, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#1a6a8f" stroke-width="1" fill="none"></path></g><g transform="translate(534 289) rotate(0 75 7)"><text x="75" y="10.584" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="14px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">拓扑管理</text></g><g stroke-linecap="round" transform="translate(10 389) rotate(0 406.5 80)"><path d="M0 0 C194.84 0, 389.69 0, 813 0 C813 0, 813 0, 813 0 C813 57.25, 813 114.51, 813 160 C813 160, 813 160, 813 160 C504.64 160, 196.29 160, 0 160 C0 160, 0 160, 0 160 C0 103.79, 0 47.59, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#99FF99"></path><path d="M0 0 C162.68 0, 325.36 0, 813 0 M0 0 C312.08 0, 624.16 0, 813 0 M813 0 C813 0, 813 0, 813 0 M813 0 C813 0, 813 0, 813 0 M813 0 C813 61.61, 813 123.22, 813 160 M813 0 C813 59.12, 813 118.24, 813 160 M813 160 C813 160, 813 160, 813 160 M813 160 C813 160, 813 160, 813 160 M813 160 C532.68 160, 252.36 160, 0 160 M813 160 C530.04 160, 247.08 160, 0 160 M0 160 C0 160, 0 160, 0 160 M0 160 C0 160, 0 160, 0 160 M0 160 C0 110.43, 0 60.86, 0 0 M0 160 C0 115.01, 0 70.03, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#2e7d32" stroke-width="2" fill="none"></path></g><g transform="translate(10 405) rotate(0 405 15)"><text x="405" y="19.608" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="18px" fill="#1b5e20" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">基础通信模块</text></g><g stroke-linecap="round" transform="translate(125 451) rotate(0 130 35)"><path d="M0 0 C72.7 0, 145.41 0, 260 0 C260 0, 260 0, 260 0 C260 14.6, 260 29.2, 260 70 C260 70, 260 70, 260 70 C194.97 70, 129.93 70, 0 70 C0 70, 0 70, 0 70 C0 53.36, 0 36.71, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C52.03 0, 104.06 0, 260 0 M0 0 C85.24 0, 170.48 0, 260 0 M260 0 C260 0, 260 0, 260 0 M260 0 C260 0, 260 0, 260 0 M260 0 C260 15.4, 260 30.81, 260 70 M260 0 C260 24.4, 260 48.79, 260 70 M260 70 C260 70, 260 70, 260 70 M260 70 C260 70, 260 70, 260 70 M260 70 C162.2 70, 64.41 70, 0 70 M260 70 C161.28 70, 62.56 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 50.16, 0 30.32, 0 0 M0 70 C0 53.62, 0 37.24, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#1b5e20" stroke-width="1" fill="none"></path></g><g transform="translate(165 472) rotate(0 77.83995056152344 14)"><text x="77.83995056152344" y="10.584" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="14px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">基础通信资源</text><text x="77.83995056152344" y="24.584" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="14px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">(Channel、Thread等)</text></g><g stroke-linecap="round" transform="translate(425 451) rotate(0 130 35)"><path d="M0 0 C83.1 0, 166.19 0, 260 0 C260 0, 260 0, 260 0 C260 18.15, 260 36.3, 260 70 C260 70, 260 70, 260 70 C176.55 70, 93.09 70, 0 70 C0 70, 0 70, 0 70 C0 47.3, 0 24.6, 0 0 C0 0, 0 0, 0 0" stroke="none" stroke-width="0" fill="#ffffff"></path><path d="M0 0 C52.03 0, 104.06 0, 260 0 M0 0 C70.68 0, 141.36 0, 260 0 M260 0 C260 0, 260 0, 260 0 M260 0 C260 0, 260 0, 260 0 M260 0 C260 17.85, 260 35.71, 260 70 M260 0 C260 22.93, 260 45.86, 260 70 M260 70 C260 70, 260 70, 260 70 M260 70 C260 70, 260 70, 260 70 M260 70 C206.05 70, 152.11 70, 0 70 M260 70 C205.05 70, 150.11 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 70, 0 70, 0 70 M0 70 C0 52.01, 0 34.01, 0 0 M0 70 C0 42.92, 0 15.84, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="#1b5e20" stroke-width="1" fill="none"></path></g><g transform="translate(425 479) rotate(0 130 7)"><text x="130" y="10.584" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="14px" fill="#000000" text-anchor="middle" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">基础通信数据面</text></g></svg> |
| 11 | \ No newline at end of file |
| 12 |
| ... | @@ -0,0 +1,19 @@ |
| 2 | +# 系统概述 |
| 3 | + |
| 4 | +## 架构分层图 |
| 5 | + |
| 6 | + |
| 7 | + |
| 8 | +## 核心模块 |
| 9 | + |
| 10 | +| 模块 | 路径 | 职责 | |
| 11 | +|------|------|------| |
| 12 | +| | | | |
| 13 | + |
| 14 | +## 数据流 |
| 15 | + |
| 16 | + |
| 17 | + |
| 18 | +## 模块依赖关系 |
| 19 | + |
| 20 | + |
| 21 |
| ... | @@ -12,7 +12,7 @@ |
| 2 | - pip3 >= 20.3.0 |
| 3 | - setuptools >= 45.0.0 |
| 4 | - wheel >= 0.34.0 |
| 5 | -- gcc >= 7.3.0 |
| 6 | +- gcc & g++ : 7.3.0 至 13.3.x |
| 7 | - cmake >= 3.16.0 |
| 8 | - pkg-config >= 0.29.1(用于编译rdma-core) |
| 9 | - ccache(可选,用于提高二次编译速度) |
| ... | @@ -229,3 +229,4 @@ bash build.sh --ut |
| 11 | | protobuf | 25.1 | [protobuf-25.1.tar.gz](https://gitcode.com/cann-src-third-party/protobuf/releases/download/v25.1/protobuf-25.1.tar.gz) | |
| 12 | | rdma-core | v42.7-h1 | [rdma-core-42.7.tar.gz](https://gitcode.com/cann-src-third-party/rdma-core/releases/download/v42.7-h1/rdma-core-42.7.tar.gz) | |
| 13 | | rdma-core-patch | v42.7-h1 | [rdma-core-42.7.patch](https://gitcode.com/cann-src-third-party/rdma-core/releases/download/v42.7-h1/rdma-core-42.7.patch)| |
| 14 | +| cann-cmake | master-001 | [cmake-master-001.tar.gz](https://cann-3rd.obs.cn-north-4.myhuaweicloud.com/cmake/cmake-master-001.tar.gz) | |
| 15 | \ No newline at end of file |
| 16 |