[med-svn] [bowtie2] 01/04: Imported Upstream version 2.2.6

Alex Mestiashvili malex-guest at moszumanska.debian.org
Fri Aug 28 07:59:41 UTC 2015


This is an automated email from the git hooks/post-receive script.

malex-guest pushed a commit to branch master
in repository bowtie2.

commit 43fc5423d2e66f821bec7c322e3c9ee25b5b8c7b
Author: Alexandre Mestiashvili <alex at biotec.tu-dresden.de>
Date:   Fri Aug 28 09:20:58 2015 +0200

    Imported Upstream version 2.2.6
---
 MANUAL                      |   6 ++-
 MANUAL.markdown             |   7 ++-
 Makefile                    |  59 ++++++++++++++++--------
 NEWS                        |  13 ++++++
 VERSION                     |   2 +-
 aligner_seed_policy.cpp     |   9 ++--
 aligner_seed_policy.h       |   5 ++
 aligner_swsse_ee_u8.cpp     |   5 +-
 aligner_swsse_loc_u8.cpp    |   4 +-
 bt2_idx.h                   |   2 +-
 bt2_search.cpp              | 109 ++++++++++++++++++++++++++++++++++++++------
 threading.h => bt2_search.h |  52 +++++++++------------
 doc/manual.html             |   6 +--
 ds.h                        |   5 +-
 reference.cpp               |   8 ++--
 threading.h                 |  19 +++++++-
 timer.h                     |  88 +++++++++++++++++++++++++++++++++--
 17 files changed, 306 insertions(+), 93 deletions(-)

diff --git a/MANUAL b/MANUAL
index 691fa91..ffcc98d 100644
--- a/MANUAL
+++ b/MANUAL
@@ -160,12 +160,16 @@ execution times on SMP architectures where this is possible. On POSIX
 platforms (like linux, Mac OS, etc) it needs the pthread library. Although
 it is possible to use pthread library on non-POSIX platform like Windows, due
 to performance reasons bowtie 2 will try to use Windows native multithreading
-if possible.
+if possible. We recommend that you first install the [Threading Building Blocks library],
+also known as TBB, and then build using `make WITH_TBB=1`. TBB comes installed
+by default on many popular linux distros. If TBB is not available, then simply omit 
+the `WITH_TBB=1` option.
 
 [MinGW]:    http://www.mingw.org/
 [MSYS]:     http://www.mingw.org/wiki/msys
 [pthreads]: http://sourceware.org/pthreads-win32/
 [GnuWin32]: http://gnuwin32.sf.net/packages/coreutils.htm
+[Threading Building Blocks library]: https://www.threadingbuildingblocks.org
 [Download]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/
 [sourceforge site]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/
 [Xcode]:    http://developer.apple.com/xcode/
diff --git a/MANUAL.markdown b/MANUAL.markdown
index c70abbe..403ced5 100644
--- a/MANUAL.markdown
+++ b/MANUAL.markdown
@@ -170,12 +170,17 @@ execution times on SMP architectures where this is possible. On POSIX
 platforms (like linux, Mac OS, etc) it needs the pthread library. Although
 it is possible to use pthread library on non-POSIX platform like Windows, due
 to performance reasons bowtie 2 will try to use Windows native multithreading
-if possible.
+if possible. We recommend that you first install the [Threading Building Blocks library],
+also known as TBB, and then build using `make WITH_TBB=1`. TBB comes installed
+by default on many popular linux distros. If TBB is not available, then simply omit 
+the `WITH_TBB=1` option.
+
 
 [MinGW]:    http://www.mingw.org/
 [MSYS]:     http://www.mingw.org/wiki/msys
 [pthreads]: http://sourceware.org/pthreads-win32/
 [GnuWin32]: http://gnuwin32.sf.net/packages/coreutils.htm
+[Threading Building Blocks library]: https://www.threadingbuildingblocks.org
 [Download]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/
 [sourceforge site]: https://sourceforge.net/projects/bowtie-bio/files/bowtie2/
 [Xcode]:    http://developer.apple.com/xcode/
diff --git a/Makefile b/Makefile
index a4cdfa7..8711bc6 100644
--- a/Makefile
+++ b/Makefile
@@ -21,34 +21,28 @@
 # Makefile for bowtie, bowtie2-build, bowtie2-inspect
 #
 
+prefix = /usr/local
+bindir = $(prefix)/bin
+
 INC =
 GCC_PREFIX = $(shell dirname `which gcc`)
 GCC_SUFFIX =
-CC = $(GCC_PREFIX)/gcc$(GCC_SUFFIX)
-CPP = $(GCC_PREFIX)/g++$(GCC_SUFFIX)
-CXX = $(CPP)
+CC ?= $(GCC_PREFIX)/gcc$(GCC_SUFFIX)
+CPP ?= $(GCC_PREFIX)/g++$(GCC_SUFFIX)
+CXX ?= $(CPP)
 HEADERS = $(wildcard *.h)
 BOWTIE_MM = 1
 BOWTIE_SHARED_MEM = 0
 
 # Detect Cygwin or MinGW
 WINDOWS = 0
-CYGWIN = 0
 MINGW = 0
-ifneq (,$(findstring CYGWIN,$(shell uname)))
-	WINDOWS = 1 
-	CYGWIN = 1
+ifneq (,$(findstring MINGW,$(shell uname)))
+	WINDOWS = 1
+	MINGW = 1
 	# POSIX memory-mapped files not currently supported on Windows
 	BOWTIE_MM = 0
 	BOWTIE_SHARED_MEM = 0
