#!/bin/bash
set -euo pipefail
show_help() {
echo "LoadData 性能测试脚本"
echo ""
echo "使用方法:"
echo " $0 <SCENARIO_NUM> [PLATFORM]"
echo ""
echo "参数:"
echo " SCENARIO_NUM 测试场景编号(必选)"
echo " PLATFORM 平台架构(可选,默认: dav-2201)"
echo ""
echo "Atlas A3/A2 训练/推理平台场景 (dav-2201, 主频1800MHz):"
echo " 1: LoadData(2D矩阵搬运)A (A矩阵 L1->L0A)"
echo " 2: LoadData(2D矩阵搬运)B (B矩阵 L1->L0B)"
echo " 3: LoadDataWithTranspose A (A矩阵转置)"
echo " 4: LoadDataWithTranspose B (B矩阵转置)"
echo " 5: LoadData(卷积数据搬运)v2 A (A矩阵 3D)"
echo " 6: LoadData(卷积数据搬运)v2 B (B矩阵 3D)"
echo " 7: LoadSparse (稀疏加载)"
echo " 8: LoadBias (Bias加载)"
echo " 9: LoadFixBuffer (FixPipe加载)"
echo ""
echo "Ascend 950PR/950DT 平台场景 (dav-3510, 主频1650MHz):"
echo " 11: LoadData(2D矩阵搬运V2)A"
echo " 12: LoadData(2D矩阵搬运V2)B"
echo " 13: LoadData(MX矩阵搬运)A (带Scale)"
echo " 14: LoadData(MX矩阵搬运)B (带Scale)"
echo " 15: LoadData(卷积数据搬运)v2 A"
echo " 16: LoadData(卷积数据搬运)v2 B"
echo " 17: LoadDataWithTranspose B"
echo " 18: LoadBias"
echo " 19: LoadFixBuffer"
echo ""
echo "示例:"
echo " $0 1 # 测试场景1,默认平台dav-2201"
echo " $0 1 dav-2201 # 测试场景1,指定平台dav-2201"
echo " $0 11 dav-3510 # 测试场景11,指定平台dav-3510"
echo ""
}
if [ $# -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
show_help
exit 0
fi
SCENARIO=$1
PLATFORM=${2:-dav-2201}
if ! [[ "$SCENARIO" =~ ^[0-9]+$ ]]; then
echo "错误: SCENARIO 必须是数字"
show_help
exit 1
fi
if [ "$SCENARIO" -ge 1 ] && [ "$SCENARIO" -le 9 ]; 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 19 ]; 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-9 (Atlas A3/A2 训练/推理平台) 或 11-19 (Ascend 950PR/950DT 平台)"
exit 1
fi
SHAPES=(
"32 32 32"
"64 64 64"
"64 128 64"
"128 128 128"
"256 128 256"
)
PERF_METRIC="aic_mte1_time"
PERF_METRIC_DESC="MTE1 (L1->L0)"
if [ "$SCENARIO" -eq 9 ] || [ "$SCENARIO" -eq 19 ]; then
PERF_METRIC="aic_fixpipe_time"
PERF_METRIC_DESC="FixPipe (L0C->GM or L1->FixPipe)"
fi
echo "性能指标: ${PERF_METRIC} (${PERF_METRIC_DESC})"
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}LoadData 性能测试 - 场景${SCENARIO}${NC}"
echo -e "${GREEN}平台: ${PLATFORM}${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}" ..
make -j
cd ..
fi
if [ "$PERF_METRIC" = "aic_fixpipe_time" ]; then
echo "Test_ID,M,K,N,Shape,AIC_FixPipe_Time(us),Cycle,Bandwidth(GB/s)" > "${RESULT_CSV}"
else
echo "Test_ID,M,K,N,Shape,AIC_MTE1_Time(us),Cycle,Bandwidth(GB/s)" > "${RESULT_CSV}"
fi
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}"
perf_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"
elif grep -q "vec" "${msprof_dir}/PipeUtilization.csv"; then
cpu_type="vec"
fi
metric_col_index=""
if [ "$PERF_METRIC" = "aic_fixpipe_time" ]; then
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
perf_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
echo -e "${GREEN}从 PipeUtilization.csv 提取: aic_fixpipe_time = ${perf_time} us${NC}"
else
metric_col_index=$(awk -F ',' 'NR==1 {for(i=1;i<=NF;i++) if($i=="aic_mte1_time(us)" || $i=="aic_mte1_time") print i}' "${msprof_dir}/PipeUtilization.csv" | head -n 1)
if [ ! -z "$metric_col_index" ]; then
perf_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_mte1_time 列索引=${metric_col_index}${NC}"
fi
echo -e "${GREEN}从 PipeUtilization.csv 提取: aic_mte1_time = ${perf_time} us${NC}"
fi
if [ -z "$perf_time" ] || [ "$perf_time" = "NA" ]; then
echo -e "${YELLOW}动态搜索失败,尝试备用方法...${NC}"
if [ "$PERF_METRIC" = "aic_fixpipe_time" ]; then
perf_time=$(awk -F ',' 'NR==2 {for(i=1;i<=NF;i++) if($i ~ /^aic_fixpipe_time/ || $i ~ /^[0-9.]+$/) print $i}' "${msprof_dir}/PipeUtilization.csv" | grep -E '^[0-9.]+$' | head -n 1 | sed 's/[[:space:]]//g' || true)
else
perf_time=$(awk -F ',' 'NR==2 {for(i=1;i<=NF;i++) if($i ~ /^aic_mte1_time/ || $i ~ /^[0-9.]+$/) print $i}' "${msprof_dir}/PipeUtilization.csv" | grep -E '^[0-9.]+$' | head -n 1 | sed 's/[[:space:]]//g' || true)
fi
if [ ! -z "$perf_time" ] && [ "$perf_time" != "NA" ]; then
echo -e "${GREEN}备用方法提取成功: ${perf_time} us${NC}"
else
echo -e "${RED}所有方法均失败${NC}"
fi
fi
else
echo -e "${YELLOW}警告: 未找到 PipeUtilization.csv${NC}"
echo -e "${YELLOW}列出 msprof 输出目录内容:${NC}"
ls -la "${msprof_dir}/" || true
fi
if [ "$perf_time" = "N/A" ] || [ -z "$perf_time" ] || [ "$perf_time" = "NA" ]; then
echo -e "${RED}未能提取有效的性能数据${NC}"
perf_time="N/A"
elif ! [[ "$perf_time" =~ ^[0-9.]+$ ]]; then
echo -e "${YELLOW}警告: 提取的数据格式异常: ${perf_time}${NC}"
perf_time=$(echo "$perf_time" | grep -oE '[0-9.]+' | head -n 1 || true)
if [ -z "$perf_time" ]; then
perf_time="N/A"
fi
fi
cycle_count="N/A"
bandwidth="N/A"
if [ "$perf_time" != "N/A" ] && [[ "$perf_time" =~ ^[0-9.]+$ ]]; then
cycle_count=$(awk "BEGIN {printf \"%.2f\", ${perf_time} * ${FREQUENCY}}")
data_type_size=2
if [ "$SCENARIO" -eq 9 ] || [ "$SCENARIO" -eq 19 ]; then
data_type_size=8
data_size_bytes=$((N * data_type_size))
data_desc="FixPipe N*sizeof(uint64_t)"
elif [ "$SCENARIO" -eq 8 ] || [ "$SCENARIO" -eq 18 ]; then
data_type_size=4
data_size_bytes=$((N * data_type_size))
data_desc="Bias N*sizeof(float)"
elif [ "$SCENARIO" -eq 7 ]; then
data_type_size=1
data_size_bytes=$((K * N * data_type_size))
data_desc="Sparse B矩阵 K*N (int8)"
elif [ "$SCENARIO" -eq 13 ] || [ "$SCENARIO" -eq 14 ]; then
data_type_size=1
if [ "$SCENARIO" -eq 13 ]; then
data_size_bytes=$((M * K * data_type_size))
data_desc="A矩阵 M*K (fp8)"
else
data_size_bytes=$((K * N * data_type_size))
data_desc="B矩阵 K*N (fp8)"
fi
elif [ "$SCENARIO" -eq 1 ] || [ "$SCENARIO" -eq 3 ] || [ "$SCENARIO" -eq 5 ] || [ "$SCENARIO" -eq 11 ] || [ "$SCENARIO" -eq 15 ]; then
data_size_bytes=$((M * K * data_type_size))
data_desc="A矩阵 M*K"
elif [ "$SCENARIO" -eq 2 ] || [ "$SCENARIO" -eq 4 ] || [ "$SCENARIO" -eq 6 ] || [ "$SCENARIO" -eq 12 ] || [ "$SCENARIO" -eq 16 ] || [ "$SCENARIO" -eq 17 ]; then
data_size_bytes=$((K * N * data_type_size))
data_desc="B矩阵 K*N"
else
data_size_bytes=$((M * K * data_type_size))
data_desc="默认 A矩阵 M*K"
fi
bandwidth=$(awk "BEGIN {printf \"%.3f\", ${data_size_bytes} / ${perf_time} / 1e3}")
echo -e "${GREEN}性能指标计算:${NC}"
echo -e "${GREEN} 性能指标: ${PERF_METRIC} (${PERF_METRIC_DESC})${NC}"
echo -e "${GREEN} 数据类型大小: ${data_type_size} bytes${NC}"
echo -e "${GREEN} 数据量: ${data_size_bytes} bytes (${data_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},${perf_time},${cycle_count},${bandwidth}" >> "${RESULT_CSV}"
perf_metric_name="AIC_MTE1_Time"
if [ "$PERF_METRIC" = "aic_fixpipe_time" ]; then
perf_metric_name="AIC_FixPipe_Time"
fi
echo -e "${GREEN}测试 ${test_id} 完成${NC}"
echo -e "${GREEN} Shape: [${M}, ${K}, ${N}]${NC}"
echo -e "${GREEN} ${perf_metric_name}: ${perf_time} us${NC}"
echo -e "${GREEN} Cycle: ${cycle_count} cycles${NC}"
echo -e "${GREEN} Bandwidth: ${bandwidth} GB/s${NC}"
if [ "$perf_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
echo -e "\n${YELLOW}提示:${NC}"
echo -e "${YELLOW}本次测试所有数据已保存到: ${PERF_DATA_DIR}${NC}"
echo -e "${YELLOW}如需生成 Roofline 图,可使用:${NC}"
echo -e "${YELLOW} python3 generate_roofline_with_latency.py --csv ${RESULT_CSV}${NC}"