diff --git a/.claude/skills/ck-docker b/.claude/skills/ck-docker new file mode 100755 index 00000000000..1217f6ae1bb --- /dev/null +++ b/.claude/skills/ck-docker @@ -0,0 +1,317 @@ +#!/bin/bash +# CK Docker Skill - Build and test composable_kernel in Docker with ROCm support + +set -e +set -o pipefail + +# Find project root (where .git directory is) +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + +# Detect git branch and sanitize for docker naming (replace / and special chars with _) +GIT_BRANCH=$(cd "${PROJECT_ROOT}" && git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '_' | tr -cd 'a-zA-Z0-9_-' || echo "") +# Handle edge cases: detached HEAD, empty branch name +GIT_BRANCH=${GIT_BRANCH:-unknown} +# If branch is just "HEAD" (detached state), make it more descriptive +if [ "${GIT_BRANCH}" = "HEAD" ]; then + GIT_BRANCH="detached" +fi + +# Ensure USER is set +USER_NAME=${USER:-$(whoami 2>/dev/null || echo "user")} + +# Default container name: ck__ +DEFAULT_NAME="ck_${USER_NAME}_${GIT_BRANCH}" +CONTAINER_NAME="${CK_CONTAINER_NAME:-${DEFAULT_NAME}}" + +# Help message +show_help() { + cat << EOF +CK Docker Skill - Build and test composable_kernel in Docker + +Usage: ck-docker [options] + +Commands: + start [name] Start Docker container + build [target] [--reconfigure] Build target (optionally reconfigure CMake) + test [options] Run test + shell [name] Open shell in container + status [name] Check container status + stop [name] Stop and remove container + +Examples: + ck-docker start + ck-docker build test_amdgcn_mma + ck-docker build --reconfigure test_amdgcn_mma + ck-docker test test_amdgcn_mma --gtest_filter=*Fp16* + ck-docker shell + +Environment: + CK_CONTAINER_NAME - Override default container name (default: ck__) + CK_DOCKER_IMAGE - Override Docker image (default: rocm/composable_kernel:ck_ub24.04_rocm7.0.1) + GPU_TARGET - Override GPU target detection (e.g., gfx950, gfx942) +EOF +} + +# Detect GPU target +detect_gpu() { + local container=$1 + # Allow override via GPU_TARGET environment variable + if [ -n "${GPU_TARGET:-}" ]; then + echo "${GPU_TARGET}" + return 0 + fi + docker exec "${container}" bash -c " + rocminfo 2>/dev/null | grep -oP 'gfx[0-9a-z]+' | head -1 || echo 'gfx950' + " | tr -d '\r\n' +} + +# Start container +cmd_start() { + local name="${1:-${CONTAINER_NAME}}" + local docker_image="${CK_DOCKER_IMAGE:-rocm/composable_kernel:ck_ub24.04_rocm7.0.1}" + + # Check if container exists (exact match to avoid substring collisions) + if docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then + # Check if container is running + if docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then + echo "Container '${name}' is already running" + return 0 + else + echo "Starting existing container '${name}'..." + docker start "${name}" + echo "Container started" + return 0 + fi + fi + + echo "Creating new Docker container '${name}'..." + docker run -d \ + --name "${name}" \ + --device=/dev/kfd --device=/dev/dri \ + --security-opt seccomp=unconfined \ + --group-add video \ + -v "${PROJECT_ROOT}":/workspace \ + -w /workspace \ + "${docker_image}" \ + tail -f /dev/null + + echo "Container '${name}' started successfully" + docker exec "${name}" bash -c "echo 'Working directory:' && pwd" +} + +# Build target +cmd_build() { + local target="" + local name="${CONTAINER_NAME}" + local reconfigure=false + + while [[ $# -gt 0 ]]; do + case $1 in + --name) + name="$2" + shift 2 + ;; + --reconfigure) + reconfigure=true + shift + ;; + *) + target="$1" + shift + ;; + esac + done + + # Check if container is running (exact match) + if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then + echo "Container '${name}' not running. Starting..." + cmd_start "${name}" + fi + + # Reconfigure CMake if requested or if build.ninja doesn't exist + if [ "$reconfigure" = true ] || ! docker exec "${name}" test -f /workspace/build/build.ninja 2>/dev/null; then + echo "Detecting GPU target..." + local gpu_target=$(detect_gpu "${name}") + + if [ "$reconfigure" = true ]; then + echo "Reconfiguring CMake from scratch for GPU target: ${gpu_target}" + else + echo "Configuring build with CMake for GPU target: ${gpu_target}" + fi + + docker exec "${name}" bash -c " + cd /workspace || exit 1 + rm -rf /workspace/build + mkdir /workspace/build + cd /workspace/build || exit 1 + cmake .. -GNinja \ + -DGPU_TARGETS=${gpu_target} \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_CXX_COMPILER=/opt/rocm/llvm/bin/clang++ \ + -DBUILD_TESTING=ON 2>&1 | tail -30 + " + fi + + if [ -z "$target" ]; then + echo "Building all configured targets..." + else + echo "Building target: ${target}" + fi + + docker exec "${name}" bash -c " + cd /workspace/build || exit 1 + ninja ${target} 2>&1 + " + + echo "Build complete" +} + +# Run test +cmd_test() { + local test_name="" + local name="${CONTAINER_NAME}" + local -a test_options=() + + while [[ $# -gt 0 ]]; do + case $1 in + --name) + name="$2" + shift 2 + ;; + --gtest_*|--help) + test_options+=("$1") + shift + ;; + *) + if [ -z "$test_name" ]; then + test_name="$1" + else + test_options+=("$1") + fi + shift + ;; + esac + done + + if [ -z "$test_name" ]; then + echo "Error: test_name required" + echo "Usage: ck-docker test [--name container_name] [gtest_options]" + return 1 + fi + + # Check if container is running (exact match) + if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then + echo "Error: Container '${name}' not running" + echo "Start it with: ck-docker start --name ${name}" + return 1 + fi + + if ! docker exec "${name}" test -f "/workspace/build/bin/${test_name}" 2>/dev/null; then + echo "Test executable not found. Building ${test_name}..." + cmd_build "${test_name}" --name "${name}" + fi + + echo "Running: ${test_name} ${test_options[*]}" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + # Build the command with proper quoting + local cmd="cd /workspace/build && ./bin/${test_name}" + for opt in "${test_options[@]}"; do + cmd="${cmd} $(printf '%q' "$opt")" + done + docker exec "${name}" bash -c "${cmd}" +} + +# Shell +cmd_shell() { + local name="${1:-${CONTAINER_NAME}}" + + # Check if container is running (exact match) + if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then + echo "Container '${name}' not running. Starting..." + cmd_start "${name}" + fi + + echo "Opening shell in '${name}' (type 'exit' to leave)..." + docker exec -it "${name}" bash +} + +# Status +cmd_status() { + local name="${1:-}" + local docker_image="${CK_DOCKER_IMAGE:-rocm/composable_kernel:ck_ub24.04_rocm7.0.1}" + + if [ -z "$name" ]; then + echo "Composable Kernel Docker Containers:" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + docker ps -a --filter "ancestor=${docker_image}" \ + --format "table {{.Names}}\t{{.Status}}\t{{.CreatedAt}}" || echo "No containers found" + else + # Check if container is running (exact match) + if docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then + echo "Container '${name}' is RUNNING" + docker ps --filter "name=^${name}$" --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" + echo "" + echo "GPU Information:" + docker exec "${name}" bash -c "rocm-smi --showproductname 2>/dev/null | head -10 || echo 'No GPU detected'" + elif docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then + echo "Container '${name}' exists but is STOPPED" + echo "Start with: ck-docker start ${name}" + else + echo "Container '${name}' does NOT exist" + echo "Create with: ck-docker start ${name}" + fi + fi +} + +# Stop +cmd_stop() { + local name="${1:-${CONTAINER_NAME}}" + + # Check if container exists (exact match) + if docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then + echo "Stopping and removing container '${name}'..." + docker stop "${name}" 2>/dev/null || true + docker rm "${name}" 2>/dev/null || true + echo "Container stopped and removed" + else + echo "Container '${name}' does not exist" + fi +} + +# Main command dispatcher +case "${1:-}" in + start) + shift + cmd_start "$@" + ;; + build) + shift + cmd_build "$@" + ;; + test) + shift + cmd_test "$@" + ;; + shell) + shift + cmd_shell "$@" + ;; + status) + shift + cmd_status "$@" + ;; + stop) + shift + cmd_stop "$@" + ;; + help|--help|-h) + show_help + ;; + *) + echo "Unknown command: ${1:-}" + echo "" + show_help + exit 1 + ;; +esac diff --git a/.claude/skills/ck-docker.md b/.claude/skills/ck-docker.md new file mode 100644 index 00000000000..f31022e0bda --- /dev/null +++ b/.claude/skills/ck-docker.md @@ -0,0 +1,80 @@ +# ck-docker + +Build and test composable_kernel in Docker with ROCm support. + +## Terminal Usage + +Direct command-line usage: + +```bash +# From composable_kernel directory +.claude/skills/ck-docker start +.claude/skills/ck-docker build test_amdgcn_mma +.claude/skills/ck-docker test test_amdgcn_mma --gtest_filter=*Fp16* +.claude/skills/ck-docker status +.claude/skills/ck-docker shell + +# Or add to PATH +export PATH="$PATH:$PWD/.claude/skills" +ck-docker start +``` + +## Ask Claude + +Just ask in natural language: +- "Start the docker container" +- "Build test_amdgcn_mma" +- "Run test_amdgcn_mma with filter *Fp16*" +- "Check container status" +- "Open a shell in the container" + +## Commands + +``` +ck-docker start [name] Start Docker container +ck-docker build [target] [--reconfigure] Build target (optionally reconfigure CMake) +ck-docker test [options] Run test +ck-docker shell [name] Interactive shell +ck-docker status [name] Check status +ck-docker stop [name] Stop container +``` + +## Configuration + +- **Image**: rocm/composable_kernel:ck_ub24.04_rocm7.0.1 +- **GPU**: Auto-detected via rocminfo (fallback: gfx950) +- **Compiler**: /opt/rocm/llvm/bin/clang++ +- **Build**: Ninja + CMake (Release) +- **Mount**: Current directory → /workspace +- **Container Name**: Auto-generated as `ck__` to avoid clashes + +## Environment + +```bash +export CK_CONTAINER_NAME=my_build # Override default container name +export CK_DOCKER_IMAGE=rocm/composable_kernel:ck_ub24.04_rocm7.0.1 # Override Docker image +export GPU_TARGET=gfx942 # Override GPU target detection +``` + +## Examples + +```bash +# Start container +ck-docker start + +# Build and run test +ck-docker build test_amdgcn_mma +ck-docker test test_amdgcn_mma + +# Force clean CMake reconfiguration and build +ck-docker build --reconfigure test_amdgcn_mma + +# Custom container +ck-docker start my_build +ck-docker build test_amdgcn_mma --name my_build +ck-docker test test_amdgcn_mma --name my_build + +# Debug +ck-docker shell +ck-docker status +```