Skip to content

Commit acae28b

Browse files
committed
Add local and remote pre-check for linpack
This is a back-port of commit b51b116 (PR #2856) from `main`. We add a local and remote pre-check function for linpack. We now wait at most 60 seconds for the linpack process to start, and then we wait for the PID to exit instead of a file to exist. That way if a file is never written that we expect, but the PID has died, we'll not wait forever. Further, we move the "version" check (of sorts) to the linpack driver script to allow for the remote check to work without having the code in two places.
1 parent afba7d5 commit acae28b

File tree

11 files changed

+157
-65
lines changed

11 files changed

+157
-65
lines changed

agent/bench-scripts/driver/linpack

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ linpack_input_file_name="linpack.input"
1010
linpack_metadata_file_name="linpack.meta"
1111
linpack_output_file_name="linpack.out"
1212
linpack_command_file_name="linpack.cmd"
13+
linpack_pid_file_name="linpack.pid"
1314

1415
binary=""
1516

@@ -38,15 +39,19 @@ kmp_affinity_args_def="nowarnings,compact,1,0,granularity=fine"
3839
kmp_affinity_args=""
3940
numactl_args=""
4041

41-
# Output directory required.
42+
# Output directory, defaults to the current working directory if not provided.
4243
output_dir=""
4344

45+
# The linpack driver always performs pre-checks. When requested, the driver will
46+
# only run the pre-check and exit.
47+
pre_check_only=0
48+
4449
function usage() {
4550
cat <<-__EOF__
4651
Usage: ${script_name} [--problem-sizes=#[[,#]...]] [--leading-dimenions=#[[,#]...]]
4752
[--run-trials=#[[,#]]...] [--alignment-values=#[[,#]...]] [--use-omp={y|n}]
4853
[--threads=#] [--kmp-affinity=<options>] [--numactl-args=<args>]
49-
[--output-dir=<directory>] <linpack binary path>
54+
[--output-dir=<directory>] <linpack version number installed>
5055
5156
Optional output control:
5257
@@ -128,7 +133,7 @@ an invocation errors.
128133
}
129134

130135
# Process options and arguments
131-
opts=$(getopt -q -o h --longoptions "header:,subheader:,problem-sizes:,leading-dimensions:,alignment-values:,run-trials:,threads:,use-omp:,kmp-affinity:,numactl-args:,output-dir:,help" -n "${script_name}" -- "${@}")
136+
opts=$(getopt -q -o h --longoptions "header:,subheader:,problem-sizes:,leading-dimensions:,alignment-values:,run-trials:,threads:,use-omp:,kmp-affinity:,numactl-args:,output-dir:,pre-check-only,help" -n "${script_name}" -- "${@}")
132137
if [[ ${?} -ne 0 ]]; then
133138
printf -- "%s %s\n\n\tunrecognized option specified\n\n" "${script_name}" "${*}" >&2
134139
usage >&2
@@ -211,6 +216,9 @@ while true; do
211216
shift
212217
fi
213218
;;
219+
--pre-check-only)
220+
pre_check_only=1
221+
;;
214222
-h|--help)
215223
help
216224
exit 0
@@ -225,16 +233,26 @@ while true; do
225233
esac
226234
done
227235

228-
binary=${1}
229-
if [[ -z "${binary}" ]]; then
230-
printf -- "[%s] ERROR: You must specify the location of the LINPACK binary\n\n" "${script_name}" >&2
236+
ver=${1}
237+
if [[ -z "${ver}" ]]; then
238+
printf -- "[%s] ERROR: You must specify the version of the LINPACK binary\n\n" "${script_name}" >&2
231239
usage >&2
232240
exit 2
233241
fi
242+
243+
# Installation directory, optional 2nd argument, defaults to /usr/local.
244+
install_prefix_dir=${2:-"/usr/local"}
245+
246+
binary="${install_prefix_dir}/pbench-linpack-${ver}/benchmarks/linpack/xlinpack_xeon64"
234247
if [[ ! -x "${binary}" ]]; then
235-
printf -- "[%s] ERROR: The --binary must exist and be executable\n" "${script_name}" >&2
248+
printf -- "[%s] ERROR: The --binary, '${binary}', must exist and be executable\n" "${script_name}" >&2
236249
exit 2
237250
fi
251+
252+
if [[ ${pre_check_only} -ne 0 ]]; then
253+
exit 0
254+
fi
255+
238256
output_dir=${output_dir:-$(pwd)}
239257
if [[ ! -d "${output_dir}" ]]; then
240258
printf -- "[%s] ERROR: Specified --output-dir '${output_dir}' is not a directory\n" "${script_name}" >&2
@@ -270,6 +288,7 @@ linpack_input_file="${output_dir}/${linpack_input_file_name}"
270288
linpack_metadata_file="${output_dir}/${linpack_metadata_file_name}"
271289
linpack_output_file="${output_dir}/${linpack_output_file_name}"
272290
linpack_command_file="${output_dir}/${linpack_command_file_name}"
291+
linpack_pid_file="${output_dir}/${linpack_pid_file_name}"
273292

274293
# N.B. - Trailing whitespace is required.
275294
numactl_cmd=${numactl_args:+"numactl ${numactl_args} "}
@@ -312,6 +331,9 @@ cat > ${linpack_input_file} <<-__EOF__
312331
${alignment_values} # alingment values (in KBytes)
313332
__EOF__
314333

334+
# Declare ourselves to anybody waiting.
335+
echo "$$" > ${linpack_pid_file}
336+
315337
# Now we can execute the final LINPACK command.
316338
source ${linpack_command_file}
317339
exit_code=${?}

agent/bench-scripts/driver/linpack-wait

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,30 @@
33

44
# A very simple method to wait for the linpack driver to report it has
55
# finished.
6-
while [[ ! -e "${1}/linpack.meta" ]]; do
6+
7+
if [[ ! -d "${1}" ]]; then
8+
printf -- "linpack-wait: target directory, '${1}', does not exist!\n" >&2
9+
exit 1
10+
fi
11+
12+
# Wait for the linpack pid file to show up.
13+
let cnt=60
14+
while [[ ${cnt} -gt 0 && -d "${1}" && ! -e "${1}/linpack.pid" ]]; do
15+
sleep 1
16+
(( cnt-- ))
17+
done
18+
if [[ ! -d "${1}" ]]; then
19+
printf -- "linpack-wait: target directory, '${1}', no longer exists!\n" >&2
20+
exit 1
21+
fi
22+
if [[ ! -e "${1}/linpack.pid" ]]; then
23+
printf -- "linpack-wait: linpack pid file, '${1}/linpack.pid', failed to show up\n" >&2
24+
exit 1
25+
fi
26+
27+
# At this point, we wait for the linpack process to stop running.
28+
pid=$(< "${1}/linpack.pid")
29+
while [[ -d /proc/${pid} ]]; do
730
sleep 1
831
done
932
exit 0

agent/bench-scripts/pbench-linpack

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ pbench_bin="$(realpath -e ${script_path}/..)"
2727
export benchmark="linpack"
2828

2929
# Defaults
30+
31+
# This script always runs a pre-check. When non-local clients are used, as part
32+
# of the pre-check operation, it invokes itself remotely to ONLY run a local
33+
# pre-check and exit.
34+
pre_check_only=0
3035
def_threads=$(cat /proc/cpuinfo | grep processor | wc -l)
3136
threads=${def_threads}
3237
def_nr_samples=2
@@ -49,7 +54,7 @@ function usage {
4954
}
5055

5156
# Process options and arguments
52-
opts=$(getopt -q -o C:c:h --longoptions "config:,clients:,samples:,threads:,tool-group:,sysinfo:,help" -n "getopt.sh" -- "${@}")
57+
opts=$(getopt -q -o C:c:h --longoptions "config:,clients:,help,pre-check-only,samples:,sysinfo:,threads:,tool-group:" -n "getopt.sh" -- "${@}")
5358
if [[ ${?} -ne 0 ]]; then
5459
printf -- "%s %s\n\n\tunrecognized option specified\n\n" "${script_name}" "${*}" >&2
5560
usage >&2
@@ -72,27 +77,30 @@ while true; do
7277
shift
7378
fi
7479
;;
80+
--pre-check-only)
81+
pre_check_only=1
82+
;;
7583
--samples)
7684
if [[ -n "${1}" ]]; then
7785
nr_samples="${1}"
7886
shift
7987
fi
8088
;;
81-
--threads)
89+
--sysinfo)
8290
if [[ -n "${1}" ]]; then
83-
threads="${1}"
91+
sysinfo="${1}"
8492
shift
8593
fi
8694
;;
87-
--tool-group)
95+
--threads)
8896
if [[ -n "${1}" ]]; then
89-
tool_group="${1}"
97+
threads="${1}"
9098
shift
9199
fi
92100
;;
93-
--sysinfo)
101+
--tool-group)
94102
if [[ -n "${1}" ]]; then
95-
sysinfo="${1}"
103+
tool_group="${1}"
96104
shift
97105
fi
98106
;;
@@ -113,24 +121,49 @@ while true; do
113121
done
114122
verify_common_bench_script_options ${tool_group} ${sysinfo}
115123

