Files
composable_kernel/script/tools/common.sh
Max Podkorytov 086a1f8861 Add LLM-agnostic Docker and build analysis tools (#3576)
This commit introduces utility tools for building, testing, and analyzing
Composable Kernel. The tools are designed to be LLM-agnostic and can be
used with any AI assistant or directly from the command line.

Tools Added:
============

1. ck-docker - Docker container management
   - Start/stop ROCm-enabled containers
   - Build targets with CMake + Ninja
   - Run tests with gtest filters
   - Auto-detect GPU targets (gfx950, gfx942, etc.)
   - Per-user, per-branch container naming to avoid conflicts

2. ck-build-analysis - Build time profiling
   - Uses Clang's -ftime-trace for compilation analysis
   - Aggregates statistics across multiple trace files
   - Identifies template instantiation bottlenecks
   - Generates detailed Markdown reports with:
     * Compilation phase breakdown
     * Top expensive instantiations
     * Template family analysis
     * Data-driven optimization recommendations
   - Configurable granularity (1µs to 500µs)
   - PEP 723 compliant Python script with auto-dependency management via uv

Key Features:
=============

- LLM-agnostic design (works with any AI assistant)
- Zero-configuration setup with automatic dependency installation
- Comprehensive documentation in script/tools/README*.md
- Security hardening (input validation, no command injection)
- Multi-file trace aggregation for accurate build analysis
- Jinja2-based report generation for customizable output

Implementation:
===============

- script/tools/ck-docker - Main Docker orchestration script
- script/tools/ck-build-analysis - Build analysis orchestration
- script/tools/common.sh - Shared utilities (container mgmt, GPU detection)
- script/tools/analyze_build_trace.py - PEP 723 compliant Python analyzer
- script/tools/templates/ - Jinja2 templates for report generation
- script/tools/README*.md - Comprehensive documentation

Directory Structure:
====================

script/tools/
├── README.md                          # Main overview
├── README_ck-docker.md                # ck-docker documentation
├── README_ck-build-analysis.md        # ck-build-analysis documentation
├── ck-docker                          # Docker orchestration script
├── ck-build-analysis                  # Build analysis orchestration
├── common.sh                          # Shared utilities
├── analyze_build_trace.py             # Python analyzer (PEP 723)
└── templates/
    └── build_analysis_report.md.jinja # Report template

The tools follow Unix philosophy: do one thing well, compose easily,
and work from both CLI and programmatic contexts.
2026-01-15 08:30:23 -08:00

98 lines
2.5 KiB
Bash

#!/bin/bash
# Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
# SPDX-License-Identifier: MIT
# Common utilities for CK Docker tools
# Shared configuration and helper functions
# Find project root (where .git directory is)
get_project_root() {
local script_dir="$1"
cd "${script_dir}/../.." && pwd
}
# Detect git branch and sanitize for Docker naming
get_sanitized_branch() {
local project_root="$1"
local branch
branch=$(cd "${project_root}" && git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '_' | tr -cd 'a-zA-Z0-9_-' || echo "")
branch=${branch:-unknown}
# Handle detached HEAD state
if [ "${branch}" = "HEAD" ]; then
branch="detached"
fi
echo "${branch}"
}
# Get username with fallback
get_username() {
echo "${USER:-$(whoami 2>/dev/null || echo "user")}"
}
# Generate default container name: ck_<username>_<branch>
get_default_container_name() {
local project_root="$1"
local user_name
local git_branch
user_name=$(get_username)
git_branch=$(get_sanitized_branch "${project_root}")
echo "ck_${user_name}_${git_branch}"
}
# Get container name (respects CK_CONTAINER_NAME env var)
get_container_name() {
local project_root="$1"
local default_name
default_name=$(get_default_container_name "${project_root}")
echo "${CK_CONTAINER_NAME:-${default_name}}"
}
# Get Docker image (respects CK_DOCKER_IMAGE env var)
get_docker_image() {
echo "${CK_DOCKER_IMAGE:-rocm/composable_kernel:ck_ub24.04_rocm7.0.1}"
}
# Check if container exists (exact match)
container_exists() {
local name="$1"
docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"
}
# Check if container is running (exact match)
container_is_running() {
local name="$1"
docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"
}
# Detect GPU target in container
detect_gpu_target() {
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'
}
# Ensure container is running, start if needed
ensure_container_running() {
local container="$1"
local script_dir="$2"
if ! container_is_running "${container}"; then
echo "Container '${container}' not running. Starting with ck-docker..."
"${script_dir}/ck-docker" start "${container}"
fi
}