Skip to content

Commit 5ba3926

Browse files
committed
try to handle corner cases
1 parent 0148810 commit 5ba3926

2 files changed

Lines changed: 82 additions & 51 deletions

File tree

.claude/skills/ck-docker

Lines changed: 79 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,26 @@
22
# CK Docker Skill - Build and test composable_kernel in Docker with ROCm support
33

44
set -e
5+
set -o pipefail
56

67
# Find project root (where .git directory is)
78
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
89
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
910

1011
# Detect git branch and sanitize for docker naming (replace / and special chars with _)
11-
GIT_BRANCH=$(cd "${PROJECT_ROOT}" && git rev-parse --abbrev-ref HEAD 2>/dev/null | tr '/' '_' | tr -cd 'a-zA-Z0-9_-')
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")}
1222

1323
# Default container name: ck_<username>_<branch>
14-
DEFAULT_NAME="ck_${USER}_${GIT_BRANCH}"
24+
DEFAULT_NAME="ck_${USER_NAME}_${GIT_BRANCH}"
1525
CONTAINER_NAME="${CK_CONTAINER_NAME:-${DEFAULT_NAME}}"
1626

1727
# Help message
@@ -38,46 +48,56 @@ Examples:
3848
3949
Environment:
4050
CK_CONTAINER_NAME - Override default container name (default: ck_<username>_<branch>)
51+
CK_DOCKER_IMAGE - Override Docker image (default: rocm/composable_kernel:ck_ub24.04_rocm7.0.1)
52+
GPU_TARGET - Override GPU target detection (e.g., gfx950, gfx942)
4153
EOF
4254
}
4355

4456
# Detect GPU target
4557
detect_gpu() {
4658
local container=$1
47-
docker exec ${container} bash -c "
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 "
4865
rocminfo 2>/dev/null | grep -oP 'gfx[0-9a-z]+' | head -1 || echo 'gfx950'
4966
" | tr -d '\r\n'
5067
}
5168

5269
# Start container
5370
cmd_start() {
5471
local name="${1:-${CONTAINER_NAME}}"
72+
local docker_image="${CK_DOCKER_IMAGE:-rocm/composable_kernel:ck_ub24.04_rocm7.0.1}"
5573

56-
if docker ps -a -f name=${name} | grep -q ${name}; then
57-
if docker ps -f name=${name} | grep -q ${name}; then
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
5878
echo "Container '${name}' is already running"
5979
return 0
6080
else
6181
echo "Starting existing container '${name}'..."
62-
docker start ${name}
82+
docker start "${name}"
6383
echo "Container started"
6484
return 0
6585
fi
6686
fi
6787

6888
echo "Creating new Docker container '${name}'..."
6989
docker run -d \
70-
--name ${name} \
90+
--name "${name}" \
7191
--device=/dev/kfd --device=/dev/dri \
7292
--security-opt seccomp=unconfined \
7393
--group-add video \
7494
-v "${PROJECT_ROOT}":/workspace \
7595
-w /workspace \
76-
rocm/composable_kernel:ck_ub24.04_rocm7.0.1 \
96+
"${docker_image}" \
7797
tail -f /dev/null
7898

7999
echo "Container '${name}' started successfully"
80-
docker exec ${name} bash -c "echo 'Working directory:' && pwd"
100+
docker exec "${name}" bash -c "echo 'Working directory:' && pwd"
81101
}
82102

