已合并
同步 CheckerL2 最新代码到 hccl_vm #5873
git_qk创建于 27 天前
同步 CheckerL2 最新代码到 hccl_vm #5873
已合并
共 844 个文件变更+124597-83889
| @@ -1,5 +1,5 @@ | |||
| 1 | # ----------------------------------------------------------------------------------------------------------- | 1 | # ----------------------------------------------------------------------------------------------------------- |
| 2 | -# Copyright (c) 2026 Huawei Technologies Co., Ltd. | 2 | +# Copyright (c) 2025 Huawei Technologies Co., Ltd. |
| 3 | # This program is free software, you can redistribute it and/or modify it under the terms and conditions of | 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"). | 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. | 5 | # Please refer to the License for details. You may not use this file except in compliance with the License. |
| @@ -8,6 +8,102 @@ | |||
| 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 | -BasedOnStyle: LLVM | 11 | +BasedOnStyle: Google |
| 12 | +Language: Cpp | ||
| 13 | +AccessModifierOffset: -4 | ||
| 14 | +AlignConsecutiveAssignments: false | ||
| 15 | +AlignConsecutiveDeclarations: false | ||
| 16 | +AlignEscapedNewlines: Left | ||
| 17 | +AlignOperands: true | ||
| 18 | +AlignTrailingComments: true | ||
| 19 | +AllowAllArgumentsOnNextLine: true | ||
| 20 | +AllowShortLambdasOnASingleLine: Empty | ||
| 21 | +AllowAllParametersOfDeclarationOnNextLine: true | ||
| 22 | +AllowShortBlocksOnASingleLine: false | ||
| 23 | +AllowShortCaseLabelsOnASingleLine: false | ||
| 24 | +AllowShortFunctionsOnASingleLine: true | ||
| 25 | +AllowShortIfStatementsOnASingleLine: false | ||
| 26 | +AllowShortLoopsOnASingleLine: false | ||
| 27 | +AlwaysBreakAfterDefinitionReturnType: None | ||
| 28 | +AlwaysBreakBeforeMultilineStrings: false | ||
| 29 | +AlwaysBreakTemplateDeclarations: true | ||
| 30 | +BinPackArguments: true | ||
| 31 | +BinPackParameters: true | ||
| 32 | +AlignAfterOpenBracket: AlwaysBreak | ||
| 33 | + | ||
| 34 | +BraceWrapping: | ||
| 35 | + AfterCaseLabel: false | ||
| 36 | + AfterClass: false | ||
| 37 | + AfterControlStatement: false | ||
| 38 | + AfterEnum: false | ||
| 39 | + AfterFunction: true | ||
| 40 | + AfterNamespace: false | ||
| 41 | + AfterStruct: false | ||
| 42 | + AfterUnion: false | ||
| 43 | + AfterExternBlock: false | ||
| 44 | + BeforeCatch: false | ||
| 45 | + BeforeElse: false | ||
| 46 | + IndentBraces: false | ||
| 47 | + SplitEmptyFunction: false | ||
| 48 | + SplitEmptyRecord: true | ||
| 49 | + SplitEmptyNamespace: true | ||
| 50 | + | ||
| 51 | +BreakBeforeBinaryOperators: All | ||
| 52 | +BreakBeforeBraces: Custom | ||
| 53 | +BreakBeforeTernaryOperators: false | ||
| 54 | +BreakConstructorInitializersBeforeComma: false | ||
| 55 | +BreakInheritanceList: AfterColon | ||
| 56 | +ColumnLimit: 120 | ||
| 57 | +CommentPragmas: '^ IWYU pragma:' | ||
| 58 | +PackConstructorInitializers: CurrentLine | ||
| 59 | +ConstructorInitializerIndentWidth: 4 | ||
| 60 | +ContinuationIndentWidth: 4 | ||
| 61 | +Cpp11BracedListStyle: true | ||
| 62 | +DerivePointerAlignment: false | ||
| 63 | +DisableFormat: false | ||
| 64 | +ExperimentalAutoDetectBinPacking: false | ||
| 65 | +ForEachMacros: [ foreach ] | ||
| 66 | + | ||
| 67 | +IncludeCategories: | ||
| 68 | + - Regex: '^<' | ||
| 69 | + Priority: 3 | ||
| 70 | + - Regex: '^"hccl' | ||
| 71 | + Priority: 2 | ||
| 72 | + - Regex: '.*' | ||
| 73 | + Priority: 1 | ||
| 74 | + | ||
| 75 | +IndentCaseLabels: true | ||
| 12 | IndentWidth: 4 | 76 | IndentWidth: 4 |
| 13 | -UseTab: Never | 77 | +IndentWrappedFunctionNames: false |
| 78 | +KeepEmptyLinesAtTheStartOfBlocks: false | ||
| 79 | +MacroBlockBegin: '' | ||
| 80 | +MacroBlockEnd: '' | ||
| 81 | +MaxEmptyLinesToKeep: 1 | ||
| 82 | +NamespaceIndentation: Inner | ||
| 83 | + | ||
| 84 | +PenaltyBreakBeforeFirstCallParameter: 19 | ||
| 85 | +PenaltyBreakComment: 300 | ||
| 86 | +PenaltyBreakFirstLessLess: 120 | ||
| 87 | +PenaltyBreakString: 1000 | ||
| 88 | +PenaltyExcessCharacter: 1000000 | ||
| 89 | +PenaltyReturnTypeOnItsOwnLine: 60 | ||
| 90 | + | ||
| 91 | +PointerAlignment: Left | ||
| 92 | +ReflowComments: true | ||
| 93 | +SortIncludes: false | ||
| 94 | +SpaceAfterCStyleCast: false | ||
| 95 | +SpaceBeforeAssignmentOperators: true | ||
| 96 | +SpaceBeforeParens: ControlStatements | ||
| 97 | +SpaceInEmptyParentheses: false | ||
| 98 | +SpacesBeforeTrailingComments: 1 | ||
| 99 | +SpacesInAngles: false | ||
| 100 | +SpacesInContainerLiterals: true | ||
| 101 | +SpacesInCStyleCastParentheses: false | ||
| 102 | +SpacesInParentheses: false | ||
| 103 | +SpacesInSquareBrackets: false | ||
| 104 | +Standard: Latest | ||
| 105 | +TabWidth: 4 | ||
| 106 | +UseTab: Never | ||
| 107 | +DeriveLineEnding: false | ||
| 108 | +UseCRLF: false | ||
| 109 | +InsertNewlineAtEOF: true | ||
| @@ -26,4 +26,8 @@ | |||
| 26 | **/dist/ | 26 | **/dist/ |
| 27 | /coverage_report/ | 27 | /coverage_report/ |
| 28 | /ut_logs/ | 28 | /ut_logs/ |
| 29 | -/third_party/ | 29 | +/third_party/ |
| 30 | +oat_reports/ | ||
| 31 | +__pycache__/ | ||
| 32 | +**/__pycache__/ | ||
| 33 | +*.pyc | ||
| @@ -8,25 +8,23 @@ | |||
| 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 | -add_library(modeldb STATIC "") | 11 | +repos: |
| 12 | - | 12 | + # C++ 代码格式化检查 |
| 13 | -target_sources(modeldb PRIVATE | 13 | + - repo: https://gitcode.com/pre-commit-clang/mirrors-clang-format |
| 14 | - ${CMAKE_CURRENT_SOURCE_DIR}/db_hccl_db_sqlite.cc | 14 | + rev: v18.1.8 |
| 15 | - ${CMAKE_CURRENT_SOURCE_DIR}/db_hccl_db_factory.cc | 15 | + hooks: |
| 16 | - ${CMAKE_CURRENT_SOURCE_DIR}/db_hccl_op_db_ops.cc | 16 | + - id: clang-format |
| 17 | -) | 17 | + types_or: [c++, c] |
| 18 | - | 18 | + files: \.(c|h|cc|hh|cpp|hpp|cxx|hxx|h.in|proto|inl)$ |
| 19 | -target_include_directories(modeldb PRIVATE | 19 | + args: |
| 20 | - ${PROJECT_SOURCE_DIR}/include | 20 | + - "--style=file" |
| 21 | - ${PROJECT_SOURCE_DIR}/include/runnerdb | 21 | + - "--verbose" |
| 22 | -) | 22 | + - "-i" |
| 23 | - | 23 | + # OAT 合规性检查 (Open Source Audit Tool) |
| 24 | -target_link_libraries(modeldb | 24 | + - repo: https://gitcode.com/HiAgent/compliance |
| 25 | - PRIVATE log | 25 | + rev: v1.0.5 |
| 26 | - PUBLIC sqlite3 | 26 | + hooks: |
| 27 | -) | 27 | + - id: oat-check |
| 28 | - | 28 | + pass_filenames: true |
| 29 | -hcclvm_apply_common_flags(modeldb) | 29 | + stages: [pre-commit] |
| 30 | - | 30 | + verbose: true |
| 31 | -# 日志染色: 模块 tag | ||
| 32 | -target_compile_definitions(modeldb PRIVATE HCCL_VM_MODULE="RUNNERDB") | ||
| @@ -17,14 +17,21 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) | |||
| 17 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") | 17 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") |
| 18 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) | 18 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) |
| 19 | 19 | ||
| 20 | +# 主机侧各 target 的优化级别:默认 -O2(原为硬编码 -O0,checker/可达性等计算密集代码 | ||
| 21 | +# 在 -O0 下慢一个数量级)。Debug/覆盖/asan 场景可用 -DHCCLVM_OPT_LEVEL=-O0 回退。 | ||
| 22 | +set(HCCLVM_OPT_LEVEL "-O2" CACHE STRING "Optimization level for host targets (use -O0 for debug)") | ||
| 23 | + | ||
| 20 | function(hcclvm_apply_common_flags target) | 24 | function(hcclvm_apply_common_flags target) |
| 21 | target_compile_options(${target} PRIVATE | 25 | target_compile_options(${target} PRIVATE |
| 22 | -Werror | 26 | -Werror |
| 23 | -fno-common | 27 | -fno-common |
| 24 | -fno-strict-aliasing | 28 | -fno-strict-aliasing |
| 25 | -pipe | 29 | -pipe |
| 26 | - -O0 | 30 | + ${HCCLVM_OPT_LEVEL} |
| 27 | -g | 31 | -g |
| 32 | + # GCC 13 在 -O2 下内联 STL(std::copy/__builtin_memmove) 处理空区间时会误报 | ||
| 33 | + # -Wnonnull(-O0 不内联故不触发);这里仅把该类告警降级为 warning,其它仍按 -Werror。 | ||
| 34 | + -Wno-error=nonnull | ||
| 28 | ) | 35 | ) |
| 29 | target_compile_definitions(${target} PRIVATE | 36 | target_compile_definitions(${target} PRIVATE |
| 30 | _GLIBCXX_USE_CXX11_ABI=0 | 37 | _GLIBCXX_USE_CXX11_ABI=0 |
| @@ -101,7 +108,12 @@ include(cmake/third_party/yaml-cpp.cmake) | |||
| 101 | include(cmake/third_party/nlohmann_json.cmake) | 108 | include(cmake/third_party/nlohmann_json.cmake) |
| 102 | include(cmake/third_party/cli11.cmake) | 109 | include(cmake/third_party/cli11.cmake) |
| 103 | include(cmake/third_party/spdlog.cmake) | 110 | include(cmake/third_party/spdlog.cmake) |
| 104 | -include(cmake/third_party/sqlite3.cmake) | 111 | +# 存储后端模块(src/storage_backends/<模块名>/,随目录整体保留或裁剪): |
| 112 | +# 通用收集器负责发现与接入——此处先发现模块并准备各自依赖(源码缓存、客户库 | ||
| 113 | +# target)与 device 子构建交接参数;engine/composition 源码在 src 各目标建立后 | ||
| 114 | +# 经 hcclvm_storage_backends_attach 接入。本层不出现具体后端名。 | ||
| 115 | +include(${CMAKE_SOURCE_DIR}/src/storage_backends/CMakeLists.txt) | ||
| 116 | +hcclvm_storage_backends_prepare() | ||
| 105 | include(cmake/third_party/cann_cmake.cmake) | 117 | include(cmake/third_party/cann_cmake.cmake) |
| 106 | 118 | ||
| 107 | include_directories( | 119 | include_directories( |
| @@ -222,6 +234,9 @@ if(BUILD_DEVICE_ARM) | |||
| 222 | # 与旧系统交叉 GCC 的 CMake cache 隔离,避免 CMake 忽略首次配置后传入的 toolchain file。 | 234 | # 与旧系统交叉 GCC 的 CMake cache 隔离,避免 CMake 忽略首次配置后传入的 toolchain file。 |
| 223 | set(DEVICE_ARM_BUILD_DIR ${CMAKE_SOURCE_DIR}/build_device/hcc) | 235 | set(DEVICE_ARM_BUILD_DIR ${CMAKE_SOURCE_DIR}/build_device/hcc) |
| 224 | set(DEVICE_ARM_INSTALL_DIR ${CMAKE_SOURCE_DIR}/hccl_vm_install) | 236 | set(DEVICE_ARM_INSTALL_DIR ${CMAKE_SOURCE_DIR}/hccl_vm_install) |
| 237 | + # 存储后端模块的 device 交接参数(各模块自述的源码缓存/校验指纹;本层只 | ||
| 238 | + # 传递列表,不出现具体后端名) | ||
| 239 | + hcclvm_storage_backends_device_args(HCCLVM_STORAGE_BACKEND_DEVICE_ARGS) | ||
| 225 | include(ExternalProject) | 240 | include(ExternalProject) |
| 226 | ExternalProject_Add(device_arm_external | 241 | ExternalProject_Add(device_arm_external |
| 227 | SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/device_arm | 242 | SOURCE_DIR ${CMAKE_SOURCE_DIR}/src/device_arm |
| @@ -237,6 +252,7 @@ if(BUILD_DEVICE_ARM) | |||
| 237 | -DHCOMM_CODE_ROOT=${HCOMM_CODE_ROOT} | 252 | -DHCOMM_CODE_ROOT=${HCOMM_CODE_ROOT} |
| 238 | -DHCCL_CODE_ROOT=${HCCL_CODE_ROOT} | 253 | -DHCCL_CODE_ROOT=${HCCL_CODE_ROOT} |
| 239 | -DYAMLCPP_AARCH64_INSTALL_PATH=${YAMLCPP_AARCH64_INSTALL_PATH} | 254 | -DYAMLCPP_AARCH64_INSTALL_PATH=${YAMLCPP_AARCH64_INSTALL_PATH} |
| 255 | + ${HCCLVM_STORAGE_BACKEND_DEVICE_ARGS} | ||
| 240 | DEPENDS ${_yaml_cpp_aarch64_dep} | 256 | DEPENDS ${_yaml_cpp_aarch64_dep} |
| 241 | BINARY_DIR ${DEVICE_ARM_BUILD_DIR} | 257 | BINARY_DIR ${DEVICE_ARM_BUILD_DIR} |
| 242 | INSTALL_DIR ${DEVICE_ARM_INSTALL_DIR} | 258 | INSTALL_DIR ${DEVICE_ARM_INSTALL_DIR} |
| @@ -0,0 +1,98 @@ | |||
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 4 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 5 | + * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | + * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | + * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | + * See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | +--> | ||
| 11 | + | ||
| 12 | +<configuration> | ||
| 13 | + <oatconfig> | ||
| 14 | + <licensefile></licensefile> | ||
| 15 | + <policylist> | ||
| 16 | + <policy name="projectPolicy" desc=""> | ||
| 17 | + <policyitem type="license" name="CANN-2.0" path=".*" desc="Dynamically linked by module X"/> | ||
| 18 | + <policyitem type="copyright" name="Huawei Technologies Co., Ltd." path=".*" desc="Huawei copyright"/> | ||
| 19 | + </policy> | ||
| 20 | + </policylist> | ||
| 21 | + <filefilterlist> | ||
| 22 | + <filefilter name="defaultFilter" desc="Files not to check"> | ||
| 23 | + <!-- CheckerL2: skip third_party directory --> | ||
| 24 | + <filteritem type="filepath" name="third_party/.*" desc="Third-party dependencies, not CheckerL2 code"/> | ||
| 25 | + <!-- CheckerL2: skip build output directories --> | ||
| 26 | + <filteritem type="filepath" name="build/.*" desc="Build output directory"/> | ||
| 27 | + <filteritem type="filepath" name="build_device/.*" desc="Device build output directory"/> | ||
| 28 | + <!-- CheckerL2: skip new_feature directory --> | ||
| 29 | + <filteritem type="filepath" name="new_feature/.*" desc="Feature documentation directory"/> | ||
| 30 | + <!-- CheckerL2: skip hccl_vm_install binaries --> | ||
| 31 | + <filteritem type="filepath" name="hccl_vm_install/bin/.*" desc="Installed binaries"/> | ||
| 32 | + <filteritem type="filepath" name="hccl_vm_install/lib/.*" desc="Installed shared libraries"/> | ||
| 33 | + <!-- CheckerL2: skip Python cache --> | ||
| 34 | + <filteritem type="filepath" name=".*__pycache__/.*" desc="Python bytecode cache"/> | ||
| 35 | + <!-- CheckerL2: skip OAT reports --> | ||
| 36 | + <filteritem type="filepath" name="oat_reports/.*" desc="OAT scan reports"/> | ||
| 37 | + <!-- CheckerL2: skip test data files --> | ||
| 38 | + <filteritem type="filename" name="test.txt" desc="skip test data file"/> | ||
| 39 | + <filteritem type="filename" name="*.toml" desc="skip TOML config files"/> | ||
| 40 | + <filteritem type="filename" name="*.example" desc="skip example config files"/> | ||
| 41 | + <filteritem type="filepath" name="hccl_vm_install/lib64/.*" desc="Installed shared libraries"/> | ||
| 42 | + </filefilter> | ||
| 43 | + <filefilter name="defaultPolicyFilter" desc="Filters for compatibility, license header policies"> | ||
| 44 | + <filteritem type="filename" name="*.csv" desc="skip csv files"/> | ||
| 45 | + <filteritem type="filename" name="*.info" desc="skip info files"/> | ||
| 46 | + <filteritem type="filename" name="LICENSE" desc="skip LICENSE"/> | ||
| 47 | + <filteritem type="filename" name="Third_Party_Open_Source_Software_Notice" desc="skip Third_Party_Open_Source_Software_Notice"/> | ||
| 48 | + <!-- CheckerL2: additional skips --> | ||
| 49 | + <filteritem type="filename" name="*.json" desc="skip JSON config files"/> | ||
| 50 | + <filteritem type="filename" name="*.lock" desc="skip lock files"/> | ||
| 51 | + <filteritem type="filename" name=".gitignore" desc="skip gitignore"/> | ||
| 52 | + <filteritem type="filename" name=".clang-format" desc="skip clang-format config"/> | ||
| 53 | + <filteritem type="filename" name=".pre-commit-config.yaml" desc="skip pre-commit config"/> | ||
| 54 | + <filteritem type="filename" name="OAT.xml" desc="skip OAT config"/> | ||
| 55 | + <filteritem type="filename" name="*.md" desc="skip markdown documentation"/> | ||
| 56 | + </filefilter> | ||
| 57 | + <filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies"> | ||
| 58 | + </filefilter> | ||
| 59 | + <filefilter name="licenseFileNamePolicyFilter" desc="Filters for LICENSE file policies"> | ||
| 60 | + </filefilter> | ||
| 61 | + <filefilter name="readmeFileNamePolicyFilter" desc="Filters for README file policies"> | ||
| 62 | + </filefilter> | ||
| 63 | + <filefilter name="readmeOpenSourcefileNamePolicyFilter" desc="Filters for README.OpenSource file policies"> | ||
| 64 | + </filefilter> | ||
| 65 | + <filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies"> | ||
| 66 | + <filteritem type="filename" name="*.png" desc="skip png files"/> | ||
| 67 | + <filteritem type="filename" name="*.gif" desc="skip gif files"/> | ||
| 68 | + <filteritem type="filename" name="*.svg" desc="skip svg files"/> | ||
| 69 | + <filteritem type="filename" name="*.ico" desc="skip ico files"/> | ||
| 70 | + <filteritem type="filename" name="*.jpg" desc="skip jpg files"/> | ||
| 71 | + <filteritem type="filename" name="*.jpeg" desc="skip jpeg files"/> | ||
| 72 | + <filteritem type="filename" name="*.woff" desc="skip woff font files"/> | ||
| 73 | + <filteritem type="filename" name="*.woff2" desc="skip woff2 font files"/> | ||
| 74 | + <filteritem type="filename" name="*.ttf" desc="skip ttf font files"/> | ||
| 75 | + <filteritem type="filename" name="*.eot" desc="skip eot font files"/> | ||
| 76 | + <filteritem type="filename" name="*.bin" desc="skip binary files"/> | ||
| 77 | + <filteritem type="filename" name="*.db" desc="skip database files"/> | ||
| 78 | + <filteritem type="filename" name="*.map" desc="skip source map files"/> | ||
| 79 | + <filteritem type="filename" name="*.pyc" desc="skip Python bytecode files"/> | ||
| 80 | + <filteritem type="filename" name="*.example" desc="skip example config files"/> | ||
| 81 | + <filteritem type="filename" name="*.toml" desc="skip TOML config files"/> | ||
| 82 | + </filefilter> | ||
| 83 | + | ||
| 84 | + </filefilterlist> | ||
| 85 | + <licensematcherlist> | ||
| 86 | + <licensematcher name="cann License" desc="If the scanning result is InvalidLicense, you can define matching rules here. Note that quotation marks must be escaped."> | ||
| 87 | + <licensetext name=" | ||
| 88 | + This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 89 | + CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 90 | + Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 91 | + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 92 | + INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 93 | + See LICENSE in the root of the software repository for the full text of the License. | ||
| 94 | + " desc=""/> | ||
| 95 | + </licensematcher> | ||
| 96 | + </licensematcherlist> | ||
| 97 | + </oatconfig> | ||
| 98 | +</configuration> | ||
| @@ -12,6 +12,7 @@ HCCL-VM是面向华为昇腾NPU卡的高性能集合通信的虚拟执行环境 | |||
| 12 | | -------- | ------------- | | 12 | | -------- | ------------- | |
| 13 | | 系统架构 | x86_64 Ubuntu22.04及以上 | | 13 | | 系统架构 | x86_64 Ubuntu22.04及以上 | |
| 14 | | 规格约束 | Ascend950,其余参照[约束详情](#45-工具规格约束) | | 14 | | 规格约束 | Ascend950,其余参照[约束详情](#45-工具规格约束) | |
| 15 | +| QEMU(仅 AICPU 模式运行需要,x86_64 宿主) | 系统自带 qemu-user-static 可直接使用;版本低于 10.2.4 时无法限制翻译代码缓存、QEMU 常驻内存较大,大规模场景可能引发换页、明显影响性能,可按 [2.3 QEMU 部署](#23-qemu-部署仅-aicpu-模式x86_64-宿主需要) 安装 10.2.4 及以上版本优化。原生 ARM 主机不需要 QEMU;编译(`build.sh`/`build_pkg.sh`)不依赖本机已安装 QEMU | | ||
| 15 | 16 | ||
| 16 | ### 2.1 CANN包安装 | 17 | ### 2.1 CANN包安装 |
| 17 | 18 | ||
| @@ -33,6 +34,37 @@ hccl_test是昇腾官方提供的HCCL性能测试工具,详见[HCCL性能测 | |||
| 33 | 34 | ||
| 34 | 备注:可选,未来支持Pytorch用例。 | 35 | 备注:可选,未来支持Pytorch用例。 |
| 35 | 36 | ||
| 37 | +### 2.3 QEMU 部署(仅 AICPU 模式、x86_64 宿主需要) | ||
| 38 | + | ||
| 39 | +AICPU 展开模式在 x86_64 宿主上需要 QEMU 用户态模拟(linux-user 模拟 aarch64)。系统自带的 qemu-user-static 可直接使用;版本低于 **10.2.4** 时不支持 `-tb-size` 限制翻译代码缓存,QEMU 常驻内存较大,可能严重影响性能,建议安装 **10.2.4 及以上**版本。 | ||
| 40 | + | ||
| 41 | +```bash | ||
| 42 | +# 1) 构建依赖(gcc/make/ninja 一般已随系统或本工具安装存在) | ||
| 43 | +sudo apt-get install -y meson flex bison libglib2.0-dev libpcre2-dev libffi-dev | ||
| 44 | + | ||
| 45 | +# 2) 官方源码归档(示例为 10.2.4,建议 10.2.4 及以上版本) | ||
| 46 | +curl -fsSL -O https://download.qemu.org/qemu-10.2.4.tar.xz | ||
| 47 | +tar -xf qemu-10.2.4.tar.xz && cd qemu-10.2.4 | ||
| 48 | + | ||
| 49 | +# 3) 构建 aarch64 linux-user 静态版本 | ||
| 50 | +mkdir build && cd build | ||
| 51 | +../configure --target-list=aarch64-linux-user --static --disable-system --disable-tools \ | ||
| 52 | + --disable-docs --disable-guest-agent --disable-slirp | ||
| 53 | +make -j$(nproc) qemu-aarch64 | ||
| 54 | + | ||
| 55 | +# 4) 部署并配置(部署路径可自定义,示例为 /opt/qemu-10.2.4) | ||
| 56 | +sudo mkdir -p /opt/qemu-10.2.4/bin | ||
| 57 | +sudo cp qemu-aarch64 /opt/qemu-10.2.4/bin/qemu-aarch64-static | ||
| 58 | +export HCCL_VM_QEMU_PATH=/opt/qemu-10.2.4/bin/qemu-aarch64-static | ||
| 59 | +export HCCL_VM_QEMU_TB_SIZE=16 | ||
| 60 | +``` | ||
| 61 | + | ||
| 62 | +运行行为与提示: | ||
| 63 | + | ||
| 64 | +- 设备进程启动时打印实际使用的 QEMU 程序路径、版本与 `-tb-size` 请求值。 | ||
| 65 | +- `HCCL_VM_QEMU_PATH` 未设置/无效、或指向不支持 `-tb-size` 的旧版 QEMU 时**不会中断**:自动回退(按 PATH 查找 `qemu-aarch64-static` / 不传 `-tb-size`)并打 WARN,包含实际回退到的程序与版本、以及“翻译缓存未限制,QEMU 内存可能过大”提示。仅当全机找不到任何 `qemu-aarch64-static` 时 AICPU 模式启动失败。 | ||
| 66 | +- `HCCL_VM_QEMU_TB_SIZE` 为 QEMU 翻译代码缓存(MiB):未设置默认 `16`;`0` 表示委托 QEMU 自身默认策略(不是禁用缓存)。不限制缓存可能会显著增大 QEMU 常驻内存并引发换页。 | ||
| 67 | + | ||
| 36 | --- | 68 | --- |
| 37 | 69 | ||
| 38 | ## 3. 快速上手 | 70 | ## 3. 快速上手 |
| @@ -50,7 +82,7 @@ git clone https://gitcode.com/cann/hcomm.git | |||
| 50 | 82 | ||
| 51 | # 3. 安装第三方依赖 | 83 | # 3. 安装第三方依赖 |
| 52 | sudo apt-get update | 84 | sudo apt-get update |
| 53 | -sudo apt install build-essential cmake libsqlite3-dev libboost-all-dev rdma-core libibverbs-dev pkg-config gcc-aarch64-linux-gnu g++-aarch64-linux-gnu qemu-user-static binfmt-support | 85 | +sudo apt install build-essential cmake libboost-all-dev rdma-core libibverbs-dev pkg-config gcc-aarch64-linux-gnu g++-aarch64-linux-gnu |
| 54 | 86 | ||
| 55 | # 4. 编译HCCL-VM工具,下载hcomm代码之后,工具源码所在路径:/home/workspace/hcomm/test/hccl_vm | 87 | # 4. 编译HCCL-VM工具,下载hcomm代码之后,工具源码所在路径:/home/workspace/hcomm/test/hccl_vm |
| 56 | cd /home/workspace/hcomm/test/hccl_vm | 88 | cd /home/workspace/hcomm/test/hccl_vm |
| @@ -69,6 +101,9 @@ bash build_pkg.sh | |||
| 69 | 101 | ||
| 70 | 若/etc路径下已存在hccl_rootinfo.json文件,请手动删除该文件。 | 102 | 若/etc路径下已存在hccl_rootinfo.json文件,请手动删除该文件。 |
| 71 | 103 | ||
| 104 | +存储初始化与连接配置请先阅读[存储后端导航](src/storage_backends/README.md),确认是否需要额外配置; | ||
| 105 | +然后回到本节按对应执行模式运行算子。 | ||
| 106 | + | ||
| 72 | #### 3.2.2 CCU模式 | 107 | #### 3.2.2 CCU模式 |
| 73 | 108 | ||
| 74 | 1. 环境变量配置。 | 109 | 1. 环境变量配置。 |
| @@ -114,6 +149,8 @@ cd /home/workspace/hcomm/test/hccl_vm/hccl_vm_install/bin | |||
| 114 | 149 | ||
| 115 | AICPU展开模式需要将算法展开步骤放到设备侧执行,因此hccl-vm工具需要将HCCL的设备侧的符号编译并模拟执行。由于设备侧符号是ARM架构的,因此在X86环境上编译时需要借助交叉编译器,运行时需要借助QEMU实现AICPU模式的模拟运行。 | 150 | AICPU展开模式需要将算法展开步骤放到设备侧执行,因此hccl-vm工具需要将HCCL的设备侧的符号编译并模拟执行。由于设备侧符号是ARM架构的,因此在X86环境上编译时需要借助交叉编译器,运行时需要借助QEMU实现AICPU模式的模拟运行。 |
| 116 | 151 | ||
| 152 | +X86宿主上运行AICPU模式借助QEMU用户态模拟:未配置 `HCCL_VM_QEMU_PATH` 时自动回退 PATH 中的 `qemu-aarch64-static` 并打告警(含实际版本),不影响启动;系统自带版本低于 10.2.4 时无法限制翻译代码缓存、内存占用较高,大规模场景可能引发换页、影响性能,可参考 [2.3 QEMU 部署](#23-qemu-部署仅-aicpu-模式x86_64-宿主需要) 安装 10.2.4 及以上版本并配置 `HCCL_VM_QEMU_PATH`。原生ARM主机不需要QEMU。 | ||
| 153 | + | ||
| 117 | 1. 环境变量配置。 | 154 | 1. 环境变量配置。 |
| 118 | 155 | ||
| 119 | ```bash | 156 | ```bash |
| @@ -123,6 +160,10 @@ source /home/workspace/Ascend/cann/set_env.sh | |||
| 123 | export LD_LIBRARY_PATH=$ASCEND_HOME_PATH/lib64:$ASCEND_HOME_PATH/devlib:$LD_LIBRARY_PATH | 160 | export LD_LIBRARY_PATH=$ASCEND_HOME_PATH/lib64:$ASCEND_HOME_PATH/devlib:$LD_LIBRARY_PATH |
| 124 | export RANK_TABLE_FILE=$(pwd)/data/ranktable.json | 161 | export RANK_TABLE_FILE=$(pwd)/data/ranktable.json |
| 125 | export HCCL_OP_EXPANSION_MODE="AI_CPU" | 162 | export HCCL_OP_EXPANSION_MODE="AI_CPU" |
| 163 | + | ||
| 164 | +# x86_64 宿主:QEMU 程序与翻译代码缓存(MiB)配置,见 §2.3 | ||
| 165 | +export HCCL_VM_QEMU_PATH=/opt/qemu-10.2.4/bin/qemu-aarch64-static | ||
| 166 | +export HCCL_VM_QEMU_TB_SIZE=16 | ||
| 126 | ``` | 167 | ``` |
| 127 | 168 | ||
| 128 | 2. 执行 | 169 | 2. 执行 |
| @@ -230,6 +271,8 @@ export HCOMM_CODE_HOME=/home/workspace/hcomm | |||
| 230 | | `HCCL_CODE_HOME` | HCCL-VM编译指定HCCL源码路径。默认未配置。 | `export HCCL_CODE_HOME=/home/workspace/hccl` | | 271 | | `HCCL_CODE_HOME` | HCCL-VM编译指定HCCL源码路径。默认未配置。 | `export HCCL_CODE_HOME=/home/workspace/hccl` | |
| 231 | | `HCOMM_CODE_HOME` | HCCL-VM编译指定HCOMM源码路径。默认未配置。 | `export HCOMM_CODE_HOME=/home/workspace/hcomm` | | 272 | | `HCOMM_CODE_HOME` | HCCL-VM编译指定HCOMM源码路径。默认未配置。 | `export HCOMM_CODE_HOME=/home/workspace/hcomm` | |
| 232 | | `HCCLVM_ENABLE_DUMP_DATA` | 1. 使能性能仿真文件输出落盘。若使能,则在测试用例执行过程中输出3个runner_hcclvm_*_data.bin文件和1个ccu_channel_jetty_config.xml文件供性能仿真使用. <br> 2.使能Runner插件dump input\&output数据。若使能,则在测试用例执行过程中,会将每个算子的input\&output数据dump到all\_rank\_input\_output.txt文件中 | `export HCCLVM_ENABLE_DUMP_DATA=1 使能,export HCCLVM_ENABLE_DUMP_DATA=0 或不配置该环境变量 禁用` | | 273 | | `HCCLVM_ENABLE_DUMP_DATA` | 1. 使能性能仿真文件输出落盘。若使能,则在测试用例执行过程中输出3个runner_hcclvm_*_data.bin文件和1个ccu_channel_jetty_config.xml文件供性能仿真使用. <br> 2.使能Runner插件dump input\&output数据。若使能,则在测试用例执行过程中,会将每个算子的input\&output数据dump到all\_rank\_input\_output.txt文件中 | `export HCCLVM_ENABLE_DUMP_DATA=1 使能,export HCCLVM_ENABLE_DUMP_DATA=0 或不配置该环境变量 禁用` | |
| 274 | +| `HCCL_VM_QEMU_PATH` | 仅AICPU模式、x86_64宿主生效:外部QEMU程序的非空绝对路径(目标为可执行普通文件,允许指向普通文件的符号链接)。未设置/无效时自动回退 PATH 查找 `qemu-aarch64-static` 并打 WARN(含实际程序与版本);全机找不到时 AICPU 启动失败。部署步骤见[2.3 QEMU 部署](#23-qemu-部署仅-aicpu-模式x86_64-宿主需要) | `export HCCL_VM_QEMU_PATH=/opt/qemu-10.2.4/bin/qemu-aarch64-static` | | ||
| 275 | +| `HCCL_VM_QEMU_TB_SIZE` | 仅AICPU模式、x86_64宿主生效:QEMU翻译代码缓存(MiB)。未设置默认`16`;`0`表示显式传`-tb-size 0`、由QEMU自身默认策略决定(不是禁用缓存);仅接受可解析到uint32_t的十进制数字串,非法值告警并回退默认16。指向不支持`-tb-size`的旧版QEMU时不传该选项并告警内存可能过大。 | `export HCCL_VM_QEMU_TB_SIZE=16` | | ||
| 233 | 276 | ||
| 234 | ### 4.2 HCCL-Test用例构建 | 277 | ### 4.2 HCCL-Test用例构建 |
| 235 | 278 | ||
| @@ -792,7 +835,7 @@ data_size(Bytes): | aveg_time(us): | alg_bandwidth(GB/s): | check_result: | |||
| 792 | 835 | ||
| 793 | ### 开源第三方软件依赖 | 836 | ### 开源第三方软件依赖 |
| 794 | 837 | ||
| 795 | -编译本项目时,依赖的第三方开源软件列表如下,离线编译场景可下载并重命名软件包后放置在本项目内的third_party目录下。 | 838 | +编译本项目时,依赖的第三方开源软件列表如下,离线编译场景可下载并重命名软件包后放置在本项目内的third_party目录下。各存储后端模块的专属依赖及离线放置方式见对应模块目录内的 README。 |
| 796 | 839 | ||
| 797 | | 开源软件 | 版本 |下载地址 | | 840 | | 开源软件 | 版本 |下载地址 | |
| 798 | | ------------ | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | 841 | | ------------ | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | |
| @@ -800,7 +843,6 @@ data_size(Bytes): | aveg_time(us): | alg_bandwidth(GB/s): | check_result: | |||
| 800 | | json | 3.11.3 | [include.zip](https://gitcode.com/cann-src-third-party/json/releases/download/v3.11.3/include.zip) | | 843 | | json | 3.11.3 | [include.zip](https://gitcode.com/cann-src-third-party/json/releases/download/v3.11.3/include.zip) | |
| 801 | | spdlog | 1.11.0 | [spdlog-v1.11.0.tar.gz](https://raw.gitcode.com/src-openeuler/spdlog/blobs/c2dfb1aca26c607393665c836155613ff283de66/v1.11.0.tar.gz) | | 844 | | spdlog | 1.11.0 | [spdlog-v1.11.0.tar.gz](https://raw.gitcode.com/src-openeuler/spdlog/blobs/c2dfb1aca26c607393665c836155613ff283de66/v1.11.0.tar.gz) | |
| 802 | | yaml-cpp | 0.8.0 | [yaml-cpp-0.8.0.tar.gz](https://raw.gitcode.com/src-openeuler/yaml-cpp/blobs/d1ead4fff417073b9cdbf98b8b55eb0efc00b0ba/yaml-cpp-0.8.0.tar.gz) | | 845 | | yaml-cpp | 0.8.0 | [yaml-cpp-0.8.0.tar.gz](https://raw.gitcode.com/src-openeuler/yaml-cpp/blobs/d1ead4fff417073b9cdbf98b8b55eb0efc00b0ba/yaml-cpp-0.8.0.tar.gz) | |
| 803 | -| sqlite | 3.51.0 | [sqlite-amalgamation-3510300.zip](https://www.sqlite.org/2026/sqlite-amalgamation-3510300.zip) | | ||
| 804 | | googletest | 1.14.0 | [googletest-1.14.0.tar.gz](https://gitcode.com/cann-src-third-party/googletest/releases/download/v1.14.0/googletest-1.14.0.tar.gz) | | 846 | | googletest | 1.14.0 | [googletest-1.14.0.tar.gz](https://gitcode.com/cann-src-third-party/googletest/releases/download/v1.14.0/googletest-1.14.0.tar.gz) | |
| 805 | | cann-cmake | master-044 | [cmake-master-044.tar.gz](https://raw.gitcode.com/cann/cmake/archive/refs/heads/master-044.tar.gz) | | 847 | | cann-cmake | master-044 | [cmake-master-044.tar.gz](https://raw.gitcode.com/cann/cmake/archive/refs/heads/master-044.tar.gz) | |
| 806 | 848 | ||
| @@ -818,5 +860,5 @@ data_size(Bytes): | aveg_time(us): | alg_bandwidth(GB/s): | check_result: | |||
| 818 | 860 | ||
| 819 | --- | 861 | --- |
| 820 | 862 | ||
| 821 | -**文档版本**:v1.1。 | 863 | +**文档版本**:v1.2。 |
| 822 | -**最后更新**:2026-06-30。 | 864 | +**最后更新**:2026-09-19。 |
| @@ -25,14 +25,22 @@ function usage() { | |||
| 25 | echo " Set ascend package install path, default /usr/local/Ascend/cann" | 25 | echo " Set ascend package install path, default /usr/local/Ascend/cann" |
| 26 | echo " --hcomm-path <PATH>" | 26 | echo " --hcomm-path <PATH>" |
| 27 | echo " Set hcomm code path, default /home/teamserver/xx/hcomm" | 27 | echo " Set hcomm code path, default /home/teamserver/xx/hcomm" |
| 28 | - echo " --version <VERSION>" | 28 | + echo " --version <VERSION>" |
| 29 | - echo " Set build version to <VERSION>" | 29 | + echo " Set build version to <VERSION>" |
| 30 | + echo " --cmake-arg <ARG>" | ||
| 31 | + echo " Pass a single CMake argument through to the configure" | ||
| 32 | + echo " step (repeatable, e.g. --cmake-arg -DBUILD_TESTS=ON)" | ||
| 33 | + echo "" | ||
| 34 | +echo "Environment:" | ||
| 35 | +echo " (存储后端模块随 src/storage_backends/ 目录编入,无环境变量开关;" | ||
| 36 | +echo " 后端模块自身的构建选项经 --cmake-arg 透传)" | ||
| 30 | echo "" | 37 | echo "" |
| 31 | } | 38 | } |
| 32 | 39 | ||
| 33 | BUILD_MODE="HCCLVM" | 40 | BUILD_MODE="HCCLVM" |
| 34 | aiv_build_enable="OFF" | 41 | aiv_build_enable="OFF" |
| 35 | package_enable=false | 42 | package_enable=false |
| 43 | +cmake_extra_args=() | ||
| 36 | 44 | ||
| 37 | while [[ $# -gt 0 ]]; do | 45 | while [[ $# -gt 0 ]]; do |
| 38 | case "$1" in | 46 | case "$1" in |
| @@ -52,6 +60,10 @@ while [[ $# -gt 0 ]]; do | |||
| 52 | aiv_build_enable="ON" | 60 | aiv_build_enable="ON" |
| 53 | shift 1 | 61 | shift 1 |
| 54 | ;; | 62 | ;; |
| 63 | + --cmake-arg) | ||
| 64 | + cmake_extra_args+=("$2") | ||
| 65 | + shift 2 | ||
| 66 | + ;; | ||
| 55 | --full) | 67 | --full) |
| 56 | BUILD_MODE="FULL" | 68 | BUILD_MODE="FULL" |
| 57 | aiv_build_enable="ON" | 69 | aiv_build_enable="ON" |
| @@ -123,28 +135,35 @@ if [[ "$BUILD_MODE" == "FULL" || "$BUILD_MODE" == "DEVICE" || "$aiv_build_enable | |||
| 123 | echo "HCCL_CODE_PATH is set to: ${HCCL_CODE_PATH}" | 135 | echo "HCCL_CODE_PATH is set to: ${HCCL_CODE_PATH}" |
| 124 | fi | 136 | fi |
| 125 | 137 | ||
| 126 | -if [ -n "${ascend_package_path}" ];then | 138 | +# Resolve CANN toolkit path via priority chain |
| 127 | - ASCEND_CANN_PACKAGE_PATH=${ascend_package_path} | 139 | +_non_empty_candidates=("${ascend_package_path}" "${ASCEND_HOME_PATH}") |
| 128 | - source ${ASCEND_CANN_PACKAGE_PATH}/set_env.sh | 140 | +[ -n "${ASCEND_OPP_PATH}" ] && _non_empty_candidates+=("$(dirname "${ASCEND_OPP_PATH}")") |
| 129 | -elif [ -n "${ASCEND_HOME_PATH}" ];then | 141 | +_dir_candidates=("${DEFAULT_TOOLKIT_INSTALL_DIR}" "${DEFAULT_INSTALL_DIR}") |
| 130 | - ASCEND_CANN_PACKAGE_PATH=${ASCEND_HOME_PATH} | 142 | + |
| 131 | -elif [ -n "${ASCEND_OPP_PATH}" ];then | 143 | +_resolved=false |
| 132 | - ASCEND_CANN_PACKAGE_PATH=$(dirname ${ASCEND_OPP_PATH}) | 144 | +for _p in "${_non_empty_candidates[@]}"; do |
| 133 | -elif [ -d "${DEFAULT_TOOLKIT_INSTALL_DIR}" ];then | 145 | + [ -n "${_p}" ] && { ASCEND_CANN_PACKAGE_PATH="${_p}"; _resolved=true; break; } |
| 134 | - ASCEND_CANN_PACKAGE_PATH=${DEFAULT_TOOLKIT_INSTALL_DIR} | 146 | +done |
| 135 | -elif [ -d "${DEFAULT_INSTALL_DIR}" ];then | 147 | +if ! ${_resolved}; then |
| 136 | - ASCEND_CANN_PACKAGE_PATH=${DEFAULT_INSTALL_DIR} | 148 | + for _p in "${_dir_candidates[@]}"; do |
| 137 | -else | 149 | + [ -d "${_p}" ] && { ASCEND_CANN_PACKAGE_PATH="${_p}"; _resolved=true; break; } |
| 138 | - echo "Error: Please set the toolkit package installation directory through parameter --package-path." | 150 | + done |
| 139 | - exit 1 | ||
| 140 | fi | 151 | fi |
| 141 | 152 | ||
| 153 | +if ${_resolved} && [ "${ASCEND_CANN_PACKAGE_PATH}" = "${ascend_package_path}" ]; then | ||
| 154 | + source "${ASCEND_CANN_PACKAGE_PATH}/set_env.sh" | ||
| 155 | +fi | ||
| 156 | +${_resolved} || { echo "Error: Unable to locate toolkit installation path. Use --package-path to specify it."; exit 1; } | ||
| 157 | + | ||
| 142 | # 检查 source 是否成功(可选) | 158 | # 检查 source 是否成功(可选) |
| 143 | if [[ $? -ne 0 ]]; then | 159 | if [[ $? -ne 0 ]]; then |
| 144 | echo "Error: Failed to source set_env.sh of cann" | 160 | echo "Error: Failed to source set_env.sh of cann" |
| 145 | exit 1 | 161 | exit 1 |
| 146 | fi | 162 | fi |
| 147 | 163 | ||
| 164 | +# CMake 选项均取目录默认(存储后端模块随目录编入);模块专属配置(如后端模块 | ||
| 165 | +# 的链接形态选项)经 --cmake-arg 逐项透传,本脚本不感知具体后端名。 | ||
| 166 | + | ||
| 148 | build_host() { | 167 | build_host() { |
| 149 | # 创建 build 目录(如果不存在)并进入 | 168 | # 创建 build 目录(如果不存在)并进入 |
| 150 | mkdir -p build | 169 | mkdir -p build |
| @@ -152,7 +171,7 @@ build_host() { | |||
| 152 | 171 | ||
| 153 | # 执行编译命令 | 172 | # 执行编译命令 |
| 154 | echo "Running cmake and make..." | 173 | echo "Running cmake and make..." |
| 155 | - cmake -DBUILD_DEVICE_ARM=OFF -DBUILD_AIV=$aiv_build_enable .. && make -j16 && make install | 174 | + cmake -DBUILD_DEVICE_ARM=OFF -DBUILD_AIV=$aiv_build_enable ${cmake_extra_args[@]+"${cmake_extra_args[@]}"} .. && make -j16 && make install |
| 156 | 175 | ||
| 157 | # 检查编译是否成功 | 176 | # 检查编译是否成功 |
| 158 | if [[ $? -eq 0 ]]; then | 177 | if [[ $? -eq 0 ]]; then |
| @@ -172,7 +191,7 @@ build_host() { | |||
| 172 | build_device() { | 191 | build_device() { |
| 173 | mkdir -p build | 192 | mkdir -p build |
| 174 | cd build | 193 | cd build |
| 175 | - cmake -DBUILD_DEVICE_ARM=ON .. && make -j16 | 194 | + cmake -DBUILD_DEVICE_ARM=ON ${cmake_extra_args[@]+"${cmake_extra_args[@]}"} .. && make -j16 |
| 176 | cd .. | 195 | cd .. |
| 177 | } | 196 | } |
| 178 | 197 | ||
| @@ -10,6 +10,7 @@ | |||
| 10 | # See LICENSE in the root of the software repository for the full text of the License. | 10 | # See LICENSE in the root of the software repository for the full text of the License. |
| 11 | # ----------------------------------------------------------------------------------------------------------- | 11 | # ----------------------------------------------------------------------------------------------------------- |
| 12 | 12 | ||
| 13 | +#!/usr/bin/env python3 | ||
| 13 | """ | 14 | """ |
| 14 | FAQ Markdown 转 HTML 转换脚本 | 15 | FAQ Markdown 转 HTML 转换脚本 |
| 15 | 16 | ||
| @@ -10,6 +10,7 @@ | |||
| 10 | # See LICENSE in the root of the software repository for the full text of the License. | 10 | # See LICENSE in the root of the software repository for the full text of the License. |
| 11 | # ----------------------------------------------------------------------------------------------------------- | 11 | # ----------------------------------------------------------------------------------------------------------- |
| 12 | 12 | ||
| 13 | +#!/usr/bin/env python3 | ||
| 13 | """ | 14 | """ |
| 14 | FAQ Markdown 转 HTML 转换脚本 | 15 | FAQ Markdown 转 HTML 转换脚本 |
| 15 | 16 | ||
| @@ -0,0 +1,354 @@ | |||
| 1 | +# CheckerL2 三方头文件依赖清单 | ||
| 2 | + | ||
| 3 | +> 基于 `CheckerL2` 版本梳理,列出所有三方头文件的依赖关系。 | ||
| 4 | + | ||
| 5 | +## 说明 | ||
| 6 | + | ||
| 7 | +本文档列出项目中通过 `#include` 实际引用的所有三方头文件,标注其来源(CANN / HCCL / HCOMM)及在磁盘上的实际路径。 | ||
| 8 | + | ||
| 9 | +**路径约定**: | ||
| 10 | +- CANN 根目录:`/home/teamserver/workspace/Ascend/cann-9.1.0/`(下文以 `CANN/` 缩写) | ||
| 11 | +- HCOMM 根目录:`/home/teamserver/workspace/hcomm/`(下文以 `HCOMM/` 缩写) | ||
| 12 | +- HCCL 根目录:`/home/teamserver/workspace/hccl/`(下文以 `HCCL/` 缩写) | ||
| 13 | +- 项目根目录:`CheckerL2/`(下文以 `项目/` 缩写) | ||
| 14 | + | ||
| 15 | +**解析原则**:CMake 中 `target_include_directories` 的声明顺序决定搜索优先级,先找到的优先使用。 | ||
| 16 | + | ||
| 17 | +--- | ||
| 18 | + | ||
| 19 | +## 一、来自 CANN 的头文件 | ||
| 20 | + | ||
| 21 | +### 1.1 ACL 运行时接口(`CANN/include/acl/`) | ||
| 22 | + | ||
| 23 | +| #include | 实际文件路径 | 引用位置 | | ||
| 24 | +|----------|------------|---------| | ||
| 25 | +| `acl/acl_base.h` | `CANN/include/acl/acl_base.h` | proxy 下所有 aclrt_*.cc、hccl_comm_stub.cc、hccp_stub.cc、hccp_ra_socket_stub.cc、ascend_hal_stub.cc、aclrt_exec_control.cc;include/runnerdb/db_sim_runner_common.h;test/proxy/ | | ||
| 26 | +| `acl/acl_rt.h` | `CANN/include/acl/acl_rt.h` | proxy 下所有 aclrt_*.cc、hccl_op_stub.cc;test/proxy/ | | ||
| 27 | + | ||
| 28 | +### 1.2 HCCL 公开接口(`CANN/include/hccl/`) | ||
| 29 | + | ||
| 30 | +| #include | 实际文件路径 | 引用位置 | | ||
| 31 | +|----------|------------|---------| | ||
| 32 | +| `hccl/hccl_types.h` | `CANN/include/hccl/hccl_types.h` | proxy/aclrt_kernel_stub.cc、hccl_op_stub.cc、hccl_proxy_common.h;plugin/runner/ccu_executor/ccu_fp16.h;common/sim_data_dump.cc;device_arm/level2/proxy/device_sqe_parse_stub.h;test/proxy/ | | ||
| 33 | +| `hccl/hccl.h` | `CANN/include/hccl/hccl.h` | **proxy/hccl_op_stub.cc**;test/proxy/hccl_comm_stub_test.cc | | ||
| 34 | +| `hccl/hcom.h` | `CANN/include/hccl/hcom.h` | proxy/hccl_inner_stub.cc;test/proxy/hccl_inner_stub_test.cc | | ||
| 35 | +| `hccl/base.h` | `CANN/include/hccl/base.h` | proxy/aclrt_context_stub.cc;plugin/runner/ccu_executor/ccu_fp16.h;plugin/checker/header/external/task_param.h;include/sim_ip_address.h | | ||
| 36 | +| `hccl/dtype_common.h` | `CANN/include/hccl/dtype_common.h` | proxy/scatter_stub.cc;test/proxy/scatter_stub_test.cc | | ||
| 37 | +| `hccl/hccl_common.h` | `CANN/x86_64-linux/asc/include/adv_api/hccl/hccl_common.h` | test/proxy/hccl_proxy_common_test.cc | | ||
| 38 | + | ||
| 39 | +### 1.3 HCCL 内部接口(`CANN/pkg_inc/hccl/`) | ||
| 40 | + | ||
| 41 | +| #include | 实际文件路径 | 引用位置 | | ||
| 42 | +|----------|------------|---------| | ||
| 43 | +| `"dtype_common.h"` | `CANN/pkg_inc/hccl/dtype_common.h` | proxy/aclrt_new_stub.cc、hccp_ccu_stub.cc、hccp_stub.cc、hccl_op_stub.cc、aclrt_device_stub.cc、hccl_proxy_common.cc;plugin/runner/runner_utils/storage_manager.h;plugin/checker/src/framework/task_graph_generator_v3/ccu_graph_generator_v3/ccu_all_rank_param_recorder_v3.h;plugin/checker/src/framework/task_graph_generator/ccu_all_rank_param_recorder.h;plugin/checker/src/utils/storage_manager.h | | ||
| 44 | + | ||
| 45 | +### 1.4 CANN Runtime 接口(`CANN/pkg_inc/runtime/`) | ||
| 46 | + | ||
| 47 | +| #include | 实际文件路径 | 引用位置 | | ||
| 48 | +|----------|------------|---------| | ||
| 49 | +| `"runtime/base.h"` | `CANN/pkg_inc/runtime/runtime/base.h` | proxy/hccl_comm_stub.cc、aclrt_runtime_config.cc、aclrt_notify_stub.cc、hccp_stub.cc、aclrt_device_stub.cc、hccp_ra_socket_stub.cc、aclrt_stream_stub.cc、aclrt_stub.cc;test/proxy/ | | ||
| 50 | +| `"runtime/event.h"` | `CANN/pkg_inc/runtime/runtime/event.h` | proxy/aclrt_runtime_config.cc、aclrt_notify_stub.cc | | ||
| 51 | +| `"runtime/rt.h"` | `CANN/pkg_inc/runtime/runtime/rt.h` | device_arm/level2/proxy/device_sqe_parse_stub.h | | ||
| 52 | + | ||
| 53 | +### 1.5 CANN Profiling 接口(`CANN/pkg_inc/profiling/`) | ||
| 54 | + | ||
| 55 | +| #include | 实际文件路径 | 引用位置 | | ||
| 56 | +|----------|------------|---------| | ||
| 57 | +| `"aprof_pub.h"` | `CANN/pkg_inc/profiling/aprof_pub.h` | proxy/aprofiling_stub.cc;device_arm/level2/proxy/aprofiling_stub.cc;test/proxy/aprofiling_stub_test.cc | | ||
| 58 | + | ||
| 59 | +### 1.6 CANN Trace 接口(`CANN/pkg_inc/trace/`) | ||
| 60 | + | ||
| 61 | +| #include | 实际文件路径 | 引用位置 | | ||
| 62 | +|----------|------------|---------| | ||
| 63 | +| `"atrace_pub.h"` | `CANN/pkg_inc/trace/atrace_pub.h` | proxy/adapter_rts_stub.cc | | ||
| 64 | +| `"atrace_types.h"` | `CANN/pkg_inc/trace/atrace_types.h` | proxy/aclrt_new_stub.cc、hccp_stub.cc | | ||
| 65 | + | ||
| 66 | +### 1.7 CANN 驱动接口(`CANN/include/driver/`) | ||
| 67 | + | ||
| 68 | +| #include | 实际文件路径 | 引用位置 | | ||
| 69 | +|----------|------------|---------| | ||
| 70 | +| `"ascend_hal.h"` | `CANN/include/driver/ascend_hal.h` | proxy/adapter_rts_stub.cc、aclrt_new_stub.cc、ascend_hal_stub.cc;device_arm/level2/proxy/device_sqe_parse_stub.h、ascend_hal_stub.cc;test/device_arm/ | | ||
| 71 | + | ||
| 72 | +### 1.8 CANN Base 接口(`CANN/pkg_inc/base/`) | ||
| 73 | + | ||
| 74 | +| #include | 实际文件路径 | 引用位置 | | ||
| 75 | +|----------|------------|---------| | ||
| 76 | +| `"dlog_pub.h"` | `CANN/pkg_inc/base/dlog_pub.h` | plugin/checker/header/external/log.h(作为 fallback) | | ||
| 77 | +| `"log_types.h"` | `CANN/pkg_inc/base/log_types.h` | plugin/checker/header/external/dlog_pub.h | | ||
| 78 | + | ||
| 79 | +### 1.9 CANN CCU 微码接口(`CANN/pkg_inc/hcomm/ccu/`) | ||
| 80 | + | ||
| 81 | +| #include | 实际文件路径 | 引用位置 | | ||
| 82 | +|----------|------------|---------| | ||
| 83 | +| `"ccu_microcode_v1.h"` | `CANN/pkg_inc/hcomm/ccu/ccu_microcode_v1.h` | proxy/hccp_ccu_stub.cc;plugin/runner/ccu_executor/ccu_resource_manager.cc、ccu_resource_common.h;plugin/checker/header/external/ccu_rep_base.h、ccu_instr_info.h;plugin/checker/header/internal/binary_data_type_pub.h;plugin/checker/src/framework/task_graph_generator_v3/ccu_graph_generator_v3/ 多个文件;plugin/checker/src/framework/task_graph_generator/ 多个文件;include/sim_binary_data_type_pub.h | | ||
| 84 | +| `"ccu_common.h"` | `CANN/pkg_inc/hcomm/ccu/ccu_common.h` | proxy/hccp_ccu_stub.cc | | ||
| 85 | + | ||
| 86 | +### 1.10 CANN RTS 设备接口(`CANN/pkg_inc/runtime/runtime/rts/`) | ||
| 87 | + | ||
| 88 | +| #include | 实际文件路径 | 引用位置 | | ||
| 89 | +|----------|------------|---------| | ||
| 90 | +| `"rts_device.h"` | `CANN/pkg_inc/runtime/runtime/rts/rts_device.h` | proxy/hccp_stub.cc、adapter_rts_stub.cc、aclrt_new_stub.cc | | ||
| 91 | + | ||
| 92 | +### 1.11 CANN Runtime 其他接口(`CANN/pkg_inc/runtime/`) | ||
| 93 | + | ||
| 94 | +| #include | 实际文件路径 | 引用位置 | | ||
| 95 | +|----------|------------|---------| | ||
| 96 | +| `"mem.h"` | `CANN/pkg_inc/runtime/mem.h` | proxy/hccp_stub.cc、aclrt_new_stub.cc | | ||
| 97 | +| `"rt_external_kernel.h"` | `CANN/pkg_inc/runtime/rt_external_kernel.h` | proxy/hccp_ccu_stub.cc | | ||
| 98 | + | ||
| 99 | +--- | ||
| 100 | + | ||
| 101 | +## 二、来自 HCOMM 的头文件 | ||
| 102 | + | ||
| 103 | +### 2.1 HCCP 网络接口(`HCOMM/src/base_comm/resources/hccp/inc/network/`) | ||
| 104 | + | ||
| 105 | +| #include | 实际文件路径 | 引用位置 | | ||
| 106 | +|----------|------------|---------| | ||
| 107 | +| `"hccp.h"` | `HCOMM/src/base_comm/resources/hccp/inc/network/hccp.h` | proxy/adapter_rts_stub.cc | | ||
| 108 | +| `"hccp_async.h"` | `HCOMM/src/base_comm/resources/hccp/inc/network/hccp_async.h` | proxy/adapter_rts_stub.cc | | ||
| 109 | +| `"hccp_ping.h"` | `HCOMM/src/base_comm/resources/hccp/inc/network/hccp_ping.h` | proxy/adapter_rts_stub.cc | | ||
| 110 | +| `"hccp_tlv.h"` | `HCOMM/src/base_comm/resources/hccp/inc/network/hccp_tlv.h` | proxy/adapter_rts_stub.cc、hccp_stub.cc、**hccp_ccu_stub.cc** | | ||
| 111 | +| `"hccp_ctx.h"` | `HCOMM/src/base_comm/resources/hccp/inc/network/hccp_ctx.h` | proxy/hccp_ccu_stub.cc、hccp_stub.cc | | ||
| 112 | +| `"hccp_common.h"` | `HCOMM/src/base_comm/resources/hccp/inc/network/hccp_common.h` | proxy/hccl_comm_stub.cc、aclrt_new_stub.cc、hccp_ccu_stub.cc、hccp_stub.cc、hccp_ra_socket_stub.cc | | ||
| 113 | + | ||
| 114 | +### 2.2 HCCP CCU 外部依赖(`HCOMM/src/base_comm/resources/hccp/external_depends/ccu/`) | ||
| 115 | + | ||
| 116 | +| #include | 实际文件路径 | 引用位置 | | ||
| 117 | +|----------|------------|---------| | ||
| 118 | +| `"ccu_u_comm.h"` | `HCOMM/src/base_comm/resources/hccp/external_depends/ccu/ccu_u_comm.h` | proxy/hccp_ccu_stub.cc | | ||
| 119 | + | ||
| 120 | +--- | ||
| 121 | + | ||
| 122 | +## 三、来自 HCCL 的头文件(仅 ARM 交叉编译使用) | ||
| 123 | + | ||
| 124 | +### 3.1 算子通用接口(`HCCL/src/ops/op_common/inc/`) | ||
| 125 | + | ||
| 126 | +| #include | 实际文件路径 | 引用位置 | | ||
| 127 | +|----------|------------|---------| | ||
| 128 | +| `"alg_param.h"` | `HCCL/src/ops/op_common/inc/alg_param.h` | device_arm/hccl_kernel_executor.cc;test/device_arm/ | | ||
| 129 | + | ||
| 130 | +### 3.2 HCCL 公共代码(`HCCL/src/common/`) | ||
| 131 | + | ||
| 132 | +| #include | 实际文件路径 | 引用位置 | | ||
| 133 | +|----------|------------|---------| | ||
| 134 | +| (多个头文件通过 include 路径暴露) | `HCCL/src/common/*.h` | 仅 device_arm 构建模块通过 include 路径间接引用 | | ||
| 135 | + | ||
| 136 | +### 3.3 动态符号加载(`HCCL/src/common/hcomm_dlsym/` 及 `ccu/`) | ||
| 137 | + | ||
| 138 | +| #include | 实际文件路径 | 引用位置 | | ||
| 139 | +|----------|------------|---------| | ||
| 140 | +| (多个头文件通过 include 路径暴露) | `HCCL/src/common/hcomm_dlsym/*.h`、`HCCL/src/common/hcomm_dlsym/ccu/*.h`、`*.hpp` | 仅 device_arm 构建模块通过 include 路径间接引用 | | ||
| 141 | + | ||
| 142 | +--- | ||
| 143 | + | ||
| 144 | +## 四、项目本地 External 头文件(Checker 专用,HCCL 接口定义副本) | ||
| 145 | + | ||
| 146 | +路径:`项目/src/plugin/checker/header/external/` | ||
| 147 | + | ||
| 148 | +当 CANN 包中不存在同名头文件时,使用这些本地副本作为 fallback。 | ||
| 149 | + | ||
| 150 | +| 文件名 | 说明 | 引用位置 | | ||
| 151 | +|-------|------|---------| | ||
| 152 | +| `hccl_types.h` | HcclResult 枚举(HCCL_SUCCESS 等 24 个错误码) | plugin/checker/ 下 50+ 文件通过 `#include "hccl_types.h"` 引用;include/sim_binary_data_type_pub.h、sim_loader.h、sim_ccu_jetty_ctx.h、sim_ccu_channel_ctx.h 等 | | ||
| 153 | +| `base.h` | 基础类型定义 | plugin/checker/ 下 19 处引用(framework、semantics_check、checker 等);header/external/log.h | | ||
| 154 | +| `data_type.h` | 数据类型定义 | plugin/checker/src/framework/task_graph_generator_v3/ 下 3 处、task_graph_generator/ 下 4 处 | | ||
| 155 | +| `ccu_instr_info.h` | CCU 指令信息 | plugin/checker/ 下 8 处引用(task_ccu.h、task_utils.cc、task_graph_generator 等) | | ||
| 156 | +| `ccu_task_param.h` | CCU 任务参数 | plugin/checker/src/utils/task_ccu.h | | ||
| 157 | +| `ccu_rep_base.h` | CCU Reporter 基础 | 文件存在,当前无直接 `#include` 引用 | | ||
| 158 | +| `ccu_rep_type.h` | CCU Reporter 类型 | 文件存在,当前无直接 `#include` 引用 | | ||
| 159 | +| `dlog_pub.h` | 日志公共接口(CANN 的 fallback) | plugin/checker/header/external/log.h | | ||
| 160 | +| `enum_factory.h` | 枚举工厂 | plugin/checker/ 内部 5 处引用(sim_task.h、check_utils.h、data_slice.h、data_type.h、task_param.h) | | ||
| 161 | +| `const_val.h` | 常量值定义 | plugin/checker/header/external/task_param.h | | ||
| 162 | +| `log.h` | 日志接口 | plugin/checker/ 内部 | | ||
| 163 | +| `log_types.h` | 日志类型(CANN 的 fallback) | plugin/checker/header/external/dlog_pub.h | | ||
| 164 | +| `string_util.h` | 字符串工具 | plugin/checker/header/external/enum_factory.h;header/internal/task_def.h;src/utils/check_utils.h | | ||
| 165 | +| `task_param.h` | 任务参数 | 文件存在,当前无直接 `#include` 引用(被其他头文件内部包含) | | ||
| 166 | + | ||
| 167 | +--- | ||
| 168 | + | ||
| 169 | +## 五、AIV 依赖(AIV 算子仿真专用) | ||
| 170 | + | ||
| 171 | +本章节说明工具中 AIV(AI Vector Core)算子仿真相关的依赖项。这些依赖源自 HCOMM 仓库和 AscendC 编程接口,工具为了解除对外部仓库的强依赖,部分关键定义已在项目内部做了备份。 | ||
| 172 | + | ||
| 173 | +### 5.1 AivOpArgs 数据结构(项目内备份) | ||
| 174 | + | ||
| 175 | +**原始来源**:HCOMM 仓库的 `hccl_aiv_utils.h` 头文件 | ||
| 176 | + | ||
| 177 | +**备份位置**:`src/proxy/level2/aclrt_kernel_stub.cc` 第 597-628 行 | ||
| 178 | + | ||
| 179 | +**说明**:`AivOpArgs` 是 AIV 集合通信算子的参数结构体,用于在 host 端与 device 端之间传递 AIV kernel 的执行参数。工具原本通过 `dlsym` 动态加载 HCOMM 库中的 `ops_hccl::ExecuteKernelLaunch()` 函数(符号名:`_ZN8ops_hccl19ExecuteKernelLaunchERKNS_9AivOpArgsE`),该函数接收此结构体作为参数。为了解除对 HCOMM 运行时库的依赖,工具在项目内部做了结构体的完整备份。 | ||
| 180 | + | ||
| 181 | +**结构体定义**: | ||
| 182 | +```cpp | ||
| 183 | +struct AivOpArgs { | ||
| 184 | + HcclCMDType cmdType = HcclCMDType::HCCL_CMD_MAX; // 集合通信命令类型 | ||
| 185 | + std::string comm = {}; // 通信域标识 | ||
| 186 | + HcclComm hcclComm = nullptr; // HCCL 通信器句柄 | ||
| 187 | + uint32_t numBlocks = AIV_STUB_MAX_NUM_BLOCKS; // AIV 核数 | ||
| 188 | + void *stream = nullptr; // 执行流 | ||
| 189 | + uint64_t beginTime = 0; // 开始时间戳 | ||
| 190 | + OpCounterInfo counter = {}; // 计数器信息 | ||
| 191 | + void *buffersIn = nullptr; // 输入缓冲区地址 | ||
| 192 | + uint64_t input = 0; // 输入偏移 | ||
| 193 | + uint64_t output = 0; // 输出偏移 | ||
| 194 | + uint32_t rank = 0; // 当前 rank | ||
| 195 | + uint32_t sendRecvRemoteRank = 0; // SendRecv 远端 rank | ||
| 196 | + uint32_t rankSize = 0; // rank 总数 | ||
| 197 | + uint64_t xRankSize = 0, yRankSize = 0, zRankSize = 0; // 拓扑维度 | ||
| 198 | + uint64_t count = 0; // 元素数量 | ||
| 199 | + HcclDataType dataType = HcclDataType::HCCL_DATA_TYPE_INT32; // 数据类型 | ||
| 200 | + HcclReduceOp op = HcclReduceOp::HCCL_REDUCE_SUM; // Reduce 操作类型 | ||
| 201 | + uint32_t root = 0; // Root rank | ||
| 202 | + uint32_t sliceId = 0; // Slice ID | ||
| 203 | + uint64_t inputSliceStride = 0; // 输入 slice 步长 | ||
| 204 | + uint64_t outputSliceStride = 0; // 输出 slice 步长 | ||
| 205 | + uint64_t repeatNum = 0; // 重复次数 | ||
| 206 | + uint64_t inputRepeatStride = 0; // 输入重复步长 | ||
| 207 | + uint64_t outputRepeatStride = 0; // 输出重复步长 | ||
| 208 | + bool isOpBase = false; // 是否为基础算子 | ||
| 209 | + ExtraArgs extraArgs = {}; // 额外参数(AllToAllV 等) | ||
| 210 | + uint64_t topo_[AIV_STUB_TOPO_LEN] = {0}; // 拓扑信息 | ||
| 211 | + KernelArgsType argsType = KernelArgsType::ARGS_TYPE_SERVER; // 参数类型 | ||
| 212 | +}; | ||
| 213 | +``` | ||
| 214 | + | ||
| 215 | +**依赖风险**:若 HCOMM 侧 `AivOpArgs` 结构体发生变化(如字段增删、顺序调整、类型变更),可能导致工具通过 `dlsym` 调用时参数错位,引发运行时错误。 | ||
| 216 | + | ||
| 217 | +### 5.2 aiv_communication_base_v2.h 头文件(项目内备份) | ||
| 218 | + | ||
| 219 | +**原始来源**:HCOMM 仓库的同名头文件 | ||
| 220 | + | ||
| 221 | +**备份位置**:`src/proxy/level2/aiv_kernel/hccl_op_stub/aiv_communication_base_v2.h` | ||
| 222 | + | ||
| 223 | +**说明**:此头文件定义了 AIV 集合通信算子的基类 `AivCommBase`,以及相关的内核参数宏定义(`KERNEL_ARGS_DEF`、`KERNEL_ARGS_CALL` 等)。工具原本直接 include HCOMM 仓库中的该文件,为了解除依赖,在项目内部做了完整备份。 | ||
| 224 | + | ||
| 225 | +**文件包含的关键定义**: | ||
| 226 | + | ||
| 227 | +| 定义 | 说明 | | ||
| 228 | +|------|------| | ||
| 229 | +| `AivSuperKernelArgs` | SuperKernel 参数结构体 | | ||
| 230 | +| `ExtraArgs` | 额外参数结构体(sendCounts/recvCounts 等,用于 AllToAllV) | | ||
| 231 | +| `KERNEL_ARGS_DEF` / `KERNEL_ARGS_CALL` | AIV kernel 参数宏定义(约 25 个参数) | | ||
| 232 | +| `SUPERKERNEL_ARGS_DEF` / `SUPERKERNEL_ARGS_CALL` | SuperKernel 参数宏定义 | | ||
| 233 | +| `AivCommBase` 类 | AIV 通信基类,封装了 Barrier、Record/WaitFlag、CpGM2GM 等核心方法 | | ||
| 234 | +| `EXPORT_AIV_META_INFO` | AIV kernel 元信息导出宏 | | ||
| 235 | +| `AIV_ATOMIC_DATA_TYPE_DEF` / `AIV_COPY_DATA_TYPE_DEF` | 支持的数据类型宏定义 | | ||
| 236 | + | ||
| 237 | +**依赖风险**:若 HCOMM 侧 AIV 通信接口或 kernel 参数发生变化,需同步更新此备份文件。 | ||
| 238 | + | ||
| 239 | +### 5.3 AIV 算子 Op 头文件(HCOMM / HCCL 依赖) | ||
| 240 | + | ||
| 241 | +工具中每种集合通信算子的 AIV kernel 实现文件(`src/proxy/level2/aiv_kernel/hccl_op_stub/*/aiv_communication_v2.cc`)通过 `#include` 引用了对应算子的 op 头文件。这些头文件**不存在于项目内部**,分别来自 HCOMM 和 HCCL 仓库: | ||
| 242 | + | ||
| 243 | +| #include | 来源 | 实际文件路径 | 引用位置 | | ||
| 244 | +|----------|------|------------|---------| | ||
| 245 | +| `"aiv_all_reduce_op.h"` | HCOMM | `hcomm/src/legacy/ascend910/algorithm/base/alg_aiv_template/all_reduce/` | hccl_op_stub/all_reduce/aiv_communication_v2.cc | | ||
| 246 | +| `"aiv_all_gather_op.h"` | HCOMM | `hcomm/src/legacy/ascend910/algorithm/base/alg_aiv_template/all_gather/` | hccl_op_stub/all_gather/aiv_communication_v2.cc | | ||
| 247 | +| `"aiv_reduce_scatter_op.h"` | HCOMM | `hcomm/src/legacy/ascend910/algorithm/base/alg_aiv_template/reduce_scatter/` | hccl_op_stub/reduce_scatter/aiv_communication_v2.cc | | ||
| 248 | +| `"aiv_broadcast_op.h"` | HCOMM | `hcomm/src/legacy/ascend910/algorithm/base/alg_aiv_template/broadcast/` | hccl_op_stub/broadcast/aiv_communication_v2.cc | | ||
| 249 | +| `"aiv_all_to_all_op.h"` | HCOMM | `hcomm/src/legacy/ascend910/algorithm/base/alg_aiv_template/all_to_all/` | hccl_op_stub/all_to_all_v/aiv_communication_v2.cc | | ||
| 250 | +| `"aiv_all_to_all_v_op.h"` | HCOMM | `hcomm/src/legacy/ascend910/algorithm/base/alg_aiv_template/all_to_all/` | hccl_op_stub/all_to_all_v/aiv_communication_v2.cc | | ||
| 251 | +| `"aiv_scatter_op.h"` | HCCL | `hccl/src/ops/scatter/template/aiv/kernel/` | hccl_op_stub/scatter/aiv_communication_v2.cc | | ||
| 252 | +| `"aiv_reduce_op.h"` | HCCL | `hccl/src/ops/reduce/template/aiv/kernel/` | hccl_op_stub/reduce/aiv_communication_v2.cc | | ||
| 253 | + | ||
| 254 | +**依赖风险**:若 HCOMM 或 HCCL 侧算子 op 头文件的接口签名、模板参数或成员函数发生变化,工具的 AIV kernel 编译将失败,或导致运行时行为不一致。 | ||
| 255 | + | ||
| 256 | +### 5.4 AscendC 接口依赖 | ||
| 257 | + | ||
| 258 | +工具依赖 CANN 包提供的 AscendC 编程接口来模拟 AIV kernel 的执行。项目中的 AscendC 接口全部通过 `src/proxy/level2/aiv_kernel/ascendc_stub/` 目录下的本地 stub 文件实现,而非直接使用 CANN SDK 中的 AscendC 头文件。 | ||
| 259 | + | ||
| 260 | +**使用的 AscendC 接口**(通过 stub 实现): | ||
| 261 | + | ||
| 262 | +| Stub 头文件 | 封装的 AscendC 接口 | 引用位置 | | ||
| 263 | +|------------|-------------------|---------| | ||
| 264 | +| `ascendc_base_stub.h` | `GlobalTensor`、`LocalTensor`、`TPipe`、`TBuf`、`TQueBind`、`pipe_barrier`、`GetBlockIdx` 等基础类 | aiv_kernel/ 下几乎所有文件 | | ||
| 265 | +| `ascendc_copy_stub.h` | `DataCopy`、`DataCopyPad` 等数据搬移接口 | ascendc_stub/kernel_operator.h | | ||
| 266 | +| `ascendc_math_stub.h` | `Add`、`Sub`、`Mul`、`Reduce` 等数学运算接口 | ascendc_stub/kernel_operator.h | | ||
| 267 | +| `ascendc_memory_stub.h` | `SetAtomicAdd`、`SetAtomicMax`、`SetAtomicMin` 等原子操作接口 | ascendc_stub/kernel_operator.h | | ||
| 268 | +| `ascendc_sync_stub.h` | `send_flag`、`recv_flag`、`SyncAll` 等同步接口 | ascendc_stub/kernel_operator.h | | ||
| 269 | +| `ascendc_utils_stub.h` | `PipeBarrier` 等工具函数 | ascendc_stub/kernel_operator.h | | ||
| 270 | + | ||
| 271 | +**依赖风险**: | ||
| 272 | +1. AscendC 接口 API 变化(如类成员函数签名变更、模板参数调整)可能导致 stub 实现与真实接口不匹配 | ||
| 273 | +2. AscendC 新增数据类型(如 `fp8_e4m3fn_t`、`fp8_e5m2_t`、`hifloat8_t`)需要同步更新 stub 支持 | ||
| 274 | +3. `AivCommBase` 类内部大量使用 AscendC 模板类(`GlobalTensor<T>`、`LocalTensor<T>`、`TQueBind` 等),这些类型的语义变化会影响 AIV 仿真的正确性 | ||
| 275 | + | ||
| 276 | +--- | ||
| 277 | + | ||
| 278 | +## 六、AICPU 依赖(AICPU 模式专用) | ||
| 279 | + | ||
| 280 | +本章节说明工具在 AICPU 模式下模拟 host-device 交互的依赖情况。该模式通过 `src/device_arm/hccl_kernel_executor.cc` 中的 `ExecuteAicpuKernel` 函数实现,模拟 AICPU kernel 下发到 device 端的执行过程,涉及多个数据结构的序列化和地址转换。 | ||
| 281 | + | ||
| 282 | +### 6.1 AICPU 交互数据结构 | ||
| 283 | + | ||
| 284 | +工具在 `src/device_arm/common/aicpu_args_stub.h` 中对以下数据结构做了本地备份,以解除对 HCOMM 运行时库的强依赖: | ||
| 285 | + | ||
| 286 | +| 数据结构 | 用途 | 对应 kernel 函数 | | ||
| 287 | +|---------|------|-----------------| | ||
| 288 | +| `CommAicpuParam` | 通信域初始化参数(hcomId、设备 ID、H2D/D2H 传输参数) | `RunAicpuIndOpCommInit` | | ||
| 289 | +| `HDCommunicateParams` | H2D/D2H 控制传输参数(deviceAddr、readCacheAddr) | 被 `CommAicpuParam` 引用 | | ||
| 290 | +| `ThreadMgrAicpuParam` | 线程管理参数(threadNum、序列化 threadParam 数组、deviceHandle) | `RunAicpuIndOpThreadInit`、`RunAicpuThreadSupplementNotify` | | ||
| 291 | +| `AicpuTsThread` | AICPU 线程信息(streamType、notifyLoadType、devId) | 被 `ThreadMgrAicpuParam` 引用 | | ||
| 292 | +| `InitTask` | 通道初始化任务(context 指针、isCustom 标志) | `RunAicpuIndOpChannelInitV2` | | ||
| 293 | +| `HcclChannelUrmaRes` | 通道 URMA 资源描述(channelList、uniqueIdAddr、remoteRankList) | `RunAicpuIndOpChannelInitV2` | | ||
| 294 | +| `UniqueIdV2Header` | UniqueId V2 头部(type、notifyNum、bufferNum、connNum) | 通道建链序列化数据解析 | | ||
| 295 | +| `ConnUniqueBlock` | 连接唯一块(柔性数组,包含 `ConnUniqueIds`) | 通道建链序列化数据解析 | | ||
| 296 | + | ||
| 297 | +### 6.2 OpParam 数据结构(外部依赖) | ||
| 298 | + | ||
| 299 | +**来源**:HCCL 仓库的 `alg_param.h` 头文件(`HCCL/src/ops/op_common/inc/`),位于 `ops_hccl` 命名空间 | ||
| 300 | + | ||
| 301 | +**说明**:`OpParam` 是 AICPU 集合通信算子的通用参数结构体,用于 `HcclLaunchAicpuKernel` 函数。与上述本地备份的结构体不同,工具**直接使用**了 HCCL 源码中的 `OpParam` 定义,未做本地备份。 | ||
| 302 | + | ||
| 303 | +**依赖风险**:若 HCCL 侧 `OpParam` 结构体发生变化(字段增删、类型变更),可能导致工具解析参数错误或运行时崩溃。 | ||
| 304 | + | ||
| 305 | +### 6.3 AICPU Kernel 函数依赖 | ||
| 306 | + | ||
| 307 | +工具通过 `dlopen` + `dlsym` 动态加载以下 HCOMM 运行时库中的 kernel 函数,模拟 AICPU 侧的实际执行: | ||
| 308 | + | ||
| 309 | +| dlsym 符号名 | 所在库 | 功能 | | ||
| 310 | +|-------------|-------|------| | ||
| 311 | +| `RunAicpuIndOpCommInit` | `libccl_kernel.so` | AICPU 通信域初始化 | | ||
| 312 | +| `RunAicpuIndOpThreadInit` | `libccl_kernel.so` | AICPU 线程初始化 | | ||
| 313 | +| `RunAicpuIndOpChannelInitV2` | `libccl_kernel.so` | AICPU 通道初始化 V2 | | ||
| 314 | +| `RunAicpuDfxOpInfoInitV2` | `libccl_kernel.so` | AICPU DFX 算子信息初始化 V2 | | ||
| 315 | +| `RunAicpuThreadSupplementNotify` | `libccl_kernel.so` | AICPU 资源补充通知 | | ||
| 316 | +| `HcclLaunchAicpuKernel` | `libscatter_aicpu_kernel.so` | AICPU 集合通信 kernel 启动 | | ||
| 317 | + | ||
| 318 | +**依赖风险**: | ||
| 319 | +1. 若 HCOMM 侧上述 kernel 函数的签名或行为发生变化,工具的 `dlsym` 调用可能失败或产生错误结果 | ||
| 320 | +2. 若 `libccl_kernel.so` 或 `libscatter_aicpu_kernel.so` 新增/移除 kernel 函数,工具需同步更新函数指针列表 | ||
| 321 | +3. `CommAicpuParam`、`ThreadMgrAicpuParam`、`HcclChannelUrmaRes` 等本地备份结构体若与 HCOMM 侧实际定义不一致,将导致地址转换错误和内存越界 | ||
| 322 | + | ||
| 323 | +### 6.4 Kernel SO 库名依赖 | ||
| 324 | + | ||
| 325 | +工具在 `InitKernelFuncHandle` 函数中硬编码了以下 SO 库名,用于加载 AICPU kernel 的执行入口: | ||
| 326 | + | ||
| 327 | +| 硬编码 SO 名称 | 加载的 dlsym 符号 | 说明 | | ||
| 328 | +|--------------|-----------------|------| | ||
| 329 | +| `libccl_kernel.so` | `RunAicpuIndOpCommInit`、`RunAicpuIndOpThreadInit`、`RunAicpuIndOpChannelInitV2`、`RunAicpuDfxOpInfoInitV2`、`RunAicpuThreadSupplementNotify` | HCOMM 通信框架核心库 | | ||
| 330 | +| `libscatter_aicpu_kernel.so` | `HcclLaunchAicpuKernel` | AICPU 集合通信算子 kernel 库 | | ||
| 331 | +| `libslog.so` | (日志库依赖) | CANN 安全日志库 | | ||
| 332 | +| `libc_sec.so` | (安全库依赖) | CANN 安全函数库 | | ||
| 333 | + | ||
| 334 | +**依赖风险**: | ||
| 335 | +1. **SO 名称变更**:若 HCOMM 侧重命名或拆分上述 SO(如将 `libccl_kernel.so` 重命名),工具的 `dlopen` 将加载失败,导致所有 AICPU kernel 无法执行 | ||
| 336 | +2. **算子 kernel SO 名称歧义**:当前无论算子类型如何(AllReduce、AllGather、ReduceScatter 等),算子 kernel 的 SO 名称固定为 `libscatter_aicpu_kernel.so`。这一命名可能引起歧义——名称中的 "scatter" 暗示仅适用于 Scatter 算子,但实际上承载了所有集合通信算子的 kernel。若 HCOMM 侧后续按算子类型拆分 SO(如 `liballreduce_aicpu_kernel.so`),工具将无法适配 | ||
| 337 | +3. **用户自定义算子场景**:HCCL 业务层未对用户自定义算子的 SO 名称做严格规定,用户可能自行编译出私有 SO(如 `libcustom_alltoall_kernel.so`)。工具目前仅识别上述固定 SO 名称,对于用户自定义算子的私有 SO 将无法加载和仿真 | ||
| 338 | + | ||
| 339 | +--- | ||
| 340 | + | ||
| 341 | +## 七、依赖总览 | ||
| 342 | + | ||
| 343 | +| 来源 | 头文件数 | 使用模块 | | ||
| 344 | +|------|---------|---------| | ||
| 345 | +| **CANN** | 23 个不同头文件 | 几乎所有模块(proxy, checker, runner, common, store, topo, utils, device_arm) | | ||
| 346 | +| **HCOMM** | 13 个不同头文件 | proxy 模块(hccp 网络接口 + AIV 算子 op) | | ||
| 347 | +| **HCCL** | 3 个直接引用 + 间接引用 | device_arm 模块(ARM 交叉编译)+ proxy(AIV scatter/reduce op) | | ||
| 348 | +| **项目本地 external** | 14 个头文件 | 仅 checker 模块(作为 CANN 缺失时的 fallback) | | ||
| 349 | +| **AIV 备份** | 2 个关键定义 | 仅 proxy/aiv_kernel 模块(AIV 算子仿真) | | ||
| 350 | +| **AIV 算子 Op** | 8 个头文件(6 个 HCOMM + 2 个 HCCL) | 仅 proxy/aiv_kernel 模块(AIV 算子仿真) | | ||
| 351 | +| **AscendC 接口** | 6 个 stub 头文件 | 仅 proxy/aiv_kernel 模块(AIV 算子仿真) | | ||
| 352 | +| **AICPU 备份** | 8 个本地结构体 + 6 个 kernel 函数 + 4 个 SO 库名 | 仅 device_arm 模块(AICPU 模式 host-device 交互) | | ||
| 353 | + | ||
| 354 | + | ||
| @@ -0,0 +1,343 @@ | |||
| 1 | +# HVRM Insight V3 使用指南 | ||
| 2 | + | ||
| 3 | +## 1. 概述 | ||
| 4 | + | ||
| 5 | +HVRM Insight V3 当前主要支持 `DAGView` 任务图查看。本文档围绕 DAGView 介绍数据准备、页面访问、数据集选择、DAG 图浏览和节点检索等常用操作。 | ||
| 6 | + | ||
| 7 | +其他页面及高级联动能力暂未实现。 | ||
| 8 | + | ||
| 9 | +--- | ||
| 10 | + | ||
| 11 | +## 2. 前置准备 | ||
| 12 | + | ||
| 13 | +使用 Insight V3 前,请确认 Checker 已完成运行,并已生成 Insight 数据。 | ||
| 14 | + | ||
| 15 | +如需配置 Checker 数据输出,请确认 Checker 配置文件中已开启 Insight dump: | ||
| 16 | + | ||
| 17 | +```json | ||
| 18 | +# 配置文件位于 /pathto/hccl_vm_install/plugin/checker/manifest.json | ||
| 19 | + | ||
| 20 | +{ | ||
| 21 | + ... | ||
| 22 | + "setting": { // Checker插件配置项 | ||
| 23 | + ... | ||
| 24 | + "enable_insight_dump": true, // 是否输出 Checker V3 Insight 数据(默认为关闭状态) | ||
| 25 | + "enable_memory_snapshot_dump": false // 是否输出内存快照数据(暂不支持,默认关闭,需要先开启 Insight 数据输出) | ||
| 26 | + } | ||
| 27 | +} | ||
| 28 | +``` | ||
| 29 | + | ||
| 30 | +DAGView 至少需要以下数据文件: | ||
| 31 | + | ||
| 32 | +```text | ||
| 33 | +<dataset_name>/ | ||
| 34 | +├── manifest.json | ||
| 35 | +└── graph/ | ||
| 36 | + ├── graph.msgpack | ||
| 37 | + └── layout.msgpack | ||
| 38 | +``` | ||
| 39 | + | ||
| 40 | +其中,`manifest.json` 用于读取数据集元信息,`graph.msgpack` 和 `layout.msgpack` 用于绘制 DAG 任务图。 | ||
| 41 | + | ||
| 42 | +--- | ||
| 43 | + | ||
| 44 | +## 3. 编译与安装 Insight 插件 | ||
| 45 | + | ||
| 46 | +Insight V3 当前前端源码位于: | ||
| 47 | + | ||
| 48 | +```text | ||
| 49 | +{hccl_vm目录}/src/plugin/insight/frontend_v3 | ||
| 50 | +``` | ||
| 51 | + | ||
| 52 | +在安装 Insight 插件前,请先完成前端编译,再执行 HCCL VM 的构建安装流程。 | ||
| 53 | + | ||
| 54 | +注意:编译 Insight 可视化前端需要依赖 `Node.js` 和 `npm`。建议使用 `Node.js 20.19.0` 或以上 与 `npm 10.x` 或以上。 | ||
| 55 | + | ||
| 56 | +推荐步骤如下: | ||
| 57 | + | ||
| 58 | +1. 进入前端目录: | ||
| 59 | + | ||
| 60 | +```bash | ||
| 61 | +cd {hccl_vm目录}/src/plugin/insight/frontend_v3 | ||
| 62 | +``` | ||
| 63 | + | ||
| 64 | +2. 安装前端依赖: | ||
| 65 | + | ||
| 66 | +```bash | ||
| 67 | +npm install | ||
| 68 | +``` | ||
| 69 | + | ||
| 70 | +3. 编译前端产物: | ||
| 71 | + | ||
| 72 | +```bash | ||
| 73 | +npm run build | ||
| 74 | +``` | ||
| 75 | + | ||
| 76 | +前端编译完成后,会生成 `src/plugin/insight/dist/` 目录。 | ||
| 77 | + | ||
| 78 | +4. 回到 HCCL_VM 根目录,执行 `build.sh` 编译并安装 hccl-vm: | ||
| 79 | + | ||
| 80 | +```bash | ||
| 81 | +cd {HCCL_VM目录} | ||
| 82 | +bash build.sh --package-path <ASCEND_CANN_PATH> --hcomm-path <HCOMM_CODE_PATH> | ||
| 83 | +``` | ||
| 84 | + | ||
| 85 | +如需打包安装目录,可附加 `--pkg`。若当前构建场景要求 AICPU / AIV / FULL 模式,可按项目常规流程追加 `--aicpu`、`--aiv` 或 `--full` 参数。 | ||
| 86 | + | ||
| 87 | +--- | ||
| 88 | + | ||
| 89 | +## 4. Insight 插件配置与启停 | ||
| 90 | + | ||
| 91 | +Insight 插件配置文件位于: | ||
| 92 | + | ||
| 93 | +```text | ||
| 94 | +hccl_vm_install/plugin/visualization/insight/manifest.json | ||
| 95 | +``` | ||
| 96 | + | ||
| 97 | +当前默认配置如下: | ||
| 98 | + | ||
| 99 | +```json | ||
| 100 | +{ | ||
| 101 | + "name": "insight", | ||
| 102 | + "version": "1.0.0", | ||
| 103 | + "entry": "python3 server.py", | ||
| 104 | + "dependency": { | ||
| 105 | + "min_core_version": "1.0.0" | ||
| 106 | + }, | ||
| 107 | + "setting": { | ||
| 108 | + "dist_path": "./dist", | ||
| 109 | + "data_path": "../../checker/data/insight", | ||
| 110 | + "topo_config_path": "../../../../../asset/cluster_model/config/cluster", | ||
| 111 | + "port": 8080 | ||
| 112 | + } | ||
| 113 | +} | ||
| 114 | +``` | ||
| 115 | + | ||
| 116 | +常用字段说明如下: | ||
| 117 | + | ||
| 118 | +| 字段 | 说明 | | ||
| 119 | +|------|------| | ||
| 120 | +| `entry` | Insight 插件启动命令,当前通过 `python3 server.py` 启动服务 | | ||
| 121 | +| `setting.dist_path` | 前端静态资源目录,默认读取 `./dist` | | ||
| 122 | +| `setting.data_path` | Insight 数据目录,默认指向 Checker 输出的 `data/insight` | | ||
| 123 | +| `setting.topo_config_path` | 集群拓扑配置目录 | | ||
| 124 | +| `setting.port` | Insight 服务端口,默认 `8080` | | ||
| 125 | + | ||
| 126 | +若需要修改端口或数据目录,可直接编辑该 `manifest.json` 中的 `setting` 字段。 | ||
| 127 | + | ||
| 128 | +> 警告:Insight 默认通过 `python3 server.py` 绑定在 `127.0.0.1`。如需监听指定 IP,而不是默认的 `localhost(127.0.0.1)`,请进入 `hccl_vm_install/plugin/visualization/insight` 目录,手动执行: | ||
| 129 | +> | ||
| 130 | +> ```bash | ||
| 131 | +> python3 server.py --host <ip> --port <port> | ||
| 132 | +> ``` | ||
| 133 | +> | ||
| 134 | +> 例如: | ||
| 135 | +> | ||
| 136 | +> ```bash | ||
| 137 | +> cd hccl_vm_install/plugin/visualization/insight | ||
| 138 | +> python3 server.py --host 0.0.0.0 --port 8080 | ||
| 139 | +> ``` | ||
| 140 | + | ||
| 141 | +插件安装与卸载命令如下: | ||
| 142 | + | ||
| 143 | +```bash | ||
| 144 | +# 安装并启动 Insight 插件 | ||
| 145 | +hccl-vm plugin install @insight | ||
| 146 | + | ||
| 147 | +# 卸载 Insight 插件 | ||
| 148 | +hccl-vm plugin uninstall @insight | ||
| 149 | +``` | ||
| 150 | + | ||
| 151 | +--- | ||
| 152 | + | ||
| 153 | +## 5. 打开 Insight | ||
| 154 | + | ||
| 155 | +若 Insight 服务已启动,请直接在浏览器中打开服务地址,例如: | ||
| 156 | + | ||
| 157 | +```text | ||
| 158 | +http://localhost:8080 | ||
| 159 | +``` | ||
| 160 | + | ||
| 161 | +若需要通过插件启动 Insight,可执行: | ||
| 162 | + | ||
| 163 | +```bash | ||
| 164 | +hccl-vm plugin install @insight | ||
| 165 | +``` | ||
| 166 | + | ||
| 167 | +插件启动后,终端会输出访问地址。请在浏览器中打开该地址进入 Insight 页面。 | ||
| 168 | + | ||
| 169 | + | ||
| 170 | + | ||
| 171 | +--- | ||
| 172 | + | ||
| 173 | +## 6. 选择数据集 | ||
| 174 | + | ||
| 175 | +打开 Insight 后,默认进入 `总览` 页面。请按以下步骤选择需要分析的数据集: | ||
| 176 | + | ||
| 177 | +1. 在中间的数据集表格中查看数据集列表。 | ||
| 178 | +2. 点击目标数据集。 | ||
| 179 | +3. 在左侧 Rank 树中确认需要查看的 Rank。 | ||
| 180 | +4. 如 DAG 图规模较大,可先减少 Rank 选择范围。 | ||
| 181 | +5. 点击右侧 `进入关联视图`。 | ||
| 182 | + | ||
| 183 | + | ||
| 184 | + | ||
| 185 | +建议首次分析时先选择少量 Rank,确认分析方向后再逐步扩大 Rank 范围。 | ||
| 186 | + | ||
| 187 | +--- | ||
| 188 | + | ||
| 189 | +## 7. 进入 DAGView | ||
| 190 | + | ||
| 191 | +进入 `关联` 页面后,重点查看下半部分的 `DAGView 任务视图`。 | ||
| 192 | + | ||
| 193 | +页面主要区域如下: | ||
| 194 | + | ||
| 195 | +| 区域 | 功能 | | ||
| 196 | +|------|------| | ||
| 197 | +| 左侧面板 | 选择 Rank、搜索节点 | | ||
| 198 | +| 中间下方 | 展示 DAG 任务图 | | ||
| 199 | +| 右侧详情栏 | 查看当前节点详情 | | ||
| 200 | + | ||
| 201 | +若上方内存视图为空,不影响下方 DAGView 的查看和使用。 | ||
| 202 | + | ||
| 203 | +--- | ||
| 204 | + | ||
| 205 | +## 8. 查看 DAG 任务图 | ||
| 206 | + | ||
| 207 | +DAG 任务图由泳道、节点和箭头组成: | ||
| 208 | + | ||
| 209 | +| 元素 | 说明 | | ||
| 210 | +|------|------| | ||
| 211 | +| 泳道 | 表示一个执行队列,通常显示为 `Rank / Stream / Queue` | | ||
| 212 | +| 节点 | 表示一个任务,例如数据搬运、Reduce、Record、Wait 等 | | ||
| 213 | +| 箭头 | 表示任务之间的依赖关系 | | ||
| 214 | +| Loop 虚线框 | 表示一个 Loop 区域,会用虚线框圈住该 Loop 内相关节点,并在框外显示 `Loop` 标记 | | ||
| 215 | + | ||
| 216 | +常见节点类型如下: | ||
| 217 | + | ||
| 218 | +| 节点类型 | 含义 | | ||
| 219 | +|----------|------| | ||
| 220 | +| `TRANS_MEM` | 数据搬运任务 | | ||
| 221 | +| `REDUCE` | Reduce 任务 | | ||
| 222 | +| `RECORD` | Notify record 任务 | | ||
| 223 | +| `WAIT` | Notify wait 任务 | | ||
| 224 | +| `CCU_GRAPH` | CCU 图任务 | | ||
| 225 | +| `AIV_GRAPH` | AIV 图任务 | | ||
| 226 | + | ||
| 227 | +推荐查看方式: | ||
| 228 | + | ||
| 229 | +1. 按箭头方向查看任务依赖顺序。 | ||
| 230 | +2. 点击关注的任务节点。 | ||
| 231 | +3. 在右侧详情栏查看该节点所属的 Rank、Stream、Queue 及节点详细信息。 | ||
| 232 | +4. 继续查看该节点的父节点和子节点,追踪上下游依赖。 | ||
| 233 | + | ||
| 234 | +关于 Loop 展示,建议额外关注以下信息: | ||
| 235 | + | ||
| 236 | +1. 若 DAG 中存在 Loop,页面会自动在任务图上叠加 Loop 虚线框。 | ||
| 237 | +2. 虚线框会覆盖该 Loop 的起点、终点及循环体内部节点,便于快速识别循环边界。 | ||
| 238 | +3. 点击 Loop 胶囊后,可直接定位到对应的 Loop Start 节点。 | ||
| 239 | +4. 选中 Loop 内部节点后,右侧详情栏会展示该节点所属的 Loop 信息和嵌套链路。 | ||
| 240 | + | ||
| 241 | + | ||
| 242 | + | ||
| 243 | +--- | ||
| 244 | + | ||
| 245 | +## 9. 画布操作 | ||
| 246 | + | ||
| 247 | +DAGView 画布支持以下操作: | ||
| 248 | + | ||
| 249 | +| 操作 | 说明 | | ||
| 250 | +|------|------| | ||
| 251 | +| 移动画布 | 拖拽空白区域 | | ||
| 252 | +| 放大 / 缩小 | 使用鼠标滚轮,或点击右下角 `+` / `-` | | ||
| 253 | +| 重置缩放 | 点击右下角百分比按钮 | | ||
| 254 | +| 选中节点 | 点击目标节点 | | ||
| 255 | + | ||
| 256 | +当图规模较大时,建议先缩小 Rank 选择范围,再放大局部区域查看依赖。 | ||
| 257 | + | ||
| 258 | +--- | ||
| 259 | + | ||
| 260 | +## 10. 查看节点详情 | ||
| 261 | + | ||
| 262 | +点击 DAG 节点后,右侧详情栏会展示节点信息。常用信息如下: | ||
| 263 | + | ||
| 264 | +| 区块 | 说明 | | ||
| 265 | +|------|------| | ||
| 266 | +| 节点概览 | 节点 ID、任务类型、Rank、Stream、Queue | | ||
| 267 | +| Loop 信息 | 当前节点所属 Loop、Loop 次数、指令范围、Loop 边界等 | | ||
| 268 | +| 父节点 | 当前节点依赖的上游节点 | | ||
| 269 | +| 子节点 | 依赖当前节点的下游节点 | | ||
| 270 | +| 节点语义 | Notify、Task 元数据、Memory Slices 等 | | ||
| 271 | +| 原始 JSON | 当前节点的完整原始信息 | | ||
| 272 | + | ||
| 273 | +排查依赖关系时,建议优先查看 `父节点` 和 `子节点`;排查循环结构时,可重点查看 `Loop 信息`;排查数据搬运相关问题时,可重点查看 `Memory Slices`。 | ||
| 274 | + | ||
| 275 | +其中 `Memory Slices` 区块有以下展示规则: | ||
| 276 | + | ||
| 277 | +1. 普通内存 Slice 会显示 `rank / type / offset / size`。 | ||
| 278 | +2. 若 Slice 属于 `MS_CCU`,Insight V3 会优先显示 `MSID`,而不是底层抽象 offset。 | ||
| 279 | +3. 对于 batch 类任务,若存在多个 `MS_CCU` Slice,会自动合并为一个汇总卡片。 | ||
| 280 | +4. 汇总卡片会显示类似 `共计使用8个MSID` 的说明。 | ||
| 281 | +5. 展开 `MSID 明细` 后,可逐项查看每个 `MSID` 对应的 `id` 和 `size`。 | ||
| 282 | + | ||
| 283 | +--- | ||
| 284 | + | ||
| 285 | +## 11. 搜索节点 | ||
| 286 | + | ||
| 287 | +左侧 `搜索` 面板可用于快速定位 DAG 节点。 | ||
| 288 | + | ||
| 289 | +支持的搜索字段如下: | ||
| 290 | + | ||
| 291 | +| 字段 | 使用场景 | | ||
| 292 | +|------|----------| | ||
| 293 | +| `taskId` | 已知节点 ID 时使用 | | ||
| 294 | +| `taskType` | 按任务类型查找,例如 `TRANS_MEM` | | ||
| 295 | +| `notifyId` | 按 notify id 查找 | | ||
| 296 | + | ||
| 297 | +操作步骤: | ||
| 298 | + | ||
| 299 | +1. 在左侧搜索面板选择搜索字段。 | ||
| 300 | +2. 输入完整关键词。 | ||
| 301 | +3. 点击搜索结果。 | ||
| 302 | +4. DAGView 会自动定位并选中对应节点。 | ||
| 303 | + | ||
| 304 | +当前搜索为精确匹配。若未找到结果,请确认关键词是否完整,以及目标 Rank 是否已被勾选。 | ||
| 305 | + | ||
| 306 | +--- | ||
| 307 | + | ||
| 308 | +## 12. 推荐分析流程 | ||
| 309 | + | ||
| 310 | +建议按以下流程进行 DAGView 分析: | ||
| 311 | + | ||
| 312 | +1. 在 `总览` 页面选择数据集。 | ||
| 313 | +2. 在左侧 Rank 树中选择少量 Rank。 | ||
| 314 | +3. 点击 `进入关联视图`。 | ||
| 315 | +4. 在 DAGView 中查看整体节点和依赖箭头。 | ||
| 316 | +5. 点击关注节点并查看右侧详情。 | ||
| 317 | +6. 通过父节点和子节点追踪上下游依赖。 | ||
| 318 | +7. 使用搜索功能快速定位已知节点。 | ||
| 319 | + | ||
| 320 | +--- | ||
| 321 | + | ||
| 322 | +## 13. 常见问题 | ||
| 323 | + | ||
| 324 | +### 13.1 页面没有数据 | ||
| 325 | + | ||
| 326 | +请确认 Insight 服务地址是否正确,并确认 Checker 已生成 Insight 数据。 | ||
| 327 | + | ||
| 328 | +### 13.2 进入关联页后 DAG 为空 | ||
| 329 | + | ||
| 330 | +请确认数据集中存在以下文件: | ||
| 331 | + | ||
| 332 | +```text | ||
| 333 | +graph/graph.msgpack | ||
| 334 | +graph/layout.msgpack | ||
| 335 | +``` | ||
| 336 | + | ||
| 337 | +### 13.3 DAG 图过于密集 | ||
| 338 | + | ||
| 339 | +建议先减少左侧 Rank 勾选数量,只查看部分 Rank,再放大局部区域进行分析。 | ||
| 340 | + | ||
| 341 | +### 13.4 搜索不到节点 | ||
| 342 | + | ||
| 343 | +请确认搜索关键词完整,并确认目标节点所在 Rank 已被勾选。 | ||
| @@ -0,0 +1,423 @@ | |||
| 1 | +# CCU Executor Debug 工具设计文档 — 可行性审视与优化报告 | ||
| 2 | + | ||
| 3 | +基于 `src/plugin/solver/virtual_runtime/ccu_executor/` 代码与 `runner_debug/debug_tool_design_doc.md` 设计方案的全面审视。 | ||
| 4 | + | ||
| 5 | +--- | ||
| 6 | + | ||
| 7 | +## 一、可行性问题(必须修正) | ||
| 8 | + | ||
| 9 | +### P0-1: CKE Wait 流程与插桩设计不匹配 | ||
| 10 | + | ||
| 11 | +**严重程度**: P0(方案可行性错误) | ||
| 12 | + | ||
| 13 | +**问题描述**: | ||
| 14 | + | ||
| 15 | +文档 4.1 节的插桩伪代码假设 `waitCKE_` 标志在 `ExecuteInstr()` 返回之前就能检测,并在之后计算 `snapshotBefore → snapshotAfter` 的 delta。但实际代码流程: | ||
| 16 | + | ||
| 17 | +``` | ||
| 18 | +WaitCkeProcess() → CKE 不满足 → ccuSimulator_->SetWaitCKEFlag(true) → return (不调用 Process()) | ||
| 19 | +→ UpdateLoopStatus() 返回 false → ExecuteInstr() 返回 false → Execute() 返回 false | ||
| 20 | +``` | ||
| 21 | + | ||
| 22 | +关键:CKE 不满足时,`Run()` 内部的 `WaitCkeProcess` 发现 CKE 不满足就设置 waitCKE 标志后直接 return,**不调用 Process(),不修改任何资源**。因此: | ||
| 23 | +- 执行前快照 = 执行后快照(delta 为空) | ||
| 24 | +- 不应该捕获 snapshotAfter 和计算 delta | ||
| 25 | + | ||
| 26 | +**代码依据**: | ||
| 27 | + | ||
| 28 | +`CcuExecutorBase.cc` 第 162-172 行: | ||
| 29 | +```cpp | ||
| 30 | +if ((waitCKE & waitCKEMask) == waitCKEMask) { | ||
| 31 | + Process(ccuResMgr); // CKE 满足 → 执行 Process | ||
| 32 | +} else { | ||
| 33 | + ccuSimulator_->SetWaitCKEFlag(true); // CKE 不满足 → 设置标志,不执行 Process | ||
| 34 | + return; | ||
| 35 | +} | ||
| 36 | +``` | ||
| 37 | + | ||
| 38 | +**修正建议**: | ||
| 39 | + | ||
| 40 | +waitCKE 不满足时,只记录关键自旋字段,不计算 delta,不创建完整 trace entry: | ||
| 41 | +```cpp | ||
| 42 | +// waitCKE 时只记录自旋信息 | ||
| 43 | +CcuTraceCollector::RecordWaitSpin(rankId_, dieId_, curInstrId, | ||
| 44 | + waitCKEId, waitCKEMask, actualCKEValue); | ||
| 45 | +// 不捕获 snapshotAfter,不计算 delta | ||
| 46 | +// 不创建完整 CcuTraceEntry | ||
| 47 | +return false; | ||
| 48 | +``` | ||
| 49 | + | ||
| 50 | +直到 CKE 通过后才创建完整 entry(合并之前的自旋信息)。 | ||
| 51 | + | ||
| 52 | +--- | ||
| 53 | + | ||
| 54 | +### P0-2: globalSeqId/execRound 的维护位置应在 SequentialExecutor | ||
| 55 | + | ||
| 56 | +**严重程度**: P0(方案可行性错误) | ||
| 57 | + | ||
| 58 | +**问题描述**: | ||
| 59 | + | ||
| 60 | +文档假设 `CcuTraceCollector` 在 `CcuSimulator::ExecuteInstr()` 内部维护 `globalSeqId/execRound/currentSqeTaskId`。但 `CcuSimulator` 只能看到本 CCU 的执行,无法感知全局调度轮次和 CCU 切换。 | ||
| 61 | + | ||
| 62 | +`CcuSimulator::ExecuteInstr()` 在单个 CCU 内执行,不知道: | ||
| 63 | +- 当前外层 `while(HasTask())` 的第几轮(`execRound`) | ||
| 64 | +- 全局执行序号(`globalSeqId`) | ||
| 65 | +- 当前执行的是哪个 SQE 任务(`sqeTaskId`) | ||
| 66 | + | ||
| 67 | +这些信息只有在 `SequentialExecutor::Execute()` 和 `TaskCcuGraph()` 的上层调用链中才能获取。 | ||
| 68 | + | ||
| 69 | +**代码依据**: | ||
| 70 | + | ||
| 71 | +`hccl_task_sequential_execute.cc` 第 51-72 行 — 全局调度循环: | ||
| 72 | +```cpp | ||
| 73 | +while (HasTask()) { | ||
| 74 | + uint32_t rankId = 0; | ||
| 75 | + for (auto& rankTasks : allRankTaskQueues_) { // 遍历所有 rank | ||
| 76 | + for (auto& streamTasks : rankTasks) { // 遍历每个 stream | ||
| 77 | + while (!streamTasks.empty()) { | ||
| 78 | + auto task = streamTasks.front(); | ||
| 79 | + auto ret = ExecuteOneTask(task); // ← globalSeqId 在此递增 | ||
| 80 | + if (ret == HCCL_SIM_VRT_HOLD_CMD) break; | ||
| 81 | + streamTasks.pop(); | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | +} | ||
| 86 | +``` | ||
| 87 | + | ||
| 88 | +`hccl_task_thread.cc` 第 135-148 行 — TaskCcuGraph: | ||
| 89 | +```cpp | ||
| 90 | +auto simulator = ccuResMgr.InitSimulator(rankId, dieId, instrStartId, endInstrId, instCnt); | ||
| 91 | +// sqeTaskId 在此可知(从 task 参数获取) | ||
| 92 | +if (simulator->Execute() == false) { | ||
| 93 | + return HCCL_SIM_VRT_HOLD_CMD; | ||
| 94 | +} | ||
| 95 | +``` | ||
| 96 | + | ||
| 97 | +**修正建议**: | ||
| 98 | + | ||
| 99 | +全局上下文由 `SequentialExecutor` 管理,通过参数传递: | ||
| 100 | +```cpp | ||
| 101 | +// SequentialExecutor::Execute() 中 | ||
| 102 | +while (HasTask()) { | ||
| 103 | + uint32_t execRound = 0; | ||
| 104 | + for (rankTasks : allRankTaskQueues_) { | ||
| 105 | + for (streamTasks : rankTasks) { | ||
| 106 | + while (!streamTasks.empty()) { | ||
| 107 | + CcuTraceCollector::BeginGlobalStep(execRound); | ||
| 108 | + // globalSeqId 在 ExecuteOneTask 内递增 | ||
| 109 | + auto ret = ExecuteOneTask(task); | ||
| 110 | + ... | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | + } | ||
| 114 | + execRound++; | ||
| 115 | +} | ||
| 116 | +``` | ||
| 117 | + | ||
| 118 | +`TaskCcuGraph()` 中将 sqeTaskId 传递给 `CcuSimulator`: | ||
| 119 | +```cpp | ||
| 120 | +uint32_t sqeTaskId = CcuTraceCollector::RegisterSqeTask(rankId, dieId, task); | ||
| 121 | +CcuSimulator::SetCurrentSqeTaskId(sqeTaskId); // Simulator 内部使用 | ||
| 122 | +``` | ||
| 123 | + | ||
| 124 | +--- | ||
| 125 | + | ||
| 126 | +### P0-3: 全量 Snapshot 采集性能开销过大 | ||
| 127 | + | ||
| 128 | +**严重程度**: P0(性能瓶颈) | ||
| 129 | + | ||
| 130 | +**问题描述**: | ||
| 131 | + | ||
| 132 | +文档 4.1 中每条指令前后各做一次 `CaptureResourceSnapshot()`(全量读取所有资源),开销极大: | ||
| 133 | + | ||
| 134 | +- 单个 snapshot:4096×8(XN) + 4096×8(GSA) + 1024×2(CKE) ≈ 67KB | ||
| 135 | +- 每条指令前后各一次 ≈ 134KB | ||
| 136 | +- 10000 条指令 ≈ 1.34GB(仅 snapshot 数据) | ||
| 137 | + | ||
| 138 | +文档 4.5 提到了增量采集优化,但 4.1 的伪代码仍然是全量 snapshot + diff 计算的流程,与优化方案矛盾。 | ||
| 139 | + | ||
| 140 | +**业界做法参考**: | ||
| 141 | + | ||
| 142 | +- **rr debugger**: 检查点(checkpoint)+ 增量记录模式,只在关键节点做全量快照 | ||
| 143 | +- **Chrome DevTools Timeline**: 事件流格式,每个 event 只包含变化的 args | ||
| 144 | +- **Perfetto (Android trace)**: protobuf 二进制增量格式 | ||
| 145 | + | ||
| 146 | +**修正建议**: | ||
| 147 | + | ||
| 148 | +改为 ResourceManager 拦截变更 + 初始快照 + 定期 checkpoint: | ||
| 149 | + | ||
| 150 | +1. **初始快照**:Run 开始时做一次全量(存储在 `CcuIdentity.initialSnapshot` 中) | ||
| 151 | +2. **变更拦截**:在 `CcuResourceManager::UpdateXnValue/UpdateGsaValue/UpdateCkeValue` 等方法中直接拦截变更,记录 delta: | ||
| 152 | +```cpp | ||
| 153 | +void CcuResourceManager::UpdateXnValue(int rankId, int dieId, uint16_t xnId, uint64_t value) { | ||
| 154 | + uint64_t oldValue = GetXnValue(rankId, dieId, xnId); | ||
| 155 | + if (oldValue != value) { | ||
| 156 | + CcuTraceCollector::RecordXnDelta(rankId, dieId, xnId, oldValue, value); | ||
| 157 | + } | ||
| 158 | + xnData_[rankId][dieId][xnId] = value; | ||
| 159 | +} | ||
| 160 | +``` | ||
| 161 | +3. **定期 checkpoint**:每 N 条指令做一次全量快照(N 可配置,默认 1000),用于快速恢复中间状态 | ||
| 162 | +4. **恢复任意点状态**:从最近的 checkpoint + 累加后续 delta | ||
| 163 | + | ||
| 164 | +--- | ||
| 165 | + | ||
| 166 | +## 二、设计优化点(建议改进) | ||
| 167 | + | ||
| 168 | +### P1-1: Loop 内偏移公式不完整 | ||
| 169 | + | ||
| 170 | +**严重程度**: P1(信息缺失) | ||
| 171 | + | ||
| 172 | +**问题描述**: | ||
| 173 | + | ||
| 174 | +代码中 `UpdateAddress()` 的偏移计算比文档中 `CcuExecutionContext.gsaOffset` 更复杂: | ||
| 175 | +```cpp | ||
| 176 | +uint64_t CcuExecutorBase::UpdateAddress(uint64_t addr, uint16_t addrExpandCoef) { | ||
| 177 | + return addr + ((ccuSimulator_->GetLoopExtendNum() * ccuSimulator_->GetGSAOffset()) << addrExpandCoef) | ||
| 178 | + + ((ccuSimulator_->GetCurLoopCnt() * ccuSimulator_->GetLoopIterStepGSA()) << addrExpandCoef); | ||
| 179 | +} | ||
| 180 | +``` | ||
| 181 | + | ||
| 182 | +涉及 5 个参数:`addr`(原始地址)、`addrExpandCoef`(扩展系数)、`loopExtendNum`、`gsaOffset`、`curLoopCnt`、`loopIterStepGSA`。 | ||
| 183 | + | ||
| 184 | +当前 `CcuExecutionContext` 只有一个简单的 `gsaOffset` 字段,无法完整恢复 Loop 内 GSA 地址偏移的计算过程。 | ||
| 185 | + | ||
| 186 | +**修正建议**: | ||
| 187 | + | ||
| 188 | +`CcuExecutionContext` 增加完整的偏移参数: | ||
| 189 | +```cpp | ||
| 190 | +struct CcuExecutionContext { | ||
| 191 | + bool inLoop; | ||
| 192 | + uint16_t loopRound; // 当前迭代轮次 | ||
| 193 | + uint16_t loopExtendIndex; // 展开索引 | ||
| 194 | + | ||
| 195 | + // Loop 内偏移参数(仅在 inLoop=true 时有效) | ||
| 196 | + uint64_t gsaAddrOffset; // = extendIndex * gsaOffset + curLoopCnt * iterStepGSA(计算后的最终偏移) | ||
| 197 | + uint64_t gsaOffset; // GSA 基础偏移系数(GetGSAOffset) | ||
| 198 | + uint64_t iterStepGSA; // 每轮迭代的 GSA 步长(GetLoopIterStepGSA) | ||
| 199 | + uint32_t curLoopCnt; // 当前迭代计数(GetCurLoopCnt) | ||
| 200 | + uint32_t loopExtendNum; // 展开数(GetLoopExtendNum) | ||
| 201 | + uint16_t addrExpandCoef; // 地址扩展系数 | ||
| 202 | + | ||
| 203 | + uint16_t msOffset; // MS ID 偏移(GetLoopMsOffset) | ||
| 204 | + uint16_t ckeOffset; // CKE ID 偏移(GetLoopCKEOffset) | ||
| 205 | + uint16_t xnIdOffset; // XN ID 偏移(GetLoopXnIdOffset) | ||
| 206 | +}; | ||
| 207 | +``` | ||
| 208 | + | ||
| 209 | +--- | ||
| 210 | + | ||
| 211 | +### P1-2: 跨 CCU 变更应在 ResourceManager 中拦截 | ||
| 212 | + | ||
| 213 | +**严重程度**: P1(采集精度) | ||
| 214 | + | ||
| 215 | +**问题描述**: | ||
| 216 | + | ||
| 217 | +文档 4.1 中跨 CCU 变更的采集点在 `CcuSimulator::ExecuteInstr()` 中事后调用 `CaptureCrossCcuChanges()`。但实际跨 CCU 操作发生在 Executor 的 `Process()` 方法中(如 `SyncCkeExecutor::Process()` 调用 `SetRmtCKESignal()`)。 | ||
| 218 | + | ||
| 219 | +事后采集的方式需要对比远端 CCU 的前后状态,这意味着需要在指令执行前后各做一次远端 CCU 的快照——开销大且可能遗漏(远端 CCU 可能被其他代码同时修改)。 | ||
| 220 | + | ||
| 221 | +**修正建议**: | ||
| 222 | + | ||
| 223 | +在 `CcuResourceManager::UpdateCkeValue()` 中直接拦截跨 CCU 变更: | ||
| 224 | +```cpp | ||
| 225 | +void CcuResourceManager::UpdateCkeValue(int rankId, int dieId, uint16_t ckeId, uint16_t value) { | ||
| 226 | + uint16_t oldValue = GetCkeValue(rankId, dieId, ckeId); | ||
| 227 | + // 检测是否为跨 CCU 操作 | ||
| 228 | + auto [execRank, execDie] = CcuTraceCollector::GetCurrentExecutingCcu(); | ||
| 229 | + if (rankId != execRank || dieId != execDie) { | ||
| 230 | + CcuTraceCollector::RecordCrossCcuCkeChange( | ||
| 231 | + rankId, dieId, ckeId, oldValue, value, execRank, execDie); | ||
| 232 | + } | ||
| 233 | + ckeData_[rankId][dieId][ckeId] = value; | ||
| 234 | +} | ||
| 235 | +``` | ||
| 236 | + | ||
| 237 | +同理适用于 `UpdateXnValue()`(TransXnToRmt 等操作)、`UpdateGsaValue()`、`TransMSToMS()` 等。 | ||
| 238 | + | ||
| 239 | +--- | ||
| 240 | + | ||
| 241 | +### P1-3: CcuInstrTraceDetail 多态过度设计 | ||
| 242 | + | ||
| 243 | +**严重程度**: P1(架构优化) | ||
| 244 | + | ||
| 245 | +**问题描述**: | ||
| 246 | + | ||
| 247 | +当前设计了 **13 个** `CcuInstrTraceDetail` 子类(Load/Arith/Trans/Sync/Loop/LoopGroup/Cke/Jump/Wait/Fence/Reduce/...),但存在以下问题: | ||
| 248 | + | ||
| 249 | +1. **与公共层重复**:`CcuTransTraceDetail` 的 `waitCKEId/setCKEId` 与 `CcuTraceEntry.waitInfo` 重复;`CcuCkeTraceDetail` 的 `ckeId/ckeValueBefore/ckeValueAfter` 与 `resourceDelta.ckeChanges` 重复 | ||
| 250 | +2. **子类数量膨胀**:代码中有 30+ 种指令类型(V1 约 20 种 + V2 约 10+ 种),每种都需要一个子类 | ||
| 251 | +3. **前端渲染复杂**:需要根据 typeName 分发不同渲染模板 | ||
| 252 | +4. **新增指令成本高**:每新增一种指令类型都需要新增一个子类结构体 + CollectTraceDetail 实现 | ||
| 253 | + | ||
| 254 | +**业界做法参考**: | ||
| 255 | + | ||
| 256 | +- **Chrome DevTools Trace Event Format**: 扁平的 `args` 字段(key-value map),不使用多态继承 | ||
| 257 | +- **LLVM Execution Trace**: 扁平的"附加信息"字段 | ||
| 258 | +- **GDB MI (Machine Interface)**: key-value 属性列表 | ||
| 259 | + | ||
| 260 | +**修正建议**: | ||
| 261 | + | ||
| 262 | +将 `CcuInstrTraceDetail` 简化为扁平结构: | ||
| 263 | +```cpp | ||
| 264 | +struct CcuInstrTraceDetail { | ||
| 265 | + std::string typeName; // 如 "TransLocMemToLocMem" | ||
| 266 | + std::map<std::string, std::string> args; // 指令特有参数的 key-value 表 | ||
| 267 | + // 示例: | ||
| 268 | + // Trans 类: {"srcAddr": "0x7f0000", "dstAddr": "0x7f1000", "length": "4KB", "channelId": "0"} | ||
| 269 | + // Reduce 类: {"op": "Add", "msList": "[0,1,2,3]", "dataType": "FP32", "castEn": "0"} | ||
| 270 | + // CKE 类: {"ckeOp": "Set", "ckeId": "3", "ckeMask": "0x0001", "isRemote": "true"} | ||
| 271 | +}; | ||
| 272 | +``` | ||
| 273 | + | ||
| 274 | +优点: | ||
| 275 | +- 不需要为每种指令定义子类 | ||
| 276 | +- 新增指令时只需在 `CollectTraceDetail()` 中填充 args | ||
| 277 | +- 前端渲染逻辑统一(key-value 表格) | ||
| 278 | +- `Describe()` 的输出可直接作为 args 来源 | ||
| 279 | + | ||
| 280 | +--- | ||
| 281 | + | ||
| 282 | +### P1-4: JSON 序列化格式与大数据量的矛盾 | ||
| 283 | + | ||
| 284 | +**严重程度**: P1(性能优化) | ||
| 285 | + | ||
| 286 | +**问题描述**: | ||
| 287 | + | ||
| 288 | +文档 3.4 采用 JSON 作为序列化格式,但 JSON 的弱点: | ||
| 289 | +- 每个 uint64_t 的 XN/GSA 值需要字符串表示(`"0x7f3a0000"`),8 字节变 ~16 字节 | ||
| 290 | +- 大量冗余的 key 名称重复(`"xnChanges"` 在每条 entry 中重复出现) | ||
| 291 | +- 10000 条指令的 JSON 文件可达 50MB+ | ||
| 292 | +- 前端加载和解析大 JSON 文件耗时严重 | ||
| 293 | + | ||
| 294 | +**业界做法参考**: | ||
| 295 | + | ||
| 296 | +| 工具 | 格式 | 特点 | | ||
| 297 | +|------|------|------| | ||
| 298 | +| Chrome DevTools | JSON 流式(每行一个 event) | 支持逐行解析 | | ||
| 299 | +| Perfetto (Android) | protobuf 二进制 | 前端 WASM 解析,体积小 | | ||
| 300 | +| rr debugger | 自定义二进制 | 高效记录/回放 | | ||
| 301 | +| Intel VTune | 自定义二进制 + SQLite | 按需查询 | | ||
| 302 | + | ||
| 303 | +**修正建议**: | ||
| 304 | + | ||
| 305 | +分层序列化策略: | ||
| 306 | +- **采集端**:msgpack/flatbuffers 二进制格式,体积小 5-10 倍,写入速度快 | ||
| 307 | +- **前端加载**:通过 Worker 将二进制解码为前端索引结构 | ||
| 308 | +- **导出/调试**:可选导出为 JSON(便于人类阅读和调试) | ||
| 309 | +- JSON Schema 中 `metadata.rankId/dieId` 应删除(改为 `rankSize/diePerRank`,与全局模型一致) | ||
| 310 | + | ||
| 311 | +--- | ||
| 312 | + | ||
| 313 | +## 三、设计优化点(建议改进,优先级较低) | ||
| 314 | + | ||
| 315 | +### P2-1: Describe() 可作为 MVP 的 trace 信息来源 | ||
| 316 | + | ||
| 317 | +**严重程度**: P2(落地策略) | ||
| 318 | + | ||
| 319 | +**问题描述**: | ||
| 320 | + | ||
| 321 | +代码中每个 Executor 都实现了 `Describe()` 方法,返回格式化字符串如: | ||
| 322 | +``` | ||
| 323 | +"[Simulation Execute] Wait CKE[3:0001], Sync LocCKE[5:00ff] To rmtCKE[8:00ff] | ||
| 324 | + Use Channel[0], Set CKE[10:0001], clearType[1]" | ||
| 325 | +``` | ||
| 326 | + | ||
| 327 | +这些字符串已经包含了指令的关键参数信息。当前设计要求每个 Executor 新增 `CollectTraceDetail()` 虚方法并实现,工作量较大(30+ 种指令类型)。 | ||
| 328 | + | ||
| 329 | +**修正建议**: | ||
| 330 | + | ||
| 331 | +分阶段落地策略: | ||
| 332 | + | ||
| 333 | +**第一阶段(MVP)**: | ||
| 334 | +- 只采集 `Describe()` 输出 + resource delta | ||
| 335 | +- `instrDescribe` 字段直接使用 `executor->Describe()` 的返回值 | ||
| 336 | +- 不实现 `CollectTraceDetail()`,detail 字段为空或仅含 typeName | ||
| 337 | + | ||
| 338 | +**第二阶段(增强)**: | ||
| 339 | +- 为高频/关键指令类型实现 `CollectTraceDetail()`(如 Trans、Reduce、SyncCke) | ||
| 340 | +- detail 采用扁平 key-value map(见 P1-3) | ||
| 341 | +- 逐步覆盖所有指令类型 | ||
| 342 | + | ||
| 343 | +这样可以快速落地 MVP,降低初始开发成本。 | ||
| 344 | + | ||
| 345 | +--- | ||
| 346 | + | ||
| 347 | +### P2-2: Notify 等非 CCU 任务不在 trace 中 | ||
| 348 | + | ||
| 349 | +**严重程度**: P2(信息缺失) | ||
| 350 | + | ||
| 351 | +**问题描述**: | ||
| 352 | + | ||
| 353 | +`SequentialExecutor::Execute()` 中除了 `CCU_GRAPH` 外,还有 `NOTIFY_RECORD/NOTIFY_WAIT/REDUCE/MEM_CPY/AIV_GRAPH` 等任务类型。`NotifyWait` 也会返回 `HOLD_CMD`,与 CCU 的 waitCKE 有类似的阻塞行为。 | ||
| 354 | + | ||
| 355 | +当前 trace 只覆盖 `CCU_GRAPH` 类型任务。但 Notify 的 Record/Wait 会影响执行流程: | ||
| 356 | +- `NotifyWait` 阻塞会导致外层循环跳过该 stream | ||
| 357 | +- `NotifyRecord` 解除阻塞后,下一轮该 stream 的 CCU 任务才能继续执行 | ||
| 358 | + | ||
| 359 | +如果不在 trace 中体现,前端回放时会出现"CCU 指令突然跳到下一轮"的现象,无法解释中间发生了什么。 | ||
| 360 | + | ||
| 361 | +**修正建议**: | ||
| 362 | + | ||
| 363 | +在 `globalEntries[]` 中增加非 CCU 任务类型的简化记录: | ||
| 364 | +```cpp | ||
| 365 | +struct CcuTraceNonCcuEntry { | ||
| 366 | + uint32_t globalSeqId; | ||
| 367 | + uint32_t execRound; | ||
| 368 | + int32_t rankId; | ||
| 369 | + HccLTaskMetaType taskType; // NOTIFY_RECORD, NOTIFY_WAIT, REDUCE, MEM_CPY... | ||
| 370 | + HcclVmResult execResult; // SUCCESS 或 HOLD_CMD | ||
| 371 | + std::string description; // 任务描述(便于前端展示) | ||
| 372 | +}; | ||
| 373 | +``` | ||
| 374 | + | ||
| 375 | +前端在 CCU 切换提示时可显示:"Round 1: Rank1 NotifyWait 阻塞,跳过"。 | ||
| 376 | + | ||
| 377 | +--- | ||
| 378 | + | ||
| 379 | +### P2-3: JSON Schema 中 metadata 模型不一致 | ||
| 380 | + | ||
| 381 | +**严重程度**: P2(模型一致性) | ||
| 382 | + | ||
| 383 | +**问题描述**: | ||
| 384 | + | ||
| 385 | +文档 3.4 的 JSON Schema 示例中 `metadata` 仍包含旧设计的 `rankId`/`dieId` 字段(per-CCU 模型),但 3.3.1 的 `CcuRunMetadata` 已改为 `rankSize`/`diePerRank`(全局模型)。两处不一致。 | ||
| 386 | + | ||
| 387 | +此外,JSON Schema 示例中使用了 `"seqId"` 而非新设计的 `"globalSeqId"`,缺少 `"execRound"`/`"sqeTaskId"`/`"ccuRegistry"`/`"sqeTaskRegistry"` 等新字段。 | ||
| 388 | + | ||
| 389 | +**修正建议**: | ||
| 390 | + | ||
| 391 | +更新 JSON Schema 示例,与 3.3.1-3.3.2 的数据结构定义保持一致: | ||
| 392 | +- 删除 `metadata.rankId`/`metadata.dieId` | ||
| 393 | +- 增加 `metadata.rankSize`/`metadata.diePerRank`/`metadata.totalExecRounds` | ||
| 394 | +- 增加 `ccuRegistry[]` 和 `sqeTaskRegistry[]` | ||
| 395 | +- entry 中 `seqId` 改为 `globalSeqId` | ||
| 396 | +- 增加 `execRound`/`sqeTaskId`/`rankId`/`dieId` 字段 | ||
| 397 | + | ||
| 398 | +--- | ||
| 399 | + | ||
| 400 | +## 四、汇总表 | ||
| 401 | + | ||
| 402 | +| 优先级 | 编号 | 问题 | 类型 | 修正要点 | | ||
| 403 | +|--------|------|------|------|---------| | ||
| 404 | +| P0 | P0-1 | CKE Wait 时不应计算 delta | 可行性错误 | waitCKE 时只记录关键字段,CKE 通过后才创建完整 entry | | ||
| 405 | +| P0 | P0-2 | globalSeqId/execRound 维护位置错误 | 可行性错误 | 全局上下文由 SequentialExecutor 管理,传参给 Simulator | | ||
| 406 | +| P0 | P0-3 | 全量 snapshot 性能瓶颈 | 性能瓶颈 | ResourceManager 拦截变更 + 初始快照 + 定期 checkpoint | | ||
| 407 | +| P1 | P1-1 | Loop 偏移公式不完整 | 信息缺失 | 补充 iterStepGSA/curLoopCnt/extendNum/addrExpandCoef | | ||
| 408 | +| P1 | P1-2 | 跨 CCU 变更采集时机 | 采集精度 | ResourceManager 内部拦截跨 CCU 变更 | | ||
| 409 | +| P1 | P1-3 | Detail 多态过度设计 | 架构优化 | 简化为扁平 key-value map | | ||
| 410 | +| P1 | P1-4 | JSON 格式不适合大数据量 | 性能优化 | 采集端 msgpack/flatbuffers,前端 WASM 解析 | | ||
| 411 | +| P2 | P2-1 | Describe() 可作为 MVP 来源 | 落地策略 | 第一阶段只做 Describe() + delta | | ||
| 412 | +| P2 | P2-2 | Notify 等非 CCU 任务缺失 | 信息缺失 | 增加简化记录 | | ||
| 413 | +| P2 | P2-3 | JSON Schema 模型不一致 | 模型一致性 | 与 3.3.1-3.3.2 保持一致 | | ||
| 414 | + | ||
| 415 | +--- | ||
| 416 | + | ||
| 417 | +## 五、修正优先级建议 | ||
| 418 | + | ||
| 419 | +**第一步(必须)**: 修正 P0-1、P0-2、P0-3,否则方案无法落地 | ||
| 420 | + | ||
| 421 | +**第二步(建议)**: 修正 P1-1、P1-2、P1-3,提高方案质量和实用性 | ||
| 422 | + | ||
| 423 | +**第三步(可选)**: 修正 P1-4、P2-1、P2-2、P2-3,完善细节和用户体验 | ||
| @@ -1868,7 +1868,7 @@ HCCP Network API | |||
| 1868 | 1868 | ||
| 1869 | ##### 落库必要性分类(进程私有候选) | 1869 | ##### 落库必要性分类(进程私有候选) |
| 1870 | 1870 | ||
| 1871 | -判定依据是**有没有别的进程/组件在运行期真调用库 API**(`Add`/`Get*`/`Update*`/`Delete*` `` `sim::X` ``);某实体的名字在别的目录出现不算数——原判据把 `cmd` 的 `PrintTable` 转储、以及同名结构体的局部变量误算成了运行期使用,本节按此修正。 | 1871 | +判定依据是**有没有别的进程/组件在运行期真调用库 API**(`Add`/`Get*`/`Update*`/`Delete*`\<sim::X\>);某实体的名字在别的目录出现不算数——原判据把 `cmd` 的 `PrintTable` 转储、以及同名结构体的局部变量误算成了运行期使用,本节按此修正。 |
| 1872 | 1872 | ||
| 1873 | - **C1 跨进程共享**:`src/device_arm`(独立 aarch64 `device` 可执行,单独链接 `db_sim_sqlite_db.cc`)、`src/plugin/runner`、`src/plugin/checker`、`src/store`(shm 通道)、`src/plugin/hccl_plugin_manager.cc` 中存在真库调用 ⇒ 必须落库。 | 1873 | - **C1 跨进程共享**:`src/device_arm`(独立 aarch64 `device` 可执行,单独链接 `db_sim_sqlite_db.cc`)、`src/plugin/runner`、`src/plugin/checker`、`src/store`(shm 通道)、`src/plugin/hccl_plugin_manager.cc` 中存在真库调用 ⇒ 必须落库。 |
| 1874 | - **C2 拓扑/硬件事实**:由 `src/topo/topo_ascend_cluster_parser.cc` 写入、多进程共读同一份 ⇒ 必须落库。 | 1874 | - **C2 拓扑/硬件事实**:由 `src/topo/topo_ascend_cluster_parser.cc` 写入、多进程共读同一份 ⇒ 必须落库。 |
| @@ -568,21 +568,6 @@ check_disk() { | |||
| 568 | fi | 568 | fi |
| 569 | } | 569 | } |
| 570 | 570 | ||
| 571 | -# 选可用的 qemu 用户态模拟包名:默认传统名 qemu-user-static(22.04/24.04/25.04 均有); | ||
| 572 | -# 新版 Ubuntu(26.04+)该名变虚拟包无安装候选,仅当 apt-cache 确认此情形时回退到 qemu-user-binfmt。 | ||
| 573 | -pick_qemu_pkg() { | ||
| 574 | - command -v apt-cache >/dev/null 2>&1 || { echo qemu-user-static; return; } | ||
| 575 | - # 命令替换取值 + || true + 判空;不在 pipefail 管道里用 grep -q(-q 早退致上游 SIGPIPE 会误判失败) | ||
| 576 | - local static_cand binfmt_cand | ||
| 577 | - static_cand="$(apt-cache policy qemu-user-static 2>/dev/null | grep -E 'Candidate: [0-9]' || true)" | ||
| 578 | - binfmt_cand="$(apt-cache policy qemu-user-binfmt 2>/dev/null | grep -E 'Candidate: [0-9]' || true)" | ||
| 579 | - if [ -z "${static_cand}" ] && [ -n "${binfmt_cand}" ]; then | ||
| 580 | - echo qemu-user-binfmt | ||
| 581 | - else | ||
| 582 | - echo qemu-user-static | ||
| 583 | - fi | ||
| 584 | -} | ||
| 585 | - | ||
| 586 | # 依赖清单:编译基础包 + 运行时 python-yaml(hccl-vm start 生成组网拓扑需);按 PKG_MGR 输出对应包名。 | 571 | # 依赖清单:编译基础包 + 运行时 python-yaml(hccl-vm start 生成组网拓扑需);按 PKG_MGR 输出对应包名。 |
| 587 | # apt 系(Ubuntu):build-essential / -dev 后缀;dnf 系(HCE/openEuler):gcc gcc-c++ make / -devel 后缀。 | 572 | # apt 系(Ubuntu):build-essential / -dev 后缀;dnf 系(HCE/openEuler):gcc gcc-c++ make / -devel 后缀。 |
| 588 | # x86_64 宿主额外装 device(arm) 交叉编译工具链(仅 apt 有此包);aarch64 本机直接编译用系统 gcc 无需交叉链。 | 573 | # x86_64 宿主额外装 device(arm) 交叉编译工具链(仅 apt 有此包);aarch64 本机直接编译用系统 gcc 无需交叉链。 |
| @@ -590,18 +575,19 @@ pick_qemu_pkg() { | |||
| 590 | dependency_list() { | 575 | dependency_list() { |
| 591 | local deps=() | 576 | local deps=() |
| 592 | if [ "${PKG_MGR}" = "apt" ]; then | 577 | if [ "${PKG_MGR}" = "apt" ]; then |
| 593 | - deps=("git" "sudo" "build-essential" "cmake" "libsqlite3-dev" "libboost-all-dev" "rdma-core" "libibverbs-dev" "pkg-config" "python3" "python3-yaml") | 578 | + deps=("git" "sudo" "build-essential" "cmake" "libboost-all-dev" "rdma-core" "libibverbs-dev" "pkg-config" "python3" "python3-yaml") |
| 594 | [ "${SKIP_HCCL_TEST}" = false ] && deps+=("openmpi-bin" "libopenmpi-dev") | 579 | [ "${SKIP_HCCL_TEST}" = false ] && deps+=("openmpi-bin" "libopenmpi-dev") |
| 595 | # curl 列举镜像/取头、wget 下载 .run;仅下载 CANN 时需要(keep 从不下载) | 580 | # curl 列举镜像/取头、wget 下载 .run;仅下载 CANN 时需要(keep 从不下载) |
| 596 | [ "${CANN_MODE}" != keep ] && deps+=("curl" "wget" "python3-pip") | 581 | [ "${CANN_MODE}" != keep ] && deps+=("curl" "wget" "python3-pip") |
| 597 | - # x86_64 宿主编译 device 侧(ARM)代码需交叉编译工具链 + qemu 模拟执行 binfmt; | 582 | + # x86_64 宿主编译 device 侧(ARM)代码需交叉编译工具链;aarch64 本机直接编译, |
| 598 | - # aarch64 本机直接编译,用系统 gcc 即可,无需交叉链和 qemu。 | 583 | + # 用系统 gcc 即可,无需交叉链。QEMU 是客户自行部署的外部运行依赖(AICPU 模式), |
| 584 | + # 本安装器不安装/升级 QEMU、不操作 binfmt;部署要求与检查见 docs/qemu-runtime.md。 | ||
| 599 | if [ "$(uname -m)" = "x86_64" ]; then | 585 | if [ "$(uname -m)" = "x86_64" ]; then |
| 600 | - deps+=("gcc-aarch64-linux-gnu" "g++-aarch64-linux-gnu" "$(pick_qemu_pkg)" "binfmt-support") | 586 | + deps+=("gcc-aarch64-linux-gnu" "g++-aarch64-linux-gnu") |
| 601 | fi | 587 | fi |
| 602 | elif [ "${PKG_MGR}" = "dnf" ]; then | 588 | elif [ "${PKG_MGR}" = "dnf" ]; then |
| 603 | # HCE/openEuler/EulerOS:gcc gcc-c++ make 替代 build-essential;-devel 替代 -dev | 589 | # HCE/openEuler/EulerOS:gcc gcc-c++ make 替代 build-essential;-devel 替代 -dev |
| 604 | - deps=("git" "sudo" "gcc" "gcc-c++" "make" "cmake" "sqlite-devel" "boost-devel" "rdma-core" "libibverbs-devel" "pkgconf-pkg-config" "python3" "python3-pyyaml") | 590 | + deps=("git" "sudo" "gcc" "gcc-c++" "make" "cmake" "boost-devel" "rdma-core" "libibverbs-devel" "pkgconf-pkg-config" "python3" "python3-pyyaml") |
| 605 | [ "${SKIP_HCCL_TEST}" = false ] && deps+=("mpich" "mpich-devel") | 591 | [ "${SKIP_HCCL_TEST}" = false ] && deps+=("mpich" "mpich-devel") |
| 606 | [ "${CANN_MODE}" != keep ] && deps+=("curl" "wget" "python3-pip") | 592 | [ "${CANN_MODE}" != keep ] && deps+=("curl" "wget" "python3-pip") |
| 607 | # aarch64 在 HCE 上本机编译,无需交叉链;x86_64 在 HCE 上的交叉链包名暂不内置 | 593 | # aarch64 在 HCE 上本机编译,无需交叉链;x86_64 在 HCE 上的交叉链包名暂不内置 |
| @@ -610,7 +596,7 @@ dependency_list() { | |||
| 610 | } | 596 | } |
| 611 | 597 | ||
| 612 | # 确保 universe 源已启用(仅 apt 系):精简/被裁过的 Ubuntu 只留 main 时,libboost-all-dev、openmpi-bin、 | 598 | # 确保 universe 源已启用(仅 apt 系):精简/被裁过的 Ubuntu 只留 main 时,libboost-all-dev、openmpi-bin、 |
| 613 | -# libopenmpi-dev、qemu-user-static 等(均在 universe 组件)会报 "Unable to locate package"。 | 599 | +# libopenmpi-dev 等(均在 universe 组件)会报 "Unable to locate package"。 |
| 614 | # dnf 系(HCE/openEuler)所有包均在官方源,无需额外启用;调用时自动跳过。 | 600 | # dnf 系(HCE/openEuler)所有包均在官方源,无需额外启用;调用时自动跳过。 |
| 615 | # 装依赖前调用;启用后不在此 apt-get update,交由 install_deps 紧接着的 update 统一刷新。 | 601 | # 装依赖前调用;启用后不在此 apt-get update,交由 install_deps 紧接着的 update 统一刷新。 |
| 616 | ensure_universe_enabled() { | 602 | ensure_universe_enabled() { |
| @@ -1239,11 +1225,41 @@ resolve_cann() { | |||
| 1239 | 1225 | ||
| 1240 | # 清理 third_party 下载缓存:build.sh 的第三方 cmake 按"文件是否存在"判定是否重下, | 1226 | # 清理 third_party 下载缓存:build.sh 的第三方 cmake 按"文件是否存在"判定是否重下, |
| 1241 | # 一次下载失败留下的半包会被下次直接复用导致持续失败。编译失败时清掉下载归档,让重跑重新下载。 | 1227 | # 一次下载失败留下的半包会被下次直接复用导致持续失败。编译失败时清掉下载归档,让重跑重新下载。 |
| 1228 | +# 覆盖两处下载归档:根 third_party/,以及各存储后端模块自己的 third_party/ | ||
| 1229 | +#(src/storage_backends/<模块>/third_party/——模块专属依赖配方同样只按存在性复用归档, | ||
| 1230 | +# 例如 SQLite amalgamation zip;不硬编码模块名,只枚举实际存在的一级模块目录)。 | ||
| 1231 | +# 只删下载归档文件:不递归删除已解压源码目录,不动 build/install 与数据库文件; | ||
| 1232 | +# 归档为符号链接且最终目标越出源码树时跳过(不跟随越界链接);目录缺失/无匹配不报错。 | ||
| 1242 | clean_thirdparty_dl_cache() { | 1233 | clean_thirdparty_dl_cache() { |
| 1243 | local tp="${CHECKER_PATH}/third_party" | 1234 | local tp="${CHECKER_PATH}/third_party" |
| 1244 | - [ -d "${tp}" ] || return 0 | 1235 | + if [ -d "${tp}" ]; then |
| 1245 | - rm -f "${tp}"/*.tar.gz "${tp}"/*.tgz "${tp}"/*.zip 2>/dev/null || true | 1236 | + rm -f "${tp}"/*.tar.gz "${tp}"/*.tgz "${tp}"/*.zip 2>/dev/null || true |
| 1246 | - info "已清理 ${tp} 下的第三方下载归档(重跑本脚本会重新下载,规避半包缓存)。" | 1237 | + info "已清理 ${tp} 下的第三方下载归档(重跑本脚本会重新下载,规避半包缓存)。" |
| 1238 | + fi | ||
| 1239 | + local real_checker | ||
| 1240 | + real_checker="$(cd "${CHECKER_PATH}" 2>/dev/null && pwd -P)" || real_checker="${CHECKER_PATH}" | ||
| 1241 | + local mod_tp archive real_archive removed | ||
| 1242 | + for mod_tp in "${CHECKER_PATH}"/src/storage_backends/*/third_party; do | ||
| 1243 | + [ -d "${mod_tp}" ] || continue | ||
| 1244 | + removed=0 | ||
| 1245 | + for archive in "${mod_tp}"/*.tar.gz "${mod_tp}"/*.tgz "${mod_tp}"/*.zip; do | ||
| 1246 | + [ -f "${archive}" ] || continue | ||
| 1247 | + real_archive="$(readlink -f "${archive}" 2>/dev/null)" | ||
| 1248 | + if [ -z "${real_archive}" ]; then | ||
| 1249 | + warn "跳过无法解析的缓存归档: ${archive}" | ||
| 1250 | + continue | ||
| 1251 | + fi | ||
| 1252 | + case "${real_archive}" in | ||
| 1253 | + "${real_checker}"/*) ;; | ||
| 1254 | + *) warn "跳过最终目标越出源码树的缓存归档: ${archive}"; continue ;; | ||
| 1255 | + esac | ||
| 1256 | + rm -f "${archive}" | ||
| 1257 | + removed=$((removed + 1)) | ||
| 1258 | + done | ||
| 1259 | + if [ "${removed}" -gt 0 ]; then | ||
| 1260 | + info "已清理 ${mod_tp} 下的后端模块下载归档 x${removed}(重跑本脚本会重新下载,规避半包缓存)。" | ||
| 1261 | + fi | ||
| 1262 | + done | ||
| 1247 | } | 1263 | } |
| 1248 | 1264 | ||
| 1249 | # 编译 HCCL-VM 工具(对应 README §3.1 的 bash ./build.sh --full) | 1265 | # 编译 HCCL-VM 工具(对应 README §3.1 的 bash ./build.sh --full) |
| @@ -0,0 +1,247 @@ | |||
| 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 | +// 文件职责:OperationData(OP_DATA_DB)的统一逻辑 DDL 目录与 OpDB 领域操作声明。 | ||
| 12 | +// 8 张表在一个 master catalog 中登记(OpTaskTab 为 PID 动态 scope 表); | ||
| 13 | +// 每张表只有一个紧凑 Table entry,字段/属性/约束/索引/外键写在同一 entry, | ||
| 14 | +// 公共生成器从这里派生全部表契约产物。短宏区段结束立即 #undef。 | ||
| 15 | +// 领域声明与 DDL 分区共存于本文件(唯一声明事实源,不设第三个声明入口)。 | ||
| 16 | +#ifndef _OPERATION_DATA_OPS_H_ | ||
| 17 | +#define _OPERATION_DATA_OPS_H_ | ||
| 18 | + | ||
| 19 | +#include <cstdint> | ||
| 20 | +#include <map> | ||
| 21 | +#include <string> | ||
| 22 | +#include <vector> | ||
| 23 | + | ||
| 24 | +#include "operation_data/operation_data_types.h" | ||
| 25 | +#include "storage/storage_catalog.h" | ||
| 26 | + | ||
| 27 | +// ==== OpDB 唯一 DDL 区(master catalog;短别名区段结束立即 #undef) ==== | ||
| 28 | +#define Field HCCL_VM_DDL_FIELD | ||
| 29 | +#define Version HCCL_VM_DDL_VERSION | ||
| 30 | +#define PrimaryKey HCCL_VM_DDL_PRIMARY_KEY | ||
| 31 | +#define Unique HCCL_VM_DDL_UNIQUE | ||
| 32 | +#define Index HCCL_VM_DDL_INDEX | ||
| 33 | +#define ForeignKey HCCL_VM_DDL_FOREIGN_KEY | ||
| 34 | +#define Scope Ddl::ScopeKind | ||
| 35 | +#define AutoIncrement Ddl::AutoIncrement | ||
| 36 | +#define Text Ddl::Text | ||
| 37 | +#define Blob Ddl::Blob | ||
| 38 | +#define Derived Ddl::Derived | ||
| 39 | +#define OnDelete Ddl::OnDelete | ||
| 40 | + | ||
| 41 | +#define HCCL_VM_OPDATA_DATABASE(Table) \ | ||
| 42 | + /* (deviceId,id):设备维度最新算子定位(deviceId 过滤 + id 倒序取首条), \ | ||
| 43 | + 服务 QueryLatestOpDetailStreamByDeviceId;id 命中索引列,streamId 回表 */ \ | ||
| 44 | + Table( \ | ||
| 45 | + sim::operation::OpDetailTab, \ | ||
| 46 | + (Version(1), Scope::Static, Field(id, AutoIncrement), Field(pid), Field(deviceId), Field(rankId), \ | ||
| 47 | + Field(commId), Field(opIter), Field(syncIter), Field(streamId), Field(root), Field(opExpansionMode), \ | ||
| 48 | + Field(devType), Field(rankSize), Field(srcRank), Field(dstRank), Field(opDetail), Field(opExtInfo), \ | ||
| 49 | + PrimaryKey(id), Index(pid, syncIter), Index(commId, deviceId, id), Index(syncIter), Index(deviceId, id))) \ | ||
| 50 | + Table( \ | ||
| 51 | + sim::operation::OpMemInfoTab, \ | ||
| 52 | + (Version(1), Scope::Static, Field(id, AutoIncrement), Field(opDetailId), Field(inputAddr), \ | ||
| 53 | + Field(inputSize), Field(outputAddr), Field(outputSize), Field(cclAddr), Field(cclSize), PrimaryKey(id), \ | ||
| 54 | + Index(opDetailId), ForeignKey(opDetailId, sim::operation::OpDetailTab::id, OnDelete::Cascade))) \ | ||
| 55 | + Table( \ | ||
| 56 | + sim::operation::SyncRecordTab, \ | ||
| 57 | + (Version(1), Scope::Static, Field(id, AutoIncrement), Field(pid), Field(rankId), Field(rankSize), \ | ||
| 58 | + Field(syncIter), Field(streamId), Field(status), PrimaryKey(id), Index(status))) \ | ||
| 59 | + Table( \ | ||
| 60 | + sim::operation::CcuChannelTab, \ | ||
| 61 | + (Version(1), Scope::Static, Field(id, AutoIncrement), Field(channelId), Field(srcDieId), \ | ||
| 62 | + Field(dstDieId), Field(srcDeviceId), Field(dstDeviceId), Field(srcRankId), Field(dstRankId), \ | ||
| 63 | + Field(leid, Blob), Field(reid, Blob), Field(protocol), Field(jettyNum), Field(jettyId, Blob), \ | ||
| 64 | + PrimaryKey(id), Index(channelId))) \ | ||
| 65 | + Table( \ | ||
| 66 | + sim::operation::JettyMapTab, \ | ||
| 67 | + (Version(1), Scope::Static, Field(id, AutoIncrement), Field(opDetailId), Field(srcDieId), \ | ||
| 68 | + Field(dstDieId), Field(srcRankId), Field(dstRankId), Field(leid, Blob), Field(reid, Blob), \ | ||
| 69 | + Field(protocol), PrimaryKey(id), Index(opDetailId), Index(srcDieId, dstDieId))) \ | ||
| 70 | + Table( \ | ||
| 71 | + sim::operation::CcuInstrResTab, \ | ||
| 72 | + (Version(1), Scope::Static, Field(id, AutoIncrement), Field(deviceId), Field(dieId), \ | ||
| 73 | + Field(instrCount), Field(instrSpace, Blob), PrimaryKey(id), Index(deviceId, dieId))) \ | ||
| 74 | + Table( \ | ||
| 75 | + sim::operation::CcuInstrTab, \ | ||
| 76 | + (Version(1), Scope::Static, Field(id, AutoIncrement), Field(ccuInstrResId), \ | ||
| 77 | + Field(startId), Field(instrInfoSize), PrimaryKey(id), \ | ||
| 78 | + ForeignKey( \ | ||
| 79 | + ccuInstrResId, sim::operation::CcuInstrResTab::id, \ | ||
| 80 | + OnDelete::Cascade))) /* (streamId,isDone):任务完成度聚合(streamId 过滤 + isDone \ | ||
| 81 | + 匹配计数)的 覆盖索引;独立 isDone \ | ||
| 82 | + 索引仍服务只按完成态过滤的查询 */ \ | ||
| 83 | + Table( \ | ||
| 84 | + sim::operation::OpTaskTab, \ | ||
| 85 | + (Version(1), Scope::DynamicPid, Field(id, AutoIncrement), Field(pid), Field(opDetailId), Field(deviceId), \ | ||
| 86 | + Field(streamId), Field(taskType), Field(isDone), Field(optaskMeta), PrimaryKey(id), Index(opDetailId), \ | ||
| 87 | + Index(streamId, isDone), Index(isDone))) \ | ||
| 88 | + Table( \ | ||
| 89 | + sim::operation::HalfRTTTab, (Version(1), Scope::Static, Field(id, AutoIncrement), Field(deviceId), \ | ||
| 90 | + Field(dieId), Field(wishCntXnIdBegin), Field(wishCntXnIdEnd), \ | ||
| 91 | + Field(totalCntId), PrimaryKey(id), Index(deviceId, dieId))) | ||
| 92 | + | ||
| 93 | +// 发布 OperationData 逻辑库目录:展开全部 9 个表条目并派生只读 manifest | ||
| 94 | +// (表数量/fingerprint/类型擦除通道均由 catalog 派生,不另写第二份清单)。 | ||
| 95 | +#define HCCL_VM_DDL_CURRENT_DATABASE "OP_DATA_DB" | ||
| 96 | +HCCL_VM_DEFINE_DATABASE(kOpDataDatabase, OP_DATA_DB, HCCL_VM_OPDATA_DATABASE) | ||
| 97 | +#undef HCCL_VM_DDL_CURRENT_DATABASE | ||
| 98 | +#undef HCCL_VM_OPDATA_DATABASE | ||
| 99 | + | ||
| 100 | +#undef OnDelete | ||
| 101 | +#undef Derived | ||
| 102 | +#undef Blob | ||
| 103 | +#undef Text | ||
| 104 | +#undef AutoIncrement | ||
| 105 | +#undef Scope | ||
| 106 | +#undef ForeignKey | ||
| 107 | +#undef Index | ||
| 108 | +#undef Unique | ||
| 109 | +#undef PrimaryKey | ||
| 110 | +#undef Version | ||
| 111 | +#undef Field | ||
| 112 | + | ||
| 113 | +namespace HcclSim::Storage::Ddl { | ||
| 114 | +// CcuChannelTab 记录语义 hook:jettyId 只编码 jettyNum 个有效元素(有效数组长度 | ||
| 115 | +// 由同记录另一字段决定),不是固定数组全部容量。 | ||
| 116 | +template <> | ||
| 117 | +struct RecordCodecHooks<sim::operation::CcuChannelTab> : DefaultRecordCodecHooks<sim::operation::CcuChannelTab> { | ||
| 118 | + static int64_t EffectiveBytesLength(const sim::operation::CcuChannelTab& record, uint16_t fieldId) | ||
| 119 | + { | ||
| 120 | + if (fieldId != 10) { | ||
| 121 | + return -1; | ||
| 122 | + } | ||
| 123 | + return static_cast<int64_t>(record.jettyNum) * static_cast<int64_t>(sizeof(record.jettyId[0])); | ||
| 124 | + } | ||
| 125 | +}; | ||
| 126 | +} // namespace HcclSim::Storage::Ddl | ||
| 127 | + | ||
| 128 | +// ==== OpDB 领域操作声明区(与实现文件分区顺序一致) ==== | ||
| 129 | +// 本域已有语义完整的业务接口(InsertOpDetail/Query.../Update... 等),不再建立 | ||
| 130 | +// 第二套 Db 薄门面;业务优先使用这些领域接口,简单或特殊场景仍可直接使用 | ||
| 131 | +// HcclSim::Storage 原子接口。后端、会话、lease、SQL 均不可见。 | ||
| 132 | +namespace sim::operation { | ||
| 133 | +// 进程当前 OpDetail 序号(实现文件定义;device 进程经头文件声明读写,替代 | ||
| 134 | +// device 侧本地的 extern 声明——命名空间随本域收敛为 sim::operation)。 | ||
| 135 | +extern uint32_t g_currOpDetailId; | ||
| 136 | +// 进程当前 OpMem 序号(实现文件定义;aclrt model 重放路径经头文件声明读写)。 | ||
| 137 | +extern uint32_t g_currOpMemId; | ||
| 138 | + | ||
| 139 | +/** | ||
| 140 | + * @brief 当前进程正在处理的算子迭代(= 最近一次 InsertOpDetail 分配的 opIter)。 | ||
| 141 | + * | ||
| 142 | + * 用途:CCU 交换表(CcuSyncResTab)需要跨 rank 一致的 op 身份来隔离不同算子的交换值。 | ||
| 143 | + * opIter 由 InsertOpDetail 按 (commName, commHash) 自增,两侧进程按同一算子序列 | ||
| 144 | + * 推进时天然对齐,可直接当 op 身份使用。 | ||
| 145 | + * | ||
| 146 | + * @return 最新分配的 opIter;尚无算子插入时为 0。 | ||
| 147 | + */ | ||
| 148 | +uint32_t GetCurOpIter(); | ||
| 149 | + | ||
| 150 | +// ==== Stream Sync 迭代分区(纯进程内状态,不落库) ==== | ||
| 151 | +// 迁移前语义:以 streamId 为键维护各流独立的 sync 迭代计数。 | ||
| 152 | +void AddSyncStreamIter(uint64_t streamId); | ||
| 153 | +void RemoveSyncStreamIter(uint64_t streamId); | ||
| 154 | +bool NextStreamSyncIdx(uint64_t streamId, uint64_t& syncIdx); | ||
| 155 | + | ||
| 156 | +// ==== Op Detail / Memory 分区 ==== | ||
| 157 | +int InsertOpDetail(OpDetailTab& rec); | ||
| 158 | +int InsertOpMem(OpMemInfoTab& rec); | ||
| 159 | +// OpDetail 与 OpMem 同事务原子提交(多表流程)。 | ||
| 160 | +int InsertOpDetailAndMem(OpDetailTab& detail, OpMemInfoTab& mem); | ||
| 161 | +int QueryNewestOpDeatailIdByPid(uint64_t pid, uint32_t& OpDetailId); | ||
| 162 | +// 同 syncIter 下目标 rank 的最新算子内存信息(组合查询)。 | ||
| 163 | +int QueryCurrentOpMemInfoByRank(uint32_t rankId, OpMemInfoTab& out); | ||
| 164 | +// 按通信域成员 + 设备维度定位最新算子内存信息(迁移前 JOIN opDetails+opMemInfo 语义)。 | ||
| 165 | +int QueryCurrentOpMemInfo(uint64_t commId, uint32_t deviceId, OpMemInfoTab& out); | ||
| 166 | +// 由 opDetailId 定位对应算子内存信息(图模式录制/重放复制内存上下文用)。 | ||
| 167 | +int QueryOpMemInfoByOpDetailId(uint32_t opDetailId, OpMemInfoTab& out); | ||
| 168 | +int UpdateOpMemCclBuffer(uint64_t cclAddr, uint64_t cclSize); | ||
| 169 | +int UpdateOpExpansionMode(uint8_t mode); | ||
| 170 | +// 把指定算子的主流 streamId 回写(graph 模式流绑定)。 | ||
| 171 | +int UpdateOpDetailMainStream(uint32_t opDetailId, uint64_t streamId); | ||
| 172 | +int QueryLatestOpExpansionMode(); | ||
| 173 | +int QueryCompositeOpDetailBySyncIter(uint32_t syncIter, std::map<uint32_t, std::vector<CompositeOpDetail>>& detail); | ||
| 174 | +// 算子执行索引:全部 opDetails 的执行身份快照(id/deviceId/rankId/commId/opIter/rankSize)。 | ||
| 175 | +int QueryOpExecutionIndexEntries(std::vector<OpExecutionIndexEntry>& out); | ||
| 176 | +// 算子明细身份解析:由 opDetailId 反查通信域成员/rank/设备。 | ||
| 177 | +int QueryOpDetailIdentity(uint32_t opDetailId, uint64_t& commId, uint32_t& rankId, uint32_t& deviceId); | ||
| 178 | +// 按主键取完整算子明细行(含 opDetail/opExtInfo BLOB;图模式录制复制用)。 | ||
| 179 | +int QueryOpDetailById(uint32_t opDetailId, OpDetailTab& out); | ||
| 180 | +// 设备维度最新算子明细(graph 模式主流发现;空表 WARN 不 ERROR)。 | ||
| 181 | +int QueryLatestOpDetailByDeviceId(uint32_t deviceId, OpDetailTab& out); | ||
| 182 | +// 设备维度最新算子的主流摘要:只取 id/streamId 两列(不读 opDetail/opExtInfo | ||
| 183 | +// BLOB);排序(id 降序取首条)与空表/失败的 -1 + WARN 处理同完整行接口。 | ||
| 184 | +int QueryLatestOpDetailStreamByDeviceId(uint32_t deviceId, uint32_t& opDetailId, uint64_t& streamId); | ||
| 185 | +// 按通信域 (commName, commHash) 解析全部成员,汇总各成员在指定 opIter 的复合算子明细 | ||
| 186 | +// (detail + memInfo + 动态 opTask 表任务),上游 QueryCompositeOpDetailByOpIter 语义。 | ||
| 187 | +int QueryCompositeOpDetailByOpIter( | ||
| 188 | + const std::string& commName, uint64_t commHash, uint32_t opIter, std::vector<CompositeOpDetail>& details); | ||
| 189 | + | ||
| 190 | +// ==== Sync Record 分区 ==== | ||
| 191 | +int InsertSyncRecord(SyncRecordTab& rec); | ||
| 192 | +int QuerySyncRecordAll(std::vector<SyncRecordTab>& out); | ||
| 193 | +int QuerySyncRecordByStatus(uint8_t status, std::vector<SyncRecordTab>& out); | ||
| 194 | +// 全部状态更新在同一事务内提交(批量流程)。 | ||
| 195 | +int UpdateSyncRecordStatus(std::vector<SyncRecordTab>& syncRecord); | ||
| 196 | + | ||
| 197 | +// ==== CCU / Jetty 分区 ==== | ||
| 198 | +int InsertCcuChannel(CcuChannelTab& rec); | ||
| 199 | +int InsertJettyMap(JettyMapTab& rec); | ||
| 200 | +int QueryCcuChannelAll(std::vector<CcuChannelTab>& out); | ||
| 201 | +int QueryJettyMapAll(std::vector<JettyMapTab>& out); | ||
| 202 | +int InsertCcuInstrRes(CcuInstrResTab& rec); | ||
| 203 | +int InsertCcuInstr(CcuInstrTab& rec); | ||
| 204 | +// 按 device+die 读改写整块指令空间,不存在则插入(状态机入口)。 | ||
| 205 | +// mergedInstrSpace/totalInstrCount 非空时返回合并后的完整指令空间与总指令数: | ||
| 206 | +// 更新路径取 max(已存指令数, startId + instrCount),插入路径为 startId + instrCount。 | ||
| 207 | +int UpdateAndInsertByCcuId( | ||
| 208 | + uint64_t& ccuId, uint32_t deviceId, uint32_t dieId, uint32_t startId, uint32_t instrCount, uint32_t instrOffset, | ||
| 209 | + uint32_t instrInfoSize, const void* instrInfo, std::vector<uint8_t>* mergedInstrSpace = nullptr, | ||
| 210 | + uint32_t* totalInstrCount = nullptr); | ||
| 211 | +int QueryCcuInstrResAll(std::vector<CcuInstrResTab>& out); | ||
| 212 | +// 指令/通道资源元数据计数(轮询感知微码下发与资源行补齐的中间状态)。 | ||
| 213 | +int QueryCcuResourceMetaCount(uint32_t& instrLoadCnt, uint32_t& channelCnt); | ||
| 214 | +// 0.5RTT 半程往返数据表。 | ||
| 215 | +int InsertHalfRTT(HalfRTTTab& rec); | ||
| 216 | +int QueryHalfRTTAll(std::vector<HalfRTTTab>& out); | ||
| 217 | + | ||
| 218 | +// ==== Dynamic Task 分区 ==== | ||
| 219 | +// 动态 PID scope 表:host 用 pid、AICPU 模式 device 进程用 ppid 解析物理表。 | ||
| 220 | +int InsertOpTask(OpTaskTab& rec, bool isDevice = false); | ||
| 221 | +// 按当前进程 pid 解析动态表,按 streamId 查任务(迁移前 getpid() 语义)。 | ||
| 222 | +int QueryOpTasksByStreamId(uint64_t streamId, std::vector<OpTaskTab>& tasks); | ||
| 223 | +// 同一聚合语句返回 stream 上任务总数与已完成数(isDone 为 true 的行数): | ||
| 224 | +// 统计在数据库端完成,不加载任务行(optaskMeta BLOB 不回传)。仅成功后 | ||
| 225 | +// 写入两个输出,失败输出不构成有效完成度。 | ||
| 226 | +int QueryOpTaskCompletionByStreamId(uint64_t streamId, uint64_t& total, uint64_t& done); | ||
| 227 | +// 把指定任务在动态 opTask_P_<pid> 表中标记为完成(isDone=1)。 | ||
| 228 | +int FinishOpTask(const OpTaskTab& task); | ||
| 229 | +// 枚举 OP_DATA_DB 全部动态 opTask 物理表名(迁移前 sqlite_master LIKE 'opTask_P_%' 语义)。 | ||
| 230 | +int QueryOpTaskTabNames(std::vector<std::string>& names); | ||
| 231 | +// 汇总全部动态 opTask 表记录(filterDone 时仅未完成任务;迁移前 QueryAllOpTasks 语义)。 | ||
| 232 | +int QueryAllOpTasks(std::vector<OpTaskTab>& tasks, bool filterDone = false); | ||
| 233 | + | ||
| 234 | +// ==== Lifecycle / Maintenance 分区 ==== | ||
| 235 | +// 确保进程存储会话已安装(解析安装根下的基线库路径并完成建表;幂等)。 | ||
| 236 | +// 迁移前语义:Host start/run 与 device 子进程在首次业务访问前的 fail-fast 建连时机。 | ||
| 237 | +int EnsureProcessStorageSession(); | ||
| 238 | + | ||
| 239 | +// 领域维护接口:换库(加载备份文件)、生成 OP_DATA_DB 物理备份、 | ||
| 240 | +// 清空全部静态操作数据表(保留自增序列)、销毁全部动态任务表。 | ||
| 241 | +int SetDbConfig(DBConfig& config); | ||
| 242 | +int BackupOperationData(const std::string& destinationPath); | ||
| 243 | +int ClearStaticData(); | ||
| 244 | +int DropDynamicData(); | ||
| 245 | +} // namespace sim::operation | ||
| 246 | + | ||
| 247 | +#endif | ||
Rtest/hccl_vm/include/runnerdb/sim_op_db_types.h→test/hccl_vm/include/operation_data/operation_data_types.h+22-26
| @@ -1,18 +1,11 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * Copyright (c) 2026 Huawei Technologies Co., Ltd. | 2 | * Copyright (c) 2026 Huawei Technologies Co., Ltd. |
| 3 | - * This program is free software, you can redistribute it and/or modify it under | 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | - * the terms and conditions of CANN Open Software License Agreement Version 2.0 | 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | - * (the "License"). Please refer to the License for details. You may not use | 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. |
| 6 | - * this file except in compliance with the License. THIS SOFTWARE IS PROVIDED ON | 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, |
| 7 | - * 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 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS | 8 | + * See LICENSE in the root of the software repository for the full text of the License. |
| 9 | - * FOR A PARTICULAR PURPOSE. See LICENSE in the root of the software repository | ||
| 10 | - * for the full text of the License. | ||
| 11 | - */ | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 15 | - * for the full text of the License. | ||
| 16 | */ | 9 | */ |
| 17 | 10 | ||
| 18 | #ifndef SIM_OP_DB_TYPES_H | 11 | #ifndef SIM_OP_DB_TYPES_H |
| @@ -21,7 +14,9 @@ | |||
| 21 | #include <string> | 14 | #include <string> |
| 22 | #include <vector> | 15 | #include <vector> |
| 23 | 16 | ||
| 24 | -namespace sim { | 17 | +#include "sim_capacity_limits.h" |
| 18 | + | ||
| 19 | +namespace sim::operation { | ||
| 25 | enum class DbType { | 20 | enum class DbType { |
| 26 | SQLITE3, | 21 | SQLITE3, |
| 27 | }; | 22 | }; |
| @@ -36,21 +31,21 @@ struct DBConfig { | |||
| 36 | }; | 31 | }; |
| 37 | 32 | ||
| 38 | struct OpDetailTab { | 33 | struct OpDetailTab { |
| 39 | - uint32_t id; // PK (自增) | 34 | + uint32_t id; // PK (自增) |
| 40 | - uint32_t pid; // proxy 进程 ID | 35 | + uint32_t pid; // proxy 进程 ID |
| 41 | uint32_t deviceId; // 物理设备 ID(全局唯一,内部逻辑统一使用) | 36 | uint32_t deviceId; // 物理设备 ID(全局唯一,内部逻辑统一使用) |
| 42 | uint32_t rankId; // 通信域内 rank ID | 37 | uint32_t rankId; // 通信域内 rank ID |
| 43 | uint64_t commId; // 通信域成员 ID,FK -> Communicator.id | 38 | uint64_t commId; // 通信域成员 ID,FK -> Communicator.id |
| 44 | uint32_t opIter; // 算子迭代次数 (从 0 开始) | 39 | uint32_t opIter; // 算子迭代次数 (从 0 开始) |
| 45 | uint32_t syncIter; // 所属 sync 周期 (从 0 开始) // todo 可删 | 40 | uint32_t syncIter; // 所属 sync 周期 (从 0 开始) // todo 可删 |
| 46 | 41 | ||
| 47 | - uint64_t streamId; // streamId | 42 | + uint64_t streamId; // streamId |
| 48 | - uint32_t root; // root | 43 | + uint32_t root; // root |
| 49 | - uint32_t opExpansionMode; // 算子执行模式 0: ccu, 1: aicpu, 2: aiv | 44 | + uint32_t opExpansionMode; // 算子执行模式 0: ccu, 1: aicpu, 2: aiv |
| 50 | - uint32_t devType; // 设备类型 | 45 | + uint32_t devType; // 设备类型 |
| 51 | - uint32_t rankSize; // ransize | 46 | + uint32_t rankSize; // ransize |
| 52 | - uint32_t srcRank; // srcRank | 47 | + uint32_t srcRank; // srcRank |
| 53 | - uint32_t dstRank; // dstRank | 48 | + uint32_t dstRank; // dstRank |
| 54 | std::vector<uint8_t> opDetail; // BLOB | 49 | std::vector<uint8_t> opDetail; // BLOB |
| 55 | std::vector<uint8_t> opExtInfo; // BLOB | 50 | std::vector<uint8_t> opExtInfo; // BLOB |
| 56 | }; | 51 | }; |
| @@ -100,7 +95,7 @@ struct CcuChannelTab { | |||
| 100 | uint8_t reid[16]; | 95 | uint8_t reid[16]; |
| 101 | uint16_t protocol; | 96 | uint16_t protocol; |
| 102 | uint16_t jettyNum; | 97 | uint16_t jettyNum; |
| 103 | - uint32_t jettyId[64]; // BLOB,动态大小 最大64个 | 98 | + uint32_t jettyId[HcclSim::HCCL_VM_MAX_CHANNEL_JETTIES]; |
| 104 | }; | 99 | }; |
| 105 | 100 | ||
| 106 | struct JettyMapTab { | 101 | struct JettyMapTab { |
| @@ -145,7 +140,8 @@ struct OpExecutionKey { | |||
| 145 | uint64_t commHash{0}; | 140 | uint64_t commHash{0}; |
| 146 | uint32_t opIter{0}; | 141 | uint32_t opIter{0}; |
| 147 | 142 | ||
| 148 | - bool operator<(const OpExecutionKey &other) const { | 143 | + bool operator<(const OpExecutionKey& other) const |
| 144 | + { | ||
| 149 | if (commName != other.commName) { | 145 | if (commName != other.commName) { |
| 150 | return commName < other.commName; | 146 | return commName < other.commName; |
| 151 | } | 147 | } |
| @@ -185,5 +181,5 @@ struct HalfRTTTab { | |||
| 185 | uint32_t wishCntXnIdEnd; | 181 | uint32_t wishCntXnIdEnd; |
| 186 | uint32_t totalCntId; | 182 | uint32_t totalCntId; |
| 187 | }; | 183 | }; |
| 188 | -} // namespace sim | 184 | +} // namespace sim::operation |
| 189 | #endif | 185 | #endif |
| @@ -1,18 +1,11 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * Copyright (c) 2026 Huawei Technologies Co., Ltd. | 2 | * Copyright (c) 2026 Huawei Technologies Co., Ltd. |
| 3 | - * This program is free software, you can redistribute it and/or modify it under | 3 | + * This program is free software, you can redistribute it and/or modify it under the terms and conditions of |
| 4 | - * the terms and conditions of CANN Open Software License Agreement Version 2.0 | 4 | + * CANN Open Software License Agreement Version 2.0 (the "License"). |
| 5 | - * (the "License"). Please refer to the License for details. You may not use | 5 | + * Please refer to the License for details. You may not use this file except in compliance with the License. |
| 6 | - * this file except in compliance with the License. THIS SOFTWARE IS PROVIDED ON | 6 | + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, |
| 7 | - * 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 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS | 8 | + * See LICENSE in the root of the software repository for the full text of the License. |
| 9 | - * FOR A PARTICULAR PURPOSE. See LICENSE in the root of the software repository | ||
| 10 | - * for the full text of the License. | ||
| 11 | - */ | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 15 | - * for the full text of the License. | ||
| 16 | */ | 9 | */ |
| 17 | 10 | ||
| 18 | #ifndef DB_SIM_COMMUNICATOR_H | 11 | #ifndef DB_SIM_COMMUNICATOR_H |
| @@ -29,12 +22,10 @@ struct CommunicatorMemberInfo { | |||
| 29 | uint32_t rankId; | 22 | uint32_t rankId; |
| 30 | }; | 23 | }; |
| 31 | 24 | ||
| 32 | -bool GetCommunicatorMembers(uint64_t commId, | 25 | +bool GetCommunicatorMembers(uint64_t commId, std::vector<CommunicatorMemberInfo>& members); |
| 33 | - std::vector<CommunicatorMemberInfo> &members); | ||
| 34 | // 根据通信域成员 ID 查询其所属通信域名称。 | 26 | // 根据通信域成员 ID 查询其所属通信域名称。 |
| 35 | -bool GetCommunicatorName(uint64_t commId, std::string &commName); | 27 | +bool GetCommunicatorName(uint64_t commId, std::string& commName); |
| 36 | -bool GetCommunicatorIdentity(uint64_t commId, std::string &commName, | 28 | +bool GetCommunicatorIdentity(uint64_t commId, std::string& commName, uint64_t& commHash); |
| 37 | - uint64_t &commHash); | ||
| 38 | } // namespace sim | 29 | } // namespace sim |
| 39 | 30 | ||
| 40 | #endif // DB_SIM_COMMUNICATOR_H | 31 | #endif // DB_SIM_COMMUNICATOR_H |
| @@ -1,102 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under | ||
| 4 | - * the terms and conditions of CANN Open Software License Agreement Version 2.0 | ||
| 5 | - * (the "License"). Please refer to the License for details. You may not use | ||
| 6 | - * this file except in compliance with the License. THIS SOFTWARE IS PROVIDED ON | ||
| 7 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS | ||
| 9 | - * FOR A PARTICULAR PURPOSE. See LICENSE in the root of the software repository | ||
| 10 | - * for the full text of the License. | ||
| 11 | - */ | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 15 | - * for the full text of the License. | ||
| 16 | - */ | ||
| 17 | - | ||
| 18 | -#ifndef SIM_OP_DB_OPS_H | ||
| 19 | -#define SIM_OP_DB_OPS_H | ||
| 20 | - | ||
| 21 | -#include <cstdint> | ||
| 22 | -#include <map> | ||
| 23 | -#include <string> | ||
| 24 | -#include <vector> | ||
| 25 | - | ||
| 26 | -#include "sim_op_db_types.h" | ||
| 27 | - | ||
| 28 | -namespace sim { | ||
| 29 | -extern uint32_t g_currOpDetailId; | ||
| 30 | -extern uint32_t g_currOpMemId; | ||
| 31 | - | ||
| 32 | -/** | ||
| 33 | - * @brief 当前进程正在处理的算子迭代(= 最近一次 InsertOpDetail 分配的 | ||
| 34 | - * opIter)。 | ||
| 35 | - * | ||
| 36 | - * 用途:CCU 交换表(CcuSyncResTab)需要跨 rank 一致的 op | ||
| 37 | - * 身份来隔离不同算子的交换值。 opIter 由 InsertOpDetail 按 (commName, commHash) | ||
| 38 | - * 自增,两侧进程按同一算子序列 推进时天然对齐,可直接当 op 身份使用。 | ||
| 39 | - * | ||
| 40 | - * @return 最新分配的 opIter;尚无算子插入时为 0。 | ||
| 41 | - */ | ||
| 42 | -uint32_t GetCurOpIter(); | ||
| 43 | - | ||
| 44 | -int InitOpDataDb(); | ||
| 45 | -int SetDbConfig(DBConfig &config); | ||
| 46 | - | ||
| 47 | -void AddSyncStreamIter(uint64_t streamId); | ||
| 48 | -void RemoveSyncStreamIter(uint64_t streamId); | ||
| 49 | -bool NextStreamSyncIdx(uint64_t streamId, uint64_t &syncIdx); | ||
| 50 | - | ||
| 51 | -int InsertOpDetail(OpDetailTab &rec); | ||
| 52 | -int InsertOpMem(OpMemInfoTab &rec); | ||
| 53 | -int InsertOpDetailAndMem(OpDetailTab &detail, OpMemInfoTab &mem); | ||
| 54 | -int InsertCcuChannel(CcuChannelTab &rec); | ||
| 55 | -int InsertJettyMap(JettyMapTab &rec); | ||
| 56 | -int InsertOpTask(OpTaskTab &rec, bool isDevice = false); | ||
| 57 | -int InsertSyncRecord(SyncRecordTab &rec); | ||
| 58 | -int InsertCcuInstrRes(CcuInstrResTab &rec); | ||
| 59 | -int InsertCcuInstr(CcuInstrTab &rec); | ||
| 60 | -int InsertHalfRTT(HalfRTTTab &rec); | ||
| 61 | - | ||
| 62 | -int UpdateAndInsertByCcuId(uint64_t &ccuId, uint32_t deviceId, uint32_t dieId, | ||
| 63 | - uint32_t startId, uint32_t instrCount, | ||
| 64 | - uint32_t instrOffset, uint32_t instrInfoSize, | ||
| 65 | - const void *instrInfo, | ||
| 66 | - std::vector<uint8_t> *mergedInstrSpace = nullptr, | ||
| 67 | - uint32_t *totalInstrCount = nullptr); | ||
| 68 | -int UpdateSyncRecordStatus(std::vector<SyncRecordTab> &syncRecord); | ||
| 69 | -int UpdateOpMemCclBuffer(uint64_t cclAddr, uint64_t cclSize); | ||
| 70 | -int UpdateOpExpansionMode(uint8_t mode); | ||
| 71 | -int UpdateOpDetailMainStream(uint32_t opDetailId, uint64_t streamId); | ||
| 72 | - | ||
| 73 | -int QueryLatestOpExpansionMode(); | ||
| 74 | -int QueryCcuChannelAll(std::vector<CcuChannelTab> &out); | ||
| 75 | -int QueryJettyMapAll(std::vector<JettyMapTab> &out); | ||
| 76 | -int QuerySyncRecordAll(std::vector<SyncRecordTab> &out); | ||
| 77 | -int QueryCcuInstrResAll(std::vector<CcuInstrResTab> &out); | ||
| 78 | -int QueryCcuResourceMetaCount(uint32_t &instrLoadCnt, uint32_t &channelCnt); | ||
| 79 | -int QueryOpDetailIdentity(uint32_t opDetailId, uint64_t &commId, | ||
| 80 | - uint32_t &rankId, uint32_t &deviceId); | ||
| 81 | -int QueryOpDetailById(uint32_t opDetailId, OpDetailTab &out); | ||
| 82 | -int QueryLatestOpDetailByDeviceId(uint32_t deviceId, OpDetailTab &out); | ||
| 83 | -int QueryCurrentOpMemInfo(uint64_t commId, uint32_t deviceId, | ||
| 84 | - OpMemInfoTab &out); | ||
| 85 | -int QueryOpMemInfoByOpDetailId(uint32_t opDetailId, OpMemInfoTab &out); | ||
| 86 | -int QuerySyncRecordByStatus(uint8_t status, std::vector<SyncRecordTab> &out); | ||
| 87 | -int QueryOpExecutionIndexEntries(std::vector<OpExecutionIndexEntry> &out); | ||
| 88 | -int QueryCompositeOpDetailBySyncIter( | ||
| 89 | - uint32_t syncIter, | ||
| 90 | - std::map<uint32_t, std::vector<CompositeOpDetail>> &detail); | ||
| 91 | -int QueryHalfRTTAll(std::vector<HalfRTTTab> &out); | ||
| 92 | -int QueryOpTaskTabNames(std::vector<std::string> &names); | ||
| 93 | -int QueryCompositeOpDetailByOpIter(const std::string &commName, | ||
| 94 | - uint64_t commHash, uint32_t opIter, | ||
| 95 | - std::vector<CompositeOpDetail> &details); | ||
| 96 | -int QueryAllOpTasks(std::vector<OpTaskTab> &tasks, bool filterDone = false); | ||
| 97 | -int QueryOpTasksByStreamId(uint64_t streamId, std::vector<OpTaskTab> &tasks); | ||
| 98 | -int FinishOpTask(const OpTaskTab &task); | ||
| 99 | -int QueryHalfRTTAll(std::vector<HalfRTTTab> &out); | ||
| 100 | -} // namespace sim | ||
| 101 | - | ||
| 102 | -#endif | ||
| @@ -1,49 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under | ||
| 4 | - * the terms and conditions of CANN Open Software License Agreement Version 2.0 | ||
| 5 | - * (the "License"). Please refer to the License for details. You may not use | ||
| 6 | - * this file except in compliance with the License. THIS SOFTWARE IS PROVIDED ON | ||
| 7 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS | ||
| 9 | - * FOR A PARTICULAR PURPOSE. See LICENSE in the root of the software repository | ||
| 10 | - * for the full text of the License. | ||
| 11 | - */ | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 15 | - * for the full text of the License. | ||
| 16 | - */ | ||
| 17 | - | ||
| 18 | -#ifndef SIM_RUNNER_DB_H | ||
| 19 | -#define SIM_RUNNER_DB_H | ||
| 20 | - | ||
| 21 | -#include <functional> | ||
| 22 | -#include <optional> | ||
| 23 | -#include <vector> | ||
| 24 | - | ||
| 25 | -#include "sim_models.h" | ||
| 26 | -#include "sim_runner_impl.inl" | ||
| 27 | -namespace RunnerDB { | ||
| 28 | -template <typename T> uint64_t Add(T &rec); | ||
| 29 | - | ||
| 30 | -template <typename T> std::vector<uint64_t> AddBatch(std::vector<T> &recs); | ||
| 31 | - | ||
| 32 | -template <typename T> std::optional<T> GetById(uint64_t id); | ||
| 33 | - | ||
| 34 | -template <typename T> | ||
| 35 | -std::vector<T> GetByPred(std::function<bool(const T &)> pred); | ||
| 36 | - | ||
| 37 | -template <typename T> | ||
| 38 | -std::pair<T, bool> GetOneByPred(std::function<bool(const T &)> pred); | ||
| 39 | - | ||
| 40 | -template <typename T> | ||
| 41 | -bool Update(uint64_t id, std::function<void(T &)> updater); | ||
| 42 | - | ||
| 43 | -template <typename T> bool Delete(uint64_t id); | ||
| 44 | - | ||
| 45 | -template <typename T> bool DeleteAll(); | ||
| 46 | - | ||
| 47 | -std::vector<std::string> GetAllTableName(); | ||
| 48 | -} // namespace RunnerDB | ||
| 49 | -#endif | ||
| @@ -1,44 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under | ||
| 4 | - * the terms and conditions of CANN Open Software License Agreement Version 2.0 | ||
| 5 | - * (the "License"). Please refer to the License for details. You may not use | ||
| 6 | - * this file except in compliance with the License. THIS SOFTWARE IS PROVIDED ON | ||
| 7 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS | ||
| 9 | - * FOR A PARTICULAR PURPOSE. See LICENSE in the root of the software repository | ||
| 10 | - * for the full text of the License. | ||
| 11 | - */ | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 15 | - * for the full text of the License. | ||
| 16 | - */ | ||
| 17 | - | ||
| 18 | -#ifndef _SIM_RUNNER_OPS_H_ | ||
| 19 | -#define _SIM_RUNNER_OPS_H_ | ||
| 20 | - | ||
| 21 | -#include <thread> | ||
| 22 | - | ||
| 23 | -#include "db_sim_runner_db.h" | ||
| 24 | -#include "sim_models.h" | ||
| 25 | - | ||
| 26 | -namespace sim { | ||
| 27 | -bool GetCurrRunnerTls(uint64_t serverKey, Runner &runner); | ||
| 28 | -bool SetCurrCtxTls(uint64_t ctx); | ||
| 29 | -uint64_t GetCurrDeviceId(); | ||
| 30 | -uint64_t GetCurrDeviceKey(); | ||
| 31 | -uint64_t GetDeviceIdByCtxId(uint64_t ctxId); | ||
| 32 | - | ||
| 33 | -void SetLastStreamIdTls(uint64_t streamId); | ||
| 34 | -void SetLastTaskIdTls(uint64_t taskId); | ||
| 35 | - | ||
| 36 | -uint64_t GetLastStreamIdTls(); | ||
| 37 | -uint64_t GetLastTaskIdTls(); | ||
| 38 | - | ||
| 39 | -void SetTsDevice(int tsId); | ||
| 40 | -uint32_t GetRankSize(); | ||
| 41 | -uint32_t GetHostSize(); | ||
| 42 | -uint64_t GetServerKeyById(uint32_t superPodIdx, uint32_t serverIdx); | ||
| 43 | -} // namespace sim | ||
| 44 | -#endif | ||
| @@ -1,368 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under | ||
| 4 | - * the terms and conditions of CANN Open Software License Agreement Version 2.0 | ||
| 5 | - * (the "License"). Please refer to the License for details. You may not use | ||
| 6 | - * this file except in compliance with the License. THIS SOFTWARE IS PROVIDED ON | ||
| 7 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS | ||
| 9 | - * FOR A PARTICULAR PURPOSE. See LICENSE in the root of the software repository | ||
| 10 | - * for the full text of the License. | ||
| 11 | - */ | ||
| 12 | - | ||
| 13 | -/** | ||
| 14 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 15 | - * for the full text of the License. | ||
| 16 | - */ | ||
| 17 | - | ||
| 18 | -#ifndef SIM_SQLITE_DB_H | ||
| 19 | -#define SIM_SQLITE_DB_H | ||
| 20 | - | ||
| 21 | -#include <functional> | ||
| 22 | -#include <memory> | ||
| 23 | -#include <mutex> | ||
| 24 | -#include <optional> | ||
| 25 | -#include <stdexcept> | ||
| 26 | -#include <string> | ||
| 27 | -#include <tuple> | ||
| 28 | -#include <type_traits> | ||
| 29 | -#include <typeindex> | ||
| 30 | -#include <unordered_map> | ||
| 31 | -#include <vector> | ||
| 32 | - | ||
| 33 | -#include "sim_models.h" | ||
| 34 | -#include "sim_sqlite_table.h" | ||
| 35 | - | ||
| 36 | -// Forward declaration to allow friend access | ||
| 37 | -struct SimRunnerSqliteDB; | ||
| 38 | - | ||
| 39 | -template <typename T> | ||
| 40 | -using TableKeyType = typename sim::SqliteTable<T>::KeyType; | ||
| 41 | -template <typename T> | ||
| 42 | -using TableValue = typename sim::SqliteTable<T>::ValueType; | ||
| 43 | - | ||
| 44 | -struct SimRunnerSqliteDB { | ||
| 45 | - private: | ||
| 46 | - sim::SqliteDatabase m_db; | ||
| 47 | - | ||
| 48 | - sim::SqliteTable<sim::Server> m_serverTbl; | ||
| 49 | - sim::SqliteTable<sim::Host> m_hostTbl; | ||
| 50 | - sim::SqliteTable<sim::Runner> m_runnerTbl; | ||
| 51 | - sim::SqliteTable<sim::Communicator> m_communicatorTbl; | ||
| 52 | - sim::SqliteTable<sim::CommunicatorDestroySync> m_communicatorDestroySyncTbl; | ||
| 53 | - sim::SqliteTable<sim::Device> m_deviceTbl; | ||
| 54 | - sim::SqliteTable<sim::DeviceStatus> m_deviceStatusTbl; | ||
| 55 | - sim::SqliteTable<sim::Context> m_contextTbl; | ||
| 56 | - sim::SqliteTable<sim::Stream> m_streamTbl; | ||
| 57 | - sim::SqliteTable<sim::Notify> m_notifyTbl; | ||
| 58 | - sim::SqliteTable<sim::Event> m_eventTbl; | ||
| 59 | - sim::SqliteTable<sim::VirtualMemBlock> m_virMemTbl; | ||
| 60 | - sim::SqliteTable<sim::PhyMemBlock> m_phyMemTbl; | ||
| 61 | - sim::SqliteTable<sim::IpcMemRecord> m_ipcMemRecordTbl; | ||
| 62 | - sim::SqliteTable<sim::IpcMemWhiteList> m_ipcMemWhiteListTbl; | ||
| 63 | - sim::SqliteTable<sim::FdMemRecord> m_fdMemRecordTbl; | ||
| 64 | - sim::SqliteTable<sim::FdMemWhiteList> m_fdMemWhiteListTbl; | ||
| 65 | - sim::SqliteTable<sim::Task> m_taskTbl; | ||
| 66 | - sim::SqliteTable<sim::EventSyncTask> m_eventSyncTaskTbl; | ||
| 67 | - sim::SqliteTable<sim::Port> m_portTbl; | ||
| 68 | - sim::SqliteTable<sim::Ccu> m_ccuTbl; | ||
| 69 | - sim::SqliteTable<sim::DeviceConnection> m_deviceConnTbl; | ||
| 70 | - sim::SqliteTable<sim::EndPointPair> m_endPointPairTbl; | ||
| 71 | - sim::SqliteTable<sim::EndPointPortMapping> m_endPointPortMappingTbl; | ||
| 72 | - sim::SqliteTable<sim::Link> m_linkTbl; | ||
| 73 | - sim::SqliteTable<sim::EndPoint> m_endPointTbl; | ||
| 74 | - sim::SqliteTable<sim::CcuChannel> m_ccuChannelTbl; | ||
| 75 | - sim::SqliteTable<sim::TaskSchedulerDevice> m_taskSchedulerDeviceTbl; | ||
| 76 | - sim::SqliteTable<sim::ComputeDie> m_computeDieTbl; | ||
| 77 | - sim::SqliteTable<sim::RaSocket> m_raSocketTbl; | ||
| 78 | - sim::SqliteTable<sim::RaSocketPair> m_raSocketPairTbl; | ||
| 79 | - sim::SqliteTable<sim::RaDevice> m_raDeviceTbl; | ||
| 80 | - sim::SqliteTable<sim::RaQP> m_raQPTbl; | ||
| 81 | - sim::SqliteTable<sim::RaCQ> m_raCQTbl; | ||
| 82 | - sim::SqliteTable<sim::RaCQE> m_raCQETbl; | ||
| 83 | - sim::SqliteTable<sim::RaMR> m_raMRTbl; | ||
| 84 | - sim::SqliteTable<sim::MemoryLayout> m_memoryLayoutTbl; | ||
| 85 | - sim::SqliteTable<sim::SimModelData> m_simModelDataTbl; | ||
| 86 | - sim::SqliteTable<sim::IpcNotify> m_ipcNotifyTbl; | ||
| 87 | - sim::SqliteTable<sim::IpcNotifyVistorList> m_ipcNotifyVistorListTbl; | ||
| 88 | - sim::SqliteTable<sim::NotifyRecordTask> m_notifyRecordTaskTbl; | ||
| 89 | - sim::SqliteTable<sim::NotifyWaitTask> m_notifyWaitTaskTbl; | ||
| 90 | - sim::SqliteTable<sim::RaContext> m_raContextTbl; | ||
| 91 | - sim::SqliteTable<sim::RaChan> m_raChanTbl; | ||
| 92 | - sim::SqliteTable<sim::RaTokenId> m_raTokenIdTbl; | ||
| 93 | - sim::SqliteTable<sim::RaTp> m_raTpTbl; | ||
| 94 | - sim::SqliteTable<sim::RaRmem> m_raRmemTbl; | ||
| 95 | - sim::SqliteTable<sim::RaLmem> m_raLmemTbl; | ||
| 96 | - sim::SqliteTable<sim::RaJetty> m_raJettyTbl; | ||
| 97 | - sim::SqliteTable<sim::RaJfc> m_raJfcTbl; | ||
| 98 | - sim::SqliteTable<sim::RaCr> m_raCrTbl; | ||
| 99 | - sim::SqliteTable<sim::RaTlv> m_raTlvTbl; | ||
| 100 | - sim::SqliteTable<sim::RunModeConfig> m_runModeConfigTbl; | ||
| 101 | - sim::SqliteTable<sim::HcclBuffer> m_hcclBufferTbl; | ||
| 102 | - sim::SqliteTable<sim::HcclThread> m_hcclThreadTbl; | ||
| 103 | - sim::SqliteTable<sim::HcclChannel> m_hcclChannelTbl; | ||
| 104 | - sim::SqliteTable<sim::HcommEndpoint> m_hcommEndpointTbl; | ||
| 105 | - sim::SqliteTable<sim::HcommMemReg> m_hcommMemRegTbl; | ||
| 106 | - sim::SqliteTable<sim::HcclEngineCtx> m_hcclEngineCtxTbl; | ||
| 107 | - sim::SqliteTable<sim::HcclMem> m_hcclMemTbl; | ||
| 108 | - sim::SqliteTable<sim::TopoMetaConfig> m_topoMetaConfigTbl; | ||
| 109 | - sim::SqliteTable<sim::Plugin> m_pluginTbl; | ||
| 110 | - sim::SqliteTable<sim::DpuPendingNotify> m_dpuPendingNotifyTbl; | ||
| 111 | - sim::SqliteTable<sim::DpuDeviceInfo> m_dpuDeviceInfoTbl; | ||
| 112 | - sim::SqliteTable<sim::CcuSyncResTab> m_ccuSyncResTbl; | ||
| 113 | - | ||
| 114 | - std::mutex m_lazyMutex; | ||
| 115 | - std::unordered_map<std::type_index, sim::TableBase *> m_tableMap; | ||
| 116 | - std::vector<std::string> m_tableNames; | ||
| 117 | - std::vector<std::unique_ptr<sim::TableBase>> m_lazyTables; | ||
| 118 | - | ||
| 119 | - template <typename T> | ||
| 120 | - void RegisterTable(sim::SqliteTable<T> &table, const std::string &name) { | ||
| 121 | - m_tableMap[std::type_index(typeid(T))] = &table; | ||
| 122 | - m_tableNames.push_back(name); | ||
| 123 | - } | ||
| 124 | - | ||
| 125 | - public: | ||
| 126 | - SimRunnerSqliteDB() | ||
| 127 | - : m_serverTbl(m_db.GetDb(), "Server"), m_hostTbl(m_db.GetDb(), "Host"), | ||
| 128 | - m_runnerTbl(m_db.GetDb(), "Runner"), | ||
| 129 | - m_communicatorTbl(m_db.GetDb(), "Communicator"), | ||
| 130 | - m_communicatorDestroySyncTbl(m_db.GetDb(), "CommunicatorDestroySync"), | ||
| 131 | - m_deviceTbl(m_db.GetDb(), "Device"), | ||
| 132 | - m_deviceStatusTbl(m_db.GetDb(), "DeviceStatus"), | ||
| 133 | - m_contextTbl(m_db.GetDb(), "Context"), | ||
| 134 | - m_streamTbl(m_db.GetDb(), "Stream"), | ||
| 135 | - m_notifyTbl(m_db.GetDb(), "Notify"), | ||
| 136 | - m_eventTbl(m_db.GetDb(), "Event"), | ||
| 137 | - m_virMemTbl(m_db.GetDb(), "VirMem"), | ||
| 138 | - m_phyMemTbl(m_db.GetDb(), "PhMem"), | ||
| 139 | - m_ipcMemRecordTbl(m_db.GetDb(), "IpcMemRecord"), | ||
| 140 | - m_ipcMemWhiteListTbl(m_db.GetDb(), "IpMemWhiteList"), | ||
| 141 | - m_fdMemRecordTbl(m_db.GetDb(), "FdMemRecord"), | ||
| 142 | - m_fdMemWhiteListTbl(m_db.GetDb(), "FdMemWhiteList"), | ||
| 143 | - m_taskTbl(m_db.GetDb(), "Task"), | ||
| 144 | - m_eventSyncTaskTbl(m_db.GetDb(), "EventSyncTask"), | ||
| 145 | - m_portTbl(m_db.GetDb(), "Port"), m_ccuTbl(m_db.GetDb(), "Ccu"), | ||
| 146 | - m_deviceConnTbl(m_db.GetDb(), "DeviceConnection"), | ||
| 147 | - m_endPointTbl(m_db.GetDb(), "EndPoint"), | ||
| 148 | - m_endPointPairTbl(m_db.GetDb(), "EndPointPair"), | ||
| 149 | - m_endPointPortMappingTbl(m_db.GetDb(), "EndPointPortMapping"), | ||
| 150 | - m_linkTbl(m_db.GetDb(), "Link"), | ||
| 151 | - m_ccuChannelTbl(m_db.GetDb(), "CcuChannel"), | ||
| 152 | - m_taskSchedulerDeviceTbl(m_db.GetDb(), "TaskSchedulerDevice"), | ||
| 153 | - m_computeDieTbl(m_db.GetDb(), "ComputeDie"), | ||
| 154 | - m_raSocketTbl(m_db.GetDb(), "RaSocket"), | ||
| 155 | - m_raSocketPairTbl(m_db.GetDb(), "RaSocketPair"), | ||
| 156 | - m_raDeviceTbl(m_db.GetDb(), "RaDevice"), | ||
| 157 | - m_raQPTbl(m_db.GetDb(), "RaQP"), m_raCQTbl(m_db.GetDb(), "RaCQ"), | ||
| 158 | - m_raCQETbl(m_db.GetDb(), "RaCQE"), m_raMRTbl(m_db.GetDb(), "RaMR"), | ||
| 159 | - m_memoryLayoutTbl(m_db.GetDb(), "MemoryLayout"), | ||
| 160 | - m_simModelDataTbl(m_db.GetDb(), "SimModelData"), | ||
| 161 | - m_ipcNotifyTbl(m_db.GetDb(), "IpcNotify"), | ||
| 162 | - m_ipcNotifyVistorListTbl(m_db.GetDb(), "IpcNotifyVistorList"), | ||
| 163 | - m_notifyRecordTaskTbl(m_db.GetDb(), "NotifyRecordTask"), | ||
| 164 | - m_notifyWaitTaskTbl(m_db.GetDb(), "NotifyWaitTask"), | ||
| 165 | - m_raContextTbl(m_db.GetDb(), "RaContext"), | ||
| 166 | - m_raChanTbl(m_db.GetDb(), "RaChan"), | ||
| 167 | - m_raTokenIdTbl(m_db.GetDb(), "RaTokenId"), | ||
| 168 | - m_raTpTbl(m_db.GetDb(), "RaTp"), m_raRmemTbl(m_db.GetDb(), "RaRmem"), | ||
| 169 | - m_raLmemTbl(m_db.GetDb(), "RaLmem"), | ||
| 170 | - m_raJettyTbl(m_db.GetDb(), "RaJetty"), | ||
| 171 | - m_raJfcTbl(m_db.GetDb(), "RaJfc"), m_raCrTbl(m_db.GetDb(), "RaCr"), | ||
| 172 | - m_raTlvTbl(m_db.GetDb(), "RaTlv"), | ||
| 173 | - m_runModeConfigTbl(m_db.GetDb(), "RunModeConfig"), | ||
| 174 | - m_hcclBufferTbl(m_db.GetDb(), "HcclBuffer"), | ||
| 175 | - m_hcclThreadTbl(m_db.GetDb(), "HcclThread"), | ||
| 176 | - m_hcclChannelTbl(m_db.GetDb(), "HcclChannel"), | ||
| 177 | - m_hcommEndpointTbl(m_db.GetDb(), "HcommEndpoint"), | ||
| 178 | - m_hcommMemRegTbl(m_db.GetDb(), "HcommMemReg"), | ||
| 179 | - m_hcclEngineCtxTbl(m_db.GetDb(), "HcclEngineCtx"), | ||
| 180 | - m_hcclMemTbl(m_db.GetDb(), "HcclMem"), | ||
| 181 | - m_topoMetaConfigTbl(m_db.GetDb(), "TopoMetaConfig"), | ||
| 182 | - m_pluginTbl(m_db.GetDb(), "Plugin"), | ||
| 183 | - m_dpuPendingNotifyTbl(m_db.GetDb(), "DpuPendingNotify"), | ||
| 184 | - m_dpuDeviceInfoTbl(m_db.GetDb(), "DpuDeviceInfo"), | ||
| 185 | - m_ccuSyncResTbl(m_db.GetDb(), "CcuSyncRes") { | ||
| 186 | - RegisterTable(m_serverTbl, "Server"); | ||
| 187 | - RegisterTable(m_hostTbl, "Host"); | ||
| 188 | - RegisterTable(m_runnerTbl, "Runner"); | ||
| 189 | - RegisterTable(m_communicatorTbl, "Communicator"); | ||
| 190 | - RegisterTable(m_communicatorDestroySyncTbl, "CommunicatorDestroySync"); | ||
| 191 | - RegisterTable(m_deviceTbl, "Device"); | ||
| 192 | - RegisterTable(m_deviceStatusTbl, "DeviceStatus"); | ||
| 193 | - RegisterTable(m_contextTbl, "Context"); | ||
| 194 | - RegisterTable(m_streamTbl, "Stream"); | ||
| 195 | - RegisterTable(m_notifyTbl, "Notify"); | ||
| 196 | - RegisterTable(m_eventTbl, "Event"); | ||
| 197 | - RegisterTable(m_virMemTbl, "VirMem"); | ||
| 198 | - RegisterTable(m_phyMemTbl, "PhMem"); | ||
| 199 | - RegisterTable(m_ipcMemRecordTbl, "IpcMemRecord"); | ||
| 200 | - RegisterTable(m_ipcMemWhiteListTbl, "IpMemWhiteList"); | ||
| 201 | - RegisterTable(m_fdMemRecordTbl, "FdMemRecord"); | ||
| 202 | - RegisterTable(m_fdMemWhiteListTbl, "FdMemWhiteList"); | ||
| 203 | - RegisterTable(m_taskTbl, "Task"); | ||
| 204 | - RegisterTable(m_eventSyncTaskTbl, "EventSyncTask"); | ||
| 205 | - RegisterTable(m_portTbl, "Port"); | ||
| 206 | - RegisterTable(m_ccuTbl, "Ccu"); | ||
| 207 | - RegisterTable(m_deviceConnTbl, "DeviceConnection"); | ||
| 208 | - RegisterTable(m_endPointPairTbl, "EndPointPair"); | ||
| 209 | - RegisterTable(m_endPointPortMappingTbl, "EndPointPortMapping"); | ||
| 210 | - RegisterTable(m_linkTbl, "Link"); | ||
| 211 | - RegisterTable(m_endPointTbl, "EndPoint"); | ||
| 212 | - RegisterTable(m_ccuChannelTbl, "CcuChannel"); | ||
| 213 | - RegisterTable(m_taskSchedulerDeviceTbl, "TaskSchedulerDevice"); | ||
| 214 | - RegisterTable(m_computeDieTbl, "ComputeDie"); | ||
| 215 | - RegisterTable(m_raSocketTbl, "RaSocket"); | ||
| 216 | - RegisterTable(m_raSocketPairTbl, "RaSocketPair"); | ||
| 217 | - RegisterTable(m_raDeviceTbl, "RaDevice"); | ||
| 218 | - RegisterTable(m_raQPTbl, "RaQP"); | ||
| 219 | - RegisterTable(m_raCQTbl, "RaCQ"); | ||
| 220 | - RegisterTable(m_raCQETbl, "RaCQE"); | ||
| 221 | - RegisterTable(m_raMRTbl, "RaMR"); | ||
| 222 | - RegisterTable(m_memoryLayoutTbl, "MemoryLayout"); | ||
| 223 | - RegisterTable(m_simModelDataTbl, "SimModelData"); | ||
| 224 | - RegisterTable(m_ipcNotifyTbl, "IpcNotify"); | ||
| 225 | - RegisterTable(m_ipcNotifyVistorListTbl, "IpcNotifyVistorList"); | ||
| 226 | - RegisterTable(m_notifyRecordTaskTbl, "NotifyRecordTask"); | ||
| 227 | - RegisterTable(m_notifyWaitTaskTbl, "NotifyWaitTask"); | ||
| 228 | - RegisterTable(m_raContextTbl, "RaContext"); | ||
| 229 | - RegisterTable(m_raChanTbl, "RaChan"); | ||
| 230 | - RegisterTable(m_raTokenIdTbl, "RaTokenId"); | ||
| 231 | - RegisterTable(m_raTpTbl, "RaTp"); | ||
| 232 | - RegisterTable(m_raRmemTbl, "RaRmem"); | ||
| 233 | - RegisterTable(m_raLmemTbl, "RaLmem"); | ||
| 234 | - RegisterTable(m_raJettyTbl, "RaJetty"); | ||
| 235 | - RegisterTable(m_raJfcTbl, "RaJfc"); | ||
| 236 | - RegisterTable(m_raCrTbl, "RaCr"); | ||
| 237 | - RegisterTable(m_raTlvTbl, "RaTlv"); | ||
| 238 | - RegisterTable(m_runModeConfigTbl, "RunModeConfig"); | ||
| 239 | - RegisterTable(m_hcclBufferTbl, "HcclBuffer"); | ||
| 240 | - RegisterTable(m_hcclThreadTbl, "HcclThread"); | ||
| 241 | - RegisterTable(m_hcclChannelTbl, "HcclChannel"); | ||
| 242 | - RegisterTable(m_hcommEndpointTbl, "HcommEndpoint"); | ||
| 243 | - RegisterTable(m_hcommMemRegTbl, "HcommMemReg"); | ||
| 244 | - RegisterTable(m_hcclEngineCtxTbl, "HcclEngineCtx"); | ||
| 245 | - RegisterTable(m_hcclMemTbl, "HcclMem"); | ||
| 246 | - RegisterTable(m_topoMetaConfigTbl, "TopoMetaConfig"); | ||
| 247 | - RegisterTable(m_pluginTbl, "Plugin"); | ||
| 248 | - RegisterTable(m_dpuPendingNotifyTbl, "DpuPendingNotify"); | ||
| 249 | - RegisterTable(m_dpuDeviceInfoTbl, "DpuDeviceInfo"); | ||
| 250 | - RegisterTable(m_ccuSyncResTbl, "CcuSyncRes"); | ||
| 251 | - } | ||
| 252 | - | ||
| 253 | - SimRunnerSqliteDB(const SimRunnerSqliteDB &) = delete; | ||
| 254 | - SimRunnerSqliteDB &operator=(const SimRunnerSqliteDB &) = delete; | ||
| 255 | - SimRunnerSqliteDB(SimRunnerSqliteDB &&) = delete; | ||
| 256 | - SimRunnerSqliteDB &operator=(SimRunnerSqliteDB &&) = delete; | ||
| 257 | - | ||
| 258 | - static SimRunnerSqliteDB &Instance() { | ||
| 259 | - static std::mutex s_mtx; | ||
| 260 | - static SimRunnerSqliteDB *s_instance = nullptr; | ||
| 261 | - | ||
| 262 | - std::lock_guard<std::mutex> lock(s_mtx); | ||
| 263 | - if (s_instance == nullptr) { | ||
| 264 | - s_instance = new SimRunnerSqliteDB(); | ||
| 265 | - } | ||
| 266 | - return *s_instance; | ||
| 267 | - } | ||
| 268 | - | ||
| 269 | - template <typename T> sim::SqliteTable<T> &GetTable() { | ||
| 270 | - std::lock_guard<std::mutex> lock(m_lazyMutex); | ||
| 271 | - auto it = m_tableMap.find(std::type_index(typeid(T))); | ||
| 272 | - if (it != m_tableMap.end()) { | ||
| 273 | - return *static_cast<sim::SqliteTable<T> *>(it->second); | ||
| 274 | - } | ||
| 275 | - std::string name = std::string("Unregistered_") + typeid(T).name(); | ||
| 276 | - HCCL_VM_WARN("[SimRunnerSqliteDB::GetTable] Lazily registering " | ||
| 277 | - "unregistered type: {}", | ||
| 278 | - name.c_str()); | ||
| 279 | - auto table = std::make_unique<sim::SqliteTable<T>>(m_db.GetDb(), name); | ||
| 280 | - auto *rawPtr = table.get(); | ||
| 281 | - m_lazyTables.push_back(std::move(table)); | ||
| 282 | - m_tableMap[std::type_index(typeid(T))] = rawPtr; | ||
| 283 | - m_tableNames.push_back(name); | ||
| 284 | - return *rawPtr; | ||
| 285 | - } | ||
| 286 | - | ||
| 287 | - template <typename T> std::optional<T> Find(TableKeyType<T> id) { | ||
| 288 | - return GetTable<T>().Find(id); | ||
| 289 | - } | ||
| 290 | - | ||
| 291 | - template <typename T> | ||
| 292 | - std::pair<TableValue<T>, bool> Query(std::function<bool(const T &)> pred) { | ||
| 293 | - return GetTable<T>().Query(pred); | ||
| 294 | - } | ||
| 295 | - | ||
| 296 | - template <typename T> | ||
| 297 | - std::vector<TableValue<T>> QueryList(std::function<bool(const T &)> pred) { | ||
| 298 | - return GetTable<T>().QueryList(pred); | ||
| 299 | - } | ||
| 300 | - | ||
| 301 | - template <typename T> TableKeyType<T> Add(T rec) { | ||
| 302 | - return GetTable<T>().Add(rec); | ||
| 303 | - } | ||
| 304 | - | ||
| 305 | - template <typename T> | ||
| 306 | - std::vector<TableKeyType<T>> AddBatch(std::vector<T> &recs) { | ||
| 307 | - return GetTable<T>().AddBatch(recs); | ||
| 308 | - } | ||
| 309 | - | ||
| 310 | - template <typename T> | ||
| 311 | - bool Update(TableKeyType<T> id, std::function<void(T &)> updater) { | ||
| 312 | - return GetTable<T>().Update(id, updater); | ||
| 313 | - } | ||
| 314 | - | ||
| 315 | - template <typename T> bool Delete(TableKeyType<T> id) { | ||
| 316 | - return GetTable<T>().Delete(id); | ||
| 317 | - } | ||
| 318 | - | ||
| 319 | - template <typename T> bool DeleteAll() { return GetTable<T>().DeleteAll(); } | ||
| 320 | - | ||
| 321 | - std::vector<std::string> GetAllTableName() const { return m_tableNames; } | ||
| 322 | - | ||
| 323 | - // 获取底层数据库连接对象(供批量写事务SqliteWriteTransaction使用) | ||
| 324 | - sim::SqliteDatabase &GetDatabase() { return m_db; } | ||
| 325 | - | ||
| 326 | - void ClearAll() { m_db.ClearAllTables(); } | ||
| 327 | -}; | ||
| 328 | - | ||
| 329 | -namespace sim { | ||
| 330 | -// RAII批量写事务守卫: 构造时在RunnerDB所在SQLite连接上开启事务, 作用域内的 | ||
| 331 | -// RunnerDB::Add/Update并入该事务统一提交, 消除逐条独立事务的提交开销; | ||
| 332 | -// 显式调用Commit()提交; 未提交即离开作用域(异常/提前返回)时自动回滚。 | ||
| 333 | -// 注意: 事务期间应保证无其他线程并发写库。 | ||
| 334 | -class SqliteWriteTransaction { | ||
| 335 | - public: | ||
| 336 | - SqliteWriteTransaction() | ||
| 337 | - : db_(SimRunnerSqliteDB::Instance().GetDatabase()), began_(false), | ||
| 338 | - committed_(false) { | ||
| 339 | - began_ = db_.BeginTransaction(); | ||
| 340 | - } | ||
| 341 | - | ||
| 342 | - ~SqliteWriteTransaction() { | ||
| 343 | - if (began_ && !committed_) { | ||
| 344 | - db_.RollbackTransaction(); | ||
| 345 | - } | ||
| 346 | - } | ||
| 347 | - | ||
| 348 | - SqliteWriteTransaction(const SqliteWriteTransaction &) = delete; | ||
| 349 | - SqliteWriteTransaction &operator=(const SqliteWriteTransaction &) = delete; | ||
| 350 | - SqliteWriteTransaction(SqliteWriteTransaction &&) = delete; | ||
| 351 | - SqliteWriteTransaction &operator=(SqliteWriteTransaction &&) = delete; | ||
| 352 | - | ||
| 353 | - bool Commit() { | ||
| 354 | - if (!began_ || committed_) { | ||
| 355 | - return began_ && committed_; | ||
| 356 | - } | ||
| 357 | - committed_ = db_.CommitTransaction(); | ||
| 358 | - return committed_; | ||
| 359 | - } | ||
| 360 | - | ||
| 361 | - private: | ||
| 362 | - SqliteDatabase &db_; | ||
| 363 | - bool began_; | ||
| 364 | - bool committed_; | ||
| 365 | -}; | ||
| 366 | -} // namespace sim | ||
| 367 | - | ||
| 368 | -#endif | ||
| @@ -1,58 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2026 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under | ||
| 4 | - * the terms and conditions of CANN Open Software License Agreement Version 2.0 | ||
| 5 | - * (the "License"). Please refer to the License for details. You may not use | ||
| 6 | - * this file except in compliance with the License. THIS SOFTWARE IS PROVIDED ON | ||
| 7 | - * AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 8 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS | ||
| 9 | - * FOR A PARTICULAR PURPOSE. See LICENSE in the root of the software repository | ||
| 10 | - * for the full text of the License. | ||
| 11 | - */ | ||
| 12 | - | ||
| 13 | -#ifndef SIM_RUNNER_IMPL_INL | ||
| 14 | -#define SIM_RUNNER_IMPL_INL | ||
| 15 | - | ||
| 16 | -#include "db_sim_runner_db.h" | ||
| 17 | -#include "db_sim_sqlite_db.h" | ||
| 18 | -#include <optional> | ||
| 19 | - | ||
| 20 | -namespace RunnerDB { | ||
| 21 | - | ||
| 22 | -template <typename T> uint64_t Add(T &rec) { | ||
| 23 | - return SimRunnerSqliteDB::Instance().Add<T>(rec); | ||
| 24 | -} | ||
| 25 | - | ||
| 26 | -template <typename T> std::vector<uint64_t> AddBatch(std::vector<T> &recs) { | ||
| 27 | - return SimRunnerSqliteDB::Instance().AddBatch<T>(recs); | ||
| 28 | -} | ||
| 29 | - | ||
| 30 | -template <typename T> std::optional<T> GetById(uint64_t id) { | ||
| 31 | - return SimRunnerSqliteDB::Instance().Find<T>(id); | ||
| 32 | -} | ||
| 33 | - | ||
| 34 | -template <typename T> | ||
| 35 | -std::vector<T> GetByPred(std::function<bool(const T &)> pred) { | ||
| 36 | - return SimRunnerSqliteDB::Instance().QueryList<T>(pred); | ||
| 37 | -} | ||
| 38 | - | ||
| 39 | -template <typename T> | ||
| 40 | -std::pair<T, bool> GetOneByPred(std::function<bool(const T &)> pred) { | ||
| 41 | - return SimRunnerSqliteDB::Instance().Query<T>(pred); | ||
| 42 | -} | ||
| 43 | - | ||
| 44 | -template <typename T> | ||
| 45 | -bool Update(uint64_t id, std::function<void(T &)> updater) { | ||
| 46 | - return SimRunnerSqliteDB::Instance().Update<T>(id, updater); | ||
| 47 | -} | ||
| 48 | - | ||
| 49 | -template <typename T> bool Delete(uint64_t id) { | ||
| 50 | - return SimRunnerSqliteDB::Instance().Delete<T>(id); | ||
| 51 | -} | ||
| 52 | - | ||
| 53 | -template <typename T> bool DeleteAll() { | ||
| 54 | - return SimRunnerSqliteDB::Instance().DeleteAll<T>(); | ||
| 55 | -} | ||
| 56 | -} // namespace RunnerDB | ||
| 57 | - | ||
| 58 | -#endif | ||
Rtest/hccl_vm/include/runnerdb/db_sim_runner_common.h→test/hccl_vm/include/runtime_state/db_sim_runner_common.h+60-71
Rtest/hccl_vm/src/runnerdb/tracedb/db_sim_runner_ops.cc→test/hccl_vm/src/runtime_state/db_sim_runner_ops.cc+144-107
Rtest/hccl_vm/cmake/third_party/sqlite3.cmake→test/hccl_vm/src/storage_backends/sqlite/cmake/sqlite3_host.cmake+23-13
Rtest/hccl_vm/test/cmd/subcmd/subcmd_run_test.cc→test/hccl_vm/test/cmd/subcmd/sqlite/subcmd_run_test.cc+185-46
Rtest/hccl_vm/test/cmd/subcmd/subcmd_start_test.cc→test/hccl_vm/test/cmd/subcmd/sqlite/subcmd_start_test.cc+194-50
Rtest/hccl_vm/test/device_arm/proxy/ascend_hal_stub_test.cc→test/hccl_vm/test/device_arm/proxy/sqlite/ascend_hal_stub_test.cc+103-76
Rtest/hccl_vm/test/device_arm/proxy/device_sqe_parse_stub_test.cc→test/hccl_vm/test/device_arm/proxy/sqlite/device_sqe_parse_stub_test.cc+563-316
Rtest/hccl_vm/test/device_arm/data_op_device_stub_test.cc→test/hccl_vm/test/device_arm/sqlite/data_op_device_stub_test.cc+81-88
Rtest/hccl_vm/test/proxy/ctrl_base_resource_stub_test.cc→test/hccl_vm/test/proxy/sqlite/ctrl_base_resource_stub_test.cc+67-89
Rtest/hccl_vm/test/runnerdb/sim_models_test.cc→test/hccl_vm/test/simulation/sim_models_test.cc+27-28
Rtest/hccl_vm/test/store/dump_shm_data_test.cc→test/hccl_vm/test/store/sqlite/dump_shm_data_test.cc+361-333
Rtest/hccl_vm/test/store/hccl_shm_pub_test.cc→test/hccl_vm/test/store/sqlite/hccl_shm_pub_test.cc+59-64
Rtest/hccl_vm/test/store/sim_check_only_off_test.cc→test/hccl_vm/test/store/sqlite/sim_check_only_off_test.cc+26-33
Rtest/hccl_vm/test/store/sim_device_memory_manager_test.cc→test/hccl_vm/test/store/sqlite/sim_device_memory_manager_test.cc+198-193
Rtest/hccl_vm/test/topo/topo_golden_test.cc→test/hccl_vm/test/topo/sqlite/topo_golden_test.cc+194-222