Skip to content

Commit d8c39ec

Browse files
committed
Improve xrt-smi bash and csh completion scripts
Modern bash versions use autoloading for completion scripts, so "Autocomplete enabled for the xrt-smi command" in the middle of completion did not look well and was removed. Other changes: - Update command set to configure/examine/validate (remove program/reset) - Add device BDF completion by reading /sys/class/accel/ symlinks - Restructure bash completion to handle global options before commands - Add terminal option handling (--version, --help) to prevent further completions - Add separate handling for --advanced options (namely, precise -r completion) - Fill all arguments supported by xrt-smi Tested with csh-6.24.16 and bash-5.3.9
1 parent 69fb2d1 commit d8c39ec

3 files changed

Lines changed: 385 additions & 149 deletions

File tree

Lines changed: 232 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,35 @@
11
# bash completion for xrt-smi -*- shell-script -*-
22
# SPDX-License-Identifier: Apache-2.0
33
# Copyright (C) 2021-2022 Xilinx, Inc. All rights reserved.
4-
#
4+
# Copyright (C) 2024-2026 Advanced Micro Devices, Inc. All rights reserved.
5+
6+
# Extract enum values for a named option from xrt-smi help output.
7+
# $1: option name to match (e.g. "--report")
8+
# Remaining args: passed to xrt-smi before --help (e.g. "examine --advanced")
9+
_xrt_smi_enum()
10+
{
11+
local opt="$1"; shift
12+
xrt-smi "$@" --help 2>&1 | awk -v opt="$opt" '
13+
index($0, opt) { found=1; next }
14+
found && /^[[:space:]]+[a-z]/ && / - / { print $1; next }
15+
found && /^[[:space:]]+-/ { exit }
16+
found && !/^[[:space:]]/ { exit }
17+
' | tr '\n' ' '
18+
}
19+
20+
# Extract all option flags from xrt-smi help output.
21+
# All args are passed to xrt-smi before --help.
22+
_xrt_smi_options()
23+
{
24+
xrt-smi "$@" --help 2>&1 | awk '
25+
/^[[:space:]]+-/ {
26+
for (i = 1; i <= NF; i++) {
27+
if ($i == "-") break
28+
if ($i ~ /^-/) { gsub(/,/, "", $i); print $i }
29+
}
30+
}
31+
' | tr '\n' ' '
32+
}
533

