Skip to content

Commit 13655f2

Browse files
tenpercentclaude
andcommitted
Extract common utilities and improve default granularity
- Extract shared configuration logic to .claude/skills/common.sh - Container naming and detection functions - Git branch sanitization - Docker image configuration - GPU target detection - Reduces ~50 lines of duplicate code between skills - Refactor ck-docker to use common.sh utilities - Replace manual docker ps checks with helper functions - Use shared container_exists() and container_is_running() - Use shared detect_gpu_target() and get_docker_image() - Refactor ck-build-analysis to use common.sh utilities - Use shared get_project_root() and get_container_name() - Use shared ensure_container_running() - Use shared detect_gpu_target() - Change default granularity from 500µs to 100µs - Provides better balance between detail and performance - Captures ~15k instantiations vs ~5k at 500µs - Still manageable 15-20 MB trace files - Update all documentation and help text Co-Authored-By: Claude <noreply@anthropic.com>
1 parent caf3f74 commit 13655f2

4 files changed

Lines changed: 140 additions & 85 deletions

File tree

.claude/skills/ck-build-analysis

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,16 @@
44
set -e
55
set -o pipefail
66

7-
# Find project root
7+
# Find script directory and load common utilities
88
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9-
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
9+
source "${SCRIPT_DIR}/common.sh"
1010

11-
# Detect git branch and sanitize for docker naming
12-
GIT_BRANCH=$(cd "${PROJECT_ROOT}" && git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '_' | tr -cd 'a-zA-Z0-9_-' || echo "")
13-
GIT_BRANCH=${GIT_BRANCH:-unknown}
14-
if [ "${GIT_BRANCH}" = "HEAD" ]; then
15-
GIT_BRANCH="detached"
16-
fi
17-
18-
# Ensure USER is set
19-
USER_NAME=${USER:-$(whoami 2>/dev/null || echo "user")}
20-
21-
# Default container name
22-
DEFAULT_NAME="ck_${USER_NAME}_${GIT_BRANCH}"
23-
CONTAINER_NAME="${CK_CONTAINER_NAME:-${DEFAULT_NAME}}"
11+
# Initialize configuration
12+
PROJECT_ROOT=$(get_project_root "${SCRIPT_DIR}")
13+
CONTAINER_NAME=$(get_container_name "${PROJECT_ROOT}")
2414

2515
# Default settings
26-
GRANULARITY="${CK_BUILD_ANALYSIS_GRANULARITY:-500}"
16+
GRANULARITY="${CK_BUILD_ANALYSIS_GRANULARITY:-100}"
2717
OUTPUT_FILE="build_time_analysis_report.md"
2818
RECONFIGURE=true
2919

@@ -38,7 +28,7 @@ Arguments:
3828
target Build target to analyze (e.g., example_convnd_fwd_xdl_fp8)
3929
4030
Options:
41-
--granularity=N Time trace granularity in microseconds (default: 500)
31+
--granularity=N Time trace granularity in microseconds (default: 100)
4232
--output=FILE Output report filename (default: build_time_analysis_report.md)
4333
--name=NAME Docker container name (default: ${CONTAINER_NAME})
4434
--no-reconfigure Skip CMake reconfiguration if build exists
@@ -50,8 +40,8 @@ Examples:
5040
ck-build-analysis test_amdgcn_mma --granularity=100 --output=mma_test_analysis.md
5141
5242
Granularity Guide:
53-
500 (default) - Quick overview, filters 86% of events (~5k instantiations, 3-5 MB)
54-
100 - Balanced detail (~15k instantiations, 15-20 MB)
43+
100 (default) - Balanced detail (~15k instantiations, 15-20 MB)
44+
500 - Quick overview, filters 86% of events (~5k instantiations, 3-5 MB)
5545
1 - Complete analysis (~36k instantiations, 80-100 MB)
5646
EOF
5747
}
@@ -116,17 +106,14 @@ echo "════════════════════════
116106
echo ""
117107

118108
# Ensure container is running
119-
if ! docker ps --filter "name=^${CONTAINER_NAME}$" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
120-
echo "Container not running. Starting with ck-docker..."
121-
"${SCRIPT_DIR}/ck-docker" start "${CONTAINER_NAME}"
122-
fi
109+
ensure_container_running "${CONTAINER_NAME}" "${SCRIPT_DIR}"
123110

