Skip to content

Commit 7a1f9ae

Browse files
authored
Merge pull request #381 from vortexgpgpu/prism
PRISM: hardware ray tracing, graphics pipeline, Vulkan/HIP stacks, and CI 2.0
2 parents b70e0d5 + ce7044a commit 7a1f9ae

790 files changed

Lines changed: 277810 additions & 10144 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/apptainer-ci.yml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,11 @@ jobs:
100100
mkdir -p build32 && cd build32
101101
../configure --tooldir=$APPTAINER_TOOLDIR --xlen=32
102102
make software -s
103-
make tests -s
104-
pip install --quiet pytest pyyaml
103+
# Build only the regression category the smoke actually runs.
104+
# `make tests` also builds the opencl category, which links
105+
# -lOpenCL from the (ICD-less prebuilt pocl) toolchain and fails
106+
# in the container -- and the smoke never runs those tests.
107+
make -C tests regression -s
105108
chmod -R +x .
106109
VX_XLEN=32 python3 -m pytest ci -m "regression and simx" --strict-markers -v
107110
EOF

‎.github/workflows/ci.yml‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ on:
2020
description: "comma list: simx,rtlsim,xrtsim,opaesim (blank = all)"
2121
default: ""
2222
tier:
23-
description: "comma list: smoke,fast,slow,nightly (blank = all)"
23+
description: "comma list: smoke,full,nightly (blank = all)"
2424
default: ""
2525

2626
env:
@@ -68,15 +68,17 @@ jobs:
6868
IN_DRIVERS: ${{ github.event.inputs.drivers }}
6969
IN_TIER: ${{ github.event.inputs.tier }}
7070
TOOLCHAIN_CACHE_HIT: ${{ steps.tc.outputs.cache-hit }}
71+
PUSH_BEFORE: ${{ github.event.before }}
72+
PR_BASE: ${{ github.event.pull_request.base.sha }}
7173
run: |
7274
set -euo pipefail
7375
# Driver/tier policy by event (workflow_dispatch overrides).
7476
case "$EVENT" in
7577
schedule) DRIVERS=""; TIER="" ;; # everything
76-
pull_request) DRIVERS="simx,rtlsim"; TIER="smoke,fast,slow" ;;
77-
push) DRIVERS="simx"; TIER="smoke,fast" ;;
78+
pull_request) DRIVERS="simx,rtlsim"; TIER="smoke,full" ;;
79+
push) DRIVERS="simx"; TIER="smoke" ;;
7880
workflow_dispatch) DRIVERS="$IN_DRIVERS"; TIER="$IN_TIER" ;;
79-
*) DRIVERS="simx"; TIER="smoke,fast" ;;
81+
*) DRIVERS="simx"; TIER="smoke" ;;
8082
esac
8183
# Toolchain (re)built -> 100% coverage. If the toolchain cache missed
8284
# (deleted / out-of-date / evicted / key changed / first run) the build
@@ -90,6 +92,21 @@ jobs:
9092
DRIVERS=""; TIER=""
9193
fi
9294
fi
95+
# Change-aware driver escalation: simx is a separate C++ model and cannot
96+
# exercise the RTL, so a change under hw/rtl, hw/dpi, sim/rtlsim|xrtsim|
97+
# opaesim, or vendored RTL must force the matching sim driver in even on a
98+
# push (which is otherwise simx-only). An indeterminate diff (zero/missing
99+
# base, e.g. a new branch or force-push) escalates to full coverage.
100+
if { [ "$EVENT" = "push" ] || [ "$EVENT" = "pull_request" ]; } && [ -n "$DRIVERS" ]; then
101+
BASE="$PUSH_BEFORE"; [ "$EVENT" = "pull_request" ] && BASE="$PR_BASE"
102+
ESC=$(python3 ci/testcase.py drivers --changed-from="$BASE" || echo ALL)
103+
if [ "$ESC" = "ALL" ]; then
104+
echo "indeterminate diff -> full driver coverage"; DRIVERS=""
105+
elif [ -n "$ESC" ]; then
106+
DRIVERS=$(printf '%s\n' "$DRIVERS" "$ESC" | tr ',' '\n' | grep . | sort -u | paste -sd,)
107+
echo "RTL-affecting change -> drivers=$DRIVERS"
108+
fi
109+
fi
93110
F=""
94111
[ -n "$DRIVERS" ] && F="$F --drivers=$DRIVERS"
95112
[ -n "$TIER" ] && F="$F --tier=$TIER"
@@ -185,6 +202,14 @@ jobs:
185202
chmod -R +x .
186203
EXPR="${{ matrix.category }}"
187204
[ "${{ matrix.driver }}" != "host" ] && EXPR="$EXPR and ${{ matrix.driver }}"
205+
# model_parity / perf_gate are cross-cutting check markers with
206+
# their own dedicated cells; exclude them from every other category's
207+
# cell so a distributed check spec runs once (in its check cell), not
208+
# twice (also in its owning category's cell).
209+
case "${{ matrix.category }}" in
210+
model_parity|perf_gate) ;;
211+
*) EXPR="$EXPR and not model_parity and not perf_gate" ;;
212+
esac
188213
VX_XLEN=${{ matrix.xlen }} python3 -m pytest ci -m "$EXPR" --strict-markers \
189214
-v \
190215
--junitxml="$GITHUB_WORKSPACE/junit-${{ matrix.category }}-${{ matrix.driver }}-${{ matrix.xlen }}.xml"

‎.gitignore‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
/build*
2-
/.*
2+
/.*
3+
# Archived/superseded docs — kept on disk, never tracked
4+
docs/archives/

