Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ held_out_tests/
# Documentation build environment and output
.docvenv/
docs/_build/

# FlyDSL kernel build artifacts and profiler output (generated at run time)
tasks/flydsl2flydsl/*/build/
tasks/flydsl2flydsl/*/.rocprofv3/
tasks/flydsl2flydsl/*/performance_report.json
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ help:
@echo "make docker-check-agents - Verify Codex, Claude Code, and Cursor Agent login reuse in Docker"
@echo "make docker-smoke - Verify Docker Python, ROCm tools, imports, and GPU access"
@echo "make docker-run CONFIG=config.yaml RUN_ARGS=\"--run-suffix test\" - Run benchmark in Docker"
@echo " Images: gfx942->mi30x, gfx950->mi35x; override with AKA_DOCKER_IMAGE=..."
@echo "make docker-setup-flydsl - Install FlyDSL into the container (needed for flydsl2flydsl tasks)"
@echo " Images: gfx942->mi30x, gfx950->mi35x, gfx10*/11*/12*->navi; override with AKA_DOCKER_IMAGE=..."
@echo "make docker-setup-flydsl - Install/upgrade FlyDSL 0.2.x in the container (needed for flydsl2flydsl tasks)"
@echo ""
@echo "Maintenance:"
@echo "make sync-perf-helpers - Refresh committed perf-helper stubs in task sources"
Expand Down Expand Up @@ -50,8 +50,8 @@ docker-smoke:
docker-run:
@$(DOCKER_RUNNER) run --config_name $(CONFIG) $(RUN_ARGS)

# Install FlyDSL into the container's persistent pip user-base (the base image does
# not ship it). Run once per machine/image; needed only for flydsl2flydsl tasks.
# Install/upgrade FlyDSL into the container's persistent Python package overlay. Run once
# per machine/image; needed only for flydsl2flydsl tasks.
docker-setup-flydsl:
@$(DOCKER_RUNNER) setup-flydsl

Expand Down
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ AgentKernelArena/
### Prerequisites

- Docker
- The SGLang Docker image for your GPU arch (`gfx942` uses `lmsysorg/sglang:v0.5.12-rocm720-mi30x`; `gfx950` uses `lmsysorg/sglang:v0.5.12-rocm720-mi35x`)
- The benchmark Docker image for your GPU arch (`gfx942` uses `lmsysorg/sglang:v0.5.12-rocm720-mi30x`; `gfx950` uses `lmsysorg/sglang:v0.5.12-rocm720-mi35x`; Navi/RDNA/Radeon `gfx10*`/`gfx11*`/`gfx12*` uses `rocm/vllm-dev:rocm7.2.1_navi_ubuntu24.04_py3.12_pytorch_2.9_vllm_0.16.0`)
- Git
- Host-installed agent CLIs for the agents you plan to evaluate

Expand Down Expand Up @@ -191,8 +191,20 @@ prompt:
source_code: null # Optional: override default source code inclusion
instructions: null # Optional: custom instructions
cheatsheet: null # Optional: provide cheatsheet/reference

# Optional: skip tasks that do not apply to this run's target GPU arch.
platform_support:
required_arch: gfx942 # Compared with target_gpu_model's resolved gfx arch
status: active # active | skip
skip_reason: null # Recommended when status is skip
```

If `platform_support` is omitted, the task runs as before. If
`platform_support.status: skip`, or if `required_arch` does not match the
current `target_gpu_model`, the framework skips the task before creating a
workspace or launching an agent. Historical fields such as
`runnable_on_gfx942` are documentation only and are not used for scheduling.


## Scoring System

Expand Down
4 changes: 4 additions & 0 deletions agents/task_validator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ make docker-run CONFIG=config.yaml

Each task workspace will contain a `validation_report.yaml` with per-check results. A `validation_summary.yaml` is written to the workspace root with aggregated statistics.

Tasks filtered by `platform_support.status: skip` or a non-matching
`platform_support.required_arch` are skipped before workspace creation and are
not included in the validation summary counts.

### Agent Configuration

Edit `agents/task_validator/agent_config.yaml`:
Expand Down
4 changes: 3 additions & 1 deletion agents/task_validator/validation_prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ def build_validation_prompt(task_config_dir: str, workspace: str, eval_config: d
- `compile_command` (list of strings)
- `correctness_command` (list of strings)
- `task_type` (string, one of: hip2hip, cuda2hip, triton2triton, torch2hip, instruction2triton, rocprim, flydsl2flydsl, repository)
Also check that optional fields (`performance_command`, `prompt`) are well-formed if present.
Also check that optional fields (`performance_command`, `prompt`, `platform_support`) are well-formed if present.
`platform_support`, when present, is a mapping with optional `status` (`active` or `skip`),
optional `required_arch` (string such as `gfx942`), and optional `skip_reason` (string).

**IMPORTANT — `task_type: repository` schema differs.** Repository tasks clone a full upstream
project and drive it through `scripts/task_runner.py` instead of shipping an isolated kernel file.
Expand Down
11 changes: 11 additions & 0 deletions docs/how-to/add-task.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,19 @@ prompt:
source_code: null # override the default source-code section
instructions: null # custom instructions
cheatsheet: null # reference/cheatsheet content

# Optional platform gate. Omit this block for tasks that run everywhere.
platform_support:
required_arch: gfx942 # compared with target_gpu_model's resolved gfx arch
status: active # active | skip
skip_reason: null # recommended when status is skip
```

