Skip to content

Commit c5b1aa0

Browse files
author
Caspar van Leeuwen
committed
Added parallel version of stack_to_json, and added script to also support spliting by duration
1 parent ef7f671 commit c5b1aa0

2 files changed

Lines changed: 137 additions & 0 deletions

File tree

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/bash
2+
3+
input_file=$1
4+
duration_threshold=${2:-180} # Default threshold to 180 minutes if not given
5+
6+
prev_eb_version="0.0.0"
7+
easystack_num=0
8+
current_duration_sum=0
9+
total_duration_sum=0
10+
current_stack_name=""
11+
12+
while read app; do
13+
# Extract JSON keys to shell variables
14+
eval $(echo $app | jq -r '. | to_entries | .[] | .key + "=" + (.value | @sh)')
15+
16+
# Check if we need to start a new easystack
17+
if [[ ${prev_eb_version} != ${easybuild} ]] || (( current_duration_sum + build_duration_minutes > duration_threshold )); then
18+
if [[ ${current_stack_name} != "" ]]; then
19+
echo "${current_stack_name}: total build duration = ${current_duration_sum} minutes"
20+
fi
21+
easystack_num=$(( easystack_num + 1 ))
22+
prev_eb_version=${easybuild}
23+
current_duration_sum=0
24+
current_stack_name="$(printf '%03d\n' ${easystack_num})-eb-${easybuild}.yml"
25+
fi
26+
27+
easystack="${current_stack_name}"
28+
if [[ ! -f "${easystack}" ]]; then
29+
echo "easyconfigs:" > "${easystack}"
30+
fi
31+
32+
echo " - ${easyconfig}:" >> "${easystack}"
33+
echo " options:" >> "${easystack}"
34+
echo " include-easyblocks: ${easyblocks}" >> "${easystack}"
35+
36+
current_duration_sum=$(( current_duration_sum + build_duration_minutes ))
37+
total_duration_sum=$(( total_duration_sum + build_duration_minutes ))
38+
39+
done < <(jq -c '.[]' "${input_file}")
40+
41+
# Print final stack duration
42+
if [[ ${current_stack_name} != "" ]]; then
43+
echo "${current_stack_name}: total build duration = ${current_duration_sum} minutes"
44+
fi
45+
46+
# Print overall total
47+
echo "Overall total build duration = ${total_duration_sum} minutes"
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/bin/bash
2+
3+
# Usage: ./script.sh [MAX_JOBS]
4+
MAX_JOBS=${1:-4} # Default to 4 concurrent jobs if not specified
5+
DEBUG=0
6+
BASE_STACK=/cvmfs/software.eessi.io/versions/2023.06/software/linux/x86_64/intel/haswell/software
7+
EB_BOOTSTRAP=4.9.4
8+
TMPDIR=$(mktemp -d)
9+
10+
declare -A gcc_to_foss=( ["12.2.0"]="2022b" ["12.3.0"]="2023a" ["13.2.0"]="2023b" )
11+
12+
if [[ ! -d ${BASE_STACK} ]]; then
13+
echo "The given base stack (${BASE_STACK}) is not a directory."
14+
exit 1
15+
fi
16+
17+
apps=$(find ${BASE_STACK} -mindepth 2 -maxdepth 2 -type d)
18+
19+
# Job limiter
20+
job_count=0
21+
run_limited() {
22+
((job_count++))
23+
if (( job_count >= MAX_JOBS )); then
24+
wait -n # wait for one job to finish
25+
((job_count--))
26+
fi
27+
}
28+
29+
for app_dir in $apps; do
30+
run_limited
31+
(
32+
app_version=$(basename "${app_dir}")
33+
app_name=$(basename "$(dirname "${app_dir}")")
34+
35+
if [[ ${app_name} == "EESSI-extend" ]]; then
36+
exit 0
37+
fi
38+
39+
easyblocks=${app_dir}/easybuild/reprod/easyblocks/*.py
40+
easyconfig=${app_dir}/easybuild/reprod/${app_name}-${app_version}.eb
41+
42+
if [[ ! -f ${easyconfig} ]]; then
43+
echo "ERROR: cannot find easyconfig for ${app_name}/${app_version}" >&2
44+
exit 1
45+
fi
46+
47+
log_file=$(ls -1 ${app_dir}/easybuild/easybuild-${app_name}*.log* 2>/dev/null | tail -n 1)
48+
build_time_start=$(bzcat "${log_file}" | head -n 1 | awk '{print $2 "T" $3}' | cut -d, -f1)
49+
build_time_end=$(bzcat "${log_file}" | tail -n 1 | awk '{print $2 "T" $3}' | cut -d, -f1)
50+
build_duration=$(( ($(date +%s -d "${build_time_end}") - $(date +%s -d "${build_time_start}")) / 60 ))
51+
52+
eb_version=$(bzgrep -oP "This is EasyBuild \K([0-9]+\.[0-9]+\.[0-9]+)" "${log_file}" | head -n 1)
53+
if [[ ${app_name} == "EasyBuild" ]] && [[ ${app_version} == ${eb_version} ]]; then
54+
eb_version=${EB_BOOTSTRAP}
55+
fi
56+
57+
if [[ ${app_version} != *-* ]]; then
58+
toolchain="SYSTEM"
59+
else
60+
if [[ ${app_version} == *-GCC* ]]; then
61+
gcc_ver=$(echo ${app_version} | grep -oP "(GCC|GCCcore)-\K.*?(?=-|$)")
62+
toolchain=${gcc_to_foss[$gcc_ver]}
63+
else
64+
toolchain=$(echo ${app_version} | grep -oP "(foss|gfbf|gompi)-\K.*?(?=-|$)")
65+
fi
66+
fi
67+
68+
jq --null-input \
69+
--arg build_time "${build_time_start}" \
70+
--arg build_duration_minutes "${build_duration}" \
71+
--arg name "${app_name}" \
72+
--arg version "${app_version}" \
73+
--arg easybuild "${eb_version}" \
74+
--arg toolchain "${toolchain}" \
75+
--arg easyconfig "${easyconfig}" \
76+
--arg easyblocks "${easyblocks}" \
77+
'$ARGS.named' > "${TMPDIR}/${app_name}_${app_version}.json"
78+
79+
[[ ${DEBUG} -ne 0 ]] && echo "Processed ${app_name}/${app_version}" >&2
80+
) &
81+
done
82+
83+
wait
84+
85+
# Combine all results and sort by build time
86+
jq -s 'sort_by(.build_time)' "${TMPDIR}"/*.json
87+
88+
# Optional cleanup
89+
rm -r "${TMPDIR}"
90+

0 commit comments

Comments
 (0)