#!/bin/bash
# 卡1 调度执行器: 已验证CPP的长时压测 (用法: card1_run.sh <api> [场景...默认normal non_contig multithread])
set -u
API="$1"; shift; SCENARIOS="${*:-normal non_contig multithread}"
BASE="$(cd "$(dirname "$0")/.." && pwd)"
FRAME="$BASE/turing_sec_card1/aclnnAPI_fuzz"
OUTD="$BASE/output/$API/fuzz_logs"
mkdir -p "$OUTD"
export ASCEND_RT_VISIBLE_DEVICES=1
export ASCEND_HOME_PATH=${ASCEND_HOME_PATH:-/usr/local/Ascend/ascend-toolkit/latest/x86_64-linux}
export ASCEND_OPP_PATH=${ASCEND_OPP_PATH:-/usr/local/Ascend/ascend-toolkit/latest/opp}
export LD_LIBRARY_PATH=${ASCEND_HOME_PATH}/lib64:${LD_LIBRARY_PATH:-}
cd "$FRAME"
up() { timeout 60 python3 "$BASE/scripts/update_batch_results.py" --api "$API" --scenario "$1" --total "$2" --success "$3" --fail "$4" --fail_reason "$5" --has_bug "$6" --has_aicore 否 --card 1 --analyzed 是 > /dev/null 2>&1; }
# plog 回传(按进程PID精确归档,修复旧版 `ls -t|head -1` 拷到历史陈旧文件的缺陷):
# 用法: plog <目标文件名> <fuzz进程PID>;该进程的全部 plog-{PID}_*.log 轮转段合并归档
plog() { local D=${ASCEND_LOG_PATH:-/root/ascend/log/debug/plog}; : > "$OUTD/$1";
  for F in $(find "$D" -maxdepth 1 -name "plog-${2}_*.log" 2>/dev/null | sort); do cat "$F" >> "$OUTD/$1"; done
  [ -s "$OUTD/$1" ] || echo "[WARN] plog-$2_*.log 未找到,归档为空" ; return 0; }
# runpid <timeout秒> <命令...>: 后台执行并捕获真实fuzz进程PID(timeout子进程),供plog归档
runpid() { local TMO=$1; shift; cd "$FRAME/out"; timeout "$TMO" "$@" & local BG=$!
  local FP=$(pgrep -P "$BG" 2>/dev/null | head -1); [ -n "$FP" ] || FP=$BG; RUN_PID=$FP; wait "$BG"; local RC=$?
  cd "$FRAME"; return $RC; }
cnt() { local V; V=$(grep -c "$1" "$2" 2>/dev/null); echo "${V:-0}"; }
echo "[$(date +%H:%M:%S)] [卡1] $API 开始 (场景: $SCENARIOS)"
if echo "$SCENARIOS" | grep -q normal; then
  rm -f src/op/*.cpp; cp "$BASE/output/$API/$API.cpp" src/op/
  if make op_fuzz > /tmp/c1mk.log 2>&1; then
    runpid 1800 ./aclnnAPI_fuzz "${API}_fuzz" 10000 > "$OUTD/${API}_fuzz_output.log" 2>&1
    S=$(cnt 'FUZZ_RESULT.*success' "$OUTD/${API}_fuzz_output.log"); F=$(cnt 'FUZZ_RESULT.*faild' "$OUTD/${API}_fuzz_output.log")
    SYNC5=$(grep -ac "sync.*507035\|ret=507035" "$OUTD/${API}_fuzz_output.log" || echo 0)
    echo "[$(date +%H:%M:%S)] [卡1] $API normal $S/10000 (sync507035=${SYNC5:-0})"
    up normal 10000 "$S" "$F" "卡1全量;guard/瞬态" "不是bug(用例shape过大OOM资源不足)"
    plog "${API}_fuzz_plog.log" "$RUN_PID"
  else echo "[$API] normal编译失败"; fi
fi
if echo "$SCENARIOS" | grep -q non_contig && [ -f "$BASE/output/$API/${API}_non_contig.cpp" ]; then
  rm -f src/op/*.cpp; cp "$BASE/output/$API/${API}_non_contig.cpp" src/op/
  if make op_fuzz > /tmp/c1mk.log 2>&1; then
    runpid 1800 ./aclnnAPI_fuzz "${API}_non_contig_fuzz" 10000 > "$OUTD/${API}_non_contig_fuzz_output.log" 2>&1
    S=$(cnt 'FUZZ_RESULT.*success' "$OUTD/${API}_non_contig_fuzz_output.log"); F=$(cnt 'FUZZ_RESULT.*faild' "$OUTD/${API}_non_contig_fuzz_output.log")
    echo "[$(date +%H:%M:%S)] [卡1] $API non_contig $S/10000"
    up non_contig 10000 "$S" "$F" "卡1;guard/瞬态" "不是bug(用例shape过大OOM资源不足)"
    plog "${API}_non_contig_fuzz_plog.log" "$RUN_PID"
  else echo "[$API] non_contig编译失败"; fi
fi
if echo "$SCENARIOS" | grep -q multithread && [ -f "$BASE/output/$API/${API}_multithread.cpp" ]; then
  rm -f src/op_multithread/*.cpp; mkdir -p src/op_multithread
  cp "$BASE/output/$API/${API}_multithread.cpp" src/op_multithread/${API}.cpp
  if make op_fuzz TARGET=multithread > /tmp/c1mk.log 2>&1; then
    runpid 900 ./aclnnAPI_fuzz_multithread 5 1000 0 5 0 > "$OUTD/${API}_multithread_fuzz_precheck.log" 2>&1
    S=$(cnt 'FUZZ_RESULT.*success' "$OUTD/${API}_multithread_fuzz_precheck.log"); F=$(cnt 'FUZZ_RESULT.*faild' "$OUTD/${API}_multithread_fuzz_precheck.log")
    up multithread_precheck 5000 "$S" "$F" "卡1调试" "不是bug(用例shape过大OOM资源不足)"
    PRE_PID=$RUN_PID
    if [ "$S" -ge 4750 ]; then
      runpid 1800 ./aclnnAPI_fuzz_multithread 5 20000 0 5 0 > "$OUTD/${API}_multithread_fuzz_output.log" 2>&1
      S=$(cnt 'FUZZ_RESULT.*success' "$OUTD/${API}_multithread_fuzz_output.log"); F=$(cnt 'FUZZ_RESULT.*faild' "$OUTD/${API}_multithread_fuzz_output.log")
      echo "[$(date +%H:%M:%S)] [卡1] $API multithread $S/100000"
      up multithread 100000 "$S" "$F" "卡1;guard/瞬态" "不是bug(用例shape过大OOM资源不足)"
      { plog "${API}_multithread_fuzz_precheck.log" "$PRE_PID"; plog "${API}_multithread_fuzz_plog.log" "$RUN_PID"; }
    else echo "[$API] mt调试未达标($S/5000)跳过全量"; plog "${API}_multithread_fuzz_precheck.log" "$PRE_PID"; fi
  else echo "[$API] mt编译失败"; fi
fi
echo "[$(date +%H:%M:%S)] [卡1] $API 完成"