summaryrefslogtreecommitdiffstats
path: root/tools/benchmark_infrastructure.sh
diff options
context:
space:
mode:
authorOpen-IOV <dev@open-iov.org>2026-09-23 05:44:08 -0400
committerOpen-IOV <dev@open-iov.org>2026-09-23 05:46:43 -0400
commit2302fc09080bad51c73f293294e19fd4db464eb0 (patch)
treec722d186347fdef5a34131e9e143b1549b1daf8e /tools/benchmark_infrastructure.sh
downloadopen-iov-2302fc09080bad51c73f293294e19fd4db464eb0.tar.gz
open-iov-2302fc09080bad51c73f293294e19fd4db464eb0.zip
Open-IOV: initial public release
Open-IOV virtualizes NVIDIA GPUs so that unmodified guest drivers run with real GPU functionality - CUDA first, 3D and video to follow - on unmodified hosts, without a proprietary vGPU license and without patching any driver, firmware or hypervisor. Core principle: emulate the interface, pass through the work. kernel/ open-iov-vfio.ko - host VFIO mdev driver: virtual GPU device (PCI config space, BAR shadows, MSI-X), GSP boot emulation, GSP-RM message-queue/RPC emulation, memory model (GPU-VA to guest-PA discovery) and the semaphore-completion service that advances guest UVM progress. userspace/ libiov.so management API and examples. tools/ guest diagnostics, firmware analysis wrappers, RM probes. scripts/ stack manager, VM harness, build/load/test automation. config/ hardware/version profiles (the portability surface). docs/ documentation tree - start at docs/README.md. wiki/ long-form firmware and protocol deep dives. Status: initialization works end to end for a stock 570.144 Linux guest on Turing (TU104): driver probe, nvidia-smi, the full GSP-RM control battery, object creation and the early CUDA/UVM start-up path. GPU work forwarding - the step that makes CUDA kernels execute on real hardware - is the active work item; see docs/04-implementation/01-known-knowns-and-unknowns.md. License: BSD-3-Clause for the project; GPL-2.0 for kernel modules that link GPL-only kernel interfaces. See LICENSE and docs/09-reference/legal-and-licensing.md.
Diffstat (limited to 'tools/benchmark_infrastructure.sh')
-rwxr-xr-xtools/benchmark_infrastructure.sh217
1 files changed, 217 insertions, 0 deletions
diff --git a/tools/benchmark_infrastructure.sh b/tools/benchmark_infrastructure.sh
new file mode 100755
index 0000000..606aa10
--- /dev/null
+++ b/tools/benchmark_infrastructure.sh
@@ -0,0 +1,217 @@
+#!/bin/bash
+# benchmark_infrastructure.sh - Benchmark runner for VM vs bare metal comparison
+
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+BASE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
+
+RESULTS_DIR="/tmp/gsp_emu_benchmarks/$(date +%Y%m%d_%H%M%S)"
+mkdir -p "$RESULTS_DIR"
+
+log_info() { echo -e "\033[0;34m[INFO]\033[0m $1"; }
+log_ok() { echo -e "\033[0;32m[OK]\033[0m $1"; }
+log_warn() { echo -e "\033[1;33m[WARN]\033[0m $1"; }
+
+run_bare_metal() {
+ local test_name=$1
+ shift
+ log_info "Running $test_name on bare metal..."
+ local output="$RESULTS_DIR/bare_metal_${test_name}.json"
+ "$@" --benchmark --output "$output" 2>&1 | tee "$RESULTS_DIR/bare_metal_${test_name}.log"
+}
+
+run_in_vm() {
+ local test_name=$1
+ shift
+ log_info "Running $test_name in VM..."
+ local output="$RESULTS_DIR/vm_${test_name}.json"
+ # This would run inside the guest via guest_test_agent
+ # For now, placeholder
+ echo '{"test": "'$test_name'", "status": "not_implemented"}' > "$output"
+}
+
+compare_results() {
+ local test_name=$1
+ local bare_file="$RESULTS_DIR/bare_metal_${test_name}.json"
+ local vm_file="$RESULTS_DIR/vm_${test_name}.json"
+
+ if [[ -f "$bare_file" && -f "$vm_file" ]]; then
+ python3 -c "
+import json, sys
+with open('$bare_file') as f: bare = json.load(f)
+with open('$vm_file') as f: vm = json.load(f)
+print(f'Test: $test_name')
+for key in bare:
+ if key in vm and isinstance(bare[key], (int, float)) and isinstance(vm[key], (int, float)):
+ ratio = vm[key] / bare[key] * 100
+ print(f' {key}: bare={bare[key]:.2f} vm={vm[key]:.2f} ratio={ratio:.1f}%')
+"
+ fi
+}
+
+# CUDA benchmarks
+benchmark_cuda() {
+ log_info "=== CUDA Benchmarks ==="
+
+ # vectorAdd
+ run_bare_metal "vectorAdd" /usr/local/cuda/samples/1_Utilities/vectorAdd/vectorAdd
+ run_in_vm "vectorAdd"
+ compare_results "vectorAdd"
+
+ # matrixMul
+ run_bare_metal "matrixMul" /usr/local/cuda/samples/0_Simple/matrixMul/matrixMul
+ run_in_vm "matrixMul"
+ compare_results "matrixMul"
+
+ # deviceQuery (bandwidth)
+ run_bare_metal "deviceQuery" /usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQuery
+ run_in_vm "deviceQuery"
+ compare_results "deviceQuery"
+
+ # bandwidthTest
+ run_bare_metal "bandwidthTest" /usr/local/cuda/samples/1_Utilities/bandwidthTest/bandwidthTest
+ run_in_vm "bandwidthTest"
+ compare_results "bandwidthTest"
+}
+
+# cuBLAS benchmarks
+benchmark_cublas() {
+ log_info "=== cuBLAS Benchmarks ==="
+ run_bare_metal "cublas_sgemm" /usr/local/cuda/samples/7_CUDALibraries/simpleCUBLAS/simpleCUBLAS
+ run_in_vm "cublas_sgemm"
+ compare_results "cublas_sgemm"
+}
+
+# Graphics benchmarks
+benchmark_graphics() {
+ log_info "=== Graphics Benchmarks ==="
+
+ # vkcube (frame time)
+ run_bare_metal "vkcube" vkcube --duration 10 --benchmark
+ run_in_vm "vkcube"
+ compare_results "vkcube"
+
+ # glmark2
+ run_bare_metal "glmark2" glmark2 --benchmark
+ run_in_vm "glmark2"
+ compare_results "glmark2"
+}
+
+# Video benchmarks
+benchmark_video() {
+ log_info "=== Video Benchmarks ==="
+
+ # NVENC encode
+ run_bare_metal "nvenc_encode" ffmpeg -i test_1080p.yuv -c:v h264_nvenc -f null -
+ run_in_vm "nvenc_encode"
+ compare_results "nvenc_encode"
+
+ # NVDEC decode
+ run_bare_metal "nvdec_decode" ffmpeg -i test_1080p.h264 -c:v h264_nvdec -f null -
+ run_in_vm "nvdec_decode"
+ compare_results "nvdec_decode"
+}
+
+# PyTorch benchmarks
+benchmark_pytorch() {
+ log_info "=== PyTorch Benchmarks ==="
+
+ cat > /tmp/bench_pytorch.py <<'EOF'
+import torch, time, json, sys
+device = 'cuda' if torch.cuda.is_available() else 'cpu'
+results = {}
+
+# Matmul benchmark
+for size in [512, 1024, 2048, 4096]:
+ x = torch.randn(size, size, device=device)
+ y = torch.randn(size, size, device=device)
+ torch.cuda.synchronize() if device == 'cuda' else None
+ start = time.time()
+ for _ in range(10):
+ z = torch.mm(x, y)
+ torch.cuda.synchronize() if device == 'cuda' else None
+ elapsed = (time.time() - start) / 10
+ gflops = 2 * size**3 / elapsed / 1e9
+ results[f'matmul_{size}'] = {'time': elapsed, 'gflops': gflops}
+ print(f"Matmul {size}x{size}: {elapsed:.4f}s ({gflops:.1f} GFLOPS)")
+
+# ResNet-50 forward
+import torchvision.models as models
+model = models.resnet50().to(device)
+model.eval()
+x = torch.randn(32, 3, 224, 224).to(device)
+torch.cuda.synchronize() if device == 'cuda' else None
+start = time.time()
+for _ in range(10):
+ with torch.no_grad():
+ _ = model(x)
+torch.cuda.synchronize() if device == 'cuda' else None
+elapsed = (time.time() - start) / 10
+results['resnet50_forward'] = {'time': elapsed, 'fps': 32/elapsed}
+print(f"ResNet-50 forward: {elapsed:.4f}s ({32/elapsed:.1f} FPS)")
+
+with open(sys.argv[1], 'w') as f:
+ json.dump(results, f, indent=2)
+EOF
+
+ run_bare_metal "pytorch" python3 /tmp/bench_pytorch.py
+ run_in_vm "pytorch"
+ compare_results "pytorch"
+}
+
+# Generate summary report
+generate_summary() {
+ log_info "Generating summary report..."
+ cat > "$RESULTS_DIR/summary.md" <<EOF
+# GSP Emulation Benchmark Summary
+Date: $(date)
+Host: $(hostname)
+Kernel: $(uname -r)
+
+## Results
+
+| Test | Bare Metal | VM | Ratio | Status |
+|------|------------|-----|-------|--------|
+EOF
+
+ for f in "$RESULTS_DIR"/bare_metal_*.json; do
+ test_name=$(basename "$f" .json | sed 's/bare_metal_//')
+ vm_f="$RESULTS_DIR/vm_${test_name}.json"
+ if [[ -f "$vm_f" ]]; then
+ python3 -c "
+import json
+with open('$f') as bf: bare = json.load(bf)
+with open('$vm_f') as vf: vm = json.load(vf)
+for k in bare:
+ if k in vm and isinstance(bare[k], (int, float)):
+ ratio = vm[k] / bare[k] * 100
+ status = '✅' if ratio > 85 else '⚠️' if ratio > 70 else '❌'
+ print(f'| {test_name} / {k} | {bare[k]:.2f} | {vm[k]:.2f} | {ratio:.1f}% | {status} |')
+" >> "$RESULTS_DIR/summary.md"
+ fi
+ done
+
+ log_ok "Summary: $RESULTS_DIR/summary.md"
+}
+
+main() {
+ case "${1:-all}" in
+ cuda) benchmark_cuda ;;
+ cublas) benchmark_cublas ;;
+ graphics) benchmark_graphics ;;
+ video) benchmark_video ;;
+ pytorch) benchmark_pytorch ;;
+ all)
+ benchmark_cuda
+ benchmark_cublas
+ benchmark_graphics
+ benchmark_video
+ benchmark_pytorch
+ ;;
+ *) echo "Usage: $0 {cuda|cublas|graphics|video|pytorch|all}"; exit 1 ;;
+ esac
+ generate_summary
+}
+
+main "$@" \ No newline at end of file