116-
ver="$(pbench-config version ${benchmark})"
117-
if [[ -z "${ver}" ]]; then
118-
error_log "${script_name}: package version is missing in config file"
119-
exit 1
120-
fi
121-
if [[ -z "${linpack_dir}" ]]; then
122-
linpack_dir="/usr/local/${script_name}-${ver}/benchmarks/linpack"
123-
linpack_dir_kind="default"
124-
else
125-
linpack_dir_kind="provided"
124+
function pre_check {
125+
# Invoke the linpack driver to perform a pre-check that it will be able to
126+
# execute the benchmark. The expected version is the first argument, and the
127+
# second is the expected directory prefix for the linpack installation.
128+
local ver=${1}
129+
local install_prefix_arg=${2}
130+
131+
${pbench_bin}/bench-scripts/driver/linpack --pre-check-only ${ver} ${install_prefix_arg}
132+
return ${?}
133+
}
134+
135+
if [[ ${pre_check_only} -ne 0 ]]; then
136+
# We have been invoked remotely to check for the expected version of
137+
# linpack installed. The remote invocation has provided the arguments to
138+
# pass to the pre-check function (see --pre-check-only invocation below).
139+
pre_check ${@}
140+
exit ${?}
126141
fi
127-
if [[ ! -d "${linpack_dir}" ]]; then
128-
error_log "${script_name}: the ${linpack_dir_kind} linpack directory, ${linpack_dir}, does not exist"
142+
143+
linpack_ver="$(pbench-config version ${benchmark})"
144+
if [[ -z "${linpack_ver}" ]]; then
145+
error_log "${script_name}: package version is missing in config file"
129146
exit 1
130147
fi
131-
linpack_cmd="${linpack_dir}/xlinpack_xeon64"
132-
if [[ ! -x "${linpack_cmd}" ]]; then
133-
error_log "${script_name}: the expected linpack command, ${linpack_cmd}, does not exist"
148+
149+
# Run the pre-check.
150+
let not_found=0
151+
for client in ${clients//,/ }; do
152+
if pbench-is-local "${client}"; then
153+
pre_check ${linpack_ver} ${PBENCH_LINPACK_INSTALL_PREFIX_DIR}
154+
if [[ ${?} -ne 0 ]]; then
155+
error_log "${script_name}: linpack not installed locally"
156+
(( not_found++ ))
157+
fi
158+
else
159+
ssh ${ssh_opts} ${client} ${script_name} --pre-check-only ${linpack_ver} ${PBENCH_LINPACK_INSTALL_PREFIX_DIR}
160+
if [[ ${?} -ne 0 ]]; then
161+
error_log "${script_name}: linpack not installed on client ${client}"
162+
(( not_found++ ))
163+
fi
164+
fi
165+
done
166+
if [[ ${not_found} -gt 0 ]]; then
134167
exit 1
135168
fi
136169

@@ -243,7 +276,8 @@ for thread in ${threads//,/ }; do
243276
pbench-start-tools --group=${tool_group} --dir="${sample_dir}"
244277

245278
run_it="pbench-linpack ${pbench_bin}/bench-scripts/driver/linpack"
246-
run_it+=" --output-dir=${sample_dir} --threads=${thread} ${linpack_cmd}"
279+
run_it+=" --output-dir=${sample_dir} --threads=${thread}"
280+
run_it+=" ${linpack_ver} ${PBENCH_LINPACK_INSTALL_PREFIX_DIR}"
247281
screen_it="screen -dmS ${run_it}"
248282
for client in ${clients//,/ }; do
249283
if pbench-is-local "${client}"; then

agent/bench-scripts/tests/pbench-linpack/test-63.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
+++ Running test-63 pbench-linpack
2-
[error][1900-01-01T00:00:00.000000] pbench-linpack: the default linpack directory, /usr/local/pbench-linpack-11.1.3/benchmarks/linpack, does not exist
2+
[linpack] ERROR: The --binary, '/usr/local/pbench-linpack-11.1.3/benchmarks/linpack/xlinpack_xeon64', must exist and be executable
3+
[error][1900-01-01T00:00:00.000000] pbench-linpack: linpack not installed locally
34
--- Finished test-63 pbench-linpack (status=1)
45
+++ pbench tree state
56
/var/tmp/pbench-test-bench/pbench-agent
@@ -12,5 +13,5 @@
1213
/var/tmp/pbench-test-bench/pbench-agent/tools-v1-default/testhost.example.com/sar
1314
--- pbench tree state
1415
+++ pbench.log file contents
15-
[error][1900-01-01T00:00:00.000000] pbench-linpack: the default linpack directory, /usr/local/pbench-linpack-11.1.3/benchmarks/linpack, does not exist
16+
[error][1900-01-01T00:00:00.000000] pbench-linpack: linpack not installed locally
1617
--- pbench.log file contents
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export linpack_dir=${_testtmp}/linpack
1+
export PBENCH_LINPACK_INSTALL_PREFIX_DIR=${_testtmp}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

33
# Setup a fake install of linpack but without the expected executable.
4-
_linpack_dir=${_testtmp}/linpack
4+
_linpack_dir=${_testtmp}/pbench-linpack-11.1.3
55
mkdir ${_linpack_dir} || exit 1
66
exit 0

agent/bench-scripts/tests/pbench-linpack/test-64.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
+++ Running test-64 pbench-linpack
2-
[error][1900-01-01T00:00:00.000000] pbench-linpack: the expected linpack command, /var/tmp/pbench-test-bench/tmp/linpack/xlinpack_xeon64, does not exist
2+
[linpack] ERROR: The --binary, '/var/tmp/pbench-test-bench/tmp/pbench-linpack-11.1.3/benchmarks/linpack/xlinpack_xeon64', must exist and be executable
3+
[error][1900-01-01T00:00:00.000000] pbench-linpack: linpack not installed locally
34
--- Finished test-64 pbench-linpack (status=1)
45
+++ pbench tree state
56
/var/tmp/pbench-test-bench/pbench-agent
@@ -12,5 +13,5 @@
1213
/var/tmp/pbench-test-bench/pbench-agent/tools-v1-default/testhost.example.com/sar
1314
--- pbench tree state
1415
+++ pbench.log file contents
15-
[error][1900-01-01T00:00:00.000000] pbench-linpack: the expected linpack command, /var/tmp/pbench-test-bench/tmp/linpack/xlinpack_xeon64, does not exist
16+
[error][1900-01-01T00:00:00.000000] pbench-linpack: linpack not installed locally
1617
--- pbench.log file contents
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/bin/bash
22

33
# Setup a fake install of linpack but with a stub for the expected executable.
4-
_linpack_dir=${_testtmp}/linpack
5-
mkdir ${_linpack_dir} || exit 1
4+
_linpack_dir=${_testtmp}/pbench-linpack-11.1.3/benchmarks/linpack
5+
mkdir -p ${_linpack_dir} || exit 1
66
printf -- "#!/bin/bash\nexit 0\n" > ${_linpack_dir}/xlinpack_xeon64 || exit 1
77
chmod 775 ${_linpack_dir}/xlinpack_xeon64 || exit 1
88
exit 0

0 commit comments

Comments
 (0)