‎AGENTS.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ See [docs/install_vortex.md](docs/install_vortex.md) for the full recipe. The no
5252
```
5353
- **Separate build dirs per major variant** (`build32/`, `build64/`, `build_fpga64/`, ...) to avoid config/tool contamination. Never reuse one build dir for incompatible configurations.
5454
- **`configure` generates a runnable tree** by copying and instantiating `ci/`, `runtime/`, `sim/`, and `tests/` into `build/`. For execution and test automation, *always* prefer the generated scripts/Makefiles under `build/` over the source-tree `.in` files.
55-
- **Re-`../configure` from `build/`** whenever you `git pull`, edit source Makefiles, or add/remove a build-participating directory. Symptom of forgetting this: stale binaries, missing targets, or "I edited this Makefile and nothing happened."
55+
- **Re-`../configure` from `build/`** whenever you `git pull`, edit source Makefiles, edit `VX_config.toml` / any `*.toml`, or add/remove a build-participating directory. Symptom of forgetting this: stale binaries, missing targets, or "I edited this Makefile and nothing happened."
56+
- **Always ensure the build is current before running any test or app** — re-run `../configure` from `build/` first. `configure` regenerates `<build>/sw/VX_config.h` and `<build>/hw/*.vh` from `VX_config.toml`, but only when the toml is newer (it guards on mtime). The simx/RTL **cores `#include` this generated header**, so a stale header makes a core compile against old config values and silently diverge from the toml — and from the runtime/RTL, which re-expand the config every build. This is a real footgun: a stale `VX_config.h` once made SimX run a write-back D-cache while the toml/RTL were write-through, producing SimX-only wrong results. **Never** work around such a divergence by injecting `-DVX_CFG_*` overrides into a Makefile — that masks the stale artifact and fights the config system. The toml is the single source of truth; fix it by re-`configure`-ing.
5657
- **`ccache` can serve stale objects on `fmt`-version mismatches** (typical symptom: `fmt::v8` undefined-reference link errors in sim builds). Before deep-diving, retry with `CCACHE_DISABLE=1`.
5758

5859
---
@@ -83,6 +84,8 @@ See [docs/testing.md](docs/testing.md) and [docs/debugging.md](docs/debugging.md
8384
- **`--rebuild=1` forces a driver rebuild** even if the hardware configuration is unchanged. Use it when iterating on the driver itself; `--rebuild=0` suppresses rebuild regardless.
8485
- **RTL coverage path is `xrt`, not `rtlsim`.** When discussing or planning RTL verification, `xrt` is the canonical path — `rtlsim` bypasses the AFU surface. `rtlsim` remains useful for fast iteration on processor RTL; `xrt` is what proves the full integration.
8586
- **`ci/regression.sh` is the canonical source of tested configurations.** Use it to discover supported parameter combinations before inventing ad hoc ones.
87+
- **Perf-regression baselines (`ci/perf/baselines/*.json`) are golden data — never hand-edit them, and never "fix" a red perf gate by bumping the number.** They are regenerated only by `pytest ci -m perf_gate --update-baselines` (a human-run, reviewed step), and CI must never pass that flag. A `perf_gate` failure means real cycles moved: root-cause it, or — if the change is intended — regenerate the baseline so the diff shows the perf delta for review. Same rule as image goldens and `known_issue:`.
88+
- **SimX is the RTL's timing model — keep them in lockstep.** Any change that moves RTL cycles (pipeline structure, arbitration, queue depths, cache/memory behavior) must land together with the matching SimX timing-model update, and vice-versa. The `model_parity` CI gate enforces this: a `check: model_parity` case (`ci/testcases/model_parity.yaml` + per-extension parity categories) runs the same app/args/configs on simx and rtlsim and asserts exact retired-instruction match plus cycle agreement within the case tolerance (default 5%). Never widen a tolerance to absorb a divergence — model the behavior. When adding a hardware feature, add or extend a parity case that exercises it.
8689
- **When RTL debugging stalls, switch to the SimX-as-oracle pattern.** For numerical bugs, deep pipeline races, or any failure mode where rtlsim is "close but wrong": (1) build/extend the SimX C++ model so it mirrors the *new* RTL architecture and gets to PASS; (2) add matching trace dumps to both SimX and RTL (cycle, FU events, SRAM addresses+data, hazards) — same CSV format on both sides; (3) diff trace files — the first divergence is the bug. Don't keep guessing from output values; localize via trace diff. See [docs/debugging.md](docs/debugging.md#simx-as-oracle-for-rtl-debug).
8790

8891
### Smoke tests
@@ -111,6 +114,8 @@ make -C tests/opencl run-rtlsim
111114

112115
- **Align with mainstream CUDA, HIP, OpenCL, and Vulkan API and driver stacks.** For any design question — driver surface, command-processor model, memory model, scheduling — pick the solution those stacks would use. This keeps Vortex's externals familiar to mainstream software and avoids one-off abstractions.
113116

117+
- **SimX Cardinal Rule — modules communicate *only* through channels.** A `SimObject` may observe or mutate another module's state *only* via its bound `SimChannel` ports (`MemReq`/`MemRsp`, `result_if`, …). **Never reach across the ownership hierarchy** to touch another object directly (`core_->processor()->memsim()`, `parent()->child()->field`, a leaf unit grabbing the global `Memory`). See [docs/simobject.md](docs/simobject.md#the-cardinal-rule).
118+
114119
---
115120

116121
## 6. Coding Conventions

0 commit comments

Comments
 (0)