634
# Generates the command word options dependant on the previous word
735
# using COMPREPLY
@@ -10,114 +38,242 @@
1038
#
1139
# Parameters:
1240
# 1: The complete list of options for the previous word
13-
_command_word_xbutil_completion()
41+
_xrt_smi_completion()
1442
{
1543
# Get the righthand most word on the command line
1644
local cur=${COMP_WORDS[COMP_CWORD]}
17-
# The previous word
45+
# The previous word
1846
local prev=${COMP_WORDS[COMP_CWORD-1]}
1947

2048
# The BDFs (for devices) contain colons which breaks the autocomplete
2149
# to get around this a helper function removes colons and helps parse the current and previous
2250
# words
2351
_get_comp_words_by_ref -n : cur prev
2452

25-
# Each defined case requires an argument so no reply is given
26-
# All other cases default to using `compgen` output to format COMPREPLY
53+
local commands="configure examine validate advanced"
54+
local globalModifiers="--verbose --batch --force --advanced"
55+
56+
# Check for terminal options first - no completions after these
57+
local i
58+
for (( i=1; i < COMP_CWORD; i++ )); do
59+
case ${COMP_WORDS[i]} in
60+
--version)
61+
# --version is terminal at top level, no more completions
62+
COMPREPLY=()
63+
return
64+
;;
65+
esac
66+
done
67+
68+
# Detect if --advanced flag is present
69+
local hasAdvanced=0 advFlag=""
70+
for (( i=1; i < COMP_CWORD; i++ )); do
71+
case ${COMP_WORDS[i]} in
72+
--advanced)
73+
hasAdvanced=1
74+
advFlag="--advanced"
75+
break
76+
;;
77+
esac
78+
done
79+
80+
# Search for a command in the current command line
81+
# Global options like --verbose can appear before the command
82+
local commandWord=""
83+
for (( i=1; i < COMP_CWORD; i++ )); do
84+
case ${COMP_WORDS[i]} in
85+
configure|examine|validate|advanced)
86+
commandWord=${COMP_WORDS[i]}
87+
break
88+
;;
89+
esac
90+
done
91+
92+
# Detect sub-option context (OptionOptions that consume remaining args)
93+
local subOption=""
94+
for (( i=1; i < COMP_CWORD; i++ )); do
95+
case ${COMP_WORDS[i]} in
96+
--event-trace|--firmware-log|--context-health|--force-preemption|\
97+
--read-mem|--write-mem|--read-aie-reg|--aie-clock)
98+
subOption=${COMP_WORDS[i]}
99+
break
100+
;;
101+
esac
102+
done
103+
104+
# Handle sub-option specific completions
105+
if [[ -n "${subOption}" ]]; then
106+
case ${prev} in
107+
-d|--device)
108+
local devices
109+
devices=$(ls -d /sys/class/accel/accel*/device 2>/dev/null | xargs -I{} readlink {} | xargs -n1 basename 2>/dev/null)
110+
COMPREPLY=($(compgen -W "${devices}" -- "${cur}"))
111+
__ltrim_colon_completions "${cur}"
112+
return
113+
;;
114+
-o|--output|-i|--input|--raw)
115+
_filedir
116+
return
117+
;;
118+
esac
119+
local subOptions=""
120+
case ${subOption} in
121+
--event-trace)
122+
if [[ "${commandWord}" == "examine" ]]; then
123+
subOptions="--device -d --help -h --status --watch --raw --payload-version"
124+
elif [[ "${commandWord}" == "configure" ]]; then
125+
subOptions="--device -d --help -h --enable --disable --list-categories --categories"
126+
fi
127+
;;
128+
--firmware-log)
129+
if [[ "${commandWord}" == "examine" ]]; then
130+
subOptions="--device -d --help -h --status --watch --raw --payload-version"
131+
elif [[ "${commandWord}" == "configure" ]]; then
132+
subOptions="--device -d --help -h --enable --disable --log-level"
133+
fi
134+
;;
135+
--context-health)
136+
subOptions="--device -d --help -h --watch --ctx-id --pid"
137+
;;
138+
--force-preemption)
139+
subOptions="--device -d --help enable disable status"
140+
;;
141+
--read-mem)
142+
subOptions="--device -d --output -o --address --size --count --help"
143+
;;
144+
--write-mem)
145+
subOptions="--input -i --device -d --address --size --count --fill -f --help"
146+
;;
147+
--read-aie-reg)
148+
subOptions="--device -d --row --col --reg --help"
149+
;;
150+
--aie-clock)
151+
subOptions="--device -d --partition -p --set -s --get -g --help -h"
152+
;;
153+
esac
154+
COMPREPLY=($(compgen -W "${subOptions}" -- "${cur}"))
155+
__ltrim_colon_completions "${cur}"
156+
return
157+
fi
158+
159+
# Handle options that require arguments
27160
case ${prev} in
28161
-d|--device)
29-
options=""
162+
# List available device BDFs by reading symlinks from /sys/class/accel/
163+
local devices
164+
devices=$(ls -d /sys/class/accel/accel*/device 2>/dev/null | xargs -I{} readlink {} | xargs -n1 basename 2>/dev/null)
165+
COMPREPLY=($(compgen -W "${devices}" -- "${cur}"))
166+
__ltrim_colon_completions "${cur}"
167+
return
168+
;;
169+
-f|--format)
170+
# Format options: JSON or JSON-2020.2
171+
COMPREPLY=($(compgen -W "JSON JSON-2020.2" -- "${cur}"))
172+
return
173+
;;
174+
--pmode)
175+
# Performance mode options (dynamically from device)
176+
local vals
177+
vals=$(_xrt_smi_enum "--pmode" configure ${advFlag})
178+
[[ -z "$vals" ]] && vals="default powersaver balanced performance turbo"
179+
COMPREPLY=($(compgen -W "${vals}" -- "${cur}"))
180+
return
30181
;;
31-
-u|--user)
182+
-o|--output)
32183
# The _filedir function is defined in the bash-completion script typically found in
33184
# /usr/share/bash-completion/bash_completions. This populates the COMP_REPLY with
34185
# All files and directories are specified by the last argument in the command line
35186
# when a tab completion event is triggered.
36187
_filedir
37-
options=""
38-
;;
39-
-f|--format)
40-
options=""
188+
return
41189
;;
42-
-o|--output)
190+
-i|--input)
43191
_filedir
44-
options=""
45-
;;
46-
-t|--type)
47-
options=""
192+
return
48193
;;
49194
-p|--path)
50-
_filedir
51-
options=""
195+
_filedir -d
196+
return
52197
;;
53-
--p2p)
54-
options=""
198+
--report)
199+
# Report types for examine command (dynamically from device)
200+
local vals
201+
vals=$(_xrt_smi_enum "--report" examine ${advFlag})
202+
[[ -z "$vals" ]] && vals="aie-partitions all host platform"
203+
COMPREPLY=($(compgen -W "${vals}" -- "${cur}"))
204+
return
205+
;;
206+
--run)
207+
# Test types for validate command (dynamically from device)
208+
local vals
209+
vals=$(_xrt_smi_enum "--run" validate ${advFlag})
210+
[[ -z "$vals" ]] && vals="all latency throughput"
211+
COMPREPLY=($(compgen -W "${vals}" -- "${cur}"))
212+
return
213+
;;
214+
-r)
215+
# -r is --report for examine, --run for validate
216+
local vals
217+
if [[ "${commandWord}" == "validate" ]]; then
218+
vals=$(_xrt_smi_enum "--run" validate ${advFlag})
219+
[[ -z "$vals" ]] && vals="all latency throughput"
220+
else
221+
vals=$(_xrt_smi_enum "--report" examine ${advFlag})
222+
[[ -z "$vals" ]] && vals="aie-partitions all host platform"
223+
fi
224+
COMPREPLY=($(compgen -W "${vals}" -- "${cur}"))
225+
return
226+
;;
227+
--force-preemption)
228+
COMPREPLY=($(compgen -W "enable disable status" -- "${cur}"))
229+
return
55230
;;
56231
--host-mem)
57-
options=""
232+
COMPREPLY=($(compgen -W "enable disable" -- "${cur}"))
233+
return
58234
;;
59-
# The -r option is used for multiple commands so extra processing is needed in here
60-
-r|--report|--run)
61-
options=""
235+
--p2p)
236+
COMPREPLY=($(compgen -W "enable disable validate" -- "${cur}"))
237+
return
62238
;;
63-
*)
64-
# Default to using the passed in options if no particular option is used
65-
options=$1
239+
-h|--help)
240+
# --help is terminal, no more completions
241+
COMPREPLY=()
242+
return
66243
;;
67244
esac
68-
# The format of the compgen commands options is seperated from the current word using a --.
69-
# The -- character signifies the end of command options. All following arguments are positional.
70-
COMPREPLY+=($(compgen -W "$options" -- $cur))
71-
# 2nd part of getting around colons in the suggested keywords
72-
__ltrim_colon_completions "$cur"
73-
}
74245

