#!/bin/bash
set -euo pipefail
SCRIPT_DIR=$(cd "$(dirname "$0")/../.." && pwd)
PROJECT_ROOT="${SCRIPT_DIR}"
PR_FILELIST="${PROJECT_ROOT}/.local_check_filelist.txt"
DEFAULT_SOC="ascend910b"
DEFAULT_JOBS=16
SOC=""
JOBS=${DEFAULT_JOBS}
CANN_3RD_LIB_PATH="${PROJECT_ROOT}/third_party"
ASCEND_3RD_LIB_PATH="${CANN_3RD_LIB_PATH}"
SKIP_BUILD=false
SKIP_LLT=false
SKIP_CANNSIM=false
OPS=""
LLT_A900_MODE=false
LLT_ST_MODE=false
LLT_EXP_UT_MODE=false
LLT_KERNEL_UT_MODE=false
LLT_STD_UT_MODE=false
CANNSIM_MODE=false
FILE_LIST=""
JIT_MODE=false
EXPERIMENTAL_MODE=false
SINGLE_MODE=false
A5_MODE=false
NORMAL_MODE=false
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
NC='\033[0m'
print_header() {
echo ""
echo -e "${CYAN}================================================================${NC}"
echo -e "${CYAN} $1${NC}"
echo -e "${CYAN}================================================================${NC}"
echo ""
}
print_step() {
echo ""
echo -e "${CYAN}>>> [$1] $2${NC}"
echo ""
}
print_ok() {
echo -e " ${GREEN}[PASS]${NC} $1"
}
print_warn() {
echo -e " ${YELLOW}[SKIP]${NC} $1"
}
print_fail() {
echo -e " ${RED}[FAIL]${NC} $1"
}
print_info() {
echo -e " ${CYAN}[INFO]${NC} $1"
}
soc_to_chip_short() {
local soc="$1"
case "${soc}" in
ascend910b) echo "910b" ;;
ascend910_93) echo "910_93" ;;
ascend950) echo "950" ;;
ascend310p) echo "310p" ;;
ascend310b) echo "310b" ;;
ascend910) echo "910" ;;
*) echo "${soc#ascend}" ;;
esac
}
op_supports_soc() {
local op="$1"
local soc="$2"
local is_experimental="${3:-false}"
local prefixes=("math" "conversion" "random")
if [[ "$is_experimental" == "true" ]]; then
prefixes=("experimental/math" "experimental/conversion" "experimental/random")
fi
for prefix in "${prefixes[@]}"; do
local def_dir="${PROJECT_ROOT}/${prefix}/${op}/op_host"
[[ -d "${def_dir}" ]] || continue
for def_file in "${def_dir}"/*_def.cpp; do
[[ -f "${def_file}" ]] || continue
grep -q "AddConfig(\"${soc}\"" "${def_file}" && return 0
done
done
return 1
}
filter_ops_by_soc() {
local ops="$1"
local soc="$2"
local is_experimental="${3:-false}"
local ops_arr=(${ops//,/ })
local filtered=()
for op in "${ops_arr[@]}"; do
if op_supports_soc "$op" "$soc" "$is_experimental"; then
filtered+=("${op}")
else
print_info "On [${soc}], [${op}] not supported, skipping" >&2
fi
done
local result="${filtered[*]}"
echo "${result// /,}"
}
make_filtered_pr_file() {
local pr_file="$1"
local filtered_ops="$2"
local out_file="$3"
> "${out_file}"
local ops_arr=(${filtered_ops//,/ })
while IFS= read -r line; do
line=$(echo "$line" | xargs)
[[ -z "$line" ]] && continue
for op in "${ops_arr[@]}"; do
if [[ "$line" == *"/$op/"* ]]; then
echo "$line" >> "${out_file}"
break
fi
done
done < "${pr_file}"
}
usage() {
cat <<EOF
Usage: bash local_check.sh [options]
Local verification script for ops-math development.
Fully covers compile.sh and LLT Flow functionality.
Change Detection Options:
-f <file> Specify file list (default: auto-detect from git diff)
Build Mode Options (single task, default runs all):
--jit JIT compilation only (compile.sh monitor/else mode)
--experimental Experimental compilation only (compile.sh experimentalX)
--single Single operator packaging only (compile.sh singleX, check_pkg.sh)
--a5 A5/ascend950 arch35 only (compile.sh A5X, compile_a5_pkg.sh)
--normal Normal compilation only (bash build.sh --pkg --soc, monitor package)
LLT/Cannsim Mode Options (single task, default runs all):
--llt-a900 PreSmoke_A900 only (Upper + Lower)
--llt-st PreSmoke_St only
--llt-exp-ut Experimental UT only
--llt-kernel-ut Kernel UT only
--llt-std-ut Standard UT only
--cannsim Cannsim tests only
Note: single-task mode auto-skips other main flows (compile/LLT/cannsim);
combining params from different flows is not allowed
Build Parameters:
--soc=<soc_version> Target SoC
Supported: ascend910b ascend910_93 ascend950 ascend310p
ascend910 ascend310b
-j <num> Parallel jobs (default: 16)
--cann_3rd_lib_path=<path> CANN third party lib path
Skip Options:
--skip-build Skip compile flow
--skip-llt Skip LLT flow (PreSmoke_A900 + PreSmoke_St + UT)
--skip-cannsim Skip cannsim tests
Other Options:
-h, --help Show this help message
Check Items (Main Flows):
1. Environment check - Verify CANN toolkit, compilers, Python
2. Compile Flow - Default: all modes (normal/jit/experimental/single/a5)
- Single task: specify --jit/--experimental/--single/--a5/--normal
- Normal mode produces: cann-{chip}-ops-math_{ver}_linux-{arch}.run
- Normal mode also verifies: install/uninstall of the package
3. LLT Flow - PreSmoke_A900 + PreSmoke_St + UT tests
- Default: all tasks (a900/st/exp-ut/kernel-ut/std-ut)
- Single task: specify --llt-a900/--llt-st/--llt-exp-ut/--llt-kernel-ut/--llt-std-ut
- PreSmoke_A900 Upper: single.tar.gz + check_example.sh
- PreSmoke_A900 Lower: experimental package + --run_example
- PreSmoke_St: ops_st_test.sh (install built-in package first)
- UT: Experimental UT + Kernel UT + Standard UT (all by default)
4. Cannsim Tests - Cannsim simulation (requires ascend950, extra feature)
- Single task: specify --cannsim
Output:
All logs saved to: logs/
Build artifacts preserved: artifacts/ (normal/jit/experimental/single/a5)
Build temp preserved: build/, build_out/
Examples:
bash local_check.sh -f pr_filelist.txt # default: run all tasks
bash local_check.sh --jit -f pr_filelist.txt # run only JIT compilation
bash local_check.sh --experimental # run only experimental compilation
bash local_check.sh --single -f pr_filelist.txt # run only single package build
bash local_check.sh --a5 # run only A5 compilation
bash local_check.sh --normal # run only normal compilation
bash local_check.sh --llt-a900 # run only PreSmoke_A900
bash local_check.sh --llt-st # run only PreSmoke_St
bash local_check.sh --llt-exp-ut # run only Experimental UT
bash local_check.sh --llt-kernel-ut # run only Kernel UT
bash local_check.sh --llt-std-ut # run only Standard UT
bash local_check.sh --cannsim # run only cannsim tests
EOF
}
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
-f)
if [[ -z "$2" ]]; then
echo "[ERROR] -f requires a file argument"
exit 1
fi
FILE_LIST="$2"
shift 2
;;
--jit)
JIT_MODE=true
shift
;;
--experimental)
EXPERIMENTAL_MODE=true
shift
;;
--single)
SINGLE_MODE=true
shift
;;
--a5)
A5_MODE=true
shift
;;
--normal)
NORMAL_MODE=true
shift
;;
--soc=*)
SOC="${1#*=}"
shift
;;
-j*)
if [[ "${1}" == "-j" ]]; then
JOBS="$2"
shift 2
else
JOBS="${1#-j}"
shift
fi
;;
--cann_3rd_lib_path=*)
CANN_3RD_LIB_PATH="${1#*=}"
shift
;;
--skip-build)
SKIP_BUILD=true
shift
;;
--skip-llt)
SKIP_LLT=true
shift
;;
--skip-cannsim)
SKIP_CANNSIM=true
shift
;;
--llt-a900)
LLT_A900_MODE=true
shift
;;
--llt-st)
LLT_ST_MODE=true
shift
;;
--llt-exp-ut)
LLT_EXP_UT_MODE=true
shift
;;
--llt-kernel-ut)
LLT_KERNEL_UT_MODE=true
shift
;;
--llt-std-ut)
LLT_STD_UT_MODE=true
shift
;;
--cannsim)
CANNSIM_MODE=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "[ERROR] Unknown option: $1"
usage
exit 1
;;
esac
done
}
detect_changed_ops() {
print_step "1.1" "Detecting changed files"
if [[ -n "${FILE_LIST}" ]]; then
print_info "Using specified file list: ${FILE_LIST}"
if [[ ! -f "${FILE_LIST}" ]]; then
print_fail "File list not found: ${FILE_LIST}"
return 1
fi
cp "${FILE_LIST}" "${PR_FILELIST}"
print_ok "Loaded $(wc -l < "${PR_FILELIST}") files"
else
local base_ref="master"
{
git -C "${PROJECT_ROOT}" diff --name-only "${base_ref}...HEAD" 2>/dev/null || true
git -C "${PROJECT_ROOT}" diff --name-only "HEAD~1...HEAD" 2>/dev/null || true
git -C "${PROJECT_ROOT}" diff --cached --name-only 2>/dev/null || true
git -C "${PROJECT_ROOT}" diff --name-only HEAD 2>/dev/null || true
} | grep -v '^$' | sort -u > "${PR_FILELIST}"
if [[ ! -s "${PR_FILELIST}" ]]; then
print_warn "No changed files detected (committed, staged, or working)"
print_info "Use -f/--file-list to manually specify which files to verify"
return 1
fi
print_ok "Detected $(wc -l < "${PR_FILELIST}") changed files (committed + staged + working)"
fi
print_step "1.2" "Parsing affected operators"
local normal_ops=""
local exp_ops=""
local merged_ops=""
normal_ops=$(python3 "${PROJECT_ROOT}/scripts/ci/gen_ci_cmd.py" \
-f "${PR_FILELIST}" --list_ops --experimental=FALSE) || {
print_fail "gen_ci_cmd.py (normal) failed"
return 1
}
exp_ops=$(python3 "${PROJECT_ROOT}/scripts/ci/gen_ci_cmd.py" \
-f "${PR_FILELIST}" --list_ops --experimental=TRUE) || {
print_fail "gen_ci_cmd.py (experimental) failed"
return 1
}
if [[ -n "${normal_ops}" && -n "${exp_ops}" ]]; then
merged_ops="${normal_ops},${exp_ops}"
elif [[ -n "${normal_ops}" ]]; then
merged_ops="${normal_ops}"
elif [[ -n "${exp_ops}" ]]; then
merged_ops="${exp_ops}"
fi
if [[ -z "${merged_ops}" ]]; then
print_warn "No affected operators detected from changed files"
print_info "Tasks requiring --ops will be skipped"
fi
OPS="${merged_ops}"
print_ok "Affected operators: ${OPS}"
return 0
}
check_environment() {
print_header "Step 1: Environment Check"
local env_ok=true
print_step "1.1" "Checking CANN toolkit"
if [[ -z "${ASCEND_HOME_PATH:-}" ]]; then
print_fail "ASCEND_HOME_PATH not set"
print_info "Please source CANN set_env.sh first, e.g.:"
print_info " source /usr/local/Ascend/cann/set_env.sh"
print_fail "Environment check failed"
return 1
fi
print_ok "ASCEND_HOME_PATH=${ASCEND_HOME_PATH}"
print_step "1.2" "Checking compilers"
command -v cmake &>/dev/null && print_ok "cmake: $(cmake --version | head -1)" || { print_fail "cmake not found"; env_ok=false; }
command -v g++ &>/dev/null && print_ok "g++: $(g++ --version | head -1)" || { print_fail "g++ not found"; env_ok=false; }
print_step "1.3" "Checking Python"
command -v python3 &>/dev/null && print_ok "python3: $(python3 --version)" || { print_fail "python3 not found"; env_ok=false; }
print_step "1.4" "Checking SoC"
if [[ -z "${SOC}" ]]; then
local chip_info=$(asys info -r=status 2>/dev/null || echo "")
if echo "${chip_info}" | grep -q "Ascend 950"; then
SOC="ascend950"
elif echo "${chip_info}" | grep -q "Ascend 910"; then
SOC="ascend910b"
else
SOC="${DEFAULT_SOC}"
print_info "No NPU device detected, using default: ${SOC}"
fi
fi
print_ok "Target SoC: ${SOC}"
[[ "${env_ok}" != "true" ]] && { print_fail "Environment check failed"; return 1; }
if [[ -n "${LD_LIBRARY_PATH:-}" ]]; then
local original_ld="${LD_LIBRARY_PATH}"
LD_LIBRARY_PATH=$(echo "${LD_LIBRARY_PATH}" | tr ':' '\n' | grep -v "opp/vendors/.*op_api/lib" | grep -v "^$" | tr '\n' ':' | sed 's/:$//')
export LD_LIBRARY_PATH
if [[ "${LD_LIBRARY_PATH}" != "${original_ld}" ]]; then
local removed_count=$(echo "${original_ld}" | tr ':' '\n' | grep "opp/vendors/.*op_api/lib" | wc -l)
print_info "Cleaned LD_LIBRARY_PATH: removed ${removed_count} vendor op_api/lib paths (prevents libcust_opapi.so naming conflict)"
fi
fi
print_ok "Environment check passed"
return 0
}
CHECK_NAMES=()
CHECK_RESULTS=()
SUB_TASK_NAMES=()
SUB_TASK_RESULTS=()
SUB_TASK_ARTIFACTS=()
SUB_TASK_LOGS=()
SUB_TASK_COMMANDS=()
record_sub_task() {
SUB_TASK_NAMES+=("$1")
SUB_TASK_RESULTS+=("$2")
SUB_TASK_ARTIFACTS+=("$3")
SUB_TASK_LOGS+=("$4")
SUB_TASK_COMMANDS+=("$5")
}
uninstall_vendor() {
local vendor="$1"
local log_file="$2"
print_info "Uninstalling ${vendor} vendor to restore environment..."
local uninstall_script="${ASCEND_HOME_PATH}/opp/vendors/${vendor}/scripts/uninstall.sh"
if [[ -f "${uninstall_script}" ]]; then
bash "${uninstall_script}" 2>&1 | tee "${log_file}" || print_warn "${vendor} vendor uninstall failed"
else
print_warn "Uninstall script not found: ${uninstall_script}"
fi
}
run_check() {
local name="$1"
local func="$2"
CHECK_NAMES+=("${name}")
print_info "Starting: ${name}"
set +e
${func}
local ret=$?
set -e
case ${ret} in
0) CHECK_RESULTS+=("PASS") ;;
2) CHECK_RESULTS+=("SKIP") ;;
*) CHECK_RESULTS+=("FAIL") ;;
esac
}
do_compile_flow() {
print_header "Step 2: Compile Flow"
if [[ "${SKIP_BUILD}" == "true" ]]; then
print_warn "Compile flow skipped (--skip-build)"
return 2
fi
local any_mode=false
[[ "${EXPERIMENTAL_MODE}" == "true" ]] && any_mode=true
[[ "${JIT_MODE}" == "true" ]] && any_mode=true
[[ "${SINGLE_MODE}" == "true" ]] && any_mode=true
[[ "${A5_MODE}" == "true" ]] && any_mode=true
[[ "${NORMAL_MODE}" == "true" ]] && any_mode=true
if [[ "${any_mode}" == "false" ]]; then
NORMAL_MODE=true
EXPERIMENTAL_MODE=true
SINGLE_MODE=true
JIT_MODE=true
A5_MODE=true
print_info "Auto mode: all compile tasks enabled (default)"
fi
local start_time=$(date +%s)
local compile_ret=0
local ARTIFACTS="${PROJECT_ROOT}/artifacts"
rm -rf "${ARTIFACTS}"
mkdir -p "${ARTIFACTS}/normal" "${ARTIFACTS}/jit" "${ARTIFACTS}/experimental" "${ARTIFACTS}/single" "${ARTIFACTS}/a5"
if [[ "${NORMAL_MODE}" == "true" ]]; then
print_step "2.1" "Normal compilation"
local cmd_array=(bash build.sh --pkg --soc="${SOC}" -j"${JOBS}")
[[ -n "${CANN_3RD_LIB_PATH}" ]] && cmd_array+=(--cann_3rd_lib_path="${CANN_3RD_LIB_PATH}")
print_info "Command: ${cmd_array[*]}"
if "${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/build_normal.txt"; then
print_ok "Normal compilation passed"
record_sub_task "Normal compilation" "PASS" "artifacts/normal/" "logs/build_normal.txt" ""
cp "${PROJECT_ROOT}"/build_out/cann-*-ops-math_*_linux-*.run "${ARTIFACTS}/normal/" 2>/dev/null || true
local normal_pkgs=("${ARTIFACTS}/normal/"cann-*-ops-math_*.run)
if [[ -f "${normal_pkgs[0]}" ]]; then
print_info "Starting: Package Verification (Normal)"
do_package_verify "${normal_pkgs[0]}"
local pkg_verify_ret=$?
case ${pkg_verify_ret} in
0) record_sub_task "Package Verification" "PASS" "" "logs/package_install.txt" "" ;;
2) record_sub_task "Package Verification" "SKIP" "" "" "" ;;
*) record_sub_task "Package Verification" "FAIL" "" "logs/package_install.txt" "${normal_pkgs[0]} --install --install-path=${PROJECT_ROOT}/tmp_verify" ;;
esac
else
print_warn "No normal package found for verification"
fi
else
print_fail "Normal compilation failed"
record_sub_task "Normal compilation" "FAIL" "artifacts/normal/" "logs/build_normal.txt" "${cmd_array[*]}"
compile_ret=1
fi
fi
if [[ "${JIT_MODE}" == "true" ]]; then
print_step "2.2" "JIT compilation"
local chip_short=$(soc_to_chip_short "${SOC}")
local cmd_array=(bash build.sh --pkg --jit --soc="${SOC}" -j"${JOBS}")
[[ -n "${CANN_3RD_LIB_PATH}" ]] && cmd_array+=(--cann_3rd_lib_path="${CANN_3RD_LIB_PATH}")
print_info "Command: ${cmd_array[*]}"
if "${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/build_jit.txt"; then
print_ok "JIT compilation passed"
local jit_src_pattern="cann-${chip_short}-ops-math_*_linux-*.run"
local jit_src_file="${PROJECT_ROOT}/build_out/${jit_src_pattern}"
if compgen -G "${jit_src_file}" > /dev/null; then
cp "${PROJECT_ROOT}"/build_out/${jit_src_pattern} "${ARTIFACTS}/jit/"
local jit_pkg=$(ls "${ARTIFACTS}/jit/${jit_src_pattern}" 2>/dev/null | head -1)
print_info "Copied package: $(basename "${jit_pkg}")"
else
print_warn "JIT package not found in build_out/ matching ${jit_src_pattern}"
fi
record_sub_task "JIT compilation" "PASS" "artifacts/jit/" "logs/build_jit.txt" ""
else
print_fail "JIT compilation failed"
record_sub_task "JIT compilation" "FAIL" "artifacts/jit/" "logs/build_jit.txt" "${cmd_array[*]}"
compile_ret=1
fi
fi
if [[ "${EXPERIMENTAL_MODE}" == "true" ]]; then
print_step "2.3" "Experimental compilation"
local ops_comma=$(filter_ops_by_soc "${OPS}" "${SOC}" "true")
if [[ -n "${OPS}" && -z "${ops_comma}" ]]; then
print_warn "No experimental operators support ${SOC}, skipping Experimental compilation"
record_sub_task "Experimental compilation" "SKIP" "artifacts/experimental/" "" ""
else
local cmd_array=(bash build.sh --experimental --pkg --soc="${SOC}" --vendor_name=experimental -j"${JOBS}")
[[ -n "${ops_comma}" ]] && cmd_array+=(--ops="${ops_comma}")
[[ -n "${CANN_3RD_LIB_PATH}" ]] && cmd_array+=(--cann_3rd_lib_path="${CANN_3RD_LIB_PATH}")
print_info "Command: ${cmd_array[*]}"
if "${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/build_experimental.txt"; then
print_ok "Experimental compilation passed"
record_sub_task "Experimental compilation" "PASS" "artifacts/experimental/" "logs/build_experimental.txt" ""
cp "${PROJECT_ROOT}"/build_out/cann-ops-math-experimental_linux-*.run "${ARTIFACTS}/experimental/" 2>/dev/null || true
else
print_fail "Experimental compilation failed"
record_sub_task "Experimental compilation" "FAIL" "artifacts/experimental/" "logs/build_experimental.txt" "${cmd_array[*]}"
compile_ret=1
fi
fi
fi
if [[ "${SINGLE_MODE}" == "true" ]]; then
print_step "2.4" "Single package build"
local cmd_array=(bash scripts/ci/check_pkg.sh "${PR_FILELIST}" --soc="${SOC}")
print_info "Command: ${cmd_array[*]}"
if "${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/build_single.txt"; then
print_ok "Single package build passed"
record_sub_task "Single package build" "PASS" "artifacts/single/" "logs/build_single.txt" ""
cp "${PROJECT_ROOT}"/single/cann-ops-math-*_linux*.run "${ARTIFACTS}/single/" 2>/dev/null || true
cp "${PROJECT_ROOT}"/single.tar.gz "${ARTIFACTS}/single/" 2>/dev/null || true
else
print_fail "Single package build failed"
record_sub_task "Single package build" "FAIL" "artifacts/single/" "logs/build_single.txt" "${cmd_array[*]}"
compile_ret=1
fi
fi
if [[ "${A5_MODE}" == "true" ]]; then
print_step "2.5" "A5 compilation"
local cmd_array=(bash scripts/ci/compile_a5_pkg.sh "${PR_FILELIST}")
if "${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/build_a5.txt"; then
print_ok "A5 compilation passed"
record_sub_task "A5 compilation" "PASS" "artifacts/a5/" "logs/build_a5.txt" ""
cp "${PROJECT_ROOT}"/build_out/cann-ops-math-*.run "${ARTIFACTS}/a5/" 2>/dev/null || true
else
print_fail "A5 compilation failed"
record_sub_task "A5 compilation" "FAIL" "artifacts/a5/" "logs/build_a5.txt" "${cmd_array[*]}"
compile_ret=1
fi
fi
local end_time=$(date +%s)
if [[ ${compile_ret} -eq 0 ]]; then
print_ok "Compile flow succeeded ($((end_time - start_time))s)"
print_info "All build artifacts preserved in: artifacts/ (normal/jit/experimental/single/a5)"
else
print_fail "Compile flow failed"
print_info "See logs/ for details"
return 1
fi
return 0
}
do_presmoke_a900() {
local task_ret=0
print_step "3.1" "PreSmoke_A900 Upper: single.tar.gz + check_example.sh"
local single_tgz="${PROJECT_ROOT}/artifacts/single/single.tar.gz"
if [[ ! -f "${single_tgz}" ]]; then
print_warn "single.tar.gz not found in artifacts/single/"
record_sub_task "PreSmoke_A900 Upper" "SKIP" "artifacts/single/single.tar.gz" "" ""
task_ret=2
else
print_info "Extracting single.tar.gz..."
if ! tar -zxf "${single_tgz}" -C "${PROJECT_ROOT}" 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_a900_upper.txt"; then
print_fail "Failed to extract single.tar.gz"
record_sub_task "PreSmoke_A900 Upper" "FAIL" "artifacts/single/single.tar.gz" "logs/presmoke_a900_upper.txt" "tar -zxf ${single_tgz}"
if [[ ${task_ret} -ne 1 ]]; then task_ret=1; fi
fi
local installed_vendors=()
for single_run in "${PROJECT_ROOT}"/single/cann-ops-math-*_linux-*.run; do
if [[ -f "${single_run}" ]]; then
local op_name=$(basename "${single_run}" | sed -E 's/cann-ops-math-(.+)_linux-.*/\1/')
installed_vendors+=("${op_name}_math")
fi
done
local filtered_ops=$(filter_ops_by_soc "${OPS}" "${SOC}" "false")
if [[ -n "${OPS}" && -z "${filtered_ops}" ]]; then
print_warn "Specified operators do not support ${SOC}, skipping PreSmoke_A900 Upper"
record_sub_task "PreSmoke_A900 Upper" "SKIP" "artifacts/single/single.tar.gz" "" "ops do not support ${SOC}"
if [[ ${task_ret} -ne 1 ]]; then task_ret=2; fi
elif [[ -z "${filtered_ops}" ]]; then
print_warn "No operators detected, skipping PreSmoke_A900 Upper"
record_sub_task "PreSmoke_A900 Upper" "SKIP" "artifacts/single/single.tar.gz" "" ""
if [[ ${task_ret} -ne 1 ]]; then task_ret=2; fi
else
local filtered_pr="${PROJECT_ROOT}/logs/filtered_a900_upper.txt"
make_filtered_pr_file "${PR_FILELIST}" "${filtered_ops}" "${filtered_pr}"
local cmd_array=(bash scripts/ci/check_example.sh "${filtered_pr}" --soc="${SOC}")
print_info "Command: ${cmd_array[*]}"
"${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_a900_upper.txt"
local ret=$?
if [[ ${ret} -eq 0 ]]; then
print_ok "PreSmoke_A900 Upper passed"
record_sub_task "PreSmoke_A900 Upper" "PASS" "artifacts/single/single.tar.gz" "logs/presmoke_a900_upper.txt" ""
else
print_fail "PreSmoke_A900 Upper failed"
record_sub_task "PreSmoke_A900 Upper" "FAIL" "artifacts/single/single.tar.gz" "logs/presmoke_a900_upper.txt" "${cmd_array[*]}"
task_ret=1
fi
fi
print_info "Uninstalling single package vendors to restore environment..."
for vendor in "${installed_vendors[@]}"; do
local uninstall_script="${ASCEND_HOME_PATH}/opp/vendors/${vendor}/scripts/uninstall.sh"
if [[ -f "${uninstall_script}" ]]; then
bash "${uninstall_script}" 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_a900_upper_uninstall_${vendor}.txt" || print_warn "Vendor ${vendor} uninstall failed"
else
print_warn "Uninstall script not found: ${uninstall_script}"
fi
done
fi
print_step "3.2" "PreSmoke_A900 Lower: experimental package + --run_example"
local exp_pkgs=("${PROJECT_ROOT}"/artifacts/experimental/cann-ops-math-experimental_linux-*.run)
if [[ ${#exp_pkgs[@]} -eq 0 ]] || [[ ! -f "${exp_pkgs[0]}" ]]; then
print_warn "experimental package not found in artifacts/experimental/"
record_sub_task "PreSmoke_A900 Lower" "SKIP" "artifacts/experimental/" "" ""
if [[ ${task_ret} -ne 1 ]]; then task_ret=2; fi
else
local exp_pkg="${exp_pkgs[0]}"
print_info "Found experimental package: $(basename ${exp_pkg})"
print_info "Installing experimental package with --quiet..."
chmod +x "${exp_pkg}"
"${exp_pkg}" --quiet --force 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_a900_lower_install.txt"
local install_ret=$?
if [[ ${install_ret} -ne 0 ]]; then
print_fail "Failed to install experimental package"
record_sub_task "PreSmoke_A900 Lower" "FAIL" "artifacts/experimental/" "logs/presmoke_a900_lower_install.txt" "${exp_pkg} --quiet"
task_ret=1
else
local filtered_exp_ops=$(filter_ops_by_soc "${OPS}" "${SOC}" "true")
if [[ -n "${OPS}" && -z "${filtered_exp_ops}" ]]; then
print_warn "Specified operators do not support ${SOC} in experimental mode, skipping PreSmoke_A900 Lower"
record_sub_task "PreSmoke_A900 Lower" "SKIP" "artifacts/experimental/" "" "ops do not support ${SOC}"
if [[ ${task_ret} -ne 1 ]]; then task_ret=2; fi
uninstall_vendor "experimental_math" "${PROJECT_ROOT}/logs/presmoke_a900_lower_uninstall.txt"
elif [[ -z "${filtered_exp_ops}" ]]; then
print_warn "No operators detected, skipping PreSmoke_A900 Lower"
record_sub_task "PreSmoke_A900 Lower" "SKIP" "artifacts/experimental/" "" ""
if [[ ${task_ret} -ne 1 ]]; then task_ret=2; fi
uninstall_vendor "experimental_math" "${PROJECT_ROOT}/logs/presmoke_a900_lower_uninstall.txt"
else
local lower_ret=0
local last_fail_cmd=""
local exp_arr=(${filtered_exp_ops//,/ })
for op in "${exp_arr[@]}"; do
local cmd_array=(bash build.sh --experimental --run_example "${op}" eager cust --vendor_name=experimental --soc="${SOC}")
print_info "Command: ${cmd_array[*]}"
"${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_a900_lower_${op}_run.txt"
local run_ret=$?
if [[ ${run_ret} -eq 0 ]]; then
print_ok "PreSmoke_A900 Lower (${op}) passed"
else
print_fail "PreSmoke_A900 Lower (${op}) failed"
last_fail_cmd="${cmd_array[*]}"
lower_ret=1
fi
done
if [[ ${lower_ret} -eq 0 ]]; then
record_sub_task "PreSmoke_A900 Lower" "PASS" "artifacts/experimental/" "logs/presmoke_a900_lower_*_run.txt" ""
else
record_sub_task "PreSmoke_A900 Lower" "FAIL" "artifacts/experimental/" "logs/presmoke_a900_lower_*_run.txt" "${last_fail_cmd}"
task_ret=1
fi
uninstall_vendor "experimental_math" "${PROJECT_ROOT}/logs/presmoke_a900_lower_uninstall.txt"
fi
fi
fi
return ${task_ret}
}
do_presmoke_st() {
print_step "3.3" "PreSmoke_St: ops_st_test.sh"
local chip_short=$(soc_to_chip_short "${SOC}")
local monitor_pkgs=("${PROJECT_ROOT}"/artifacts/normal/cann-${chip_short}-ops-math_*_linux-*.run)
if [[ ${#monitor_pkgs[@]} -gt 0 ]] && [[ -f "${monitor_pkgs[0]}" ]]; then
local monitor_pkg="${monitor_pkgs[0]}"
print_info "Found package: $(basename ${monitor_pkg})"
chmod +x "${monitor_pkg}"
"${monitor_pkg}" --full --install-path="${ASCEND_HOME_PATH}" 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_st_install.txt"
local install_ret=$?
if [[ ${install_ret} -eq 0 ]]; then
print_ok "Package installed"
else
print_fail "Package install failed (exit code: ${install_ret})"
return 1
fi
else
print_warn "Package not found in artifacts/normal/: cann-${chip_short}-ops-math_*_linux-*.run"
fi
if [[ -z "${OPS}" ]]; then
print_warn "No operators detected"
if [[ -n "${monitor_pkg:-}" ]] && [[ -f "${monitor_pkg}" ]]; then
print_info "Uninstalling normal package to restore environment..."
"${monitor_pkg}" --uninstall --install-path="${ASCEND_HOME_PATH}" 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_st_uninstall.txt" || print_warn "Normal package uninstall failed"
fi
return 2
fi
local cmd_array=(bash scripts/ci/ops_st_test.sh --soc_version="${SOC}" --ops="${OPS}" --pr_filelist="${PR_FILELIST}")
print_info "Command: ${cmd_array[*]}"
"${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_st.txt"
local ret=$?
if [[ -n "${monitor_pkg:-}" ]] && [[ -f "${monitor_pkg}" ]]; then
print_info "Uninstalling normal package to restore environment..."
"${monitor_pkg}" --uninstall --install-path="${ASCEND_HOME_PATH}" 2>&1 | tee "${PROJECT_ROOT}/logs/presmoke_st_uninstall.txt" || print_warn "Normal package uninstall failed"
fi
if [[ ${ret} -eq 0 ]]; then
print_ok "PreSmoke_St passed"
record_sub_task "PreSmoke_St" "PASS" "" "logs/presmoke_st.txt" ""
return 0
else
print_fail "PreSmoke_St failed"
record_sub_task "PreSmoke_St" "FAIL" "" "logs/presmoke_st.txt" "${cmd_array[*]}"
return 1
fi
}
do_llt_flow() {
print_header "Step 3: LLT Flow"
if [[ "${SKIP_LLT}" == "true" ]]; then
print_warn "LLT flow skipped (--skip-llt)"
return 2
fi
local any_llt_mode=false
[[ "${LLT_A900_MODE}" == "true" ]] && any_llt_mode=true
[[ "${LLT_ST_MODE}" == "true" ]] && any_llt_mode=true
[[ "${LLT_EXP_UT_MODE}" == "true" ]] && any_llt_mode=true
[[ "${LLT_KERNEL_UT_MODE}" == "true" ]] && any_llt_mode=true
[[ "${LLT_STD_UT_MODE}" == "true" ]] && any_llt_mode=true
if [[ "${any_llt_mode}" == "false" ]]; then
LLT_A900_MODE=true
LLT_ST_MODE=true
LLT_EXP_UT_MODE=true
LLT_KERNEL_UT_MODE=true
LLT_STD_UT_MODE=true
print_info "Auto mode: all LLT tasks enabled (default)"
fi
local llt_ret=0
if [[ "${LLT_A900_MODE}" == "true" ]]; then
do_presmoke_a900
local a900_ret=$?
if [[ ${a900_ret} -eq 1 ]]; then llt_ret=1; fi
else
print_warn "PreSmoke_A900 skipped (use --llt-a900 to enable)"
record_sub_task "PreSmoke_A900" "SKIP" "" "" ""
fi
if [[ "${LLT_ST_MODE}" == "true" ]]; then
do_presmoke_st
local st_ret=$?
if [[ ${st_ret} -eq 1 ]]; then llt_ret=1; fi
else
print_warn "PreSmoke_St skipped (use --llt-st to enable)"
record_sub_task "PreSmoke_St" "SKIP" "" "" ""
fi
if [[ "${LLT_EXP_UT_MODE}" == "true" ]]; then
print_step "3.4" "Experimental UT"
local ops_comma=$(filter_ops_by_soc "${OPS}" "ascend910b" "true")
if [[ -n "${OPS}" && -z "${ops_comma}" ]]; then
print_warn "No experimental operators support ascend910b, skipping Experimental UT"
record_sub_task "Experimental UT" "SKIP" "" "" ""
else
local cmd_array=(bash build.sh --experimental -u -j"${JOBS}")
[[ -n "${ops_comma}" ]] && cmd_array+=(--ops="${ops_comma}")
[[ -n "${CANN_3RD_LIB_PATH}" ]] && cmd_array+=(--cann_3rd_lib_path="${CANN_3RD_LIB_PATH}")
print_info "Command: ${cmd_array[*]}"
"${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/ut_experimental.txt"
local ret=$?
if [[ ${ret} -eq 0 ]]; then
print_ok "Experimental UT passed"
record_sub_task "Experimental UT" "PASS" "" "logs/ut_experimental.txt" ""
else
print_fail "Experimental UT failed"
record_sub_task "Experimental UT" "FAIL" "" "logs/ut_experimental.txt" "${cmd_array[*]}"
llt_ret=1
fi
fi
else
print_warn "Experimental UT skipped (use --llt-exp-ut to enable)"
record_sub_task "Experimental UT" "SKIP" "" "" ""
fi
if [[ "${LLT_KERNEL_UT_MODE}" == "true" ]]; then
print_step "3.5" "Kernel UT"
local cmd_array=(bash scripts/ci/check_kernel_ut.sh "${PR_FILELIST}")
print_info "Command: ${cmd_array[*]}"
"${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/ut_kernel.txt"
local ret=$?
if [[ ${ret} -eq 0 ]]; then
print_ok "Kernel UT passed"
record_sub_task "Kernel UT" "PASS" "" "logs/ut_kernel.txt" ""
else
print_fail "Kernel UT failed"
record_sub_task "Kernel UT" "FAIL" "" "logs/ut_kernel.txt" "${cmd_array[*]}"
llt_ret=1
fi
else
print_warn "Kernel UT skipped (use --llt-kernel-ut to enable)"
record_sub_task "Kernel UT" "SKIP" "" "" ""
fi
if [[ "${LLT_STD_UT_MODE}" == "true" ]]; then
print_step "3.6" "Standard UT"
local ops_comma=$(filter_ops_by_soc "${OPS}" "ascend910b" "false")
if [[ -n "${OPS}" && -z "${ops_comma}" ]]; then
print_warn "No operators support ascend910b, skipping Standard UT"
record_sub_task "Standard UT" "SKIP" "" "" ""
else
local cmd_array=(bash build.sh -u -j"${JOBS}")
[[ -n "${ops_comma}" ]] && cmd_array+=(--ops="${ops_comma}")
[[ -n "${CANN_3RD_LIB_PATH}" ]] && cmd_array+=(--cann_3rd_lib_path="${CANN_3RD_LIB_PATH}")
print_info "Command: ${cmd_array[*]}"
"${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/ut_standard.txt"
local ret=$?
if [[ ${ret} -eq 0 ]]; then
print_ok "Standard UT passed"
record_sub_task "Standard UT" "PASS" "" "logs/ut_standard.txt" ""
else
print_fail "Standard UT failed"
record_sub_task "Standard UT" "FAIL" "" "logs/ut_standard.txt" "${cmd_array[*]}"
llt_ret=1
fi
fi
else
print_warn "Standard UT skipped (use --llt-std-ut to enable)"
record_sub_task "Standard UT" "SKIP" "" "" ""
fi
if [[ ${llt_ret} -eq 0 ]]; then
print_ok "LLT Flow completed (all tasks passed)"
else
print_fail "LLT Flow completed with failures"
fi
return ${llt_ret}
}
do_cannsim_check() {
print_header "Step 4: Cannsim Tests"
if [[ "${SKIP_CANNSIM}" == "true" ]]; then
print_warn "Cannsim skipped"
return 2
fi
if [[ "${SOC}" != "ascend950" ]]; then
print_warn "cannsim only supports ascend950"
return 2
fi
if [[ -z "${OPS}" ]]; then
print_warn "No operators detected"
return 2
fi
local ops_arr=(${OPS//,/ })
local cannsim_ops=()
print_info "cannsim requires ascend950 support; operators without AddConfig(\"ascend950\") will be skipped"
for op in "${ops_arr[@]}"; do
if op_supports_soc "$op" "ascend950" "false" || \
op_supports_soc "$op" "ascend950" "true"; then
cannsim_ops+=("${op}")
else
print_warn "Skipping cannsim: ${op} (no ascend950 support)"
fi
done
if [[ ${#cannsim_ops[@]} -eq 0 ]]; then
print_warn "No ascend950-compatible operators for cannsim"
return 2
fi
for op in "${cannsim_ops[@]}"; do
print_step "4" "Running cannsim: ${op}"
local cmd_array=(bash scripts/ci/run_cannsim_example.sh "${op}" -j "${JOBS}")
print_info "Command: ${cmd_array[*]}"
if "${cmd_array[@]}" 2>&1 | tee "${PROJECT_ROOT}/logs/cannsim_${op}.txt"; then
print_ok "Cannsim passed: ${op}"
else
print_fail "Cannsim failed: ${op}"
return 1
fi
done
}
do_package_verify() {
local pkg_file="$1"
if [[ -z "${pkg_file}" ]] || [[ ! -f "${pkg_file}" ]]; then
print_warn "Package file not found: ${pkg_file}"
return 2
fi
print_info "Package: $(basename "${pkg_file}")"
local temp_dir="${PROJECT_ROOT}/tmp_verify"
chmod +x "${pkg_file}"
print_step "2.1.1" "Installing package"
local install_log="${PROJECT_ROOT}/logs/package_install.txt"
print_info "Command: ${pkg_file} --full --install-path=${temp_dir}"
if "${pkg_file}" --full --install-path="${temp_dir}" 2>&1 | tee "${install_log}"; then
print_ok "Install succeeded"
else
print_fail "Install failed"
rm -rf "${temp_dir}"
return 1
fi
print_step "2.1.2" "Uninstalling package"
local uninstall_log="${PROJECT_ROOT}/logs/package_uninstall.txt"
print_info "Command: ${pkg_file} --uninstall --install-path=${temp_dir}"
if "${pkg_file}" --uninstall --install-path="${temp_dir}" 2>&1 | tee "${uninstall_log}"; then
print_ok "Uninstall succeeded"
else
print_fail "Uninstall failed"
rm -rf "${temp_dir}"
return 1
fi
rm -rf "${temp_dir}"
print_ok "Package verification completed"
}
print_summary() {
local total_start=$1
local total_end=$(date +%s)
local elapsed=$((total_end - total_start))
local mins=$((elapsed / 60))
local secs=$((elapsed % 60))
print_header "Summary"
local idx=0
for result in "${CHECK_RESULTS[@]}"; do
idx=$((idx + 1))
local name="${CHECK_NAMES[$((idx - 1))]}"
case "${result}" in
PASS) print_ok "${idx}. ${name}" ;;
SKIP) print_warn "${idx}. ${name}" ;;
FAIL) print_fail "${idx}. ${name}" ;;
esac
done
print_header "Sub-task Details"
local idx=0
for result in "${SUB_TASK_RESULTS[@]}"; do
idx=$((idx + 1))
local name="${SUB_TASK_NAMES[$((idx - 1))]}"
local artifact="${SUB_TASK_ARTIFACTS[$((idx - 1))]}"
local log="${SUB_TASK_LOGS[$((idx - 1))]}"
local cmd="${SUB_TASK_COMMANDS[$((idx - 1))]}"
case "${result}" in
PASS) echo -e " ${GREEN}[PASS]${NC} ${name}" ;;
SKIP) echo -e " ${YELLOW}[SKIP]${NC} ${name}" ;;
FAIL) echo -e " ${RED}[FAIL]${NC} ${name}" ;;
esac
[[ -n "${artifact}" ]] && echo -e " Artifact: ${artifact}"
echo -e " Log: ${log}"
if [[ "${result}" == "FAIL" ]] && [[ -n "${cmd}" ]]; then
echo -e " Command: ${RED}${cmd}${NC}"
fi
done
echo ""
[[ ${mins} -gt 0 ]] && print_info "Total time: ${mins}m${secs}s" || print_info "Total time: ${secs}s"
local has_fail=false
for result in "${CHECK_RESULTS[@]}"; do
[[ "${result}" == "FAIL" ]] && { has_fail=true; break; }
done
for result in "${SUB_TASK_RESULTS[@]}"; do
[[ "${result}" == "FAIL" ]] && { has_fail=true; break; }
done
if [[ "${has_fail}" == "true" ]]; then
print_fail "Some checks FAILED"
return 1
else
print_ok "All checks PASSED"
rm -f "${PR_FILELIST}"
rm -rf "${PROJECT_ROOT}/tmp_verify"
return 0
fi
}
main() {
parse_args "$@"
export REPOSITORY_NAME="ops-math"
export WORKSPACE="${PROJECT_ROOT}"
export CANN_3RD_LIB_PATH="${CANN_3RD_LIB_PATH}"
export ASCEND_3RD_LIB_PATH="${ASCEND_3RD_LIB_PATH}"
local compile_task=false
local llt_task=false
local cannsim_task=false
[[ "${JIT_MODE}" == "true" || "${EXPERIMENTAL_MODE}" == "true" || "${SINGLE_MODE}" == "true" || "${A5_MODE}" == "true" || "${NORMAL_MODE}" == "true" ]] && compile_task=true
[[ "${LLT_A900_MODE}" == "true" || "${LLT_ST_MODE}" == "true" || "${LLT_EXP_UT_MODE}" == "true" || "${LLT_KERNEL_UT_MODE}" == "true" || "${LLT_STD_UT_MODE}" == "true" ]] && llt_task=true
[[ "${CANNSIM_MODE}" == "true" ]] && cannsim_task=true
local task_count=0
[[ "${compile_task}" == "true" ]] && task_count=$((task_count + 1))
[[ "${llt_task}" == "true" ]] && task_count=$((task_count + 1))
[[ "${cannsim_task}" == "true" ]] && task_count=$((task_count + 1))
if [[ ${task_count} -gt 1 ]]; then
echo "[ERROR] Cannot specify single-task parameters from different flows simultaneously"
echo " Compile: --jit/--experimental/--single/--a5/--normal"
echo " LLT: --llt-a900/--llt-st/--llt-exp-ut/--llt-kernel-ut/--llt-std-ut"
echo " Cannsim: --cannsim"
exit 1
fi
if [[ "${compile_task}" == "true" ]]; then
SKIP_LLT=true
SKIP_CANNSIM=true
print_info "Single-task mode: compile only, LLT and cannsim auto-skipped"
fi
if [[ "${llt_task}" == "true" ]]; then
SKIP_BUILD=true
SKIP_CANNSIM=true
print_info "Single-task mode: LLT only, compile and cannsim auto-skipped"
fi
if [[ "${cannsim_task}" == "true" ]]; then
SKIP_BUILD=true
SKIP_LLT=true
print_info "Single-task mode: cannsim only, compile and LLT auto-skipped"
fi
cd "${PROJECT_ROOT}"
mkdir -p "${PROJECT_ROOT}/logs"
local TOTAL_START=$(date +%s)
print_header "ops-math Local Check"
echo -e " Project: ${PROJECT_ROOT}"
echo -e " SoC: ${SOC:-auto-detect}"
echo -e " Jobs: ${JOBS}"
echo -e " Ops: ${OPS:-auto-detect}"
echo -e " Exp: ${EXPERIMENTAL_MODE}"
echo -e " Mode: JIT=${JIT_MODE} Exp=${EXPERIMENTAL_MODE} Single=${SINGLE_MODE} A5=${A5_MODE} Normal=${NORMAL_MODE}"
echo -e " LLT: A900=${LLT_A900_MODE} St=${LLT_ST_MODE} ExpUT=${LLT_EXP_UT_MODE} KernelUT=${LLT_KERNEL_UT_MODE} StdUT=${LLT_STD_UT_MODE} Cannsim=${CANNSIM_MODE}"
echo -e " Logs: ${PROJECT_ROOT}/logs/"
check_environment || exit 1
detect_changed_ops || { print_fail "Failed to detect changed files"; exit 1; }
run_check "Compile Flow" do_compile_flow
run_check "LLT Flow" do_llt_flow
run_check "Cannsim Tests" do_cannsim_check
print_summary "${TOTAL_START}"
}
main "$@"