83103
# Build target
@@ -98,21 +118,22 @@ cmd_build() {
98118
esac
99119
done
100120

101-
if ! docker ps -f name=${name} | grep -q ${name}; then
121+
# Check if container is running (exact match)
122+
if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
102123
echo "Container '${name}' not running. Starting..."
103-
cmd_start ${name}
124+
cmd_start "${name}"
104125
fi
105126

106-
if ! docker exec ${name} test -f /workspace/build/build.ninja 2>/dev/null; then
127+
if ! docker exec "${name}" test -f /workspace/build/build.ninja 2>/dev/null; then
107128
echo "Detecting GPU target..."
108-
local gpu_target=$(detect_gpu ${name})
129+
local gpu_target=$(detect_gpu "${name}")
109130

110131
echo "Configuring build with CMake for GPU target: ${gpu_target}"
111-
docker exec ${name} bash -c "
112-
cd /workspace &&
113-
rm -rf build &&
114-
mkdir build &&
115-
cd build &&
132+
docker exec "${name}" bash -c "
133+
cd /workspace || exit 1
134+
rm -rf /workspace/build
135+
mkdir /workspace/build
136+
cd /workspace/build || exit 1
116137
cmake .. -GNinja \
117138
-DGPU_TARGETS=${gpu_target} \
118139
-DCMAKE_BUILD_TYPE=Release \
@@ -127,8 +148,8 @@ cmd_build() {
127148
echo "Building target: ${target}"
128149
fi
129150

130-
docker exec ${name} bash -c "
131-
cd /workspace/build &&
151+
docker exec "${name}" bash -c "
152+
cd /workspace/build || exit 1
132153
ninja ${target} 2>&1
133154
"
134155

@@ -139,7 +160,7 @@ cmd_build() {
139160
cmd_test() {
140161
local test_name=""
141162
local name="${CONTAINER_NAME}"
142-
local test_options=""
163+
local -a test_options=()
143164

144165
while [[ $# -gt 0 ]]; do
145166
case $1 in
@@ -148,14 +169,14 @@ cmd_test() {
148169
shift 2
149170
;;
150171
--gtest_*|--help)
151-
test_options="${test_options} $1"
172+
test_options+=("$1")
152173
shift
153174
;;
154175
*)
155176
if [ -z "$test_name" ]; then
156177
test_name="$1"
157178
else
158-
test_options="${test_options} $1"
179+
test_options+=("$1")
159180
fi
160181
shift
161182
;;
@@ -168,55 +189,61 @@ cmd_test() {
168189
return 1
169190
fi
170191

171-
if ! docker ps -f name=${name} | grep -q ${name}; then
192+
# Check if container is running (exact match)
193+
if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
172194
echo "Error: Container '${name}' not running"
173195
echo "Start it with: ck-docker start --name ${name}"
174196
return 1
175197
fi
176198

177-
if ! docker exec ${name} test -f "/workspace/build/bin/${test_name}" 2>/dev/null; then
199+
if ! docker exec "${name}" test -f "/workspace/build/bin/${test_name}" 2>/dev/null; then
178200
echo "Test executable not found. Building ${test_name}..."
179-
cmd_build ${test_name} --name ${name}
201+
cmd_build "${test_name}" --name "${name}"
180202
fi
181203

182-
echo "Running: ${test_name} ${test_options}"
204+
echo "Running: ${test_name} ${test_options[*]}"
183205
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
184-
docker exec ${name} bash -c "
185-
cd /workspace/build &&
186-
./bin/${test_name} ${test_options}
187-
"
206+
# Build the command with proper quoting
207+
local cmd="cd /workspace/build && ./bin/${test_name}"
208+
for opt in "${test_options[@]}"; do
209+
cmd="${cmd} $(printf '%q' "$opt")"
210+
done
211+
docker exec "${name}" bash -c "${cmd}"
188212
}
189213

190214
# Shell
191215
cmd_shell() {
192216
local name="${1:-${CONTAINER_NAME}}"
193217

194-
if ! docker ps -f name=${name} | grep -q ${name}; then
218+
# Check if container is running (exact match)
219+
if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
195220
echo "Container '${name}' not running. Starting..."
196-
cmd_start ${name}
221+
cmd_start "${name}"
197222
fi
198223

199224
echo "Opening shell in '${name}' (type 'exit' to leave)..."
200-
docker exec -it ${name} bash
225+
docker exec -it "${name}" bash
201226
}
202227

203228
# Status
204229
cmd_status() {
205230
local name="${1:-}"
231+
local docker_image="${CK_DOCKER_IMAGE:-rocm/composable_kernel:ck_ub24.04_rocm7.0.1}"
206232

207233
if [ -z "$name" ]; then
208234
echo "Composable Kernel Docker Containers:"
209235
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
210-
docker ps -a --filter "ancestor=rocm/composable_kernel:ck_ub24.04_rocm7.0.1" \
236+
docker ps -a --filter "ancestor=${docker_image}" \
211237
--format "table {{.Names}}\t{{.Status}}\t{{.CreatedAt}}" || echo "No containers found"
212238
else
213-
if docker ps -f name=${name} | grep -q ${name}; then
239+
# Check if container is running (exact match)
240+
if docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
214241
echo "Container '${name}' is RUNNING"
215-
docker ps -f name=${name} --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
242+
docker ps --filter "name=^${name}$" --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
216243
echo ""
217244
echo "GPU Information:"
218-
docker exec ${name} bash -c "rocm-smi --showproductname 2>/dev/null | head -10 || echo 'No GPU detected'"
219-
elif docker ps -a -f name=${name} | grep -q ${name}; then
245+
docker exec "${name}" bash -c "rocm-smi --showproductname 2>/dev/null | head -10 || echo 'No GPU detected'"
246+
elif docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
220247
echo "Container '${name}' exists but is STOPPED"
221248
echo "Start with: ck-docker start ${name}"
222249
else
@@ -230,10 +257,11 @@ cmd_status() {
230257
cmd_stop() {
231258
local name="${1:-${CONTAINER_NAME}}"
232259

233-
if docker ps -a -f name=${name} | grep -q ${name}; then
260+
# Check if container exists (exact match)
261+
if docker ps -a --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
234262
echo "Stopping and removing container '${name}'..."
235-
docker stop ${name} 2>/dev/null || true
236-
docker rm ${name} 2>/dev/null || true
263+
docker stop "${name}" 2>/dev/null || true
264+
docker rm "${name}" 2>/dev/null || true
237265
echo "Container stopped and removed"
238266
else
239267
echo "Container '${name}' does not exist"
@@ -244,20 +272,21 @@ cmd_stop() {
244272
cmd_rebuild_cmake() {
245273
local name="${1:-${CONTAINER_NAME}}"
246274

247-
if ! docker ps -f name=${name} | grep -q ${name}; then
275+
# Check if container is running (exact match)
276+
if ! docker ps --filter "name=^${name}$" --format '{{.Names}}' | grep -q "^${name}$"; then
248277
echo "Container '${name}' not running. Starting..."
249-
cmd_start ${name}
278+
cmd_start "${name}"
250279
fi
251280

252281
echo "Detecting GPU target..."
253-
local gpu_target=$(detect_gpu ${name})
282+
local gpu_target=$(detect_gpu "${name}")
254283

255284
echo "Reconfiguring CMake from scratch in '${name}' for GPU target: ${gpu_target}"
256-
docker exec ${name} bash -c "
257-
cd /workspace &&
258-
rm -rf build &&
259-
mkdir build &&
260-
cd build &&
285+
docker exec "${name}" bash -c "
286+
cd /workspace || exit 1
287+
rm -rf /workspace/build
288+
mkdir /workspace/build
289+
cd /workspace/build || exit 1
261290
cmake .. -GNinja \
262291
-DGPU_TARGETS=${gpu_target} \
263292
-DCMAKE_BUILD_TYPE=Release \

.claude/skills/ck-docker.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ ck-docker rebuild-cmake [name] Reconfigure CMake
5252
## Environment
5353

5454
```bash
55-
export CK_CONTAINER_NAME=my_build # Override default container name
55+
export CK_CONTAINER_NAME=my_build # Override default container name
56+
export CK_DOCKER_IMAGE=rocm/composable_kernel:ck_ub24.04_rocm7.0.1 # Override Docker image
57+
export GPU_TARGET=gfx942 # Override GPU target detection
5658
```
5759

5860
## Examples

0 commit comments

Comments
 (0)