From 017e6c97955c652bc4a18fda949a4ed291406cbe Mon Sep 17 00:00:00 2001 From: Ben Vandervalk Date: Tue, 4 Dec 2018 10:39:37 -0800 Subject: [PATCH] abyss-pe: increase stack size limit for certain ABySS programs We were seeing stack overflows in the `abyss-bloom-dbg` program on conifer genomes, caused by graph searches implemented with recursion. We also occasionally see stack overflows in `SimpleGraph` and `PathConsensus`, also due to recursive graph searches. As a workaround for this problem, I have added a wrapper script called `abyss-stack-size` which runs a shell command with an increased max stack size, using `ulimit -s`. --- bin/Makefile.am | 4 +++- bin/abyss-pe | 13 ++++++++----- bin/abyss-stack-size | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100755 bin/abyss-stack-size diff --git a/bin/Makefile.am b/bin/Makefile.am index 624de4134..8563665f3 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -17,8 +17,10 @@ dist_bin_SCRIPTS = \ abyss-samtoafg \ abyss-tabtomd \ abyss-bloom-dist.mk \ - abyss-dida + abyss-dida \ + abyss-stack-size \ $(nompi) + dist_noinst_SCRIPTS = \ abyss-adjtodot.pl \ abyss-cstont \ diff --git a/bin/abyss-pe b/bin/abyss-pe index 663f425be..2bbbfdc98 100755 --- a/bin/abyss-pe +++ b/bin/abyss-pe @@ -21,6 +21,9 @@ gtime=command time -v -o $@.time endif endif +# Wrapper script for commands that require an increased stack size limit +stack=abyss-stack-size 65536 + # Define this environment variable on Mac OS X to read # compressed files. export DYLD_FORCE_FLAT_NAMESPACE=1 @@ -532,7 +535,7 @@ endif ifdef B %-1.fa: - $(gtime) abyss-bloom-dbg $(abyssopt) $(ABYSS_OPTIONS) $(in) $(se) > $@ + $(gtime) $(stack) abyss-bloom-dbg $(abyssopt) $(ABYSS_OPTIONS) $(in) $(se) > $@ else ifdef K ifdef np @@ -626,7 +629,7 @@ endif # Assemble contigs %-4.path1: %-4.$g %-3.dist - $(gtime) SimpleGraph $v $(sgopt) $(SIMPLEGRAPH_OPTIONS) -j$j -k$k -o $@ $^ + $(gtime) $(stack) SimpleGraph $v $(sgopt) $(SIMPLEGRAPH_OPTIONS) -j$j -k$k -o $@ $^ %-4.path2: %-4.path1 %-3.fa.fai %-4.fa.fai cat $*-3.fa.fai $*-4.fa.fai \ @@ -639,7 +642,7 @@ ifndef cs %-5.path %-5.fa %-5.$g: %-3.fa %-4.fa %-4.$g %-4.path3 cat $(wordlist 1, 2, $^) \ - |$(gtime) PathConsensus $v --$g -k$k $(pcopt) $(PATHCONSENSUS_OPTIONS) -o $*-5.path -s $*-5.fa -g $*-5.$g - $(wordlist 3, 4, $^) + |$(gtime) $(stack) PathConsensus $v --$g -k$k $(pcopt) $(PATHCONSENSUS_OPTIONS) -o $*-5.path -s $*-5.fa -g $*-5.$g - $(wordlist 3, 4, $^) %-6.fa: %-3.fa %-4.fa %-5.fa %-5.$g %-5.path cat $(wordlist 1, 3, $^) |$(gtime) MergeContigs $(mcopt) -o $@ - $(wordlist 4, 5, $^) @@ -704,7 +707,7 @@ endif $(gtime) abyss-scaffold $(scopt) -s$S -n$N -g $@.dot $(SCAFFOLD_OPTIONS) $^ >$@ %-7.path %-7.$g %-7.fa: %-6.fa %-6.$g %-6.path - $(gtime) PathConsensus $v --$g -k$k $(pcopt) $(PATHCONSENSUS_OPTIONS) -s $*-7.fa -g $*-7.$g -o $*-7.path $^ + $(gtime) $(stack) PathConsensus $v --$g -k$k $(pcopt) $(PATHCONSENSUS_OPTIONS) -s $*-7.fa -g $*-7.$g -o $*-7.path $^ %-8.fa: %-6.fa %-7.fa %-7.$g %-7.path cat $(wordlist 1, 2, $^) \ @@ -850,7 +853,7 @@ sealer_ks?=-k90 -k80 -k70 -k60 -k50 -k40 -k30 $(gtime) abyss-scaffold $(scopt) -s$S -n1 -g $@.$g $(SCAFFOLD_OPTIONS) $^ >$@ %-9.path %-9.$g %-9.fa: %-8.fa %-8.$g %-8.path - $(gtime) PathConsensus $v --$g -k$k $(pcopt) $(PATHCONSENSUS_OPTIONS) -s $*-9.fa -g $*-9.$g -o $*-9.path $^ + $(gtime) $(stack) PathConsensus $v --$g -k$k $(pcopt) $(PATHCONSENSUS_OPTIONS) -s $*-9.fa -g $*-9.$g -o $*-9.path $^ %-10.fa: %-8.fa %-9.fa %-9.$g %-9.path cat $(wordlist 1, 2, $^) \ diff --git a/bin/abyss-stack-size b/bin/abyss-stack-size new file mode 100755 index 000000000..8546ad09f --- /dev/null +++ b/bin/abyss-stack-size @@ -0,0 +1,25 @@ +#!/bin/sh + +if [ $# -lt 2 ]; then + echo "Usage: $(basename $0) " >&2 + echo "Run COMMAND in a shell with a maximum stack size of" >&2 + echo "at least STACK_SIZE in kilobytes." >&2 + exit 1 +fi +min_stack=$1; shift + +# Note: A max stack size of "unlimited" may not actually +# be unlimited. For example, on Linux, using "unlimited" +# results in a max stack size of 2 MB, which +# is less than the default max stack size of 8 MB. +# How confusing! + +stack=$(ulimit -s) +if [ "$stack" = "unlimited" ] || [ "$stack" -lt "$min_stack" ]; then + ulimit -s $min_stack +fi +stack=$(ulimit -s) + +echo "Running with max stack size of $stack KB: $*" >&2 +exec /bin/sh -c "$*" +