将 QEMU(KVM 加速的宿主机 CPU/系统仿真)与 gem5(周期精确的 MI300X GPU 模型)相结合的联合仿真框架,无需物理 GPU 硬件即可运行真实的 AMD ROCm/HIP 工作负载。
+-----------------------------+ +----------------------------+
| QEMU (Q35 + KVM) | | gem5 (Docker) |
| +-----------------------+ | | +----------------------+ |
| | Guest Linux | | | | MI300X GPU Model | |
| | amdgpu driver | | | | Shader / CU / SDMA | |
| | ROCm 7.0 / HIP | | | | PM4 / Ruby caches | |
| +----------+------------+ | | +---------+------------+ |
| +----------v------------+ | | +---------v------------+ |
| | vfio-user-pci |<-------->| | MI300XVfioUser | |
| | (QEMU built-in) | |vfio- | | (libvfio-user) | |
| +-----------------------+ |user | +----------------------+ |
+-----------------------------+ +----------------------------+
| |
v v
/dev/shm/cosim-guest-ram /dev/shm/mi300x-vram
(shared guest RAM) (shared GPU VRAM)
- 完整驱动加载 — amdgpu DRM 初始化,7 个 XCP 分区,gfx942 架构
- HIP 计算验证 — hipMalloc、内核调度、hipDeviceSynchronize 全流程通过
- MSI-X 中断转发 — gem5 → QEMU 中断转发,IH ring buffer 正常工作
- 共享内存 DMA — 通过
/dev/shm实现 VRAM 和 Guest RAM 的零拷贝共享 - 驱动自动加载 — systemd 服务自动以
ip_block_mask=0x67 discovery=2加载
| 需求 | 说明 |
|---|---|
| 宿主机系统 | Linux x86_64,支持 KVM(已在 WSL2 6.6.x 验证) |
| Docker | 守护进程运行中,当前用户在 docker 组 |
| KVM | /dev/kvm 可访问 |
| 磁盘空间 | 约 120 GB(55G 磁盘镜像 + 构建中间产物) |
| 内存 | 建议 16 GB 以上 |
git clone --recurse-submodules git@github.com:zevorn/cosim.git
cd cosim
# 构建 gem5 + QEMU + 磁盘镜像(总计约 2 小时,需要 KVM + Docker + 约 60GB 磁盘空间)
GEM5_BUILD_IMAGE=ghcr.io/gem5/gpu-fs:latest ./scripts/run_mi300x_fs.sh build-all
# 构建运行时 Docker 镜像(用于在 Docker 内运行 gem5)
cd scripts && docker build -t gem5-run:local -f Dockerfile.run . && cd ..
# 启动联合仿真
./scripts/cosim_launch.sh# 1. 克隆仓库(含子模块)
git clone --recurse-submodules git@github.com:zevorn/cosim.git
cd cosim
# 2. 编译 gem5(Docker 内,约 30 分钟;链接阶段 OOM 可改用 -j1)
cd gem5
docker run --rm -v "$(pwd):/gem5" -w /gem5 \
-e PYTHONPATH=/usr/lib/python3.12/lib-dynload \
ghcr.io/gem5/gpu-fs:latest \
bash -c "scons build/VEGA_X86/gem5.opt -j4 GOLD_LINKER=True --linker=gold"
cd ..
# 3. 构建运行时 Docker 镜像(用于在 Docker 内运行 gem5)
cd scripts && docker build -t gem5-run:local -f Dockerfile.run . && cd ..
# 4. 编译 QEMU(标准构建;vfio-user-pci 自 QEMU 10.0 起内置)
cd qemu && mkdir -p build && cd build
../configure --target-list=x86_64-softmmu
make -j$(nproc)
cd ../..
# 5. 预编译 m5 工具(推荐 - 避免构建磁盘镜像时在 Guest 内 git clone)
docker run --rm -v "$(pwd)/gem5:/gem5" -w /gem5 \
ghcr.io/gem5/gpu-fs:latest \
bash -c "cd util/m5 && scons build/x86/out/m5"
cp gem5/util/m5/build/x86/out/m5 gem5-resources/src/x86-ubuntu-gpu-ml/files/
# 6. 构建磁盘镜像(Ubuntu 24.04 + ROCm 7.0,约 40 分钟,需要 KVM + 约 60GB 磁盘空间)
./scripts/run_mi300x_fs.sh build-disk
# 7. 启动联合仿真
./scripts/cosim_launch.shGuest 启动后(自动以 root 登录),GPU 驱动通过 cosim-gpu-setup.service
自动加载(约 40 秒)。验证:
rocm-smi # 应显示设备 0x74a0
rocminfo # 应显示 gfx942
# 手动加载(如果 systemd 服务未安装):
dd if=/root/roms/mi300.rom of=/dev/mem bs=1k seek=768 count=128
modprobe amdgpu ip_block_mask=0x67 discovery=2 ras_enable=0
# 运行 HIP 测试
cat > /tmp/test.cpp << 'EOF'
#include <hip/hip_runtime.h>
#include <cstdio>
__global__ void add(int *a, int *b, int *c, int n) {
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < n) c[i] = a[i] + b[i];
}
int main() {
const int N = 4;
int ha[] = {1,2,3,4}, hb[] = {10,20,30,40}, hc[4] = {};
int *da, *db, *dc;
hipMalloc(&da, N*4); hipMalloc(&db, N*4); hipMalloc(&dc, N*4);
hipMemcpy(da, ha, N*4, hipMemcpyHostToDevice);
hipMemcpy(db, hb, N*4, hipMemcpyHostToDevice);
add<<<1, N>>>(da, db, dc, N);
hipMemcpy(hc, dc, N*4, hipMemcpyDeviceToHost);
printf("Result: %d %d %d %d\n", hc[0], hc[1], hc[2], hc[3]);
printf("%s\n", (hc[0]==11&&hc[1]==22&&hc[2]==33&&hc[3]==44) ? "PASSED!" : "FAILED!");
hipFree(da); hipFree(db); hipFree(dc);
}
EOF
/opt/rocm/bin/hipcc --offload-arch=gfx942 -o /tmp/test /tmp/test.cpp
/tmp/test
# 预期输出: Result: 11 22 33 44
# PASSED!cosim/
|-- gem5/ # gem5 simulator (submodule, cosim-gpu branch)
| |-- src/dev/amdgpu/ # MI300X GPU device model & vfio-user bridge
| |-- ext/libvfio-user/ # libvfio-user library (Nutanix)
| `-- configs/example/gpufs/mi300_cosim.py # cosim configuration
|-- qemu/ # QEMU emulator (submodule, stock QEMU 10.0+)
|-- gem5-resources/ # disk images, kernels, GPU apps (submodule)
|-- scripts/ # build & launch scripts
| |-- cosim_launch.sh # one-click cosim launcher
| |-- run_mi300x_fs.sh # build orchestration
| |-- cosim_guest_setup.sh # guest-side GPU setup
| |-- cosim_test_client.py # socket test client
| `-- Dockerfile.run # gem5 runtime Docker image
|-- docs/ # technical documentation (zh + en)
| |-- en/ # English
| `-- zh/ # Chinese
|-- LICENSE # Apache 2.0
`-- README.md
详细技术文档位于 docs/ 目录下:
- 完整使用指南 — 从编译到运行 HIP 测试的全流程
- 技术笔记 — 架构设计、踩坑记录、修复方案
- MI300X 内存管理 — GART、地址翻译、内存映射
- GPU 全系统仿真指南 — gem5 单机 GPU FS 仿真复现
- Guest GPU 初始化流程 — 驱动加载与设备初始化
- 内存架构 — 共享内存、VRAM 路由、DMA
- 调试踩坑记录 — 常见问题与解决方案
- 开发故事 — 一天时间用 Claude 构建 cosim-gpu 的全过程
| 组件 | 版本 |
|---|---|
| Guest 操作系统 | Ubuntu 24.04.2 LTS |
| Guest 内核 | 6.8.0-79-generic |
| ROCm | 7.0.0 |
| GPU 设备 | MI300X (gfx942, DeviceID 0x74A0) |
| gem5 构建目标 | VEGA_X86, GPU_VIPER 一致性协议 |
本项目采用 Apache License 2.0 许可证。
注意:gem5 和 qemu 子模块分别遵循各自的许可证(gem5: BSD-3-Clause, QEMU: GPL-2.0)。