refactor: 将DCache prefetch纳入低优先级MSHR路径 #122
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: ["**"] | |
| pull_request: | |
| branches: ["**"] | |
| jobs: | |
| build-test: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 120 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Init Submodules | |
| run: git submodule update --init --recursive | |
| - name: Install Test Dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libgtest-dev \ | |
| gcc-riscv64-unknown-elf \ | |
| binutils-riscv64-unknown-elf \ | |
| picolibc-riscv64-unknown-elf \ | |
| device-tree-compiler \ | |
| libboost-regex-dev \ | |
| libboost-system-dev \ | |
| libboost-filesystem-dev | |
| sudo cmake -S /usr/src/googletest -B /tmp/gtest | |
| sudo cmake --build /tmp/gtest | |
| sudo install -m 644 /tmp/gtest/lib/libgtest*.a /usr/lib | |
| - name: Resolve Spike Commit | |
| id: spike_ref | |
| run: | | |
| set -euo pipefail | |
| SPIKE_COMMIT="$(git ls-remote https://github.com/riscv-software-src/riscv-isa-sim.git HEAD | awk '{print $1}')" | |
| echo "commit=${SPIKE_COMMIT}" >> "$GITHUB_OUTPUT" | |
| - name: Cache Spike Install | |
| id: cache_spike | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: | | |
| ~/.cache/riscv-isa-sim/install | |
| key: spike-${{ runner.os }}-${{ steps.spike_ref.outputs.commit }} | |
| restore-keys: | | |
| spike-${{ runner.os }}- | |
| - name: Build and Install Spike (riscv-isa-sim) | |
| id: build_spike | |
| run: | | |
| set -euo pipefail | |
| SPIKE_PREFIX="${HOME}/.cache/riscv-isa-sim/install" | |
| if [[ ! -x "${SPIKE_PREFIX}/bin/spike" ]]; then | |
| rm -rf /tmp/riscv-isa-sim | |
| git clone --depth 1 https://github.com/riscv-software-src/riscv-isa-sim.git /tmp/riscv-isa-sim | |
| cd /tmp/riscv-isa-sim | |
| mkdir -p build | |
| cd build | |
| ../configure --prefix="${SPIKE_PREFIX}" | |
| make -j"$(nproc)" | |
| make install | |
| fi | |
| echo "${SPIKE_PREFIX}/bin" >> "$GITHUB_PATH" | |
| export PATH="${SPIKE_PREFIX}/bin:${PATH}" | |
| command -v spike | |
| - name: Save Spike Cache | |
| if: ${{ always() && steps.cache_spike.outputs.cache-hit != 'true' && steps.build_spike.outcome == 'success' }} | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: | | |
| ~/.cache/riscv-isa-sim/install | |
| key: spike-${{ runner.os }}-${{ steps.spike_ref.outputs.commit }} | |
| - name: Install RISCOF | |
| run: | | |
| python3 -m pip install --upgrade pip | |
| python3 -m pip install git+https://github.com/riscv/riscof.git | |
| # Pin to repository-local versions to avoid riscof/riscv-isac API mismatch. | |
| python3 -m pip install -e ./riscv-arch-test/riscv-isac | |
| python3 -m pip install -e ./riscv-arch-test/riscv-ctg | |
| python3 - <<'PY' | |
| from riscv_isac import isac | |
| assert hasattr(isac, "preprocessing"), "riscv-isac missing preprocessing()" | |
| print("riscv-isac API check: preprocessing() available") | |
| PY | |
| - name: Build ISA Tests (p-only) | |
| run: | | |
| make -C riscv-tests/isa -f Makefile \ | |
| src_dir="${GITHUB_WORKSPACE}/riscv-tests/isa" \ | |
| XLEN=64 \ | |
| tests='$(rv32ui_p_tests) $(rv32uc_p_tests) $(rv32um_p_tests) $(rv32ua_p_tests) $(rv32uf_p_tests) $(rv32ud_p_tests) $(rv32uzfh_p_tests) $(rv32uzba_p_tests) $(rv32uzbb_p_tests) $(rv32uzbc_p_tests) $(rv32uzbs_p_tests) $(rv32si_p_tests) $(rv32mi_p_tests) $(rv64ui_p_tests) $(rv64ua_p_tests) $(rv64uc_p_tests) $(rv64ud_p_tests) $(rv64uf_p_tests) $(rv64um_p_tests)' | |
| - name: Build riscv-tests Benchmarks | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| include_dir="/usr/lib/picolibc/riscv64-unknown-elf/include" | |
| if [[ ! -d "${include_dir}" ]]; then | |
| include_dir="$(dpkg -L picolibc-riscv64-unknown-elf | grep '/include$' | head -n1)" | |
| fi | |
| libm_path="$(find /usr/lib/picolibc/riscv64-unknown-elf/lib -path '*rv64*lp64d*/libm.a' -print | head -n1 || true)" | |
| if [[ -z "${libm_path}" ]]; then | |
| libm_path="$(dpkg -L picolibc-riscv64-unknown-elf | grep '/libm\.a$' | grep 'rv64' | grep 'lp64d' | head -n1 || true)" | |
| fi | |
| if [[ -z "${libm_path}" ]]; then | |
| echo "ERROR: 未找到 rv64/lp64d 的 picolibc libm.a,请检查 runner 上的 picolibc 包内容" >&2 | |
| exit 1 | |
| fi | |
| lib_dir="$(dirname "${libm_path}")" | |
| riscv_gcc_benchmark="riscv64-unknown-elf-gcc" | |
| specs_file="$(riscv64-unknown-elf-gcc -print-file-name=picolibc.specs)" | |
| if [[ "${specs_file}" != "picolibc.specs" && -f "${specs_file}" ]]; then | |
| riscv_gcc_benchmark="riscv64-unknown-elf-gcc -specs=${specs_file}" | |
| echo "Detected picolibc specs: ${specs_file}" | |
| else | |
| echo "picolibc.specs not found in GCC search path, fallback to default gcc + LIBRARY_PATH" | |
| fi | |
| echo "Detected include dir: ${include_dir}" | |
| echo "Detected lib dir: ${lib_dir}" | |
| make -C riscv-tests/benchmarks -f Makefile \ | |
| src_dir="${GITHUB_WORKSPACE}/riscv-tests/benchmarks" \ | |
| XLEN=64 \ | |
| CPATH="${include_dir}" \ | |
| C_INCLUDE_PATH="${include_dir}" \ | |
| LIBRARY_PATH="${lib_dir}" \ | |
| RISCV_GCC="${riscv_gcc_benchmark}" | |
| - name: Configure | |
| run: cmake -S . -B build | |
| - name: Build | |
| run: cmake --build build -j | |
| - name: Unit Tests | |
| run: ctest --test-dir build --output-on-failure | |
| - name: ISA Tests (rv64, in-order + ooo) | |
| run: | | |
| python3 run_tests.py -p "rv64*-p-*" -w 1 --timeout 20 | |
| python3 run_tests.py -p "rv64*-p-*" --ooo -w 1 --timeout 30 | |
| - name: RISCOF Arch Tests (full, in-order + ooo) | |
| run: | | |
| set -euo pipefail | |
| command -v spike | |
| command -v riscof | |
| cd tools/riscof | |
| export PYTHONPATH="$PWD/plugins/riscv_sim:${PYTHONPATH:-}" | |
| for mode in in_order ooo; do | |
| if [[ "${mode}" == "in_order" ]]; then | |
| CONFIG_FILE="./config.ini" | |
| WORK_DIR="${GITHUB_WORKSPACE}/build/riscof-work" | |
| else | |
| CONFIG_FILE="./config_ooo.ini" | |
| WORK_DIR="${GITHUB_WORKSPACE}/build/riscof-work-ooo" | |
| fi | |
| RAW_TEST_LIST="${WORK_DIR}/test_list.yaml" | |
| FILTERED_TEST_LIST="${WORK_DIR}/test_list_ci.yaml" | |
| export RAW_TEST_LIST FILTERED_TEST_LIST | |
| echo "=== RISCOF mode: ${mode} (config=${CONFIG_FILE}) ===" | |
| riscof validateyaml \ | |
| --config "${CONFIG_FILE}" \ | |
| --work-dir "${WORK_DIR}" | |
| riscof testlist \ | |
| --config "${CONFIG_FILE}" \ | |
| --suite ../../riscv-arch-test/riscv-test-suite \ | |
| --env ../../riscv-arch-test/riscv-test-suite/env \ | |
| --work-dir "${WORK_DIR}" | |
| # CI 临时跳过已知不稳定集合:pmp / privilege | |
| python3 -c ' | |
| import os | |
| import yaml | |
| from pathlib import Path | |
| src = Path(os.environ["RAW_TEST_LIST"]) | |
| dst = Path(os.environ["FILTERED_TEST_LIST"]) | |
| data = yaml.safe_load(src.read_text()) or {} | |
| def should_skip(test_key: str, test_entry: dict) -> bool: | |
| path = str(test_key) | |
| test_path = str(test_entry.get("test_path", "")) | |
| target = f"{path} {test_path}" | |
| if "/pmp/src/" in target: | |
| return True | |
| if "/privilege/src/" in target: | |
| return True | |
| return False | |
| filtered = {k: v for k, v in data.items() if not should_skip(k, v)} | |
| dst.write_text(yaml.safe_dump(filtered, sort_keys=False)) | |
| print(f"RISCOF CI test filter: total={len(data)}, kept={len(filtered)}, skipped={len(data)-len(filtered)}") | |
| if not filtered: | |
| raise SystemExit("No tests left after CI filtering") | |
| ' | |
| ls -l "${FILTERED_TEST_LIST}" | |
| riscof run \ | |
| --config "${CONFIG_FILE}" \ | |
| --suite ../../riscv-arch-test/riscv-test-suite \ | |
| --env ../../riscv-arch-test/riscv-test-suite/env \ | |
| --work-dir "${WORK_DIR}" \ | |
| --testfile "${FILTERED_TEST_LIST}" \ | |
| --no-browser | |
| done | |
| - name: Benchmarks (supported, blocking) | |
| run: | | |
| supported_benchmarks=( | |
| dhrystone.riscv | |
| median.riscv | |
| memcpy.riscv | |
| mm.riscv | |
| mt-matmul.riscv | |
| mt-memcpy.riscv | |
| mt-vvadd.riscv | |
| multiply.riscv | |
| qsort.riscv | |
| rsort.riscv | |
| spmv.riscv | |
| towers.riscv | |
| vvadd.riscv | |
| ) | |
| for benchmark in "${supported_benchmarks[@]}"; do | |
| echo "Running benchmark: ${benchmark}" | |
| python3 run_tests.py --tests-subdir benchmarks -p "${benchmark}" -w 1 --timeout 180 | |
| done | |
| - name: Benchmarks (known unsupported, non-blocking) | |
| continue-on-error: true | |
| run: | | |
| known_unsupported=( | |
| vec-daxpy.riscv | |
| vec-memcpy.riscv | |
| vec-sgemm.riscv | |
| vec-strcmp.riscv | |
| ) | |
| for benchmark in "${known_unsupported[@]}"; do | |
| echo "Running known-unsupported benchmark: ${benchmark}" | |
| python3 run_tests.py --tests-subdir benchmarks -p "${benchmark}" -w 1 --timeout 180 || true | |
| done | |
| - name: Upload RISCOF Report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: riscof-report | |
| path: | | |
| build/riscof-work/report.html | |
| build/riscof-work/test_list.yaml | |
| build/riscof-work/test_list_ci.yaml | |
| build/riscof-work/**/*.log | |
| build/riscof-work/**/*.signature | |
| build/riscof-work-ooo/report.html | |
| build/riscof-work-ooo/test_list.yaml | |
| build/riscof-work-ooo/test_list_ci.yaml | |
| build/riscof-work-ooo/**/*.log | |
| build/riscof-work-ooo/**/*.signature |