#!/bin/bash
set -euo pipefail
show_help() {
echo "Fixpipe 性能测试脚本"
echo ""
echo "使用方法:"
echo " $0 <SCENARIO_NUM> [PLATFORM]"
echo ""
echo "参数:"
echo " SCENARIO_NUM 测试场景编号(必选)"
echo " PLATFORM 平台架构(可选,默认按场景号推导)"
echo ""
echo "Atlas A3/A2 训练/推理平台场景 (dav-2201, 主频1800MHz):"
echo " 1: L0C->L1 DataCopy float -> half"
echo " 2: L0C->L1 DataCopy float -> int8_t"
echo ""
echo "Ascend 950PR/950DT 平台场景 (dav-3510, 主频1650MHz):"
echo " 11: L0C->L1 DataCopy float -> half"
echo " 12: L0C->L1 DataCopy float -> int8_t"
echo " 13: L0C->UB Fixpipe float -> float 非双目标模式"
echo " 14: L0C->UB Fixpipe float -> float 双目标模式(按 M 拆分)"
echo ""
echo "示例:"
echo " $0 1 # 测试场景1,默认平台dav-2201"
echo " $0 13 dav-3510 # 测试场景13,指定平台dav-3510"
echo ""
}
if [ $# -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
show_help
exit 0
fi
SCENARIO=$1
if ! [[ "$SCENARIO" =~ ^[0-9]+$ ]]; then
echo "错误: SCENARIO 必须是数字"
show_help
exit 1
fi
if [ "$SCENARIO" -ge 1 ] && [ "$SCENARIO" -le 2 ]; then
PLATFORM=${2:-dav-2201}
if [ "$PLATFORM" != "dav-2201" ]; then
echo "错误: 场景 ${SCENARIO} 仅支持 dav-2201,当前平台为 ${PLATFORM}"
exit 1
fi
FREQUENCY=1800
echo "场景 $SCENARIO 属于 Atlas A3/A2 训练/推理平台 (dav-2201)"
echo "主频: ${FREQUENCY} MHz"
elif [ "$SCENARIO" -ge 11 ] && [ "$SCENARIO" -le 14 ]; then
PLATFORM=${2:-dav-3510}
if [ "$PLATFORM" != "dav-3510" ]; then
echo "错误: 场景 ${SCENARIO} 仅支持 dav-3510,当前平台为 ${PLATFORM}"
exit 1
fi
FREQUENCY=1650
echo "场景 $SCENARIO 属于 Ascend 950PR/950DT 平台 (dav-3510)"
echo "主频: ${FREQUENCY} MHz"
else
echo "错误: 无效的场景编号 $SCENARIO"
echo "有效范围: 1-2 (Atlas A3/A2 训练/推理平台) 或 11-14 (Ascend 950PR/950DT 平台)"
exit 1
fi
case "$SCENARIO" in
1|11) DST_TYPE_SIZE=2; DST_TYPE_DESC="half" ;;
2|12) DST_TYPE_SIZE=1; DST_TYPE_DESC="int8_t" ;;
13|14) DST_TYPE_SIZE=4; DST_TYPE_DESC="float" ;;
esac
if [ "$PLATFORM" = "dav-3510" ]; then
SHAPES=(
"16 64 16"
"32 64 32"
"64 64 64"
"128 64 128"
"256 64 256"
)
else
SHAPES=(
"16 64 16"
"32 64 32"
"64 64 64"
"128 64 128"
"128 64 256"
)
fi
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
PERF_DATA_DIR="perf_data_${TIMESTAMP}_scenario${SCENARIO}"
RESULT_CSV="${PERF_DATA_DIR}/perf_result_scenario${SCENARIO}.csv"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Fixpipe 性能测试 - 场景${SCENARIO}${NC}"
echo -e "${GREEN}平台: ${PLATFORM},目的类型: ${DST_TYPE_DESC}${NC}"
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}创建性能数据目录: ${PERF_DATA_DIR}${NC}"
mkdir -p "${PERF_DATA_DIR}"
if [ ! -f "build/demo" ]; then
echo -e "${YELLOW}未找到可执行文件,开始编译...${NC}"
mkdir -p build && cd build
cmake -DCMAKE_ASC_ARCHITECTURES="${PLATFORM}" \
-DASC_DIR="${ASC_DIR:-${ASCEND_HOME_PATH}/lib64/cmake}" ..
make -j
cd ..
fi
echo "Test_ID,M,K,N,Shape,AIC_FixPipe_Time(us),Cycle,Bandwidth(GB/s)" > "${RESULT_CSV}"
test_id=1
for shape in "${SHAPES[@]}"; do
read M K N <<< "$shape"
shape_str="${M}_${K}_${N}"
echo -e "${YELLOW}----------------------------------------${NC}"
echo -e "${YELLOW}测试 ${test_id}: Shape [${M}, ${K}, ${N}]${NC}"
echo -e "${YELLOW}----------------------------------------${NC}"
rm -rf OPPROF_* 2>/dev/null || true
echo -e "${GREEN}开始 msopprof 性能采集...${NC}"
set +e
msopprof build/demo "${SCENARIO}" "${M}" "${K}" "${N}" > /dev/null 2>&1
msprof_exit_code=$?
set -e
if [ "${msprof_exit_code}" -ne 0 ]; then
echo -e "${RED}msprof 执行失败(退出码: ${msprof_exit_code})${NC}"
echo "${test_id},${M},${K},${N},${shape_str},ERROR,ERROR,ERROR" >> "${RESULT_CSV}"
test_id=$((test_id + 1))
continue
fi
msprof_dir=$(ls -dt OPPROF_* 2>/dev/null | head -n 1 || true)
if [ -z "$msprof_dir" ] || [ ! -d "$msprof_dir" ]; then
echo -e "${RED}未找到 msopprof 输出目录 OPPROF_*${NC}"
echo "${test_id},${M},${K},${N},${shape_str},N/A,N/A,N/A" >> "${RESULT_CSV}"
test_id=$((test_id + 1))
continue
fi
echo -e "${GREEN}msprof 输出目录: ${msprof_dir}${NC}"
fixpipe_time="N/A"
if [ -f "${msprof_dir}/PipeUtilization.csv" ]; then
echo -e "${GREEN}找到 PipeUtilization.csv${NC}"
echo -e "${YELLOW}PipeUtilization.csv 内容:${NC}"
head -n 2 "${msprof_dir}/PipeUtilization.csv"
cpu_type="cube"
if grep -q "cube0" "${msprof_dir}/PipeUtilization.csv"; then
cpu_type="cube0"
elif grep -q "cube" "${msprof_dir}/PipeUtilization.csv"; then
cpu_type="cube"
fi
metric_col_index=$(awk -F ',' 'NR==1 {for(i=1;i<=NF;i++) if($i=="aic_fixpipe_time(us)" || $i=="aic_fixpipe_time") print i}' "${msprof_dir}/PipeUtilization.csv" | head -n 1)
if [ ! -z "$metric_col_index" ]; then
fixpipe_time=$(awk -F ',' -v col="$metric_col_index" -v type="$cpu_type" '$2==type {print $col}' "${msprof_dir}/PipeUtilization.csv" | sed 's/[[:space:]]//g')
echo -e "${GREEN}动态搜索列名: aic_fixpipe_time 列索引=${metric_col_index}${NC}"
fi
if [ -z "$fixpipe_time" ] || [ "$fixpipe_time" = "NA" ]; then
echo -e "${YELLOW}动态搜索失败,尝试备用方法...${NC}"
fixpipe_time=$(awk -F ',' 'NR==2 {for(i=1;i<=NF;i++) if($i ~ /^[0-9.]+$/) print $i}' "${msprof_dir}/PipeUtilization.csv" | grep -E '^[0-9.]+$' | head -n 1 | sed 's/[[:space:]]//g' || true)
if [ ! -z "$fixpipe_time" ] && [ "$fixpipe_time" != "NA" ]; then
echo -e "${GREEN}备用方法提取成功: ${fixpipe_time} us${NC}"
else
echo -e "${RED}所有方法均失败${NC}"
fi
fi
echo -e "${GREEN}从 PipeUtilization.csv 提取: aic_fixpipe_time = ${fixpipe_time} us${NC}"
else
echo -e "${YELLOW}警告: 未找到 PipeUtilization.csv${NC}"
ls -la "${msprof_dir}/" || true
fi
if [ "$fixpipe_time" = "N/A" ] || [ -z "$fixpipe_time" ] || [ "$fixpipe_time" = "NA" ]; then
echo -e "${RED}未能提取有效的性能数据${NC}"
fixpipe_time="N/A"
elif ! [[ "$fixpipe_time" =~ ^[0-9.]+$ ]]; then
echo -e "${YELLOW}警告: 提取的数据格式异常: ${fixpipe_time}${NC}"
fixpipe_time=$(echo "$fixpipe_time" | grep -oE '[0-9.]+' | head -n 1 || true)
if [ -z "$fixpipe_time" ]; then
fixpipe_time="N/A"
fi
fi
cycle_count="N/A"
bandwidth="N/A"
if [ "$fixpipe_time" != "N/A" ] && [[ "$fixpipe_time" =~ ^[0-9.]+$ ]]; then
cycle_count=$(awk "BEGIN {printf \"%.2f\", ${fixpipe_time} * ${FREQUENCY}}")
data_size_bytes=$((M * N * DST_TYPE_SIZE))
bandwidth=$(awk "BEGIN {printf \"%.3f\", ${data_size_bytes} / ${fixpipe_time} / 1e3}")
echo -e "${GREEN}性能指标计算:${NC}"
echo -e "${GREEN} Fixpipe 搬出耗时: ${fixpipe_time} us${NC}"
echo -e "${GREEN} 搬出量: ${data_size_bytes} bytes (M*N*sizeof(${DST_TYPE_DESC}))${NC}"
echo -e "${GREEN} Cycle数: ${cycle_count} cycles${NC}"
echo -e "${GREEN} 带宽: ${bandwidth} GB/s${NC}"
fi
echo "${test_id},${M},${K},${N},${shape_str},${fixpipe_time},${cycle_count},${bandwidth}" >> "${RESULT_CSV}"
echo -e "${GREEN}测试 ${test_id} 完成${NC}"
echo -e "${GREEN} Shape: [${M}, ${K}, ${N}]${NC}"
echo -e "${GREEN} AIC_FixPipe_Time: ${fixpipe_time} us${NC}"
echo -e "${GREEN} Cycle: ${cycle_count} cycles${NC}"
echo -e "${GREEN} Bandwidth: ${bandwidth} GB/s${NC}"
if [ "$fixpipe_time" != "N/A" ]; then
mv "${msprof_dir}" "${PERF_DATA_DIR}/test_${test_id}_${shape_str}" 2>/dev/null || true
fi
test_id=$((test_id + 1))
done
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}性能测试汇总结果${NC}"
echo -e "${GREEN}========================================${NC}"
cat "${RESULT_CSV}"
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}测试完成!${NC}"
echo -e "${GREEN}场景: ${SCENARIO}${NC}"
echo -e "${GREEN}平台: ${PLATFORM}${NC}"
echo -e "${GREEN}结果文件: ${RESULT_CSV}${NC}"
echo -e "${GREEN}性能数据目录: ${PERF_DATA_DIR}${NC}"
echo -e "${GREEN}========================================${NC}"
echo -e "\n${YELLOW}性能数据表格:${NC}"
if command -v column >/dev/null 2>&1; then
column -t -s ',' "${RESULT_CSV}"
else
cat "${RESULT_CSV}"
fi