Skip to content

Commit 8e6ebf7

Browse files
committed
An XML based solution to mpirun output processing.
1 parent 06120fc commit 8e6ebf7

File tree

1 file changed

+39
-15
lines changed

1 file changed

+39
-15
lines changed

src/psij/launchers/scripts/mpi_launch.sh

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,53 @@ fi
1515

1616
pre_launch
1717

18-
filter_out() {
19-
sed -nE 's/^\[[^]]+\]<stdout>:(.*)/\1/p'
20-
}
21-
22-
filter_err() {
23-
sed -nE 's/^\[[^]]+\]<stderr>:(.*)/\1/p'
18+
# We need to use a marker for when actual output starts because some mpi deployments add
19+
# banners at the beginning of the mpirun output. There are two seemingly reasonable
20+
# ways of extracting the output: --tag-output and --xml. Unfortunately, --tag-output is broken
21+
# and occasionally mashes two lines together in the form "part1<TAG>:part2" instead of
22+
# "<TAG>:part1part2". So we really only have XML
23+
process_line() {
24+
LINE="$1"
25+
if [[ "$LINE" =~ \<stdout ]]; then
26+
FILE="$_PSI_J_STDOUT"
27+
elif [[ "$LINE" =~ \<stderr ]]; then
28+
FILE="$_PSI_J_STDERR"
29+
else
30+
return
31+
fi
32+
# We first remove </mpirun>, which can be found after </stdout>.
33+
# The rest is about converting &#nnnn; entities to something that we can print with other
34+
# POSIX tools. The %c specified does not work properly for the bash printf, since it requires
35+
# an integer as input, but we can only supply strings. We can either use awk's printf or
36+
#
37+
P1=$(echo $LINE | sed -nE 's/<\/?mpirun>//g; s/&#0*/\&#/g; s/<std...[^>]*>([^<]*)<\/std...>/\1/g p')
38+
FMT=$(echo "$P1" | sed 's/\\/\\\\/g;s/%/%%/g;s/&#[0-9]*;/%c/g;s/&gt;/>/g;s/&lt;/</g;s/&amp;/\&/g;s/"/\"/g')
39+
NUMS=$(echo "$P1" | grep -o '&#[0-9]*;' | tr '&#;' ' ,' )
40+
awk "BEGIN {printf \"$FMT%s\", $NUMS \"\"}" >>"$FILE"
2441
}
2542

26-
filter_out_5() {
27-
sed -nE 's/^\[[^]]+\]<stdout>: (.*)/\1/p'
43+
filter_out() {
44+
while IFS= read LINE; do
45+
process_line "$LINE"
46+
done
47+
# If the last line does not end in a newline, read will exit with a non-zero code but still
48+
# set the variable to the contents of that line. Not sure how portable this is.
49+
if [ "$LINE" != "" ]; then
50+
process_line "$LINE"
51+
fi
2852
}
2953

30-
filter_err_5() {
31-
sed -nE 's/^\[[^]]+\]<stderr>: (.*)/\1/p'
32-
}
54+
# truncate output since we append in the functions above
55+
> $_PSI_J_STDOUT
56+
> $_PSI_J_STDERR
3357

3458
set +e
3559
if [ "$IS_OPENMPI_5" == "1" ]; then
36-
mpirun --oversubscribe --output TAG -n $_PSI_J_PROCESS_COUNT "$@" \
37-
1> >(filter_out_5 > $_PSI_J_STDOUT) 2> >(filter_err_5 > $_PSI_J_STDERR) <$_PSI_J_STDIN
60+
mpirun --oversubscribe --output XML -n $_PSI_J_PROCESS_COUNT "$@" \
61+
1> >(filter_out) <$_PSI_J_STDIN
3862
elif [ "$IS_OPENMPI" == "1" ]; then
39-
mpirun --oversubscribe --tag-output -q -n $_PSI_J_PROCESS_COUNT "$@" \
40-
1> >(filter_out > "$_PSI_J_STDOUT") 2> >(filter_err > $_PSI_J_STDERR) <$_PSI_J_STDIN
63+
mpirun --oversubscribe -q -xml -n $_PSI_J_PROCESS_COUNT "$@" \
64+
1> >(filter_out) <$_PSI_J_STDIN
4165
else
4266
mpirun -n $_PSI_J_PROCESS_COUNT "$@" 1>$_PSI_J_STDOUT 2>$_PSI_J_STDERR <$_PSI_J_STDIN
4367
fi

0 commit comments

Comments
 (0)