Tasks with `platform_support.status: skip`, or with a `required_arch` that does
not match the current run, are skipped before workspace creation. Historical
per-suite helper fields such as `runnable_on_gfx942` are documentation only;
the scheduler uses `platform_support.status` and `platform_support.required_arch`.

## Authoring rules

To produce trustworthy, comparable scores, every task must have a reproducible
Expand Down
5 changes: 4 additions & 1 deletion docs/how-to/task-validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ make docker-run CONFIG=config.yaml

Each task workspace receives a `validation_report.yaml` with per-check results,
and a `validation_summary.yaml` with aggregated statistics is written to the
workspace root.
workspace root. Tasks skipped by `platform_support.status: skip` or by a
non-matching `platform_support.required_arch` are filtered before workspace
creation, so they do not produce a validation report or appear in the summary
counts.

## Validator configuration

Expand Down
21 changes: 12 additions & 9 deletions docs/install/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,21 @@ myst:

AgentKernelArena runs AI coding agents against GPU kernel tasks on an AMD GPU and
evaluates the results. **Docker is the only supported workflow**: the evaluator runs
inside the GPU-arch-specific SGLang Docker image and bind-mounts the local agent CLIs
inside the GPU-arch-specific Docker image and bind-mounts the local agent CLIs
plus their login state.

## Prerequisites

- **Docker**
- **AMD GPU with ROCm-compatible Docker access** — the runner mounts `/dev/kfd`,
`/dev/dri`, and `/dev/mem` when present.
- **SGLang benchmark image** — `gfx942` uses
- **Benchmark image** — `gfx942` uses
`lmsysorg/sglang:v0.5.12-rocm720-mi30x`; `gfx950` uses
`lmsysorg/sglang:v0.5.12-rocm720-mi35x`. The runner selects from
`target_gpu_model` for benchmark runs and from the visible host GPU for shell
and smoke commands.
`lmsysorg/sglang:v0.5.12-rocm720-mi35x`; Navi/RDNA/Radeon
`gfx10*`/`gfx11*`/`gfx12*` uses
`rocm/vllm-dev:rocm7.2.1_navi_ubuntu24.04_py3.12_pytorch_2.9_vllm_0.16.0`.
The runner selects from `target_gpu_model` for benchmark runs and from the
visible host GPU for shell and smoke commands.
- **Git**
- At least one supported agent CLI already installed and logged in on the host. The
Docker runner provisions the configured agent for a run. Codex, Claude Code,
Expand Down Expand Up @@ -74,15 +76,16 @@ npm install -g @anthropic-ai/claude-code

## FlyDSL tasks (optional)

`flydsl2flydsl` tasks need the `flydsl` package inside the container. Most images
already ship it (`make docker-smoke` prints `flydsl=ok <version>`). If yours does
not, install it once into the container's persistent pip user-base:
`flydsl2flydsl` tasks need the `flydsl` package inside the container. Install or
upgrade FlyDSL once into the container's persistent Python package overlay:

```bash
make docker-setup-flydsl
```

This is a no-op when the image already provides FlyDSL.
By default this installs a FlyDSL `0.2.x` wheel, even if the selected Docker image
already provides an older FlyDSL. Override the requirement with
`AKA_FLYDSL_SPEC` when a task suite needs a different version.

## Configure API keys