124111
# Configure CMake with -ftime-trace if needed
125112
if [ "$RECONFIGURE" = true ] || ! docker exec "${CONTAINER_NAME}" test -f /workspace/build/build.ninja 2>/dev/null; then
126113
echo ""
127114
echo "Configuring CMake with -ftime-trace (granularity=${GRANULARITY}µs)..."
128115

129-
GPU_TARGET=$(docker exec "${CONTAINER_NAME}" bash -c "rocminfo 2>/dev/null | grep -oP 'gfx[0-9a-z]+' | head -1 || echo 'gfx950'" | tr -d '\r\n')
116+
GPU_TARGET=$(detect_gpu_target "${CONTAINER_NAME}")
130117

131118
docker exec "${CONTAINER_NAME}" bash -c "
132119
cd /workspace || exit 1

.claude/skills/ck-build-analysis.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Just ask in natural language:
3030
ck-build-analysis <target> [options]
3131
3232
Options:
33-
--granularity=N Time trace granularity in microseconds (default: 500)
33+
--granularity=N Time trace granularity in microseconds (default: 100)
3434
--output=FILE Output report filename (default: build_time_analysis_report.md)
3535
--name=NAME Docker container name (default: from CK_CONTAINER_NAME or auto-generated)
3636
--no-reconfigure Skip CMake reconfiguration if build exists
@@ -58,27 +58,27 @@ Options:
5858
## Environment
5959

6060
```bash
61-
export CK_CONTAINER_NAME=my_build # Override container name
62-
export CK_BUILD_ANALYSIS_GRANULARITY=1 # Default granularity in µs
61+
export CK_CONTAINER_NAME=my_build # Override container name
62+
export CK_BUILD_ANALYSIS_GRANULARITY=100 # Default granularity in µs
6363
```
6464

6565
## Examples
6666