-else
-	ifneq (,$(findstring MINGW,$(shell uname)))
-		WINDOWS = 1
-		MINGW = 1
-		# POSIX memory-mapped files not currently supported on Windows
-		BOWTIE_MM = 0
-		BOWTIE_SHARED_MEM = 0
-	endif
 endif
 
 MACOS = 0
@@ -57,13 +51,13 @@ ifneq (,$(findstring Darwin,$(shell uname)))
 	ifneq (,$(findstring 13,$(shell uname -r)))
 		CPP = clang++
 		CC = clang
-		EXTRA_FLAGS += -stdlib=libstdc++
+		override EXTRA_FLAGS += -stdlib=libstdc++
 	endif
 endif
 
 POPCNT_CAPABILITY ?= 1
 ifeq (1, $(POPCNT_CAPABILITY))
-    EXTRA_FLAGS += -DPOPCNT_CAPABILITY
+    override EXTRA_FLAGS += -DPOPCNT_CAPABILITY
     INC += -I third_party
 endif
 
@@ -88,7 +82,16 @@ else
 	PTHREAD_LIB = -lpthread
 endif
 
-LIBS = $(PTHREAD_LIB)
+ifeq (1,$(NO_SPINLOCK))
+	override EXTRA_FLAGS += -DNO_SPIN_LOCK
+endif
+
+ifeq (1,$(WITH_TBB))
+	LIBS = $(PTHREAD_LIB) -ltbb -ltbbmalloc_proxy
+	override EXTRA_FLAGS += -DWITH_TBB
+else
+	LIBS = $(PTHREAD_LIB)
+endif
 SEARCH_LIBS = 
 BUILD_LIBS = 
 INSPECT_LIBS =
@@ -98,10 +101,18 @@ ifeq (1,$(MINGW))
 	INSPECT_LIBS = 
 endif
 
+ifeq (1,$(WITH_THREAD_PROFILING))
+	override EXTRA_FLAGS += -DPER_THREAD_TIMING=1
+endif
+
 SHARED_CPPS = ccnt_lut.cpp ref_read.cpp alphabet.cpp shmem.cpp \
               edit.cpp bt2_idx.cpp bt2_io.cpp bt2_util.cpp \
               reference.cpp ds.cpp multikey_qsort.cpp limit.cpp \
-			  random_source.cpp tinythread.cpp
+			  random_source.cpp
+ifneq (1,$(WITH_TBB))
+	SHARED_CPPS += tinythread.cpp
+endif
+
 SEARCH_CPPS = qual.cpp pat.cpp sam.cpp \
               read_qseq.cpp aligner_seed_policy.cpp \
               aligner_seed.cpp \
@@ -137,6 +148,9 @@ BITS=32
 ifeq (x86_64,$(shell uname -m))
 	BITS=64
 endif
+ifeq (amd64,$(shell uname -m))
+	BITS=64
+endif
 # msys will always be 32 bit so look at the cpu arch instead.
 ifneq (,$(findstring AMD64,$(PROCESSOR_ARCHITEW6432)))
 	ifeq (1,$(MINGW))
@@ -435,6 +449,13 @@ doc/manual.html: MANUAL.markdown
 MANUAL: MANUAL.markdown
 	perl doc/strip_markdown.pl < $^ > $@
 
+.PHONY: install
+install: all
+	mkdir -p $(DESTDIR)$(bindir)
+	for file in $(BOWTIE2_BIN_LIST) bowtie2-inspect bowtie2-build bowtie2 ; do \
+		cp -f $$file $(DESTDIR)$(bindir) ; \
+	done
+
 .PHONY: clean
 clean:
 	rm -f $(BOWTIE2_BIN_LIST) $(BOWTIE2_BIN_LIST_AUX) \
diff --git a/NEWS b/NEWS
index 7f0e810..4c00344 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,19 @@ Please report any issues using the Sourceforge bug tracker:
 Version Release History
 =======================
 
+Version 2.2.6 - Jul 22, 2015
+   * Switched to a stable sort to avoid some potential reproducibility confusions.
+   * Added 'install' target for *nix platforms.
+   * Added the Intel TBB option which provides in most situations a better performance
+     output. TBB is not present by default in the current build but can be added 
+     by compiling the source code with WITH_TBB=1 option.
+   * Fixed a bug that caused seed lenght to be dependent of the -L and -N parameters order.
+   * Fixed a bug that caused --local followed by -N to reset seed lenght to 22 which is
+     actually the default value for global.
+   * Enable compilation on FreeBDS and clang, although gmake port is still required.
+   * Fixed an issue that made bowtie2 compilation process to fail on Snow Leopard.
+
+
 Version 2.2.5 - Mar 9, 2015
    * Fixed some situations where incorrectly we could detect a Mavericks platform.
    * Fixed some manual issues including some HTML bad formating.
diff --git a/VERSION b/VERSION
index 21bb5e1..bda8fbe 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.5
+2.2.6
diff --git a/aligner_seed_policy.cpp b/aligner_seed_policy.cpp
index 495f3ef..32e4bb9 100644
--- a/aligner_seed_policy.cpp
+++ b/aligner_seed_policy.cpp
@@ -305,7 +305,7 @@ void SeedAlignmentPolicy::parseString(
 	}
 	
 	multiseedMms      = DEFAULT_SEEDMMS;
