# -----------------------------------------------------------------------------------------------------------
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
# CANN Open Software License Agreement Version 2.0 (the "License").
# Please refer to the License for details. You may not use this file except in compliance with the License.
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
# See LICENSE in the root of the software repository for the full text of the License.
# -----------------------------------------------------------------------------------------------------------
########################################################################################################################
# 预定义变量
########################################################################################################################
# 缓存所有算子 UTest 场景 OpApi 动态库相关信息
set(_OpsTestUt_OpApiSources "" CACHE INTERNAL "" FORCE) # Sources
set(_OpsTestUt_OpApiPrivateIncludesExt "" CACHE INTERNAL "" FORCE) # PrivateIncludesExt
set(_OpsTestUt_OpApiLinkLibrariesExt "" CACHE INTERNAL "" FORCE) # LinkLibrariesExt
add_library(_OpsTestUt_OpApi_Wno INTERFACE)
target_compile_options(_OpsTestUt_OpApi_Wno
INTERFACE
$<$<CXX_COMPILER_ID:Clang>:-Wno-mismatched-tags>
$<$<CXX_COMPILER_ID:GNU>:-Wno-format-signedness>
-Wno-extra
-Wno-redundant-decls
)
add_definitions(-DNOT_DYNAMIC_COMPILE)
# 缓存所有算子 UTest 场景 OpProto 动态库相关信息
set(_OpsTestUt_OpProtoSources "" CACHE INTERNAL "" FORCE) # Sources
set(_OpsTestUt_OpProtoPrivateIncludesExt "" CACHE INTERNAL "" FORCE) # PrivateIncludesExt
set(_OpsTestUt_OpProtoLinkLibrariesExt "" CACHE INTERNAL "" FORCE) # LinkLibrariesExt
# 缓存所有算子 UTest 场景 OpTiling 动态库相关信息
set(_OpsTestUt_OpTilingSources "" CACHE INTERNAL "" FORCE) # Sources
set(_OpsTestUt_OpTilingPrivateIncludesExt "" CACHE INTERNAL "" FORCE) # PrivateIncludesExt
set(_OpsTestUt_OpTilingLinkLibrariesExt "" CACHE INTERNAL "" FORCE) # LinkLibrariesExt
add_library(_OpsTestUt_OpTiling_Wno INTERFACE)
target_compile_options(_OpsTestUt_OpTiling_Wno
INTERFACE
$<$<CXX_COMPILER_ID:Clang>:-Wno-unused-private-field>
$<$<CXX_COMPILER_ID:Clang>:-Wno-redundant-move>
-Wno-shadow
$<$<CXX_COMPILER_ID:GNU>:-Wno-format-signedness>
-Wno-extra
)
# 缓存当前算子 UTest 场景 OpKernel 目标
set(_OpsTestUt_OpKernelLibraries "" CACHE INTERNAL "" FORCE) # LinkLibrariesExt
add_library(_OpsTestUt_OpKernel_Wno INTERFACE)
target_compile_options(_OpsTestUt_OpKernel_Wno
INTERFACE
-Wno-undef
-Wno-cast-qual
-Wno-shadow
-Wno-sign-compare
-Wno-unused-macros
-Wno-unused-variable
$<$<CXX_COMPILER_ID:GNU>:-Wno-unused-but-set-variable>
$<$<CXX_COMPILER_ID:Clang>:$<$<VERSION_GREATER_EQUAL:${CMAKE_C_COMPILER_VERSION},15.0.4>:-Wno-unused-but-set-variable>>
$<$<CXX_COMPILER_ID:GNU>:-Wno-duplicated-branches>
-Wno-extra
-Wno-float-conversion
-Wno-parentheses
)
# 缓存当前算子 UTest 场景 UTestCommon 目标
set(_OpsTestUt_UTestCommonLibrary "" CACHE INTERNAL "" FORCE)
# 缓存所有算子 UTest 场景 UTest用例 动态库相关信息
set(_OpsTestUt_UTestCaseLibraries "" CACHE INTERNAL "" FORCE)
set(_OpsTestUt_UTestAclnnCaseLibraries "" CACHE INTERNAL "" FORCE)
add_library(_OpsTestUt_UTestCaseStatic_Wno INTERFACE)
target_compile_options(_OpsTestUt_UTestCaseStatic_Wno
INTERFACE
$<$<CXX_COMPILER_ID:Clang>:-Wno-vla>
)
# GTest 版本兼容性保证
add_library(_OpsTestUt_GTest_Wno INTERFACE)
target_compile_options(_OpsTestUt_GTest_Wno
INTERFACE
-Wno-undef
)
########################################################################################################################
# 编译方法
########################################################################################################################
# Level1, 添加算子 OpApi 动态库
#[[
调用参数:
one_value_keywords:
SUB_SYSTEM : 必选参数, 用于指定算子所属子系统, 如 transformer
BRIEF : 必选参数, 用于指定算子缩略名(建议以大驼峰命名, 与算子实际名称无强制对应关系), 如 Fag/Fas/Fa
SNAKE : 必选参数, 用于指定算子全名, 如 flash_attention_score_grad
multi_value_keywords:
SOURCES_EXT : 可选参数, 额外源文件
PRIVATE_INCLUDES_EXT : 可选参数, 额外头文件搜索路径
PRIVATE_LINK_LIBRARIES_EXT : 可选参数, 额外链接库
备注说明:
本函数提供编译算子对应 opapi.so 的功能. 下面介绍在调用本函数时所需了解的一些背景知识和注意事项.
1. 本函数假设算子对应 OpApi 的源文件位于 'src/${SUB_SYSTEM}/${SNAKE}/op_host' 路径, 并自动添加以下内容:
a) 源文件: ${SNAKE}.cpp, aclnn_${SNAKE}.cpp
b) 头文件搜索路径: 'src/${SUB_SYSTEM}/${SNAKE}/op_host'
2. 若算子 '需要额外的源文件’ 或 ‘源文件不满足上述约定的默认路径', 则可通过 SOURCES_EXT 参数指定 '额外的源文件';
3. 若算子 '需要额外头文件搜索路径’ 或 ‘本函数现有实现的头文件搜索路径设置不满足',
则可通过 PRIVATE_INCLUDES_EXT 参数指定 '额外的头文件搜索路径'; 参数 PRIVATE_LINK_LIBRARIES_EXT 设置逻辑同理;
]]
function(OpsTest_Level1_AddOpApiShared)
cmake_parse_arguments(
TMP
""
"SUB_SYSTEM;BRIEF;SNAKE"
"SOURCES_EXT;PRIVATE_INCLUDES_EXT;PRIVATE_LINK_LIBRARIES_EXT"
""
${ARGN}
)
get_filename_component(_L0_Src "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}/op_host/${TMP_SNAKE}.cpp" REALPATH)
if (NOT EXISTS "${_L0_Src}")
set(_L0_Src)
endif ()
get_filename_component(_L2_Src "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}/op_host/aclnn_${TMP_SNAKE}.cpp" REALPATH)
if (NOT EXISTS "${_L2_Src}")
set(_L2_Src)
endif ()
get_filename_component(_Inc "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}/op_host/" REALPATH)
if (NOT EXISTS "${_Inc}")
set(_Inc)
endif ()
set(_Sources ${TMP_SOURCES_EXT} ${_L0_Src} ${_L2_Src})
list(REMOVE_DUPLICATES _Sources)
if (_Sources)
set(_PrivateIncludeDirs ${TMP_PRIVATE_INCLUDES_EXT} ${_Inc})
list(REMOVE_DUPLICATES _PrivateIncludeDirs)
set(_OpsTestUt_OpApiSources ${_OpsTestUt_OpApiSources} ${_Sources} CACHE INTERNAL "" FORCE)
set(_OpsTestUt_OpApiPrivateIncludesExt ${_OpsTestUt_OpApiPrivateIncludesExt} ${_PrivateIncludeDirs} CACHE INTERNAL "" FORCE)
set(_OpsTestUt_OpApiLinkLibrariesExt ${_OpsTestUt_OpApiLinkLibrariesExt} ${TMP_PRIVATE_LINK_LIBRARIES_EXT} CACHE INTERNAL "" FORCE)
endif ()
endfunction()
# 私有函数, 外部不可直接调用, 用于实际生成 OpApi 动态库
#[[
]]
function(OpsTest_AddOpApiShared)
list(REMOVE_DUPLICATES _OpsTestUt_OpApiSources)
list(REMOVE_DUPLICATES _OpsTestUt_OpApiPrivateIncludesExt)
list(REMOVE_DUPLICATES _OpsTestUt_OpApiLinkLibrariesExt)
if ("${_OpsTestUt_OpApiSources}" STREQUAL "")
return()
endif ()
set(_Target ${UTest_NamePrefix}_OpApi)
add_library(${_Target} SHARED)
target_sources(${_Target}
PRIVATE
${_OpsTestUt_OpApiSources}
)
target_include_directories(${_Target}
PRIVATE
${OPAPI_INCLUDE}
${_OpsTestUt_OpApiPrivateIncludesExt}
${ASCEND_CANN_PACKAGE_PATH}/runtime/pkg_inc
${ASCEND_CANN_PACKAGE_PATH}/runtime/pkg_inc/profiling
)
target_compile_options(${_Target}
PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-std=gnu++1z>
)
target_compile_definitions(${_Target}
PRIVATE
ACLNN_LOG_FMT_CHECK
LOG_CPP
PROCESS_LOG
)
target_link_libraries(${_Target}
PRIVATE
-Wl,--whole-archive
${_OpsTestUt_OpApiLinkLibrariesExt}
$<BUILD_INTERFACE:intf_pub_utest>
$<BUILD_INTERFACE:_OpsTestUt_OpApi_Wno>
-Wl,--no-whole-archive
PRIVATE $<$<BOOL:${BUILD_WITH_INSTALLED_DEPENDENCY_CANN_PKG}>:$<BUILD_INTERFACE:opapi_math>>
nnopbase
profapi
ge_common_base
ascend_dump
ascendalog
dl
)
set(_UTest_OpApiLibrary ${_Target} PARENT_SCOPE)
endfunction()
# Level1, 添加算子 OpProto 动态库
#[[
调用参数:
one_value_keywords:
SUB_SYSTEM : 必选参数, 用于指定算子所属子系统, 如 transformer
BRIEF : 必选参数, 用于指定算子缩略名(建议以大驼峰命名, 与算子实际名称无强制对应关系), 如 Fag/Fas/Fa
SNAKE : 必选参数, 用于指定算子全名, 如 flash_attention_score_grad
multi_value_keywords:
SOURCES_EXT : 可选参数, 额外源文件
PRIVATE_INCLUDES_EXT : 可选参数, 额外头文件搜索路径
PRIVATE_LINK_LIBRARIES_EXT : 可选参数, 额外链接库
备注说明:
本函数提供编译算子对应 OpProto.so 的功能. 下面介绍在调用本函数时所需了解的一些背景知识和注意事项.
1. 本函数假设算子对应 OpProto 的源文件位于 'src/${SUB_SYSTEM}/${SNAKE}/op_host' 路径, 并自动添加以下内容:
a) 源文件: ${SNAKE}_proto.cpp
b) 头文件搜索路径: 'src/${SUB_SYSTEM}/${SNAKE}/op_host'
2. 若算子 '需要额外的源文件’ 或 ‘源文件不满足上述约定的默认路径', 则可通过 SOURCES_EXT 参数指定 '额外的源文件';
3. 若算子 '需要额外头文件搜索路径’ 或 ‘本函数现有实现的头文件搜索路径设置不满足',
则可通过 PRIVATE_INCLUDES_EXT 参数指定 '额外的头文件搜索路径'; 参数 PRIVATE_LINK_LIBRARIES_EXT 设置逻辑同理;
]]
function(OpsTest_Level1_AddOpProtoShared)
cmake_parse_arguments(
TMP
""
"SUB_SYSTEM;BRIEF;SNAKE"
"SOURCES_EXT;PRIVATE_INCLUDES_EXT;PRIVATE_LINK_LIBRARIES_EXT"
""
${ARGN}
)
get_filename_component(_Src "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}/op_host/${TMP_SNAKE}_proto.cpp" REALPATH)
if (NOT EXISTS "${_Src}")
set(_Src)
endif ()
get_filename_component(_Inc "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}/op_host/" REALPATH)
if (NOT EXISTS "${_Inc}")
set(_Inc)
endif ()
set(_Sources ${TMP_SOURCES_EXT} ${_Src})
list(REMOVE_DUPLICATES _Sources)
if (_Sources)
set(_PrivateIncludeDirs ${TMP_PRIVATE_INCLUDES_EXT} ${_Inc})
list(REMOVE_DUPLICATES _PrivateIncludeDirs)
set(_OpsTestUt_OpProtoSources ${_OpsTestUt_OpProtoSources} ${_Sources} CACHE INTERNAL "" FORCE)
set(_OpsTestUt_OpProtoPrivateIncludesExt ${_OpsTestUt_OpProtoPrivateIncludesExt} ${_PrivateIncludeDirs} CACHE INTERNAL "" FORCE)
set(_OpsTestUt_OpProtoLinkLibrariesExt ${_OpsTestUt_OpProtoLinkLibrariesExt} ${TMP_PRIVATE_LINK_LIBRARIES_EXT} CACHE INTERNAL "" FORCE)
endif ()
endfunction()
# 私有函数, 外部不可直接调用, 用于实际生成 OpProto 动态库
#[[
]]
function(OpsTest_AddOpProtoShared)
list(REMOVE_DUPLICATES _OpsTestUt_OpProtoSources)
list(REMOVE_DUPLICATES _OpsTestUt_OpProtoPrivateIncludesExt)
list(REMOVE_DUPLICATES _OpsTestUt_OpProtoLinkLibrariesExt)
if ("${_OpsTestUt_OpProtoSources}" STREQUAL "")
return()
endif ()
set(_Target ${UTest_NamePrefix}_OpProto)
add_library(${_Target} SHARED)
target_sources(${_Target}
PRIVATE
${_OpsTestUt_OpProtoSources}
)
target_include_directories(${_Target}
PRIVATE
${OPBASE_INC_DIRS}
${_OpsTestUt_OpProtoPrivateIncludesExt}
)
target_compile_options(${_Target}
PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-std=gnu++1z>
)
target_compile_definitions(${_Target}
PRIVATE
LOG_CPP
PROCESS_LOG
)
target_link_libraries(${_Target}
PRIVATE
-Wl,--whole-archive
${_OpsTestUt_OpProtoLinkLibrariesExt}
$<BUILD_INTERFACE:intf_pub_utest>
$<BUILD_INTERFACE:ops_transformer_utils_proto_headers>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:alog_headers>>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:dlog_headers>>
-Wl,--no-whole-archive
ascendalog
)
set(_UTest_OpProtoLibrary ${_Target} PARENT_SCOPE)
endfunction()
# Level1, 添加算子 OpTiling 动态库
#[[
调用参数:
one_value_keywords:
SUB_SYSTEM : 必选参数, 用于指定算子所属子系统, 如 transformer
BRIEF : 必选参数, 用于指定算子缩略名(建议以大驼峰命名, 与算子实际名称无强制对应关系), 如 Fag/Fas/Fa
SNAKE : 必选参数, 用于指定算子全名, 如 flash_attention_score_grad
multi_value_keywords:
SOURCES_EXT : 可选参数, 额外源文件
PRIVATE_INCLUDES_EXT : 可选参数, 额外头文件搜索路径
PRIVATE_LINK_LIBRARIES_EXT : 可选参数, 额外链接库
备注说明:
本函数提供编译算子对应 OpTiling.so 的功能. 下面介绍在调用本函数时所需了解的一些背景知识和注意事项.
1. 本函数假设算子对应 OpTiling 的源文件位于 'src/${SUB_SYSTEM}/${SNAKE}/op_host/${SNAKE}_tiling.cpp/.cc' 路径;
2. 若算子 '需要额外的源文件’ 或 ‘源文件不满足上述约定的默认路径', 则可通过 SOURCES_EXT 参数指定 '额外的源文件';
3. 若算子 '需要额外头文件搜索路径’ 或 ‘本函数现有实现的头文件搜索路径设置不满足',
则可通过 PRIVATE_INCLUDES_EXT 参数指定 '额外的头文件搜索路径'; 参数 PRIVATE_LINK_LIBRARIES_EXT 设置逻辑同理;
]]
function(OpsTest_Level1_AddOpTilingShared)
cmake_parse_arguments(
TMP
""
"SUB_SYSTEM;BRIEF;SNAKE"
"SOURCES_EXT;PRIVATE_INCLUDES_EXT;PRIVATE_LINK_LIBRARIES_EXT"
""
${ARGN}
)
file(GLOB _Src1 "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}/op_host/${TMP_SNAKE}_tiling.cc")
file(GLOB _Src2 "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}/op_host/${TMP_SNAKE}_tiling.cpp")
list(APPEND _Sources ${TMP_SOURCES_EXT} ${_Src1} ${_Src2})
list(REMOVE_DUPLICATES _Sources)
get_filename_component(_Inc "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}/op_host/" REALPATH)
if (NOT EXISTS "${_Inc}")
set(_Inc)
endif ()
if (_Sources)
set(_PrivateIncludeDirs ${TMP_PRIVATE_INCLUDES_EXT} ${_Inc})
list(REMOVE_DUPLICATES _PrivateIncludeDirs)
set(_OpsTestUt_OpTilingSources ${_OpsTestUt_OpTilingSources} ${_Sources} CACHE INTERNAL "" FORCE)
set(_OpsTestUt_OpTilingPrivateIncludesExt ${_OpsTestUt_OpTilingPrivateIncludesExt} ${_PrivateIncludeDirs} CACHE INTERNAL "" FORCE)
set(_OpsTestUt_OpTilingLinkLibrariesExt ${_OpsTestUt_OpTilingLinkLibrariesExt} ${TMP_PRIVATE_LINK_LIBRARIES_EXT} CACHE INTERNAL "" FORCE)
endif ()
endfunction()
# 私有函数, 外部不可直接调用, 用于实际生成 OpTiling 动态库
#[[
]]
function(OpsTest_AddOpTilingShared)
list(REMOVE_DUPLICATES _OpsTestUt_OpTilingSources)
list(REMOVE_DUPLICATES _OpsTestUt_OpTilingPrivateIncludesExt)
list(REMOVE_DUPLICATES _OpsTestUt_OpTilingLinkLibrariesExt)
set(_Target ${UTest_NamePrefix}_OpTiling)
add_library(${_Target} SHARED)
target_sources(${_Target}
PRIVATE
${_OpsTestUt_OpTilingSources}
${OPS_ADV_DIR}/tests/ut/framework_special/stubs/tiling/tiling_templates_registry.cpp
)
target_include_directories(${_Target}
PRIVATE
${OPBASE_INC_DIRS}
${_OpsTestUt_OpTilingPrivateIncludesExt}
${OPS_TRANSFORMER_DIR}/common/include
)
target_compile_definitions(${_Target}
PRIVATE
OP_TILING_LIB
LOG_CPP
PROCESS_LOG
)
target_compile_options(${_Target}
PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-std=c++11>
)
target_link_libraries(${_Target}
PRIVATE
-Wl,--as-needed
-Wl,--no-whole-archive
${_OpsTestUt_OpTilingLinkLibrariesExt}
$<BUILD_INTERFACE:intf_pub_utest>
$<BUILD_INTERFACE:_OpsTestUt_OpTiling_Wno>
$<BUILD_INTERFACE:ops_transformer_utils_tiling_headers>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:alog_headers>>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:dlog_headers>>
graph
graph_base
exe_graph
platform
register
ascendalog
tiling_api
c_sec
)
set(_UTest_OpTilingLibrary ${_Target} PARENT_SCOPE)
endfunction()
# Level1, 添加算子 Kernel 静态库
#[[
调用参数:
one_value_keywords:
SUB_SYSTEM : 必选参数, 用于指定算子所属子系统, 如 transformer
BRIEF : 必选参数, 用于指定算子缩略名(建议以大驼峰命名, 与算子实际名称无强制对应关系), 如 Fag/Fas/Fa
SNAKE : 必选参数, 用于指定算子全名, 如 flash_attention_score_grad
multi_value_keywords:
SOURCES_EXT : 可选参数, 额外源文件
TILING_DATA_DEF_H : 可选参数, 算子 Kernel 所需 TilingData 定义头文件
PRIVATE_INCLUDES_EXT : 可选参数, 额外头文件搜索路径
PRIVATE_COMPILE_DEFINITIONS_EXT : 可选参数, 额外编译宏
备注说明:
本函数提供编译算子对应 kernel.a 的功能. 下面介绍在调用本函数时所需了解的一些背景知识和注意事项.
1. 本函数假设算子对应 Kernel 的源文件位于 'src/${SUB_SYSTEM}/${SNAKE}/${SNAKE}.cpp' 路径;
2. 若算子 '需要额外的源文件’ 或 ‘源文件不满足上述约定的默认路径', 则可通过 SOURCES_EXT 参数指定 '额外的源文件';
3. 当前 Ascend C 融合算子 Kernel 一般需要多个(>2) TilingData 定义头文件,
如 flash_attention_score 算子需要 data_copy_transpose_tiling_def.h 和 flash_attention_score_tiling.h;
- 在 NPU 编译时, 编译框架使用 ccec 编译器并使用 -include 编译选项注入所需的多个 TilingData 定义头文件 至 Kernel 源文件;
- 但 CPU 编译时, CMake 早期版本在处理 -include 选项时有 Bug(只第一个 -include 指定的头文件生效).
故本框架通过新增一个 {BRIEF}_tiling_data.h, 再在该文件中 include 所需的多个 TilingData 定义头文件,
再通过 -include 编译选项注入 {BRIEF}_tiling_data.h 的方式规避 CPU 编译时 CMake 不能处理多个 -include 选项的 Bug;
4. PRIVATE_COMPILE_DEFINITIONS_EXT 设置格式如下:
optional{KernelCtrlParam func suffix} optional{OtherCompileDefinitions}}
其中 KernelCtrlParam 用于指定 Kernel 编译控制参数, func 为标识 Kernel 原始入口函数名,
suffix 为标识当前 Kernel 二进制及 Kernel 入口函数后缀; 其设置逻辑如下:
4.0 KernelCtrlParam 内 func, suffix 必需按序设置;
4.1 当不设置 KernelCtrlParam 时, 仅会编译一个 Kernel.a 并以 OtherCompileDefinitions 设置编译 Definitions(如设置);
4.2 若当设置 KernelCtrlParam 时, 本函数会按 KernelCtrlParam 个数逐个编译 Kernel.a,
并以 KernelCtrlParam 间 OtherCompileDefinitions 设置编译宏定义; 并将 func 重命名为 {func}_{suffix};
4.3 KernelCtrlParam 内 func 支持指定多个, 指定多个时 func 之间用','间隔;
]]
function(OpsTest_Level1_AddOpKernelStatic)
cmake_parse_arguments(
TMP
""
"SUB_SYSTEM;BRIEF;SNAKE"
"SOURCES_EXT;TILING_DATA_DEF_H;PRIVATE_INCLUDES_EXT;PRIVATE_COMPILE_DEFINITIONS_EXT"
""
${ARGN}
)
# 生成 Kernel 所需的结构体表示的对应 tiling.h
string(TOLOWER ${TMP_BRIEF} tmp_brief)
set(_tmp_files ${TMP_TILING_DATA_DEF_H})
list(REMOVE_DUPLICATES _tmp_files)
set(_ori_files)
set(_define_py ${OPS_ADV_DIR}/cmake/scripts/utest/gen_tiling_data_stub.py)
foreach (_tmp ${_tmp_files})
if (EXISTS ${_tmp})
list(APPEND _ori_files "-s=${_tmp}")
else ()
message(FATAL_ERROR "${_tmp} not exist.")
endif ()
endforeach ()
# 生成目标根目录
get_filename_component(_OpsTest_GenDir "${CMAKE_CURRENT_BINARY_DIR}/gen" REALPATH)
get_filename_component(_OpsTest_GenDirInc "${_OpsTest_GenDir}/inc" REALPATH)
execute_process(
COMMAND ${HI_PYTHON} ${_define_py} "-o=${tmp_brief}" ${_ori_files} "-d=${_OpsTest_GenDirInc}"
)
set(_Target ${UTest_NamePrefix}_${TMP_BRIEF}_OpTilingDataDef)
add_library(${_Target} INTERFACE)
target_include_directories(${_Target} INTERFACE ${_OpsTest_GenDirInc} ${OPS_ADV_UTILS_KERNEL_INC})
# 编译变量处理
set(_TargetPrefix ${UTest_NamePrefix}_${TMP_BRIEF}_OpKernel)
aux_source_directory(${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE} _Sources)
list(APPEND _Sources ${TMP_SOURCES_EXT})
set(_PrivateIncludeDirectories
${_OpsTest_GenDirInc}
${TMP_PRIVATE_INCLUDES_EXT}
<ASCEND_CANN_PACKAGE_PATH>/${SYSTEM_PREFIX}/ascendc/include/basic_api
<ASCEND_CANN_PACKAGE_PATH>/${SYSTEM_PREFIX}/ascendc/include/basic_api/impl
<ASCEND_CANN_PACKAGE_PATH>/${SYSTEM_PREFIX}/ascendc/include/basic_api/interface
<ASCEND_CANN_PACKAGE_PATH>/tools/tikicpulib/lib/include
<ASCEND_CANN_PACKAGE_PATH>/include/ascendc
<ASCEND_CANN_PACKAGE_PATH>/x86_64-linux/include/ascendc/highlevel_api
<ASCEND_CANN_PACKAGE_PATH>/pkg_inc/runtime/runtime
<ASCEND_CANN_PACKAGE_PATH>/runtime/pkg_inc
)
get_filename_component(_Inc "${OPS_ADV_DIR}/${TMP_SUB_SYSTEM}/${TMP_SNAKE}" REALPATH)
if (EXISTS "${_Inc}")
list(APPEND _PrivateIncludeDirectories ${_Inc})
endif ()
set(_PrivateCompileOptions
-include ${_OpsTest_GenDirInc}/tiling/${tmp_brief}/tiling_stub.h
)
set(_PrivateLinkLibraries
-Wl,--as-needed
-Wl,--no-whole-archive
c_sec
$<BUILD_INTERFACE:intf_pub_utest>
$<BUILD_INTERFACE:_OpsTestUt_OpKernel_Wno>
)
# 多 Kernel 处理
set(_OpKernelLibraries)
list(FIND TMP_PRIVATE_COMPILE_DEFINITIONS_EXT KernelCtrlParam _GrpIdx)
if ("${_GrpIdx}" STREQUAL "-1")
# 不存在多 Kernel 配置时, 不添加后缀, 编译一个 Kernel.a
set(_Target ${_TargetPrefix})
add_library(${_Target} STATIC)
target_sources(${_Target} PRIVATE ${_Sources})
target_include_directories(${_Target} PRIVATE ${_PrivateIncludeDirectories})
target_compile_definitions(${_Target} PRIVATE ${TMP_PRIVATE_COMPILE_DEFINITIONS_EXT})
target_compile_options(${_Target} PRIVATE ${_PrivateCompileOptions})
target_link_libraries(${_Target}
PUBLIC
tikicpulib::${OPS_ADV_UTEST_OPS_TEST_ASCEND_PRODUCT_TYPE}
PRIVATE
${_PrivateLinkLibraries}
)
list(APPEND _OpKernelLibraries ${_Target})
else ()
# 存在 1/n 多 Kernel 配置时, 添加后缀, 编译多 Kernel.a
while (NOT "${_GrpIdx}" STREQUAL "-1")
# 获取当前 Func, Suffix, CompileDefinitions
math(EXPR _FuncIdx "${_GrpIdx} + 1")
math(EXPR _SuffixIdx "${_GrpIdx} + 2")
math(EXPR _SubLstBgnIdx "${_GrpIdx} + 3")
list(GET TMP_PRIVATE_COMPILE_DEFINITIONS_EXT ${_FuncIdx} _FuncOriValList)
list(GET TMP_PRIVATE_COMPILE_DEFINITIONS_EXT ${_SuffixIdx} _SuffixVal)
list(SUBLIST TMP_PRIVATE_COMPILE_DEFINITIONS_EXT ${_SubLstBgnIdx} -1 TMP_PRIVATE_COMPILE_DEFINITIONS_EXT)
list(FIND TMP_PRIVATE_COMPILE_DEFINITIONS_EXT KernelCtrlParam _GrpIdx) # _GrpIdx 移动
list(SUBLIST TMP_PRIVATE_COMPILE_DEFINITIONS_EXT 0 ${_GrpIdx} _SubCompileDefinitions)
string(REPLACE "," ";" _FuncOriValList "${_FuncOriValList}")
set(_FuncValDef)
foreach (_f ${_FuncOriValList})
list(APPEND _FuncValDef "-D${_f}=${_f}_${_SuffixVal}")
endforeach ()
# 编译目标
set(_Target ${_TargetPrefix}_${_SuffixVal})
add_library(${_Target} STATIC)
target_sources(${_Target} PRIVATE ${_Sources})
target_include_directories(${_Target} PRIVATE ${_PrivateIncludeDirectories})
target_compile_definitions(${_Target} PRIVATE ${_FuncValDef} ${_SubCompileDefinitions})
target_compile_options(${_Target} PRIVATE ${_PrivateCompileOptions})
target_link_libraries(${_Target}
PUBLIC
tikicpulib::${OPS_ADV_UTEST_OPS_TEST_ASCEND_PRODUCT_TYPE}
PRIVATE
${_PrivateLinkLibraries}
)
list(APPEND _OpKernelLibraries ${_Target})
endwhile ()
endif ()
set(_OpsTestUt_OpKernelLibraries ${_OpKernelLibraries} CACHE INTERNAL "" FORCE)
endfunction()
# Level1, 添加算子 UTest 用例 Common 静态库
#[[
调用参数:
one_value_keywords:
BRIEF : 必选参数, 用于指定算子缩略名(建议以大驼峰命名, 与算子实际名称无强制对应关系), 如 Fag/Fas/Fa
SNAKE : 必选参数, 用于指定算子全名, 如 flash_attention_score_grad
TILING_DATA_DEF_BRIEF: 可选参数, 用于指定链接的 TilingData 头文件目标
multi_value_keywords:
SOURCES_EXT : 可选参数, 额外源文件
SOURCES_EXT_FORCE : 可选参数, 强制使用 SOURCES_EXT 指定的额外源文件 (Common), 不再自动寻找 comm 下源文件
PUBLIC_INCLUDES_EXT : 可选参数, 额外头文件搜索路径(public)
PRIVATE_INCLUDES_EXT : 可选参数, 额外头文件搜索路径
PRIVATE_LINK_LIBRARIES_EXT : 可选参数, 额外链接库
PRIVATE_COMPILE_DEFINITIONS : 可选参数, 额外的编译宏定义
]]
function(OpsTest_Level1_AddUTestCommonStatic)
cmake_parse_arguments(
TMP
""
"BRIEF;SNAKE;TILING_DATA_DEF_BRIEF"
"SOURCES_EXT;SOURCES_EXT_FORCE;PUBLIC_INCLUDES_EXT;PRIVATE_INCLUDES_EXT;PRIVATE_LINK_LIBRARIES_EXT;PRIVATE_COMPILE_DEFINITIONS"
""
${ARGN}
)
if (NOT TMP_TILING_DATA_DEF_BRIEF)
set(TMP_TILING_DATA_DEF_BRIEF ${TMP_BRIEF})
endif ()
# 强制指定源码处理
set(_Src1)
set(_Src2)
set(_Common_Sources ${TMP_SOURCES_EXT})
if (NOT TMP_SOURCES_EXT_FORCE)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/comm)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/comm/inc)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/comm/src _Src1)
else ()
file(GLOB_RECURSE _Src1 "${CMAKE_CURRENT_SOURCE_DIR}/comm/*.cc")
file(GLOB_RECURSE _Src2 "${CMAKE_CURRENT_SOURCE_DIR}/comm/*.cpp")
endif ()
endif ()
endif ()
list(APPEND _Common_Sources ${_Src1} ${_Src2})
list(REMOVE_DUPLICATES _Common_Sources)
set(_Target_UTest_Common)
if (_Common_Sources)
set(_Target_UTest_Common ${UTest_NamePrefix}_${TMP_BRIEF}_UTest_Common)
add_library(${_Target_UTest_Common} STATIC)
target_sources(${_Target_UTest_Common} PRIVATE ${_Common_Sources})
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/comm/inc)
target_include_directories(${_Target_UTest_Common} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/comm/inc)
elseif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/comm)
target_include_directories(${_Target_UTest_Common} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/comm)
endif ()
target_include_directories(${_Target_UTest_Common}
PUBLIC
${TMP_PUBLIC_INCLUDES_EXT}
PRIVATE
${OPBASE_INC_DIRS}
${OPS_TRANSFORMER_DIR}/common/include
${ASCEND_CANN_PACKAGE_PATH}/include
${TMP_PRIVATE_INCLUDES_EXT}
)
target_compile_definitions(${_Target_UTest_Common}
PRIVATE
${TMP_PRIVATE_COMPILE_DEFINITIONS}
)
target_link_libraries(${_Target_UTest_Common}
PRIVATE
-Wl,--as-needed
-Wl,--no-whole-archive
platform
register
opp_registry
error_manager
metadef
tiling_api
$<BUILD_INTERFACE:intf_pub_utest>
$<BUILD_INTERFACE:_OpsTestUt_UTestCaseStatic_Wno>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:alog_headers>>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:dlog_headers>>
tikicpulib::${OPS_ADV_UTEST_OPS_TEST_ASCEND_PRODUCT_TYPE}
${UTest_NamePrefix}_${TMP_TILING_DATA_DEF_BRIEF}_OpTilingDataDef
${UTest_NamePrefix}_Utils
${TMP_PRIVATE_LINK_LIBRARIES_EXT}
${_OpsTestUt_OpKernelLibraries} # 当前各算子 common 内以 extern 方式声明 kernel 入口, 故添加依赖
)
endif ()
set(_OpsTestUt_UTestCommonLibrary ${_Target_UTest_Common} CACHE INTERNAL "" FORCE)
endfunction()
# Level1, 添加算子 UTest 用例静态库
#[[
调用参数:
one_value_keywords:
BRIEF : 必选参数, 用于指定算子缩略名(建议以大驼峰命名, 与算子实际名称无强制对应关系), 如 Fag/Fas/Fa
SNAKE : 必选参数, 用于指定算子全名, 如 flash_attention_score_grad
TILING_DATA_DEF_BRIEF: 可选参数, 用于指定链接的 TilingData 头文件目标
multi_value_keywords:
SOURCES_EXT : 可选参数, 额外源文件
SOURCES_EXT_FORCE : 可选参数, 强制使用 SOURCES_EXT 指定的额外源文件 (UTest), 不再自动寻找 utest 下源文件
PRIVATE_INCLUDES_EXT : 可选参数, 额外头文件搜索路径
PRIVATE_LINK_LIBRARIES_EXT : 可选参数, 额外链接库
PRIVATE_COMPILE_DEFINITIONS : 可选参数, 额外的编译宏定义
]]
function(OpsTest_Level1_AddUTestCaseStatic)
cmake_parse_arguments(
TMP
""
"BRIEF;SNAKE;TILING_DATA_DEF_BRIEF"
"SOURCES_EXT;SOURCES_EXT_FORCE;PRIVATE_INCLUDES_EXT;PRIVATE_LINK_LIBRARIES_EXT;PRIVATE_COMPILE_DEFINITIONS"
""
${ARGN}
)
if (NOT TMP_TILING_DATA_DEF_BRIEF)
set(TMP_TILING_DATA_DEF_BRIEF ${TMP_BRIEF})
endif ()
# 强制指定源码处理
set(_UTest_Sources ${TMP_SOURCES_EXT})
if (NOT TMP_SOURCES_EXT_FORCE)
file(GLOB_RECURSE _Src1 "${CMAKE_CURRENT_SOURCE_DIR}/utest/*.cc")
file(GLOB_RECURSE _Src2 "${CMAKE_CURRENT_SOURCE_DIR}/utest/*.cpp")
list(APPEND _UTest_Sources ${_Src1} ${_Src2})
endif ()
list(REMOVE_DUPLICATES _UTest_Sources)
if (_UTest_Sources)
set(_Target_UTest ${UTest_NamePrefix}_${TMP_BRIEF}_UTest_Case)
add_library(${_Target_UTest} STATIC)
target_sources(${_Target_UTest} PRIVATE ${_UTest_Sources})
target_include_directories(${_Target_UTest}
PRIVATE
${ASCEND_CANN_PACKAGE_PATH}/include
${TMP_PRIVATE_INCLUDES_EXT}
${CMAKE_CURRENT_SOURCE_DIR}/utest
)
target_compile_definitions(${_Target_UTest}
PRIVATE
${TMP_PRIVATE_COMPILE_DEFINITIONS}
)
target_link_libraries(${_Target_UTest}
PRIVATE
-Wl,--as-needed
-Wl,--no-whole-archive
gtest
$<BUILD_INTERFACE:intf_pub_utest>
$<BUILD_INTERFACE:_OpsTestUt_UTestCaseStatic_Wno>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:alog_headers>>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:dlog_headers>>
tikicpulib::${OPS_ADV_UTEST_OPS_TEST_ASCEND_PRODUCT_TYPE}
${UTest_NamePrefix}_${TMP_TILING_DATA_DEF_BRIEF}_OpTilingDataDef
${UTest_NamePrefix}_Utils
$<BUILD_INTERFACE:_OpsTestUt_GTest_Wno>
${UTest_NamePrefix}_Utest
${TMP_PRIVATE_LINK_LIBRARIES_EXT}
${_OpsTestUt_UTestCommonLibrary}
)
set(_OpsTestUt_UTestCaseLibraries ${_OpsTestUt_UTestCaseLibraries} ${_Target_UTest} CACHE INTERNAL "" FORCE)
endif ()
endfunction()
# Level1, 添加算子 UTest 用例(Aclnn)静态库
#[[
调用参数:
one_value_keywords:
BRIEF : 必选参数, 用于指定算子缩略名(建议以大驼峰命名, 与算子实际名称无强制对应关系), 如 Fag/Fas/Fa
SNAKE : 必选参数, 用于指定算子全名, 如 flash_attention_score_grad
TILING_DATA_DEF_BRIEF: 可选参数, 用于指定链接的 TilingData 头文件目标
multi_value_keywords:
SOURCES_EXT : 可选参数, 额外源文件
SOURCES_EXT_FORCE : 可选参数, 强制使用 SOURCES_EXT 指定的额外源文件 (UTest_Aclnn), 不再自动寻找 utest_aclnn 下源文件
PRIVATE_INCLUDES_EXT : 可选参数, 额外头文件搜索路径
PRIVATE_COMPILE_DEFINITIONS : 可选参数, 额外的编译宏定义
PRIVATE_LINK_LIBRARIES_EXT : 可选参数, 额外链接库
]]
function(OpsTest_Level1_AddUTestAclnnCaseStatic)
cmake_parse_arguments(
TMP
""
"BRIEF;SNAKE;TILING_DATA_DEF_BRIEF"
"SOURCES_EXT;SOURCES_EXT_FORCE;PRIVATE_INCLUDES_EXT;PRIVATE_COMPILE_DEFINITIONS;PRIVATE_LINK_LIBRARIES_EXT"
""
${ARGN}
)
if (NOT TMP_TILING_DATA_DEF_BRIEF)
set(TMP_TILING_DATA_DEF_BRIEF ${TMP_BRIEF})
endif ()
# 强制指定源码处理
set(_UTest_Aclnn_Sources ${TMP_SOURCES_EXT})
if (NOT TMP_SOURCES_EXT_FORCE)
file(GLOB_RECURSE _Src1 "${CMAKE_CURRENT_SOURCE_DIR}/utest_aclnn/*.cc")
file(GLOB_RECURSE _Src2 "${CMAKE_CURRENT_SOURCE_DIR}/utest_aclnn/*.cpp")
list(APPEND _UTest_Aclnn_Sources ${_Src1} ${_Src2})
endif ()
list(REMOVE_DUPLICATES _UTest_Aclnn_Sources)
if (_UTest_Aclnn_Sources)
set(_Target_UTest_Aclnn ${UTest_NamePrefix}_${TMP_BRIEF}_UTest_Case_Aclnn)
add_library(${_Target_UTest_Aclnn} STATIC)
target_sources(${_Target_UTest_Aclnn} PRIVATE ${_UTest_Aclnn_Sources})
target_include_directories(${_Target_UTest_Aclnn}
PRIVATE
${ASCEND_CANN_PACKAGE_PATH}/include
${TMP_PRIVATE_INCLUDES_EXT}
${CMAKE_CURRENT_SOURCE_DIR}/utest_aclnn
)
target_compile_definitions(${_Target_UTest_Aclnn}
PRIVATE
${TMP_PRIVATE_COMPILE_DEFINITIONS}
)
target_link_libraries(${_Target_UTest_Aclnn}
PRIVATE
-Wl,--as-needed
-Wl,--no-whole-archive
gtest
$<BUILD_INTERFACE:intf_pub_utest>
$<BUILD_INTERFACE:_OpsTestUt_UTestCaseStatic_Wno>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:alog_headers>>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:dlog_headers>>
tikicpulib::${OPS_ADV_UTEST_OPS_TEST_ASCEND_PRODUCT_TYPE}
${UTest_NamePrefix}_${TMP_TILING_DATA_DEF_BRIEF}_OpTilingDataDef
${UTest_NamePrefix}_Utils
$<BUILD_INTERFACE:_OpsTestUt_GTest_Wno>
${UTest_NamePrefix}_Utest
${TMP_PRIVATE_LINK_LIBRARIES_EXT}
${_OpsTestUt_UTestCommonLibrary}
)
set(_OpsTestUt_UTestAclnnCaseLibraries ${_OpsTestUt_UTestAclnnCaseLibraries} ${_Target_UTest_Aclnn} CACHE INTERNAL "" FORCE)
endif ()
endfunction()
# Level2, 添加算子 UTest 用例动态库 及其所需全部库(OpTiling.so, OpKernel.a 等)
#[[
调用参数:
one_value_keywords:
SUB_SYSTEM : 必选参数, 用于指定算子所属子系统, 如 transformer
BRIEF : 必选参数, 用于指定算子缩略名(建议以大驼峰命名, 与算子实际名称无强制对应关系), 如 Fag/Fas/Fa
SNAKE : 必选参数, 用于指定算子全名, 如 flash_attention_score_grad
TILING_DATA_DEF_BRIEF: 可选参数, 用于指定链接的 TilingData 头文件目标
multi_value_keywords:
OPAPI_SOURCES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpApiShared 函数说明
OPAPI_PRIVATE_INCLUDES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpApiShared 函数说明
OPAPI_PRIVATE_LINK_LIBRARIES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpApiShared 函数说明
PROTO_SOURCES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpProtoShared 函数说明
PROTO_PRIVATE_INCLUDES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpProtoShared 函数说明
PROTO_PRIVATE_LINK_LIBRARIES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpProtoShared 函数说明
TILING_SOURCES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpTilingShared 函数说明
TILING_PRIVATE_INCLUDES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpTilingShared 函数说明
TILING_PRIVATE_LINK_LIBRARIES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpTilingShared 函数说明
KERNEL_SOURCES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpKernelStatic 函数说明
KERNEL_TILING_DATA_DEF_H : 透传参数, 详情参见 OpsTest_Level1_AddOpKernelStatic 函数说明
KERNEL_PRIVATE_INCLUDES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpKernelStatic 函数说明
KERNEL_PRIVATE_COMPILE_DEFINITIONS_EXT : 透传参数, 详情参见 OpsTest_Level1_AddOpKernelStatic 函数说明
UTEST_COMMON_SOURCES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestCommonStatic 函数说明
UTEST_COMMON_SOURCES_EXT_FORCE : 透传参数, 详情参见 OpsTest_Level1_AddUTestCommonStatic 函数说明
UTEST_COMMON_PUBLIC_INCLUDES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestCommonStatic 函数说明
UTEST_COMMON_PRIVATE_INCLUDES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestCommonStatic 函数说明
UTEST_COMMON_PRIVATE_COMPILE_DEFINITIONS : 透传参数, 详情参见 OpsTest_Level1_AddUTestCommonStatic 函数说明
UTEST_COMMON_PRIVATE_LINK_LIBRARIES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestCommonStatic 函数说明
UTEST_SOURCES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestCaseStatic 函数说明
UTEST_SOURCES_EXT_FORCE : 透传参数, 详情参见 OpsTest_Level1_AddUTestCaseStatic 函数说明
UTEST_PRIVATE_INCLUDES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestCaseStatic 函数说明
UTEST_PRIVATE_COMPILE_DEFINITIONS : 透传参数, 详情参见 OpsTest_Level1_AddUTestCaseStatic 函数说明
UTEST_PRIVATE_LINK_LIBRARIES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestCaseStatic 函数说明
UTEST_ACLNN_SOURCES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestAclnnCaseStatic 函数说明
UTEST_ACLNN_SOURCES_EXT_FORCE : 透传参数, 详情参见 OpsTest_Level1_AddUTestAclnnCaseStatic 函数说明
UTEST_ACLNN_PRIVATE_INCLUDES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestAclnnCaseStatic 函数说明
UTEST_ACLNN_PRIVATE_COMPILE_DEFINITIONS : 透传参数, 详情参见 OpsTest_Level1_AddUTestAclnnCaseStatic 函数说明
UTEST_ACLNN_PRIVATE_LINK_LIBRARIES_EXT : 透传参数, 详情参见 OpsTest_Level1_AddUTestAclnnCaseStatic 函数说明
]]
function(OpsTest_Level2_AddOp)
cmake_parse_arguments(
TMP
""
"SUB_SYSTEM;BRIEF;SNAKE;TILING_DATA_DEF_BRIEF"
"OPAPI_SOURCES_EXT;OPAPI_PRIVATE_INCLUDES_EXT;OPAPI_PRIVATE_LINK_LIBRARIES_EXT;PROTO_SOURCES_EXT;PROTO_PRIVATE_INCLUDES_EXT;PROTO_PRIVATE_LINK_LIBRARIES_EXT;TILING_SOURCES_EXT;TILING_PRIVATE_INCLUDES_EXT;TILING_PRIVATE_LINK_LIBRARIES_EXT;KERNEL_SOURCES_EXT;KERNEL_TILING_DATA_DEF_H;KERNEL_PRIVATE_INCLUDES_EXT;KERNEL_PRIVATE_COMPILE_DEFINITIONS_EXT;UTEST_COMMON_SOURCES_EXT;UTEST_COMMON_SOURCES_EXT_FORCE;UTEST_COMMON_PUBLIC_INCLUDES_EXT;UTEST_COMMON_PRIVATE_INCLUDES_EXT;UTEST_COMMON_PRIVATE_COMPILE_DEFINITIONS;UTEST_COMMON_PRIVATE_LINK_LIBRARIES_EXT;UTEST_SOURCES_EXT;UTEST_SOURCES_EXT_FORCE;UTEST_PRIVATE_INCLUDES_EXT;UTEST_PRIVATE_COMPILE_DEFINITIONS;UTEST_PRIVATE_LINK_LIBRARIES_EXT;UTEST_ACLNN_SOURCES_EXT;UTEST_ACLNN_SOURCES_EXT_FORCE;UTEST_ACLNN_PRIVATE_INCLUDES_EXT;UTEST_ACLNN_PRIVATE_COMPILE_DEFINITIONS;UTEST_ACLNN_PRIVATE_LINK_LIBRARIES_EXT"
""
${ARGN}
)
OpsTest_Level1_AddOpApiShared(
SUB_SYSTEM ${TMP_SUB_SYSTEM}
BRIEF ${TMP_BRIEF}
SNAKE ${TMP_SNAKE}
SOURCES_EXT ${TMP_OPAPI_SOURCES_EXT}
PRIVATE_INCLUDES_EXT ${TMP_OPAPI_PRIVATE_INCLUDES_EXT}
PRIVATE_LINK_LIBRARIES_EXT ${TMP_OPAPI_PRIVATE_LINK_LIBRARIES_EXT}
)
OpsTest_Level1_AddOpProtoShared(
SUB_SYSTEM ${TMP_SUB_SYSTEM}
BRIEF ${TMP_BRIEF}
SNAKE ${TMP_SNAKE}
SOURCES_EXT ${TMP_PROTO_SOURCES_EXT}
PRIVATE_INCLUDES_EXT ${TMP_PROTO_PRIVATE_INCLUDES_EXT}
PRIVATE_LINK_LIBRARIES_EXT ${TMP_PROTO_PRIVATE_LINK_LIBRARIES_EXT}
)
OpsTest_Level1_AddOpTilingShared(
SUB_SYSTEM ${TMP_SUB_SYSTEM}
BRIEF ${TMP_BRIEF}
SNAKE ${TMP_SNAKE}
SOURCES_EXT ${TMP_TILING_SOURCES_EXT}
PRIVATE_INCLUDES_EXT ${TMP_TILING_PRIVATE_INCLUDES_EXT}
PRIVATE_LINK_LIBRARIES_EXT ${TMP_TILING_PRIVATE_LINK_LIBRARIES_EXT}
)
OpsTest_Level1_AddOpKernelStatic(
SUB_SYSTEM ${TMP_SUB_SYSTEM}
BRIEF ${TMP_BRIEF}
SNAKE ${TMP_SNAKE}
SOURCES_EXT ${TMP_KERNEL_SOURCES_EXT}
TILING_DATA_DEF_H ${TMP_KERNEL_TILING_DATA_DEF_H}
PRIVATE_INCLUDES_EXT ${TMP_KERNEL_PRIVATE_INCLUDES_EXT}
PRIVATE_COMPILE_DEFINITIONS_EXT ${TMP_KERNEL_PRIVATE_COMPILE_DEFINITIONS_EXT}
)
OpsTest_Level1_AddUTestCommonStatic(
BRIEF ${TMP_BRIEF}
SNAKE ${TMP_SNAKE}
SOURCES_EXT ${TMP_UTEST_COMMON_SOURCES_EXT}
SOURCES_EXT_FORCE ${TMP_UTEST_COMMON_SOURCES_EXT_FORCE}
TILING_DATA_DEF_BRIEF ${TMP_TILING_DATA_DEF_BRIEF}
PUBLIC_INCLUDES_EXT ${TMP_UTEST_COMMON_PUBLIC_INCLUDES_EXT}
PRIVATE_INCLUDES_EXT ${TMP_UTEST_COMMON_PRIVATE_INCLUDES_EXT}
PRIVATE_COMPILE_DEFINITIONS ${TMP_UTEST_COMMON_PRIVATE_COMPILE_DEFINITIONS}
PRIVATE_LINK_LIBRARIES_EXT ${TMP_UTEST_COMMON_PRIVATE_LINK_LIBRARIES_EXT}
)
OpsTest_Level1_AddUTestCaseStatic(
BRIEF ${TMP_BRIEF}
SNAKE ${TMP_SNAKE}
TILING_DATA_DEF_BRIEF ${TMP_TILING_DATA_DEF_BRIEF}
SOURCES_EXT ${TMP_UTEST_SOURCES_EXT}
SOURCES_EXT_FORCE ${TMP_UTEST_SOURCES_EXT_FORCE}
PRIVATE_INCLUDES_EXT ${TMP_UTEST_PRIVATE_INCLUDES_EXT}
PRIVATE_COMPILE_DEFINITIONS ${TMP_UTEST_PRIVATE_COMPILE_DEFINITIONS}
PRIVATE_LINK_LIBRARIES_EXT ${TMP_UTEST_PRIVATE_LINK_LIBRARIES_EXT}
)
OpsTest_Level1_AddUTestAclnnCaseStatic(
BRIEF ${TMP_BRIEF}
SNAKE ${TMP_SNAKE}
TILING_DATA_DEF_BRIEF ${TMP_TILING_DATA_DEF_BRIEF}
SOURCES_EXT ${TMP_UTEST_ACLNN_SOURCES_EXT}
SOURCES_EXT_FORCE ${TMP_UTEST_ACLNN_SOURCES_EXT_FORCE}
PRIVATE_INCLUDES_EXT ${TMP_UTEST_ACLNN_PRIVATE_INCLUDES_EXT}
PRIVATE_COMPILE_DEFINITIONS ${TMP_UTEST_ACLNN_PRIVATE_COMPILE_DEFINITIONS}
PRIVATE_LINK_LIBRARIES_EXT ${TMP_UTEST_ACLNN_PRIVATE_LINK_LIBRARIES_EXT}
)
endfunction()
function(op_add_ut_subdirectory OP_UT_LIST OP_UT_DIR_LIST)
set(_OP_UT_LIST)
set(_OP_UT_DIR_LIST)
file(GLOB OP_HOST_CMAKE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/**/**/tests/CMakeLists.txt")
foreach(OP_CMAKE_FILE ${OP_HOST_CMAKE_FILES})
if ("${OP_CMAKE_FILE}" MATCHES "tests")
get_filename_component(OP_HOST_DIR "${OP_CMAKE_FILE}" DIRECTORY)
get_filename_component(OP_DIR "${OP_HOST_DIR}" DIRECTORY)
else()
get_filename_component(OP_DIR "${OP_CMAKE_FILE}" DIRECTORY)
endif()
get_filename_component(OP_NAME "${OP_DIR}" NAME)
if (DEFINED ASCEND_OP_NAME AND NOT "${ASCEND_OP_NAME}" STREQUAL "")
if (NOT "${ASCEND_OP_NAME}" STREQUAL "all" AND NOT "${ASCEND_OP_NAME}" STREQUAL "ALL")
if (NOT ${OP_NAME} IN_LIST ASCEND_OP_NAME)
continue()
endif ()
endif ()
endif ()
list(APPEND _OP_UT_LIST ${OP_NAME})
list(APPEND _OP_UT_DIR_LIST ${OP_DIR})
endforeach()
list(REMOVE_DUPLICATES _OP_UT_LIST)
list(REMOVE_DUPLICATES _OP_UT_DIR_LIST)
list(SORT _OP_UT_LIST)
list(SORT _OP_UT_DIR_LIST)
set(${OP_UT_LIST} ${_OP_UT_LIST} PARENT_SCOPE)
set(${OP_UT_DIR_LIST} ${_OP_UT_DIR_LIST} PARENT_SCOPE)
endfunction()
# 私有函数, 外部不可直接调用, 用于执行包含多个算子的 UT 可执行程序
#[[
]]
function(OpsTest_RunLaunch)
cmake_parse_arguments(
TMP
""
"TARGET;EXECUTABLE"
""
""
${ARGN}
)
if (ENABLE_UT_EXEC)
set(LD_LIBRARY_PATH_ "LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}:${ASCEND_CANN_PACKAGE_PATH}/compiler/lib64:${ASCEND_CANN_PACKAGE_PATH}/toolkit/tools/simulator/Ascend910B1/lib")
if (ENABLE_ASAN OR ENABLE_UBSAN)
if (ENABLE_ASAN)
# 谨慎修改 ASAN_OPTIONS_ 取值, 当前出现告警会使 UT 失败.
# halt_on_error=1, 出现告警时停止运行进而触发构建失败, 避免主进程或 CPU孪生调试 fork 出的子进程出现错误无法发现的情况
# detect_stack_use_after_return=1, 栈空间返回后使用检测
# check_initialization_order, 尝试捕获初始化顺序问题
# strict_init_order, 动态初始化器永远不能访问来自其他模块的全局变量, 及时或者已经初始化
# strict_string_checks, 检查字符串参数是否正确以 null 终止
# detect_leaks=1, 内存泄漏检测
set(ASAN_OPTIONS_ "ASAN_OPTIONS=halt_on_error=1,detect_stack_use_after_return=1,check_initialization_order=1,strict_init_order=1,strict_string_checks=1,detect_leaks=1")
message(STATUS "${TMP_EXECUTABLE}: ${ASAN_OPTIONS_}")
endif ()
if (ENABLE_UBSAN)
# 谨慎修改 UBSAN_OPTIONS_ 取值, 当前出现告警会使 UT 失败.
# halt_on_error=1, 出现告警时停止运行进而触发构建失败, 避免主进程或 CPU孪生调试 fork 出的子进程出现错误无法发现的情况
# print_stacktrace=1, 出错时打印调用栈
set(UBSAN_OPTIONS_ "UBSAN_OPTIONS=halt_on_error=1,print_stacktrace=1")
message(STATUS "${TMP_EXECUTABLE}: ${UBSAN_OPTIONS_}")
endif ()
# 用例执行
# 采用链接 ASAN/MSAN 动态库方式执行, 受 SAN 机制限制, 若采用静态库, 则会导致如 OpTiling/OpProto 内 SAN 功能失效.
if (NOT "${SAN_LD_PRELOAD}" STREQUAL "")
message(STATUS "${SAN_LD_PRELOAD}")
endif ()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_custom_command(
TARGET ${TMP_TARGET} POST_BUILD
COMMAND export ${LD_LIBRARY_PATH_} && ulimit -s 32768 && ${ASAN_OPTIONS_} ${UBSAN_OPTIONS_} ./${TMP_EXECUTABLE}
COMMENT "Run ${TMP_EXECUTABLE} with Sanitizer, ASAN(${ENABLE_ASAN}), UBSAN(${ENABLE_UBSAN})"
)
else ()
add_custom_command(
TARGET ${TMP_TARGET} POST_BUILD
COMMAND export ${LD_LIBRARY_PATH_} && export ${SAN_LD_PRELOAD} && ulimit -s 32768 && ${ASAN_OPTIONS_} ${UBSAN_OPTIONS_} ./${TMP_EXECUTABLE}
COMMENT "Run ${TMP_EXECUTABLE} with Sanitizer, ASAN(${ENABLE_ASAN}), UBSAN(${ENABLE_UBSAN})"
)
endif ()
else()
# 用例执行
add_custom_command(
TARGET ${TMP_TARGET} POST_BUILD
COMMAND export ${LD_LIBRARY_PATH_} && ./${TMP_EXECUTABLE}
COMMENT "Run ${TMP_EXECUTABLE}"
)
endif ()
endif ()
endfunction()
# 生成覆盖率
#[[
调用参数:
one_value_keywords:
TARGET : 必选参数, 用于指定覆盖率生成所依赖的目标(POST_BUILD)
multi_value_keywords:
FILTER_DIRECTORIES : 可选参数, 用于指定覆盖率结果过滤目录
]]
function(OpsTest_GenerateCoverage)
cmake_parse_arguments(
TMP
""
"TARGET"
"FILTER_DIRECTORIES"
""
${ARGN}
)
if (ENABLE_UT_EXEC)
if (ENABLE_GCOV)
find_program(LCOV lcov REQUIRED)
get_filename_component(GEN_COV_PY ${OPS_ADV_CMAKE_DIR}/scripts/utest/gen_coverage.py REALPATH)
get_filename_component(ASCEND_CANN_PACKAGE_PATH_PARENT "${ASCEND_CANN_PACKAGE_PATH}/../" REALPATH)
get_filename_component(GEM_COV_DATA_DIR "${CMAKE_CURRENT_BINARY_DIR}" REALPATH)
# 获取 gcc 默认头文件搜索路径
execute_process(
COMMAND ${CMAKE_C_COMPILER} --print-sysroot-headers-suffix
RESULT_VARIABLE _RST
OUTPUT_VARIABLE _SUFFIX
ERROR_QUIET
)
if (_RST)
get_filename_component(SYS_ROOT "/usr/include" REALPATH)
else ()
get_filename_component(SYS_ROOT "${_SUFFIX}/usr/include" REALPATH)
endif ()
list(REMOVE_DUPLICATES _FilterCmds)
add_custom_command(
TARGET ${TMP_TARGET} POST_BUILD
COMMAND ${HI_PYTHON} ${GEN_COV_PY}
"-s=${OPS_ADV_DIR}"
"-c=${GEM_COV_DATA_DIR}"
"-f=/tmp/*"
"-f=/usr/include/*"
"-f=${ASCEND_CANN_PACKAGE_PATH_PARENT}/*"
"-y=${OPS_ADV_DIR}/tests/test_config.yaml"
COMMENT "Generate coverage for ${TMP_TARGET}"
)
endif ()
endif ()
endfunction()
# 生成包含多个算子的 UT 可执行程序
#[[
]]
function(OpsTest_AddLaunch)
add_custom_target(ops_test_utest)
if (NOT _OpsTestUt_UTestCaseLibraries AND NOT _OpsTestUt_UTestAclnnCaseLibraries)
# 当 _OpsTestUt_UTestCaseLibraries 与 _OpsTestUt_UTestAclnnCaseLibraries 都为空时
# 说明区分领域的 TESTS_UT_OPS_TEST 选项被错误设置, 需排查对应触发 ut 的 python 脚本逻辑及 build.sh.
message(STATUS "_OpsTestUt_UTestCaseLibraries = ${_OpsTestUt_UTestCaseLibraries}.")
message(STATUS "_OpsTestUt_UTestAclnnCaseLibraries = ${_OpsTestUt_UTestAclnnCaseLibraries}")
message(STATUS "_OpsTestUt_UTestCaseLibraries and _OpsTestUt_UTestAclnnCaseLibraries both empty.")
return ()
endif ()
set(_UTest_OpApiLibrary)
set(_UTest_OpProtoLibrary)
set(_UTest_OpTilingLibrary)
set(_UTest_Main) # UTest 用例可执行程序(常规)
set(_UTest_Main_Aclnn) # UTest 用例可执行程序(Aclnn)
set(_Utest_ExecutableList) # 为提高PR场景执行效率, PR场景各可执行文件并行执行, 否则串行执行
# OpApi 动态库(可选)
OpsTest_AddOpApiShared()
# OpProto 动态库(可选)
OpsTest_AddOpProtoShared()
# OpTiling 动态库(必选)
OpsTest_AddOpTilingShared()
# UTest 用例可执行程序(常规)
if (_OpsTestUt_UTestCaseLibraries)
# 支持按算子分离可执行文件, 便于彼此冲突的 Kernel 侧编译宏设置
foreach (_OpsTestUt_UTestCaseLibrary ${_OpsTestUt_UTestCaseLibraries})
# 获取算子工程名
string(REPLACE "_UTest_Case" "" _OpBrief ${_OpsTestUt_UTestCaseLibrary})
string(REPLACE "UTest_" "" _OpBrief ${_OpBrief})
set(_UTest_Main ${UTest_NamePrefix}_Main_Normal_${_OpBrief})
add_executable(${_UTest_Main})
target_sources(${_UTest_Main} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests/ut/framework_special/main.cpp)
target_compile_options(${_UTest_Main} PRIVATE -fPIC)
target_link_libraries(${_UTest_Main}
PRIVATE
-Wl,--no-as-needed
-Wl,--whole-archive
$<BUILD_INTERFACE:intf_pub_utest>
gtest
$<BUILD_INTERFACE:_OpsTestUt_GTest_Wno>
${_OpsTestUt_UTestCaseLibrary}
${UTest_NamePrefix}_Stubs
${UTest_NamePrefix}_Utils
${_UTest_OpApiLibrary} # 若算子在 UTest_{Op}_Common 内实现 Aclnn 相关执行逻辑, 则需要连接
-Wl,--as-needed
-Wl,--no-whole-archive
c_sec
)
add_dependencies(${_UTest_Main} ${_UTest_OpTilingLibrary})
add_dependencies(ops_test_utest ${_UTest_Main})
if (TESTS_UT_OPS_TEST_CI_PR)
OpsTest_RunLaunch(TARGET ${_UTest_Main} EXECUTABLE ${_UTest_Main})
else ()
list(APPEND _Utest_ExecutableList ${_UTest_Main})
endif ()
endforeach ()
endif ()
# UTest 用例可执行程序(Aclnn)
set(_param
"--cann_path=${ASCEND_CANN_PACKAGE_PATH}"
"--cann_package_name=opp"
"get_package_version"
)
if (_OpsTestUt_UTestAclnnCaseLibraries)
# 支持按算子分离可执行文件, 便于彼此冲突的 Kernel 侧编译宏设置
foreach (_OpsTestUt_UTestAclnnCaseLibrary ${_OpsTestUt_UTestAclnnCaseLibraries})
# 获取算子工程名
string(REPLACE "_UTest_Case_Aclnn" "" _OpBrief ${_OpsTestUt_UTestAclnnCaseLibrary})
string(REPLACE "UTest_" "" _OpBrief ${_OpBrief})
set(_UTest_Main_Aclnn ${UTest_NamePrefix}_Main_Aclnn_${_OpBrief})
add_executable(${_UTest_Main_Aclnn})
target_sources(${_UTest_Main_Aclnn} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests/ut/framework_special/main_aclnn.cpp)
target_compile_options(${_UTest_Main_Aclnn} PRIVATE -fPIC)
target_link_libraries(${_UTest_Main_Aclnn}
PRIVATE
-Wl,--no-as-needed
-Wl,--whole-archive
$<BUILD_INTERFACE:intf_pub_utest>
gtest
$<BUILD_INTERFACE:_OpsTestUt_GTest_Wno>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:alog_headers>>
$<$<BOOL:${BUILD_OPEN_PROJECT}>:$<BUILD_INTERFACE:dlog_headers>>
${_OpsTestUt_UTestAclnnCaseLibrary}
${UTest_NamePrefix}_Stubs
${UTest_NamePrefix}_Utils
${_UTest_OpApiLibrary}
-Wl,--as-needed
-Wl,--no-whole-archive
c_sec
)
add_dependencies(${_UTest_Main_Aclnn} ${_UTest_OpProtoLibrary} ${_UTest_OpTilingLibrary})
add_dependencies(ops_test_utest ${_UTest_Main_Aclnn})
if (TESTS_UT_OPS_TEST_CI_PR)
OpsTest_RunLaunch(TARGET ${_UTest_Main_Aclnn} EXECUTABLE ${_UTest_Main_Aclnn})
else ()
list(APPEND _Utest_ExecutableList ${_UTest_Main_Aclnn})
endif ()
endforeach ()
endif ()
# 为提高PR场景执行效率, PR场景各可执行文件并行执行, 否则串行执行
if (NOT TESTS_UT_OPS_TEST_CI_PR)
foreach (_Exe ${_Utest_ExecutableList})
OpsTest_RunLaunch(TARGET ops_test_utest EXECUTABLE ${_Exe})
endforeach ()
endif ()
# 生成覆盖率
set(_FilterDirectories)
list(REMOVE_DUPLICATES _FilterDirectories)
OpsTest_GenerateCoverage(TARGET ops_test_utest FILTER_DIRECTORIES ${_FilterDirectories})
endfunction()
# 添加算子UT路径
#[[
]]
function(OpsTestUt_AddSubdirectory)
cmake_parse_arguments(
TMP
""
""
"CLANG_NOT_SUPPORTED_OP_LIST"
""
${ARGN}
)
if ("${TESTS_UT_OPS_TEST}" STREQUAL "")
return()
elseif ("ALL" IN_LIST TESTS_UT_OPS_TEST OR "all" IN_LIST TESTS_UT_OPS_TEST)
file(GLOB sub_dirs ${CMAKE_CURRENT_SOURCE_DIR}/*)
foreach (_dir ${sub_dirs})
if (IS_DIRECTORY ${_dir})
get_filename_component(_op_type ${_dir} NAME)
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" AND "${_op_type}" IN_LIST TMP_CLANG_NOT_SUPPORTED_OP_LIST)
message(STATUS "The UTest of ${_op_type} don't supported clang compiler yet.")
continue()
endif ()
add_subdirectory(${_dir})
endif ()
endforeach ()
else ()
set(_added_op_type_list)
foreach (_op_type ${TESTS_UT_OPS_TEST})
if (DEFINED ${_op_type}_alias)
set(_op_type ${${_op_type}_alias})
endif ()
if (NOT "${_op_type}" IN_LIST _added_op_type_list)
set(_dir ${CMAKE_CURRENT_SOURCE_DIR}/${_op_type})
if (IS_DIRECTORY ${_dir})
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" AND "${_op_type}" IN_LIST TMP_CLANG_NOT_SUPPORTED_OP_LIST)
message(STATUS "The UTest of ${_op_type} don't supported clang compiler yet.")
continue()
endif ()
add_subdirectory(${_dir})
list(APPEND _added_op_type_list ${_op_type})
endif ()
endif ()
endforeach ()
endif ()
endfunction()