6767
```bash
68-
# Basic analysis with default granularity (500µs)
68+
# Basic analysis with default granularity (100µs)
6969
ck-build-analysis example_convnd_fwd_xdl_fp8
7070

71-
# High-resolution analysis (1µs granularity, 22x larger trace)
72-
ck-build-analysis example_convnd_fwd_xdl_fp8 --granularity=1
71+
# Quick overview (500µs granularity, filters minor events)
72+
ck-build-analysis example_convnd_fwd_xdl_fp8 --granularity=500
7373

74-
# Medium-resolution analysis (100µs granularity, good balance)
75-
ck-build-analysis example_convnd_fwd_xdl_fp8 --granularity=100
74+
# High-resolution analysis (1µs granularity, complete picture)
75+
ck-build-analysis example_convnd_fwd_xdl_fp8 --granularity=1
7676

7777
# Custom output filename
7878
ck-build-analysis example_convnd_fwd_xdl_fp8 --output=fp8_conv_analysis.md
7979

8080
# Analyze test target
81-
ck-build-analysis test_amdgcn_mma --granularity=1
81+
ck-build-analysis test_amdgcn_mma
8282

8383
# Use existing build (skip reconfigure)
8484
ck-build-analysis example_convnd_fwd_xdl_fp8 --no-reconfigure
@@ -99,17 +99,17 @@ The report includes:
9999

100100
| Granularity | Events | Trace Size | Use Case |
101101
|-------------|--------|------------|----------|
102-
| 500µs (default) | ~50k | 3-5 MB | Quick overview, major bottlenecks |
103-
| 100µs | ~150k | 15-20 MB | Balanced detail and performance |
102+
| 500µs | ~50k | 3-5 MB | Quick overview, major bottlenecks only |
103+
| 100µs (default) | ~150k | 15-20 MB | Balanced detail and performance |
104104
| 50µs | ~200k | 30-40 MB | Detailed analysis |
105105
| 1µs (high-res) | ~300k | 80-100 MB | Complete picture, all instantiations |
106106

107107
## Notes
108108

109109
- Lower granularity = more events = larger files = longer analysis
110-
- Default 500µs captures major bottlenecks (filters out 86% of instantiations)
110+
- Default 100µs provides balanced detail for most use cases
111+
- 500µs captures only major bottlenecks (filters out 86% of instantiations)
111112
- 1µs granularity reveals all 36,000+ instantiations but takes longer to analyze
112-
- 100µs is a good middle ground for most use cases
113113

114114
## Implementation Details
115115

.claude/skills/ck-docker

Lines changed: 22 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,13 @@
44
set -e
55
set -o pipefail
66

7-
# Find project root (where .git directory is)
7+
# Find script directory and load common utilities
88
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9-
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
9+
source "${SCRIPT_DIR}/common.sh"
1010

11-
# Detect git branch and sanitize for docker naming (replace / and special chars with _)
12-
GIT_BRANCH=$(cd "${PROJECT_ROOT}" && git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '_' | tr -cd 'a-zA-Z0-9_-' || echo "")
13-
# Handle edge cases: detached HEAD, empty branch name
14-
GIT_BRANCH=${GIT_BRANCH:-unknown}
15-
# If branch is just "HEAD" (detached state), make it more descriptive
16-
if [ "${GIT_BRANCH}" = "HEAD" ]; then
17-
GIT_BRANCH="detached"
18-
fi
19-
20-
# Ensure USER is set
21-
USER_NAME=${USER:-$(whoami 2>/dev/null || echo "user")}
22-
23-
# Default container name: ck_<username>_<branch>
24-
DEFAULT_NAME="ck_${USER_NAME}_${GIT_BRANCH}"
25-
CONTAINER_NAME="${CK_CONTAINER_NAME:-${DEFAULT_NAME}}"
11+
# Initialize configuration
12+
PROJECT_ROOT=$(get_project_root "${SCRIPT_DIR}")
13+
CONTAINER_NAME=$(get_container_name "${PROJECT_ROOT}")
2614

2715
# Help message
2816
show_help() {
@@ -53,28 +41,14 @@ Environment:
5341
EOF
5442
}
5543

56-
# Detect GPU target
57-
detect_gpu() {
58-
local container=$1
59-
# Allow override via GPU_TARGET environment variable
60-
if [ -n "${GPU_TARGET:-}" ]; then
61-
echo "${GPU_TARGET}"
62-
return 0
63-
fi
64-
docker exec "${container}" bash -c "
65-
rocminfo 2>/dev/null | grep -oP 'gfx[0-9a-z]+' | head -1 || echo 'gfx950'
66-
" | tr -d '\r\n'
67-
}
68-
6944
# Start container
7045
cmd_start() {
7146
local name="${1:-${CONTAINER_NAME}}"
72-
local docker_image="${CK_DOCKER_IMAGE:-rocm/composable_kernel:ck_ub24.04_rocm7.0.1}"
47+
local docker_image=$(get_docker_image)
7348

74-
# Check if container exists (exact match to avoid substring collisions)
75-
if docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
76-
# Check if container is running
77-
if docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
49+
# Check if container exists and is running
50+
if container_exists "${name}"; then
51+
if container_is_running "${name}"; then
7852
echo "Container '${name}' is already running"
7953
return 0
8054
else
@@ -123,16 +97,16 @@ cmd_build() {
12397
esac
12498
done
12599

126-
# Check if container is running (exact match)
127-
if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
100+
# Check if container is running
101+
if ! container_is_running "${name}"; then
128102
echo "Container '${name}' not running. Starting..."
129103
cmd_start "${name}"
130104
fi
131105

132106
# Reconfigure CMake if requested or if build.ninja doesn't exist
133107
if [ "$reconfigure" = true ] || ! docker exec "${name}" test -f /workspace/build/build.ninja 2>/dev/null; then
134108
echo "Detecting GPU target..."
135-
local gpu_target=$(detect_gpu "${name}")
109+
local gpu_target=$(detect_gpu_target "${name}")
136110

137111
if [ "$reconfigure" = true ]; then
138112
echo "Reconfiguring CMake from scratch for GPU target: ${gpu_target}"
@@ -200,8 +174,8 @@ cmd_test() {
200174
return 1
201175
fi
202176

203-
# Check if container is running (exact match)
204-
if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
177+
# Check if container is running
178+
if ! container_is_running "${name}"; then
205179
echo "Error: Container '${name}' not running"
206180
echo "Start it with: ck-docker start --name ${name}"
207181
return 1
@@ -226,8 +200,8 @@ cmd_test() {
226200
cmd_shell() {
227201
local name="${1:-${CONTAINER_NAME}}"
228202

229-
# Check if container is running (exact match)
230-
if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
203+
# Check if container is running
204+
if ! container_is_running "${name}"; then
231205
echo "Container '${name}' not running. Starting..."
232206
cmd_start "${name}"
233207
fi
@@ -239,22 +213,22 @@ cmd_shell() {
239213
# Status
240214
cmd_status() {
241215
local name="${1:-}"
242-
local docker_image="${CK_DOCKER_IMAGE:-rocm/composable_kernel:ck_ub24.04_rocm7.0.1}"
216+
local docker_image=$(get_docker_image)
243217

244218
if [ -z "$name" ]; then
245219
echo "Composable Kernel Docker Containers:"
246220
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
247221
docker ps -a --filter "ancestor=${docker_image}" \
248222
--format "table {{.Names}}\t{{.Status}}\t{{.CreatedAt}}" || echo "No containers found"
249223
else
250-
# Check if container is running (exact match)
251-
if docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
224+
# Check container status
225+
if container_is_running "${name}"; then
252226
echo "Container '${name}' is RUNNING"
253227
docker ps --filter "name=^${name}$" --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
254228
echo ""
255229
echo "GPU Information:"
256230
docker exec "${name}" bash -c "rocm-smi --showproductname 2>/dev/null | head -10 || echo 'No GPU detected'"
257-
elif docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
231+
elif container_exists "${name}"; then
258232
echo "Container '${name}' exists but is STOPPED"
259233
echo "Start with: ck-docker start ${name}"
260234
else
@@ -268,8 +242,8 @@ cmd_status() {
268242
cmd_stop() {
269243
local name="${1:-${CONTAINER_NAME}}"
270244

271-
# Check if container exists (exact match)
272-
if docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
245+
# Check if container exists
246+
if container_exists "${name}"; then
273247
echo "Stopping and removing container '${name}'..."
274248
docker stop "${name}" 2>/dev/null || true
275249
docker rm "${name}" 2>/dev/null || true

.claude/skills/common.sh

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/bin/bash
2+
# Common utilities for CK Docker skills
3+
# Shared configuration and helper functions
4+
5+
# Find project root (where .git directory is)
6+
get_project_root() {
7+
local script_dir="$1"
8+
cd "${script_dir}/../.." && pwd
9+
}
10+
11+
# Detect git branch and sanitize for Docker naming
12+
get_sanitized_branch() {
13+
local project_root="$1"
14+
local branch
15+
16+
branch=$(cd "${project_root}" && git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '_' | tr -cd 'a-zA-Z0-9_-' || echo "")
17+
branch=${branch:-unknown}
18+
19+
# Handle detached HEAD state
20+
if [ "${branch}" = "HEAD" ]; then
21+
branch="detached"
22+
fi
23+
24+
echo "${branch}"
25+
}
26+
27+
# Get username with fallback
28+
get_username() {
29+
echo "${USER:-$(whoami 2>/dev/null || echo "user")}"
30+
}
31+
32+
# Generate default container name: ck_<username>_<branch>
33+
get_default_container_name() {
34+
local project_root="$1"
35+
local user_name
36+
local git_branch
37+
38+
user_name=$(get_username)
39+
git_branch=$(get_sanitized_branch "${project_root}")
40+
41+
echo "ck_${user_name}_${git_branch}"
42+
}
43+
44+
# Get container name (respects CK_CONTAINER_NAME env var)
45+
get_container_name() {
46+
local project_root="$1"
47+
local default_name
48+
49+
default_name=$(get_default_container_name "${project_root}")
50+
echo "${CK_CONTAINER_NAME:-${default_name}}"
51+
}
52+
53+
# Get Docker image (respects CK_DOCKER_IMAGE env var)
54+
get_docker_image() {
55+
echo "${CK_DOCKER_IMAGE:-rocm/composable_kernel:ck_ub24.04_rocm7.0.1}"
56+
}
57+
58+
# Check if container exists (exact match)
59+
container_exists() {
60+
local name="$1"
61+
docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"
62+
}
63+
64+
# Check if container is running (exact match)
65+
container_is_running() {
66+
local name="$1"
67+
docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"
68+
}
69+
70+
# Detect GPU target in container
71+
detect_gpu_target() {
72+
local container="$1"
73+
74+
# Allow override via GPU_TARGET environment variable
75+
if [ -n "${GPU_TARGET:-}" ]; then
76+
echo "${GPU_TARGET}"
77+
return 0
78+
fi
79+
80+
docker exec "${container}" bash -c "
81+
rocminfo 2>/dev/null | grep -oP 'gfx[0-9a-z]+' | head -1 || echo 'gfx950'
82+
" | tr -d '\r\n'
83+
}
84+
85+
# Ensure container is running, start if needed
86+
ensure_container_running() {
87+
local container="$1"
88+
local script_dir="$2"
89+
90+
if ! container_is_running "${container}"; then
91+
echo "Container '${container}' not running. Starting with ck-docker..."
92+
"${script_dir}/ck-docker" start "${container}"
93+
fi
94+
}

0 commit comments

Comments
 (0)