22# CK Docker Skill - Build and test composable_kernel in Docker with ROCm support
33
44set -e
5+ set -o pipefail
56
67# Find project root (where .git directory is)
78SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
89PROJECT_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} "
1525CONTAINER_NAME=" ${CK_CONTAINER_NAME:- ${DEFAULT_NAME} } "
1626
1727# Help message
@@ -38,46 +48,56 @@ Examples:
3848
3949Environment:
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)
4153EOF
4254}
4355
4456# Detect GPU target
4557detect_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
5370cmd_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() {
139160cmd_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
191215cmd_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
204229cmd_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() {
230257cmd_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() {
244272cmd_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 \
0 commit comments