Expand Down
17 changes: 17 additions & 0 deletions docs/reference/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ For isolated-kernel tasks (`hip2hip`, `cuda2hip`, `triton2triton`,
| `task_type` | Yes | One of `hip2hip`, `cuda2hip`, `triton2triton`, `instruction2triton`, `torch2hip`, or `flydsl2flydsl` |
| `performance_command` | No | Command(s) to measure performance |
| `task_result_template` | No | Override the result template (`null` = default) |
| `platform_support` | No | Optional run-gating metadata; see below |
| `prompt.source_code` | No | Override the prompt's source-code section |
| `prompt.instructions` | No | Custom prompt instructions |
| `prompt.cheatsheet` | No | Reference/cheatsheet content for the prompt |
Expand All @@ -91,9 +92,25 @@ For repository-level tasks (`task_type: repository`):
| `post_clone_install_mode` | No | Controls when `post_clone_install` runs, for example `every_setup` |
| `source_file_path` | No | Optional target source-file hints, relative to the cloned repository root |
| `target_kernel_functions` | No | Optional target function or kernel-symbol hints |
| `platform_support` | No | Optional run-gating metadata; see below |
| `prompt.instructions` | No | Custom prompt instructions |
| `prompt.cheatsheet` | No | Reference/cheatsheet content for the prompt |

Optional platform support metadata:

```yaml
platform_support:
required_arch: gfx942 # optional; compared with target_gpu_model's gfx arch
status: active # optional; active or skip
skip_reason: null # recommended when status is skip
```

If `platform_support` is omitted, the task is scheduled normally. If
`status: skip`, or if `required_arch` does not match the current run's resolved
GPU architecture, the task is skipped before workspace creation and agent
launch. Historical task-specific fields such as `runnable_on_gfx942` are
documentation only and do not affect scheduling.

See [Add a task](../how-to/add-task.md) for layout and authoring rules.

## Result schema (`task_result.yaml`)
Expand Down
8 changes: 4 additions & 4 deletions docs/reference/compatibility-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ The following software versions are required or verified.
| Component | Version | Notes |
| --- | --- | --- |
| Docker | Current stable release | Required; evaluations run through `make docker-run`. |
| SGLang benchmark image | `lmsysorg/sglang:v0.5.12-rocm720-mi30x` for `gfx942`; `lmsysorg/sglang:v0.5.12-rocm720-mi35x` for `gfx950` | Override with `AKA_DOCKER_IMAGE`, `AKA_DOCKER_IMAGE_GFX942`, or `AKA_DOCKER_IMAGE_GFX950`. |
| ROCm | Bundled in the selected SGLang image | The default images are ROCm 7.2 based. |
| Python | Provided by the image (e.g. 3.10) | Bundled in the SGLang image. |
| PyTorch | ROCm build bundled in the image | Provided by the SGLang Docker image. |
| Benchmark image | `lmsysorg/sglang:v0.5.12-rocm720-mi30x` for `gfx942`; `lmsysorg/sglang:v0.5.12-rocm720-mi35x` for `gfx950`; `rocm/vllm-dev:rocm7.2.1_navi_ubuntu24.04_py3.12_pytorch_2.9_vllm_0.16.0` for Navi/RDNA/Radeon `gfx10*`/`gfx11*`/`gfx12*` | Override with `AKA_DOCKER_IMAGE`, `AKA_DOCKER_IMAGE_GFX942`, `AKA_DOCKER_IMAGE_GFX950`, `AKA_DOCKER_IMAGE_NAVI`, or `AKA_DOCKER_IMAGE_<ARCH>`. |
| ROCm | Bundled in the selected benchmark image | The default images are ROCm 7.2 based. |
| Python | Provided by the image | Bundled in the selected benchmark image. |
| PyTorch | ROCm build bundled in the image | Provided by the selected benchmark image. |
| Triton | Bundled with the image's ROCm PyTorch | Required for Triton task categories. |
| FlyDSL | Provided by the image (or `make docker-setup-flydsl`) | Required for `flydsl2flydsl` tasks. |
| hipcc | Matches image ROCm | Required for HIP tasks. |
Expand Down
112 changes: 111 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@
from pathlib import Path
from datetime import datetime
from src.tasks import get_task_config
from src.preprocessing import setup_workspace, setup_rocm_env, is_task_complete
from src.preprocessing import (
setup_workspace,
setup_rocm_env,
is_task_complete,
resolve_gfx_arch,
)
from src.module_registration import AgentType, load_agent_launcher, load_post_processing_handler
from src.evaluator import measure_baseline, evaluate_kernel, write_task_result
from src.runtime_env import apply_subprocess_python_path
Expand All @@ -23,6 +28,105 @@
parser.add_argument("--resume-latest", action="store_true",
help="Resume the most recent run in the workspace")


def should_run_task_for_platform(
task_name: str,
task_config: dict,
current_gfx_arch: str | None,
logger: logging.Logger,
) -> bool:
"""Return False when a task declares platform support that excludes this run."""
platform_support = task_config.get("platform_support")
if platform_support is None:
return True
if not isinstance(platform_support, dict):
logger.warning(
"Task %s has non-dict platform_support=%r; treating task as runnable",
task_name,
platform_support,
)
return True

raw_status = platform_support.get("status", "active")
status = str(raw_status).strip().lower() if raw_status is not None else "active"
if status == "skip":
skip_reason = str(platform_support.get("skip_reason") or "").strip()
suffix = f": {skip_reason}" if skip_reason else ""
logger.warning(
"Skipping task %s before workspace setup: platform_support.status=skip%s",
task_name,
suffix,
)
return False
if status and status != "active":
logger.warning(
"Task %s has unsupported platform_support.status=%r; treating task as runnable",
task_name,
raw_status,
)

required_arch = platform_support.get("required_arch")
if not required_arch:
return True
if not isinstance(required_arch, str):
logger.warning(
"Task %s has non-string platform_support.required_arch=%r; treating task as runnable",
task_name,
required_arch,
)
return True

required_arch = required_arch.strip()
if not required_arch:
return True
if not current_gfx_arch:
logger.warning(
"Skipping task %s before workspace setup: platform_support.required_arch=%s, "
"but current target GPU arch could not be resolved",
task_name,
required_arch,
)
return False
if required_arch != current_gfx_arch:
logger.warning(
"Skipping task %s before workspace setup: platform_support.required_arch=%s "
"does not match current target GPU arch %s",
task_name,
required_arch,
current_gfx_arch,
)
return False

return True


def filter_tasks_by_platform(
task_config_dict: dict[str, str],
current_gfx_arch: str | None,
logger: logging.Logger,
) -> dict[str, str]:
"""Drop tasks that declare platform_support constraints for another runtime."""
runnable_tasks: dict[str, str] = {}
skipped_tasks: list[str] = []

for task_name, task_config_dir in task_config_dict.items():
with open(task_config_dir, "r") as f:
task_config = yaml.safe_load(f) or {}
if should_run_task_for_platform(task_name, task_config, current_gfx_arch, logger):
runnable_tasks[task_name] = task_config_dir
else:
skipped_tasks.append(task_name)

if skipped_tasks:
logger.warning(
"Platform support preflight skipped %d task(s): %s",
len(skipped_tasks),
skipped_tasks,
)

return runnable_tasks


def main() -> None:
"""Main entry point for AgentKernelArena framework."""
args = parser.parse_args()
Expand Down Expand Up @@ -136,6 +240,7 @@ def main() -> None:

# Set PYTORCH_ROCM_ARCH based on target_gpu_model before any task runs
setup_rocm_env(target_gpu_model, logger)
current_gfx_arch = resolve_gfx_arch(target_gpu_model)

# Load agent launcher
try:
Expand All @@ -153,6 +258,11 @@ def main() -> None:
for category in tasks:
task_config_dict.update(get_task_config(category=category))

task_config_dict = filter_tasks_by_platform(task_config_dict, current_gfx_arch, logger)
if len(task_config_dict) == 0:
logger.info("No tasks remain after platform support preflight. Nothing to run.")
return

# Filter out completed tasks if resuming
if resume_mode:
original_task_count = len(task_config_dict)
Expand Down
4 changes: 2 additions & 2 deletions src/preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from src.perf_helper_materialization import materialize_perf_helpers_in_workspace


def _resolve_gfx_arch(target_gpu_model: str) -> str | None:
def resolve_gfx_arch(target_gpu_model: str) -> str | None:
"""
Look up the gfx architecture token (e.g. 'gfx942') for a given GPU model
name (e.g. 'MI300') from default_cheatsheet.yaml.
Expand Down Expand Up @@ -47,7 +47,7 @@ def setup_rocm_env(target_gpu_model: str, logger: logging.Logger) -> None:

Should be called once at the start of main(), before any task is launched.
"""
gfx_arch = _resolve_gfx_arch(target_gpu_model)
gfx_arch = resolve_gfx_arch(target_gpu_model)
if not gfx_arch:
logger.warning(
f"Could not resolve gfx arch for GPU model '{target_gpu_model}'. "
Expand Down
Loading
Loading