Skip to content

Commit 5daa6e5

Browse files
committed
Add a run validation script
1 parent 5bde07b commit 5daa6e5

1 file changed

Lines changed: 233 additions & 0 deletions

File tree

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
#!/usr/bin/env bash
2+
3+
set -uo pipefail
4+
5+
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
6+
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
7+
8+
SRC_ROOT="${SRC_ROOT:-${PTOAS_OUT_DIR:-${REPO_ROOT}/build/output}}"
9+
OUTPUT_ROOT="${OUTPUT_ROOT:-${REPO_ROOT}/build/output_npu_validation}"
10+
LOG_ROOT="${LOG_ROOT:-${REPO_ROOT}/build/output_npu_validation_log}"
11+
PYTHON_BIN="${PYTHON_BIN:-python3}"
12+
RUN_MODE="${RUN_MODE:-npu}"
13+
SOC_VERSION="${SOC_VERSION:-Ascend950}"
14+
CASE_FILTER="${CASE_FILTER:-}"
15+
SAMPLE_FILTER="${SAMPLE_FILTER:-}"
16+
17+
usage() {
18+
cat <<EOF
19+
顺序执行 runop.sh 生成的 output 目录下所有 case 的上板验证,并实时打印结果。
20+
21+
用法:
22+
$0 [--src-root <dir>] [--output-root <dir>] [--log-root <dir>]
23+
[--python <python>] [--run-mode <npu|sim>] [--soc-version <soc>]
24+
[--sample <sample>] [--case <case>]
25+
26+
参数:
27+
--src-root 输入 .cpp 根目录,默认: \$PTOAS_OUT_DIR 或 ${REPO_ROOT}/build/output
28+
--output-root generate_testcase.py 输出目录,默认: ${REPO_ROOT}/build/output_npu_validation
29+
--log-root 每个 case 的日志目录,默认: ${REPO_ROOT}/build/output_npu_validation_log
30+
--python Python 解释器,默认: python3
31+
--run-mode 传给 generate_testcase.py 的运行模式,默认: npu
32+
--soc-version 传给 generate_testcase.py / run.sh 的 SoC,默认: Ascend910B1
33+
--sample 仅运行指定 sample 目录,例如 Abs
34+
--case 仅运行指定 case 名,例如 abs 或 abs-pto
35+
-h, --help 显示帮助
36+
37+
示例:
38+
$0
39+
$0 --sample Abs
40+
$0 --case abs
41+
$0 --run-mode sim --soc-version Ascend910
42+
EOF
43+
}
44+
45+
log() {
46+
printf '[%s] %s\n' "$(date +'%F %T')" "$*"
47+
}
48+
49+
normalize_case_name() {
50+
local name="$1"
51+
name="${name%.cpp}"
52+
name="${name%-pto}"
53+
name="${name%_pto}"
54+
printf '%s\n' "${name}"
55+
}
56+
57+
matches_filter() {
58+
local value="$1"
59+
local filter="$2"
60+
[[ -z "${filter}" ]] && return 0
61+
[[ "${value}" == "${filter}" ]]
62+
}
63+
64+
while [[ $# -gt 0 ]]; do
65+
case "$1" in
66+
--src-root)
67+
[[ $# -ge 2 ]] || { echo "[ERROR] --src-root 缺少参数" >&2; exit 2; }
68+
SRC_ROOT="$2"
69+
shift 2
70+
;;
71+
--output-root)
72+
[[ $# -ge 2 ]] || { echo "[ERROR] --output-root 缺少参数" >&2; exit 2; }
73+
OUTPUT_ROOT="$2"
74+
shift 2
75+
;;
76+
--log-root)
77+
[[ $# -ge 2 ]] || { echo "[ERROR] --log-root 缺少参数" >&2; exit 2; }
78+
LOG_ROOT="$2"
79+
shift 2
80+
;;
81+
--python)
82+
[[ $# -ge 2 ]] || { echo "[ERROR] --python 缺少参数" >&2; exit 2; }
83+
PYTHON_BIN="$2"
84+
shift 2
85+
;;
86+
--run-mode)
87+
[[ $# -ge 2 ]] || { echo "[ERROR] --run-mode 缺少参数" >&2; exit 2; }
88+
RUN_MODE="$2"
89+
shift 2
90+
;;
91+
--soc-version)
92+
[[ $# -ge 2 ]] || { echo "[ERROR] --soc-version 缺少参数" >&2; exit 2; }
93+
SOC_VERSION="$2"
94+
shift 2
95+
;;
96+
--sample)
97+
[[ $# -ge 2 ]] || { echo "[ERROR] --sample 缺少参数" >&2; exit 2; }
98+
SAMPLE_FILTER="$2"
99+
shift 2
100+
;;
101+
--case)
102+
[[ $# -ge 2 ]] || { echo "[ERROR] --case 缺少参数" >&2; exit 2; }
103+
CASE_FILTER="$2"
104+
shift 2
105+
;;
106+
-h|--help)
107+
usage
108+
exit 0
109+
;;
110+
*)
111+
echo "[ERROR] 未知参数: $1" >&2
112+
usage >&2
113+
exit 2
114+
;;
115+
esac
116+
done
117+
118+
[[ -d "${SRC_ROOT}" ]] || { echo "[ERROR] 输入目录不存在: ${SRC_ROOT}" >&2; exit 1; }
119+
command -v "${PYTHON_BIN}" >/dev/null 2>&1 || { echo "[ERROR] Python 不可用: ${PYTHON_BIN}" >&2; exit 1; }
120+
121+
mkdir -p "${OUTPUT_ROOT}" "${LOG_ROOT}" || { echo "[ERROR] 创建输出目录失败" >&2; exit 1; }
122+
123+
declare -a CPP_FILES=()
124+
while IFS= read -r -d '' file; do
125+
[[ "$(basename -- "${file}")" == ._* ]] && continue
126+
sample_name="$(basename -- "$(dirname -- "${file}")")"
127+
case_base_name="$(basename -- "${file}" .cpp)"
128+
case_name="$(normalize_case_name "$(basename -- "${file}")")"
129+
matches_filter "${sample_name}" "${SAMPLE_FILTER}" || continue
130+
if [[ -n "${CASE_FILTER}" ]] && [[ "${case_name}" != "${CASE_FILTER}" ]] && [[ "${case_base_name}" != "${CASE_FILTER}" ]]; then
131+
continue
132+
fi
133+
CPP_FILES+=("${file}")
134+
done < <(find "${SRC_ROOT}" -type f -name "*.cpp" -print0 | sort -z)
135+
136+
TOTAL_COUNT="${#CPP_FILES[@]}"
137+
if [[ "${TOTAL_COUNT}" -eq 0 ]]; then
138+
echo "[ERROR] 未找到可执行的 .cpp case: ${SRC_ROOT}" >&2
139+
exit 1
140+
fi
141+
142+
log "SRC_ROOT=${SRC_ROOT}"
143+
log "OUTPUT_ROOT=${OUTPUT_ROOT}"
144+
log "LOG_ROOT=${LOG_ROOT}"
145+
log "RUN_MODE=${RUN_MODE}"
146+
log "SOC_VERSION=${SOC_VERSION}"
147+
log "TOTAL_CASES=${TOTAL_COUNT}"
148+
149+
status_file="$(mktemp -t output_npu_validation.XXXXXX)"
150+
trap 'rm -f "${status_file}"' EXIT
151+
152+
ok_count=0
153+
fail_count=0
154+
idx=0
155+
156+
for cpp in "${CPP_FILES[@]}"; do
157+
idx=$((idx + 1))
158+
sample_name="$(basename -- "$(dirname -- "${cpp}")")"
159+
case_base="$(basename -- "${cpp}")"
160+
testcase="$(normalize_case_name "${case_base}")"
161+
case_output_dir="${OUTPUT_ROOT}/${sample_name}/${testcase}"
162+
case_log_dir="${LOG_ROOT}/${sample_name}"
163+
case_log_path="${case_log_dir}/${testcase}.log"
164+
165+
mkdir -p "${case_log_dir}" || {
166+
printf '%s\t%s\t%s\n' "FAIL" "${sample_name}/${testcase}" "mkdir log dir failed" >> "${status_file}"
167+
fail_count=$((fail_count + 1))
168+
continue
169+
}
170+
171+
echo
172+
log "[${idx}/${TOTAL_COUNT}] CASE ${sample_name}/${testcase}"
173+
log "INPUT=${cpp}"
174+
log "LOG=${case_log_path}"
175+
176+
{
177+
echo "[INFO] generate_testcase: ${cpp}"
178+
"${PYTHON_BIN}" "${REPO_ROOT}/test/npu_validation/scripts/generate_testcase.py" \
179+
--input "${cpp}" \
180+
--testcase "${testcase}" \
181+
--output-root "${OUTPUT_ROOT}" \
182+
--run-mode "${RUN_MODE}" \
183+
--soc-version "${SOC_VERSION}"
184+
} 2>&1 | tee "${case_log_path}"
185+
gen_rc=${PIPESTATUS[0]}
186+
187+
if [[ ${gen_rc} -ne 0 ]]; then
188+
log "FAIL generate_testcase: ${sample_name}/${testcase} (exit=${gen_rc})"
189+
printf '%s\t%s\t%s\n' "FAIL" "${sample_name}/${testcase}" "${case_log_path}" >> "${status_file}"
190+
fail_count=$((fail_count + 1))
191+
continue
192+
fi
193+
194+
if [[ ! -x "${case_output_dir}/run.sh" ]]; then
195+
echo "[ERROR] run.sh 未生成: ${case_output_dir}/run.sh" | tee -a "${case_log_path}"
196+
printf '%s\t%s\t%s\n' "FAIL" "${sample_name}/${testcase}" "${case_log_path}" >> "${status_file}"
197+
fail_count=$((fail_count + 1))
198+
continue
199+
fi
200+
201+
(
202+
cd "${case_output_dir}" || exit 1
203+
env RUN_MODE="${RUN_MODE}" SOC_VERSION="${SOC_VERSION}" ./run.sh
204+
) 2>&1 | tee -a "${case_log_path}"
205+
run_rc=${PIPESTATUS[0]}
206+
207+
if [[ ${run_rc} -eq 0 ]]; then
208+
log "OK ${sample_name}/${testcase}"
209+
printf '%s\t%s\t%s\n' "OK" "${sample_name}/${testcase}" "${case_log_path}" >> "${status_file}"
210+
ok_count=$((ok_count + 1))
211+
else
212+
log "FAIL run.sh: ${sample_name}/${testcase} (exit=${run_rc})"
213+
printf '%s\t%s\t%s\n' "FAIL" "${sample_name}/${testcase}" "${case_log_path}" >> "${status_file}"
214+
fail_count=$((fail_count + 1))
215+
fi
216+
done
217+
218+
echo
219+
echo "========== NPU VALIDATION SUMMARY =========="
220+
echo "TOTAL=${TOTAL_COUNT} OK=${ok_count} FAIL=${fail_count}"
221+
222+
if [[ ${fail_count} -gt 0 ]]; then
223+
echo "---------- FAIL CASES ----------"
224+
while IFS=$'\t' read -r st case_name log_path; do
225+
[[ "${st}" == "FAIL" ]] || continue
226+
echo "${case_name} FAIL"
227+
echo "log: ${log_path}"
228+
done < "${status_file}"
229+
exit 1
230+
fi
231+
232+
echo "All cases passed."
233+
exit 0

0 commit comments

Comments
 (0)