75-
# The main function populating the COMPREPLY
76-
_xbutil_completion()
77-
{
78-
commonSubCommands="--verbose --batch --force --help -h --version"
79-
# COMP_CWORD is the current index of the cursor in the command line
80-
# 0 is the first argument (xrt-smi), 1 is the desired command for xrt-smi,
81-
# 2 is an option for the command, etc.
82-
case ${COMP_CWORD} in
83-
# Case for command after xrt-smi
84-
1)
85-
options="program validate examine configure reset ${commonSubCommands}"
86-
;;
87-
# Case for options after the above command is entered
88-
*)
89-
# Command word is used to specify further options as the command expands
90-
commandWord=${COMP_WORDS[1]}
91-
# Options that appear for all commands
92-
commonSubCommands="--device -d ${commonSubCommands}"
93-
# Once a command is identified the options will always be the same
246+
# Build completion options based on context
247+
local options=""
248+
249+
if [[ -z "${commandWord}" ]]; then
250+
# No command found yet, suggest commands and global options
251+
options="${commands} ${globalModifiers} --help -h --version"
252+
else
253+
# Dynamically get available options from help output
254+
options=$(_xrt_smi_options ${commandWord} ${advFlag})
255+
if [[ -n "${options}" ]]; then
256+
# Add --advanced since it's a global option not shown in subcommand help
257+
options="${options} --advanced"
258+
else
259+
# Fallback to static options
260+
local commonOptions="--device -d --help -h ${globalModifiers}"
94261
case ${commandWord} in
95-
"program")
96-
options="--user -u ${commonSubCommands}"
97-
;;
98-
"validate")
99-
options="--run -r --format -f --output -o --path -p ${commonSubCommands}"
100-
;;
101-
"examine")
102-
options="--report -r --format -f --output -o ${commonSubCommands}"
103-
;;
104-
"configure")
105-
options="--host-mem --p2p --size ${commonSubCommands}"
106-
;;
107-
"reset")
108-
options="--type -t ${commonSubCommands}"
109-
;;
110-
# Return an empty reply if an invalid command is entered
111-
*)
112-
options=""
113-
;;
262+
configure) options="--pmode ${commonOptions}" ;;
263+
examine) options="--report -r --format -f --output -o ${commonOptions}" ;;
264+
validate) options="--run -r --format -f --output -o ${commonOptions}" ;;
265+
advanced) options="--read-mem --write-mem --device -d --help" ;;
114266
esac
115-
;;
116-
esac
117-
_command_word_xbutil_completion "${options}"
267+
fi
268+
fi
269+
270+
# The format of the compgen commands options is seperated from the current word using a --.
271+
# The -- character signifies the end of command options. All following arguments are positional.
272+
COMPREPLY=($(compgen -W "${options}" -- "${cur}"))
273+
# 2nd part of getting around colons in the suggested keywords
274+
__ltrim_colon_completions "${cur}"
118275
}
119276

120-
complete -F _xbutil_completion xrt-smi
121-
echo Autocomplete enabled for the xrt-smi command
277+
complete -F _xrt_smi_completion xrt-smi
122278

123279
# ex: filetype=sh

0 commit comments

Comments
 (0)