-	multiseedLen      = DEFAULT_SEEDLEN;
+	multiseedLen      = gDefaultSeedLen;
 	
 	EList<string> toks(MISC_CAT);
 	string tok;
@@ -557,7 +557,8 @@ void SeedAlignmentPolicy::parseString(
 				istringstream tmpss(ctoks[1]);
 				tmpss >> multiseedLen;
 			} else {
-				multiseedLen = DEFAULT_SEEDLEN;
+				multiseedLen = gDefaultSeedLen;
+;
 			}
 		}
 		else if(tag == "SEEDLEN") {
@@ -701,7 +702,6 @@ int main() {
 		assert_eq(DEFAULT_REF_GAP_CONST,      penRfExConst);
 		assert_eq(DEFAULT_REF_GAP_LINEAR,     penRfExLinear);
 		assert_eq(DEFAULT_SEEDMMS,            multiseedMms);
-		assert_eq(DEFAULT_SEEDLEN,            multiseedLen);
 		assert_eq(DEFAULT_IVAL,               msIval.getType());
 		assert_eq(DEFAULT_IVAL_A,             msIval.getCoeff());
 		assert_eq(DEFAULT_IVAL_B,             msIval.getConst());
@@ -755,7 +755,6 @@ int main() {
 		assert_eq(DEFAULT_REF_GAP_CONST_BADHPOLY,   penRfExConst);
 		assert_eq(DEFAULT_REF_GAP_LINEAR_BADHPOLY,  penRfExLinear);
 		assert_eq(DEFAULT_SEEDMMS,            multiseedMms);
-		assert_eq(DEFAULT_SEEDLEN,            multiseedLen);
 		assert_eq(DEFAULT_IVAL,               msIval.getType());
 		assert_eq(DEFAULT_IVAL_A,             msIval.getCoeff());
 		assert_eq(DEFAULT_IVAL_B,             msIval.getConst());
@@ -810,7 +809,6 @@ int main() {
 		assert_eq(DEFAULT_REF_GAP_CONST,      penRfExConst);
 		assert_eq(DEFAULT_REF_GAP_LINEAR,     penRfExLinear);
 		assert_eq(DEFAULT_SEEDMMS,            multiseedMms);
-		assert_eq(DEFAULT_SEEDLEN,            multiseedLen);
 		assert_eq(DEFAULT_IVAL,               msIval.getType());
 		assert_eq(DEFAULT_IVAL_A,             msIval.getCoeff());
 		assert_eq(DEFAULT_IVAL_B,             msIval.getConst());
@@ -864,7 +862,6 @@ int main() {
 		assert_eq(24.0f,                      penRfExConst);
 		assert_eq(12.0f,                      penRfExLinear);
 		assert_eq(DEFAULT_SEEDMMS,            multiseedMms);
-		assert_eq(DEFAULT_SEEDLEN,            multiseedLen);
 		assert_eq(DEFAULT_IVAL,               msIval.getType());
 		assert_eq(DEFAULT_IVAL_A,             msIval.getCoeff());
 		assert_eq(DEFAULT_IVAL_B,             msIval.getConst());
diff --git a/aligner_seed_policy.h b/aligner_seed_policy.h
index 7bdaab7..3b51b22 100644
--- a/aligner_seed_policy.h
+++ b/aligner_seed_policy.h
@@ -25,6 +25,7 @@
 
 #define DEFAULT_SEEDMMS 0
 #define DEFAULT_SEEDLEN 22
+#define DEFAULT_LOCAL_SEEDLEN 20
 
 #define DEFAULT_IVAL SIMPLE_FUNC_SQRT
 #define DEFAULT_IVAL_A 1.15f
@@ -227,4 +228,8 @@ public:
 		size_t&     seedRounds);
 };
 
+
+extern int gDefaultSeedLen;
+
+
 #endif /*ndef ALIGNER_SEED_POLICY_H_*/
diff --git a/aligner_swsse_ee_u8.cpp b/aligner_swsse_ee_u8.cpp
index 0060a3d..d53800a 100644
--- a/aligner_swsse_ee_u8.cpp
+++ b/aligner_swsse_ee_u8.cpp
@@ -57,7 +57,7 @@
 
 static const size_t NBYTES_PER_REG  = 16;
 static const size_t NWORDS_PER_REG  = 16;
-static const size_t NBITS_PER_WORD  = 8;
+//static const size_t NBITS_PER_WORD  = 8;
 static const size_t NBYTES_PER_WORD = 1;
 
 // In end-to-end mode, we start high (255) and go low (0).  Factoring in
@@ -1347,7 +1347,8 @@ bool SwAligner::backtraceNucleotidesEnd2EndSseU8(
 		int readq = (*qu_)[row];
 		assert_leq(col, origCol);
 		// Get score in this cell
-		bool empty, reportedThru, canMoveThru, branch = false;
+		bool empty = false;
+		bool reportedThru, canMoveThru, branch = false;
 		int cur = SSEMatrix::H;
 		if(!d.mat_.reset_[row]) {
 			d.mat_.resetRow(row);
diff --git a/aligner_swsse_loc_u8.cpp b/aligner_swsse_loc_u8.cpp
index 71da4ec..71819f2 100644
--- a/aligner_swsse_loc_u8.cpp
+++ b/aligner_swsse_loc_u8.cpp
@@ -55,9 +55,9 @@
 #include <limits>
 #include "aligner_sw.h"
 
-static const size_t NBYTES_PER_REG  = 16;
+//static const size_t NBYTES_PER_REG  = 16;
 static const size_t NWORDS_PER_REG  = 16;
-static const size_t NBITS_PER_WORD  = 8;
+//static const size_t NBITS_PER_WORD  = 8;
 static const size_t NBYTES_PER_WORD = 1;
 
 // In local mode, we start low (0) and go high (255).  Factoring in a query
diff --git a/bt2_idx.h b/bt2_idx.h
index 030c99f..752cbd7 100644
--- a/bt2_idx.h
+++ b/bt2_idx.h
@@ -446,7 +446,7 @@ inline static int pop64(uint64_t x) {
     struct USE_POPCNT_INSTRUCTION {
         inline static int pop64(uint64_t x) {
             int64_t count;
-            asm ("popcntq %[x],%[count]\n": [count] "=&r" (count): [x] "r" (x));
+            asm ("popcnt %[x],%[count]\n": [count] "=&r" (count): [x] "r" (x));
             return count;
         }
     };
diff --git a/bt2_search.cpp b/bt2_search.cpp
index 04f495a..751367b 100644
--- a/bt2_search.cpp
+++ b/bt2_search.cpp
@@ -53,6 +53,7 @@
 #include "opts.h"
 #include "outq.h"
 #include "aligner_seed2.h"
+#include "bt2_search.h"
 
 using namespace std;
 
@@ -159,6 +160,7 @@ static bool sam_print_zp;
 static bool sam_print_zu;
 static bool sam_print_zt;
 static bool bwaSwLike;
+static bool gSeedLenIsSet;
 static float bwaSwLikeC;
 static float bwaSwLikeT;
 static bool qcFilter;
@@ -168,6 +170,7 @@ static string rgs;            // SAM outputs for @RG header line
 static string rgs_optflag;    // SAM optional flag to add corresponding to @RG ID
 static bool msample;          // whether to report a random alignment when maxed-out via -m/-M
 int      gGapBarrier;         // # diags on top/bot only to be entered diagonally
+int gDefaultSeedLen;
 static EList<string> qualities;
 static EList<string> qualities1;
 static EList<string> qualities2;
@@ -348,8 +351,10 @@ static void resetOptions() {
 	sam_print_zu            = false;
 	sam_print_zt            = false;
 	bwaSwLike               = false;
+	gSeedLenIsSet			= false;
 	bwaSwLikeC              = 5.5f;
 	bwaSwLikeT              = 20.0f;
+	gDefaultSeedLen			= DEFAULT_SEEDLEN;
 	qcFilter                = false; // don't believe upstream qc by default
 	rgid					= "";    // SAM outputs for @RG header line
 	rgs						= "";    // SAM outputs for @RG header line
@@ -384,7 +389,7 @@ static void resetOptions() {
 	descentTotSz.init(SIMPLE_FUNC_LINEAR, 1024.0, DMAX, 0.0, 1024.0);
 	descentTotFmops.init(SIMPLE_FUNC_LINEAR, 100.0, DMAX, 0.0, 10.0);
 	multiseedMms    = DEFAULT_SEEDMMS;
-	multiseedLen    = DEFAULT_SEEDLEN;
+	multiseedLen    = gDefaultSeedLen;
 	multiseedOff    = 0;
 	seedCacheLocalMB   = 32; // # MB to use for non-shared seed alignment cacheing
 	seedCacheCurrentMB = 20; // # MB to use for current-read seed hit cacheing
@@ -1230,7 +1235,11 @@ static void parseOption(int next_option, const char *arg) {
 			}
 			origString = arg;
 			break;
-		case ARG_LOCAL: localAlign = true; break;
+		case ARG_LOCAL: {
+			localAlign = true;
+			gDefaultSeedLen = DEFAULT_LOCAL_SEEDLEN;
+			break;
+		}
 		case ARG_END_TO_END: localAlign = false; break;
 		case ARG_SSE8: enable8 = true; break;
 		case ARG_SSE8_NO: enable8 = false; break;
@@ -1276,7 +1285,13 @@ static void parseOption(int next_option, const char *arg) {
 			}
 			break;
 		}
-		case 'N': { polstr += ";SEED="; polstr += arg; break; }
+		case 'N': {
+			if (!gSeedLenIsSet){
+				polstr += ";SEED=";
+				polstr += arg;
+			}
+			break;
+		}
 		case 'L': {
 			int64_t len = parse<size_t>(arg);
 			if(len < 0) {
@@ -1287,7 +1302,10 @@ static void parseOption(int next_option, const char *arg) {
 				cerr << "Error: -L argument must be <= 32; was " << arg << endl;
 				throw 1;
 			}
-			polstr += ";SEEDLEN="; polstr += arg; break;
+			polstr += ";SEEDLEN=";
+			polstr += arg;
+			gSeedLenIsSet = true;
+			break;
 		}
 		case 'O':
 			multiseedOff = parse<size_t>(arg);
@@ -2748,6 +2766,16 @@ static void setupMinScores(
 	x.resetCounters(); \
 }
 
+#ifdef PER_THREAD_TIMING
+/// Based on http://stackoverflow.com/questions/16862620/numa-get-current-node-core
+void get_cpu_and_node(int& cpu, int& node) {
+	unsigned long a,d,c;
+	__asm__ volatile("rdtscp" : "=a" (a), "=d" (d), "=c" (c));
+	node = (c & 0xFFF000)>>12;
+	cpu = c & 0xFFF;
+}
+#endif
+
 /**
  * Called once per thread.  Sets up per-thread pointers to the shared global
  * data structures, creates per-thread structures, then enters the alignment
@@ -2763,8 +2791,12 @@ static void setupMinScores(
  *   + If not identical, continue
  * - 
  */
+#ifdef WITH_TBB
+void multiseedSearchWorker::operator()() {
+#else
 static void multiseedSearchWorker(void *vp) {
 	int tid = *((int*)vp);
+#endif
 	assert(multiseed_ebwtFw != NULL);
 	assert(multiseedMms == 0 || multiseed_ebwtBw != NULL);
 	PairedPatternSource&    patsrc   = *multiseed_patsrc;
@@ -2776,6 +2808,20 @@ static void multiseedSearchWorker(void *vp) {
 	AlnSink&                msink    = *multiseed_msink;
 	OutFileBuf*             metricsOfb = multiseed_metricsOfb;
 
+#ifdef PER_THREAD_TIMING
+	uint64_t ncpu_changeovers = 0;
+	uint64_t nnuma_changeovers = 0;
+	
+	int current_cpu = 0, current_node = 0;
+	get_cpu_and_node(current_cpu, current_node);
+	
+	std::stringstream ss;
+	std::string msg;
+	ss << "thread: " << tid << " time: ";
+	msg = ss.str();
+	Timer timer(std::cout, msg.c_str());
+#endif
+
 	// Sinks: these are so that we can print tables encoding counts for
 	// events of interest on a per-read, per-seed, per-join, or per-SW
 	// level.  These in turn can be used to diagnose performance
@@ -2948,6 +2994,18 @@ static void multiseedSearchWorker(void *vp) {
 			if(sam_print_xt) {
 				gettimeofday(&prm.tv_beg, &prm.tz_beg);
 			}
+#ifdef PER_THREAD_TIMING
+			int cpu = 0, node = 0;
+			get_cpu_and_node(cpu, node);
+			if(cpu != current_cpu) {
+				ncpu_changeovers++;
+				current_cpu = cpu;
+			}
+			if(node != current_node) {
+				nnuma_changeovers++;
+				current_node = node;
+			}
+#endif
 			// Try to align this read
 			while(retry) {
 				retry = false;
@@ -3826,11 +3884,23 @@ static void multiseedSearchWorker(void *vp) {
 	if(dpLog    != NULL) dpLog->close();
 	if(dpLogOpp != NULL) dpLogOpp->close();
 
+#ifdef PER_THREAD_TIMING
+	ss.str("");
+	ss.clear();
+	ss << "thread: " << tid << " cpu_changeovers: " << ncpu_changeovers << std::endl
+	   << "thread: " << tid << " node_changeovers: " << nnuma_changeovers << std::endl;
+	std::cout << ss.str();
+#endif
+
 	return;
 }
 
+#ifdef WITH_TBB
+void multiseedSearchWorker_2p5::operator()() {
+#else
 static void multiseedSearchWorker_2p5(void *vp) {
 	int tid = *((int*)vp);
+#endif
 	assert(multiseed_ebwtFw != NULL);
 	assert(multiseedMms == 0 || multiseed_ebwtBw != NULL);
 	PairedPatternSource&    patsrc   = *multiseed_patsrc;
@@ -4197,8 +4267,12 @@ static void multiseedSearch(
 	delete _t;
 	if(!refs->loaded()) throw 1;
 	multiseed_refs = refs.get();
-	AutoArray<tthread::thread*> threads(nthreads);
-	AutoArray<int> tids(nthreads);
+#ifdef WITH_TBB
+	tbb::task_group tbb_grp;
+#else
+	AutoArray<tthread::thread*> threads(nthreads+1);
+	AutoArray<int> tids(nthreads+1);
+#endif
 	{
 		// Load the other half of the index into memory
 		assert(!ebwtFw.isInMemory());
@@ -4231,19 +4305,28 @@ static void multiseedSearch(
 	{
 		Timer _t(cerr, "Multiseed full-index search: ", timing);
 
-		for(int i = 0; i < nthreads; i++) {
+		for(int i = 1; i <= nthreads; i++) {
+#ifdef WITH_TBB
+			if(bowtie2p5) {
+				tbb_grp.run(multiseedSearchWorker_2p5(i));
+			} else {
+				tbb_grp.run(multiseedSearchWorker(i));
+			}
+		}
+		tbb_grp.wait();
+#else
 			// Thread IDs start at 1
-			tids[i] = i+1;
+			tids[i] = i;
 			if(bowtie2p5) {
 				threads[i] = new tthread::thread(multiseedSearchWorker_2p5, (void*)&tids[i]);
 			} else {
-			    threads[i] = new tthread::thread(multiseedSearchWorker, (void*)&tids[i]);
+				threads[i] = new tthread::thread(multiseedSearchWorker, (void*)&tids[i]);
 			}
 		}
-
-        for (int i = 0; i < nthreads; i++)
-            threads[i]->join();
-
+		for (int i = 1; i <= nthreads; i++) {
+			threads[i]->join();
+		}
+#endif
 	}
 	if(!metricsPerRead && (metricsOfb != NULL || metricsStderr)) {
 		metrics.reportInterval(metricsOfb, metricsStderr, true, false, NULL);
diff --git a/threading.h b/bt2_search.h
similarity index 54%
copy from threading.h
copy to bt2_search.h
index fca4086..3ca3feb 100644
--- a/threading.h
+++ b/bt2_search.h
@@ -17,41 +17,31 @@
  * along with Bowtie 2.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef THREADING_H_
-#define THREADING_H_
+#ifndef BT2_SEARCH_H_
+#define BT2_SEARCH_H_
+#ifdef WITH_TBB
 
-#include <iostream>
-#include "tinythread.h"
-#include "fast_mutex.h"
+#include <tbb/tbb.h>
+#include <tbb/task_group.h>
 
-#ifdef NO_SPINLOCK
-#   define MUTEX_T tthread::mutex
-#else
-#  	define MUTEX_T tthread::fast_mutex
-#endif /* NO_SPINLOCK */
+class multiseedSearchWorker {
+	int tid;
 
+public:
+	multiseedSearchWorker(const multiseedSearchWorker& W): tid(W.tid) {};
+	multiseedSearchWorker(int id):tid(id) {};
+	void operator()();
+};
+
+class multiseedSearchWorker_2p5 {
+	int tid;
 
-/**
- * Wrap a lock; obtain lock upon construction, release upon destruction.
- */
-class ThreadSafe {
 public:
-    ThreadSafe(MUTEX_T* ptr_mutex, bool locked = true) {
-		if(locked) {
-		    this->ptr_mutex = ptr_mutex;
-		    ptr_mutex->lock();
-		}
-		else
-		    this->ptr_mutex = NULL;
-	}
-
-	~ThreadSafe() {
-	    if (ptr_mutex != NULL)
-	        ptr_mutex->unlock();
-	}
-    
-private:
-	MUTEX_T *ptr_mutex;
+	multiseedSearchWorker_2p5(const multiseedSearchWorker_2p5& W): tid(W.tid) {};
+	multiseedSearchWorker_2p5(int id):tid(id) {};
+	void operator()();
+
 };
 
-#endif
+#endif /* WITH_TBB */
+#endif /* BT2_SEARCH_H_ */
diff --git a/doc/manual.html b/doc/manual.html
index 63fa76b..361e664 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -125,7 +125,7 @@
 <h2 id="building-from-source">Building from source</h2>
 <p>Building Bowtie 2 from source requires a GNU-like environment with GCC, GNU Make and other basics. It should be possible to build Bowtie 2 on most vanilla Linux installations or on a Mac installation with <a href="http://developer.apple.com/xcode/">Xcode</a> installed. Bowtie 2 can also be built on Windows using a 64-bit MinGW distribution and MSYS. In order to simplify the MinGW setup it might be worth investigating popular MinGW personal builds since these are coming already prepare [...]
 <p>First, download the source package from the <a href="https://sourceforge.net/projects/bowtie-bio/files/bowtie2/">sourceforge site</a>. Make sure you're getting the source package; the file downloaded should end in <code>-source.zip</code>. Unzip the file, change to the unzipped directory, and build the Bowtie 2 tools by running GNU <code>make</code> (usually with the command <code>make</code>, but sometimes with <code>gmake</code>) with no arguments. If building with MinGW, run <code> [...]
-<p>Bowtie 2 is using the multithreading software model in order to speed up execution times on SMP architectures where this is possible. On POSIX platforms (like linux, Mac OS, etc) it needs the pthread library. Although it is possible to use pthread library on non-POSIX platform like Windows, due to performance reasons bowtie 2 will try to use Windows native multithreading if possible.</p>
+<p>Bowtie 2 is using the multithreading software model in order to speed up execution times on SMP architectures where this is possible. On POSIX platforms (like linux, Mac OS, etc) it needs the pthread library. Although it is possible to use pthread library on non-POSIX platform like Windows, due to performance reasons bowtie 2 will try to use Windows native multithreading if possible. We recommend that you first install the <a href="https://www.threadingbuildingblocks.org">Threading Bu [...]
 <h2 id="adding-to-path">Adding to PATH</h2>
 <p>By adding your new Bowtie 2 directory to your <a href="http://en.wikipedia.org/wiki/PATH_(variable)">PATH environment variable</a>, you ensure that whenever you run <code>bowtie2</code>, <code>bowtie2-build</code> or <code>bowtie2-inspect</code> from the command line, you will get the version you just installed without having to specify the entire path. This is recommended for most users. To do this, follow your operating system's instructions for adding the directory to your <a href= [...]
 <p>If you would like to install Bowtie 2 by copying the Bowtie 2 executable files to an existing directory in your <a href="http://en.wikipedia.org/wiki/PATH_(variable)">PATH</a>, make sure that you copy all the executables, including <code>bowtie2</code>, <code>bowtie2-align-s</code>, <code>bowtie2-align-l</code>, <code>bowtie2-build</code>, <code>bowtie2-build-s</code>, <code>bowtie2-build-l</code>, <code>bowtie2-inspect</code>, <code>bowtie2-inspect-s</code> and <code>bowtie2-inspect- [...]
@@ -510,7 +510,7 @@ Reference: GCAGATTATATGAGTCAGCTACGATATTGTTTGGGGTGACACATTACGCGTCTTTGAC</code></pr
 <pre><code>-L <int></code></pre>
 </td><td>
 
-<p>Sets the length of the seed substrings to align during <a href="#multiseed-heuristic">multiseed alignment</a>. Smaller values make alignment slower but more senstive. Default: the <a href="#bowtie2-options-sensitive"><code>--sensitive</code></a> preset is used by default, which sets <code>-L</code> to 22 in <a href="#bowtie2-options-end-to-end"><code>--end-to-end</code></a> mode and to 20 in <a href="#bowtie2-options-local"><code>--local</code></a> mode.</p>
+<p>Sets the length of the seed substrings to align during <a href="#multiseed-heuristic">multiseed alignment</a>. Smaller values make alignment slower but more senstive. Default: the <a href="#bowtie2-options-sensitive"><code>--sensitive</code></a> preset is used by default, which sets <code>-L</code> to 20 both in <a href="#bowtie2-options-end-to-end"><code>--end-to-end</code></a> mode and in <a href="#bowtie2-options-local"><code>--local</code></a> mode.</p>
 </td></tr>
 <tr><td id="bowtie2-options-i">
 
@@ -527,7 +527,7 @@ Seed 3 fw:             ACGCTATCAT
 Seed 3 rc:             ATGATAGCGT
 Seed 4 fw:                   TCATGCATAA
 Seed 4 rc:                   TTATGCATGA</code></pre>
-<p>Since it's best to use longer intervals for longer reads, this parameter sets the interval as a function of the read length, rather than a single one-size-fits-all number. For instance, specifying <code>-i S,1,2.5</code> sets the interval function <code>f</code> to <code>f(x) = 1 + 2.5 * sqrt(x)</code>, where x is the read length. See also: <a href="#setting-function-options">setting function options</a>. If the function returns a result less than 1, it is rounded up to 1. Default: th [...]
+<p>Since it's best to use longer intervals for longer reads, this parameter sets the interval as a function of the read length, rather than a single one-size-fits-all number. For instance, specifying <code>-i S,1,2.5</code> sets the interval function <code>f</code> to <code>f(x) = 1 + 2.5 * sqrt(x)</code>, where x is the read length. See also: <a href="#setting-function-options">setting function options</a>. If the function returns a result less than 1, it is rounded up to 1. Default: th [...]
 </td></tr>
 <tr><td id="bowtie2-options-n-ceil">
 
diff --git a/ds.h b/ds.h
index 5453762..7e322c4 100644
--- a/ds.h
+++ b/ds.h
@@ -770,7 +770,7 @@ public:
 	void sortPortion(size_t begin, size_t num) {
 		assert_leq(begin+num, cur_);
 		if(num < 2) return;
-		std::sort(list_ + begin, list_ + begin + num);
+		std::stable_sort(list_ + begin, list_ + begin + num);
 	}
 	
 	/**
@@ -3010,7 +3010,6 @@ public:
 		int cat = 0) :
 		cat_(cat),
 		cur_(0),
-		bytes_(bytes),
 		pagesz_(pagesz),
 		pages_(cat)
 	{
@@ -3065,7 +3064,6 @@ public:
 	bool repOk() const {
 		assert_leq(cur_, pages_.size());
 		assert(!pages_.empty());
-		assert_gt(bytes_, 0);
 		assert_gt(pagesz_, 0);
 		return true;
 	}
@@ -3074,7 +3072,6 @@ public:
 private:
 	int             cat_;    // memory category, for accounting purposes
 	size_t          cur_;    // next page to hand out
-	const size_t    bytes_;  // total bytes in the pool
 	const size_t    pagesz_; // size of a single page
 	EList<uint8_t*> pages_;  // the pages themselves
 };
diff --git a/reference.cpp b/reference.cpp
index bb4ca08..cf41003 100644
--- a/reference.cpp
+++ b/reference.cpp
@@ -447,13 +447,13 @@ int BitPairReference::getStretch(
 	uint64_t off = 0;
 	int64_t offset = 4;
 	bool firstStretch = true;
-	bool binarySearched = false;
+	ASSERT_ONLY(bool binarySearched = false);
 	uint64_t left  = reci;
 	uint64_t right = recf;
 	uint64_t mid   = 0;
 	// For all records pertaining to the target reference sequence...
 	for(uint64_t i = reci; i < recf; i++) {
-		uint64_t origBufOff = bufOff;
+		ASSERT_ONLY(uint64_t origBufOff = bufOff);
 		assert_geq(toff, off);
 		if (firstStretch && recf > reci + 16){
 			// binary search finds smallest i s.t. toff >= cumRefOff_[i]
@@ -466,10 +466,10 @@ int BitPairReference::getStretch(
 			}
 			off = cumRefOff_[left];
 			bufOff = cumUnambig_[left];
-			origBufOff = bufOff;
+			ASSERT_ONLY(origBufOff = bufOff);
 			i = left;
 			assert(cumRefOff_[i+1] == 0 || cumRefOff_[i+1] > toff);
-			binarySearched = true;
+			ASSERT_ONLY(binarySearched = true);
 		}
 		off += recs_[i].off; // skip Ns at beginning of stretch
 		assert_gt(count, 0);
diff --git a/threading.h b/threading.h
index fca4086..25356c2 100644
--- a/threading.h
+++ b/threading.h
@@ -21,13 +21,28 @@
 #define THREADING_H_
 
 #include <iostream>
-#include "tinythread.h"
-#include "fast_mutex.h"
+
+#ifdef WITH_TBB
+# include <tbb/mutex.h>
+# include <tbb/spin_mutex.h>
+# include <tbb/task_group.h>
+#else
+# include "tinythread.h"
+# include "fast_mutex.h"
+#endif
 
 #ifdef NO_SPINLOCK
+# ifdef WITH_TBB
+#   define MUTEX_T tbb::mutex
+# else
 #   define MUTEX_T tthread::mutex
+# endif
 #else
+# ifdef WITH_TBB
+#  	define MUTEX_T tbb::spin_mutex
+# else
 #  	define MUTEX_T tthread::fast_mutex
+# endif
 #endif /* NO_SPINLOCK */
 
 
diff --git a/timer.h b/timer.h
index 5d0c844..0dd9ae1 100644
--- a/timer.h
+++ b/timer.h
@@ -24,9 +24,90 @@
 #include <iostream>
 #include <sstream>
 #include <iomanip>
+#ifdef USE_FINE_TIMER
+#include <sys/time.h>
+#endif
 
 using namespace std;
 
+#ifdef USE_FINE_TIMER
+
+/* Subtract the ‘struct timeval’ values X and Y, storing the result in RESULT.
+ Return 1 if the difference is negative, otherwise 0.
+ Borrowed from: https://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html
+ */
+static inline bool timeval_subtract(timeval& result, const timeval& xin, const timeval& yin) {
+	/* Perform the carry for the later subtraction by updating y. */
+	timeval x = xin;
+	timeval y = yin;
+	if (x.tv_usec < y.tv_usec) {
+		int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
+		y.tv_usec -= 1000000 * nsec;
+		y.tv_sec += nsec;
+	}
+	if (x.tv_usec - y.tv_usec > 1000000) {
+		int nsec = (x.tv_usec - y.tv_usec) / 1000000;
+		y.tv_usec += 1000000 * nsec;
+		y.tv_sec -= nsec;
+	}
+
+	/* Compute the time remaining to wait. tv_usec is certainly positive. */
+	result.tv_sec = x.tv_sec - y.tv_sec;
+	result.tv_usec = x.tv_usec - y.tv_usec;
+
+	/* Return 1 if result is negative. */
+	return x.tv_sec < y.tv_sec;
+}
+
+/**
+ * Use gettimeofday() call to keep track of elapsed time between creation and
+ * destruction.  If verbose is true, Timer will print a message showing
+ * elapsed time to the given output stream upon destruction.
+ */
+class Timer {
+public:
+	Timer(ostream& out = cout, const char *msg = "", bool verbose = true) :
+		_t(), _out(out), _msg(msg), _verbose(verbose)
+	{
+		gettimeofday(&_t, NULL);
+	}
+
+	/// Optionally print message
+	~Timer() {
+		if(_verbose) write(_out);
+	}
+
+	/// Return elapsed time since Timer object was created
+	time_t elapsed() const {
+		timeval f;
+		gettimeofday(&f, NULL);
+		return f.tv_sec - _t.tv_sec;
+	}
+
+	void write(ostream& out) {
+		timeval f;
+		gettimeofday(&f, NULL);
+		timeval diff;
+		timeval_subtract(diff, f, _t);
+		time_t hours   = (diff.tv_sec / 60) / 60;
+		time_t minutes = (diff.tv_sec / 60) % 60;
+		time_t seconds = (diff.tv_sec % 60);
+		time_t milliseconds = (diff.tv_usec / 1000);
+		std::ostringstream oss;
+		oss << _msg << setfill ('0') << setw (2) << hours << ":"
+			<< setfill ('0') << setw (2) << minutes << ":"
+			<< setfill ('0') << setw (2) << seconds << "."
+			<< setfill ('0') << setw (3) << milliseconds << endl;
+		out << oss.str().c_str();
+	}
+
+private:
+	timeval     _t;
+	ostream&    _out;
+	const char *_msg;
+	bool        _verbose;
+};
+#else
 /**
  * Use time() call to keep track of elapsed time between creation and
  * destruction.  If verbose is true, Timer will print a message showing
@@ -50,14 +131,14 @@ public:
 	void write(ostream& out) {
 		time_t passed = elapsed();
 		// Print the message supplied at construction time followed
-		// by time elapsed formatted HH:MM:SS 
+		// by time elapsed formatted HH:MM:SS
 		time_t hours   = (passed / 60) / 60;
 		time_t minutes = (passed / 60) % 60;
 		time_t seconds = (passed % 60);
 		std::ostringstream oss;
 		oss << _msg << setfill ('0') << setw (2) << hours << ":"
-		           << setfill ('0') << setw (2) << minutes << ":"
-		           << setfill ('0') << setw (2) << seconds << endl;
+			<< setfill ('0') << setw (2) << minutes << ":"
+			<< setfill ('0') << setw (2) << seconds << endl;
 		out << oss.str().c_str();
 	}
 	
@@ -67,6 +148,7 @@ private:
 	const char *_msg;
 	bool        _verbose;
 };
+#endif // USE_FINE_TIMER
 
 static inline void logTime(std::ostream& os, bool nl = true) {
 	struct tm *current;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/bowtie2.git



More information about the debian-med-commit mailing list