name: Performance Regression Template (Unified)

on:
  #run it manually when the workflow is in the default branch
  workflow_call:
    inputs:
      test_branch:
        description: 'Branch to run the workflow on'
        required: true
        type: string
      test_commit:
        description: 'Commit SHA to run the workflow on'
        required: false
        type: string
        default: ''
      benchmark_type:
        required: true
        type: string
        description: "Benchmark type: spec06-0.3c, spec06-0.8c, spec06-1.0c"

jobs:
  run:
    runs-on: perf
    continue-on-error: false
    #At most 2 days to finish
    timeout-minutes: 2880
    name: Checkpoints
    steps:
      - name: Set benchmark configuration
        run: |
          case "${{ inputs.benchmark_type }}" in
            "spec06-0.3c")
              echo "CKPT_JSON_PATH=/nfs/home/share/ci-workloads/json/gcc12o3-incFpcOff-jeMalloc-0.3.json" >> $GITHUB_ENV
              ;;
            "spec06-0.8c")
              echo "CKPT_JSON_PATH=/nfs/home/share/ci-workloads/json/gcc12o3-incFpcOff-jeMalloc-0.8.json" >> $GITHUB_ENV
              ;;
            "spec06-1.0c")
              echo "CKPT_JSON_PATH=/nfs/home/share/checkpoints_profiles/spec06_rv64gcb_O3_20m_gcc12.2.0-intFpcOff-jeMalloc/checkpoint-0-0-0/cluster-0-0.json" >> $GITHUB_ENV
              ;;
            *)
              echo "Error: Invalid benchmark_type '${{ inputs.benchmark_type }}'. Must be one of: spec06-0.3c, spec06-0.8c, spec06-1.0c"
              exit 1
              ;;
          esac

      - name: Set test branch or commit
        id: set_test
        run: |
          if [ "${{ inputs.test_commit }}" = "" ]; then
            echo "Using specified branch: ${{ inputs.test_branch }}"
            echo "commit_sha=${{ inputs.test_branch }}" >> $GITHUB_OUTPUT
          else
            echo "Using specified commit: ${{ inputs.test_commit }}"
            echo "commit_sha=${{ inputs.test_commit }}" >> $GITHUB_OUTPUT
          fi

      - name: Checkout code at specific commit
        uses: actions/checkout@v2
        with:
          ref: ${{ steps.set_test.outputs.commit_sha }}
          submodules: 'recursive'

      - name: Set env
        run: |
          SHORT_SHA=$(git rev-parse --short HEAD)
          DATE=$(git show -s --format=%cd --date=format:%y%m%d HEAD)
          source /nfs/home/ci-runner/.ci_env
          echo "NODE_SERVER_LIST=$NODE_SERVER_LIST" >> $GITHUB_ENV
          echo "NOOP_HOME=$GITHUB_WORKSPACE" >> $GITHUB_ENV
          echo "NEMU_HOME=/nfs/home/share/ci-workloads/NEMU" >> $GITHUB_ENV
          echo "AM_HOME=/nfs/home/share/ci-workloads/nexus-am" >> $GITHUB_ENV
          echo "PERF_HOME=/nfs/home/share/ci-workloads/env-scripts/perf" >> $GITHUB_ENV
          echo "SPEC_DIR=/nfs/home/ci-runner/master-perf-report/cr${DATE}-${SHORT_SHA}" >> $GITHUB_ENV
          echo "CKPT_HOME=/nfs/home/share/checkpoints_profiles/spec06_rv64gcb_O3_20m_gcc12.2.0-intFpcOff-jeMalloc/checkpoint-0-0-0" >> $GITHUB_ENV

      - name: Clean Up
        run: |
          python3 $GITHUB_WORKSPACE/scripts/xiangshan.py --clean

      - name: Build EMU with DRAMsim3
        run: |
          if [ -e "$SPEC_DIR/emu" ]; then
            mkdir -p $NOOP_HOME/build
            cp $SPEC_DIR/emu $NOOP_HOME/build/emu
          else
            python3 $GITHUB_WORKSPACE/scripts/xiangshan.py --build          \
              --dramsim3 /nfs/home/share/ci-workloads/DRAMsim3              \
              --with-dramsim3 --threads 16                                  \
              --pgo $GITHUB_WORKSPACE/ready-to-run/coremark-2-iteration.bin \
              --llvm-profdata llvm-profdata --trace-fst
            mkdir -p $SPEC_DIR
            cp $NOOP_HOME/build/emu $SPEC_DIR/emu
          fi

      - name: Run SPEC CPU2006 checkpoints
        run: |
          cd $PERF_HOME
          python3 xs_autorun_multiServer.py $CKPT_HOME $CKPT_JSON_PATH \
            --xs $NOOP_HOME --threads 16 --dir $SPEC_DIR --resume \
            -L "$NODE_SERVER_LIST"
          find $NOOP_HOME/build/ -maxdepth 1 -name "*.vcd" -exec mv {} $SPEC_DIR \;
          find $NOOP_HOME/build/ -maxdepth 1 -name "*.fst" -exec mv {} $SPEC_DIR \;

      - name: Report SPEC CPU2006 score
        run: |
          cd $PERF_HOME
          python3 xs_autorun_multiServer.py $CKPT_HOME $CKPT_JSON_PATH \
            --xs $NOOP_HOME --threads 16 --dir $SPEC_DIR \
            --check --dump-json-path $SPEC_DIR/err_ckps.json
          python3 xs_autorun_multiServer.py $CKPT_HOME $CKPT_JSON_PATH \
            --xs $NOOP_HOME --threads 16 --dir $SPEC_DIR --report \
            > $SPEC_DIR/score.txt
          # mkdir $GITHUB_WORKSPACE/result
          # cp $SPEC_DIR/err_ckps.json $GITHUB_WORKSPACE/result/err_ckps.json
          # cp $SPEC_DIR/score.txt $GITHUB_WORKSPACE/result/score.txt

      - name: Summary result
        run: |
          echo "### :rocket: Performance Test Result" >> $GITHUB_STEP_SUMMARY
          echo '```' >> $GITHUB_STEP_SUMMARY
          echo "$SPEC_DIR/score.txt" >> $GITHUB_STEP_SUMMARY
          tail -n 39 $SPEC_DIR/score.txt >> $GITHUB_STEP_SUMMARY
          echo '```' >> $GITHUB_STEP_SUMMARY
          
          echo "### :rainbow: Key Indicators" >> $GITHUB_STEP_SUMMARY
          echo "Estimated SPEC CPU2006 Score per GHz: " >> $GITHUB_STEP_SUMMARY
          TOTAL_SCORE=$(grep "SPEC2006/GHz:" $SPEC_DIR/score.txt | awk '{print $NF}')
          INT_SCORE=$(grep "SPECint2006/GHz:" $SPEC_DIR/score.txt | awk '{print $NF}')
          FP_SCORE=$(grep "SPECfp2006/GHz:" $SPEC_DIR/score.txt | awk '{print $NF}')
          echo "- int: **${INT_SCORE}**" >> $GITHUB_STEP_SUMMARY
          echo "- fp: **${FP_SCORE}**" >> $GITHUB_STEP_SUMMARY
          echo "- total: **${TOTAL_SCORE}**" >> $GITHUB_STEP_SUMMARY

          if ! grep -q '^{\s*}$' $SPEC_DIR/err_ckps.json; then
            echo "### :sos: Failed Tests" >> $GITHUB_STEP_SUMMARY  
            echo '```' >> $GITHUB_STEP_SUMMARY
            cat $SPEC_DIR/err_ckps.json >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
          fi

      # - name: Upload result
      #   uses: actions/upload-artifact@v4
      #   with:
      #     name: result
      #     path: result
