mirror of
https://github.com/lh3/minimap2.git
synced 2026-09-24 21:38:13 +08:00
Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e88e6ea5d5 | ||
|
|
66c90fdb83 | ||
|
|
3b2eca139a | ||
|
|
23d4edfa31 | ||
|
|
249c180b29 | ||
|
|
798ea0a4a3 | ||
|
|
bedd87f61f | ||
|
|
03540c47b3 | ||
|
|
3b1deac0a5 | ||
|
|
de90f2e655 | ||
|
|
ba186a4c78 | ||
|
|
ba2f19ba37 | ||
|
|
c7cdb758db | ||
|
|
7358a1ead1 | ||
|
|
32f552957e | ||
|
|
59488f0271 | ||
|
|
5cc3d2239f |
@@ -1,3 +1,6 @@
|
|||||||
[submodule "lib/simde"]
|
[submodule "lib/simde"]
|
||||||
path = lib/simde
|
path = lib/simde
|
||||||
url = https://github.com/nemequ/simde.git
|
url = https://github.com/nemequ/simde.git
|
||||||
|
[submodule "ext/TAL"]
|
||||||
|
path = ext/TAL
|
||||||
|
url = https://github.com/IntelLabs/Trans-Omics-Acceleration-Library.git
|
||||||
|
|||||||
@@ -1,6 +1,43 @@
|
|||||||
CFLAGS= -g -Wall -O2 -Wc++-compat #-Wextra
|
CFLAGS= -g -Wall -O2 -Wc++-compat #-Wextra
|
||||||
CPPFLAGS= -DHAVE_KALLOC
|
CPPFLAGS= -DHAVE_KALLOC #-march=native #-DALIGN_AVX -DPARALLEL_CHAINING #-DMANUAL_PROFILING
|
||||||
INCLUDES=
|
COMP_FLAG = -march=native
|
||||||
|
|
||||||
|
ifeq ($(avx2_compile), 1)
|
||||||
|
COMP_FLAG = -mavx2
|
||||||
|
endif
|
||||||
|
|
||||||
|
#CPPFLAGS= -DHAVE_KALLOC -mavx2 -DALIGN_AVX -DAPPLY_AVX2 -DPARALLEL_CHAINING #-DLISA_HASH -DUINT64 -DVECTORIZE #-DMANUAL_PROFILING
|
||||||
|
#CPPFLAGS= -DHAVE_KALLOC -mavx2 -DPARALLEL_CHAINING #-DMANUAL_PROFILING
|
||||||
|
|
||||||
|
OPT_FLAGS= -DPARALLEL_CHAINING -DALIGN_AVX -DAPPLY_AVX2
|
||||||
|
OPT_FLAGS+=$(COMP_FLAG)
|
||||||
|
ifeq ($(lhash_index), 1)
|
||||||
|
CPPFLAGS+= -DLISA_INDEX
|
||||||
|
endif
|
||||||
|
ifeq ($(lhash), 1)
|
||||||
|
OPT_FLAGS+= -DLISA_HASH -DUINT64 -DVECTORIZE
|
||||||
|
endif
|
||||||
|
ifeq ($(manual_profile), 1)
|
||||||
|
CPPFLAGS+= -DMANUAL_PROFILING
|
||||||
|
endif
|
||||||
|
|
||||||
|
#ifeq ($(use_avx2), 1)
|
||||||
|
# OPT_FLAGS+= -DAPPLY_AVX2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ifeq ($(disable_output), 1)
|
||||||
|
CPPFLAGS+= -DDISABLE_OUTPUT
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(no_opt),)
|
||||||
|
CPPFLAGS+= $(OPT_FLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#INCLUDES=
|
||||||
|
#INCLUDES= -I./ext/TAL_offline/src/LISA-hash #-I./ext/TAL/src/dynamic-programming
|
||||||
|
INCLUDES= -I./ext/TAL/src/LISA-hash -I./ext/TAL/src/dynamic-programming
|
||||||
OBJS= kthread.o kalloc.o misc.o bseq.o sketch.o sdust.o options.o index.o \
|
OBJS= kthread.o kalloc.o misc.o bseq.o sketch.o sdust.o options.o index.o \
|
||||||
lchain.o align.o hit.o seed.o map.o format.o pe.o esterr.o splitidx.o \
|
lchain.o align.o hit.o seed.o map.o format.o pe.o esterr.o splitidx.o \
|
||||||
ksw2_ll_sse.o
|
ksw2_ll_sse.o
|
||||||
@@ -8,9 +45,14 @@ PROG= minimap2
|
|||||||
PROG_EXTRA= sdust minimap2-lite
|
PROG_EXTRA= sdust minimap2-lite
|
||||||
LIBS= -lm -lz -lpthread
|
LIBS= -lm -lz -lpthread
|
||||||
|
|
||||||
|
CC=$(CXX)
|
||||||
|
ifeq ($(CC), g++)
|
||||||
|
CC=g++ -std=c++11
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(arm_neon),) # if arm_neon is not defined
|
ifeq ($(arm_neon),) # if arm_neon is not defined
|
||||||
ifeq ($(sse2only),) # if sse2only is not defined
|
ifeq ($(sse2only),) # if sse2only is not defined
|
||||||
OBJS+=ksw2_extz2_sse41.o ksw2_extd2_sse41.o ksw2_exts2_sse41.o ksw2_extz2_sse2.o ksw2_extd2_sse2.o ksw2_exts2_sse2.o ksw2_dispatch.o
|
OBJS+=ksw2_extz2_sse41.o ksw2_extd2_sse41.o ksw2_exts2_sse41.o ksw2_extz2_sse2.o ksw2_extd2_sse2.o ksw2_exts2_sse2.o ksw2_dispatch.o ksw2_extd2_avx.o
|
||||||
else # if sse2only is defined
|
else # if sse2only is defined
|
||||||
OBJS+=ksw2_extz2_sse.o ksw2_extd2_sse.o ksw2_exts2_sse.o
|
OBJS+=ksw2_extz2_sse.o ksw2_extd2_sse.o ksw2_exts2_sse.o
|
||||||
endif
|
endif
|
||||||
@@ -56,6 +98,17 @@ libminimap2.a:$(OBJS)
|
|||||||
sdust:sdust.c kalloc.o kalloc.h kdq.h kvec.h kseq.h ketopt.h sdust.h
|
sdust:sdust.c kalloc.o kalloc.h kdq.h kvec.h kseq.h ketopt.h sdust.h
|
||||||
$(CC) -D_SDUST_MAIN $(CFLAGS) $< kalloc.o -o $@ -lz
|
$(CC) -D_SDUST_MAIN $(CFLAGS) $< kalloc.o -o $@ -lz
|
||||||
|
|
||||||
|
multi:
|
||||||
|
$(MAKE) clean
|
||||||
|
$(MAKE)
|
||||||
|
mv minimap2 mm2-fast
|
||||||
|
$(MAKE) clean
|
||||||
|
$(MAKE) lhash=1
|
||||||
|
mv minimap2 mm2-fast-lhash
|
||||||
|
$(MAKE) clean
|
||||||
|
$(MAKE) no_opt=1
|
||||||
|
mv minimap2 mm2-fast-no-opt
|
||||||
|
|
||||||
# SSE-specific targets on x86/x86_64
|
# SSE-specific targets on x86/x86_64
|
||||||
|
|
||||||
ifeq ($(arm_neon),) # if arm_neon is defined, compile this target with the default setting (i.e. no -msse2)
|
ifeq ($(arm_neon),) # if arm_neon is defined, compile this target with the default setting (i.e. no -msse2)
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
CFLAGS= -g -Wall -O2 -Wc++-compat #-Wextra
|
CFLAGS= -g -Wall -O2 -Wc++-compat #-Wextra
|
||||||
CPPFLAGS= -DHAVE_KALLOC -DUSE_SIMDE -DSIMDE_ENABLE_NATIVE_ALIASES
|
CPPFLAGS= -DHAVE_KALLOC -DUSE_SIMDE -DSIMDE_ENABLE_NATIVE_ALIASES
|
||||||
INCLUDES= -Ilib/simde
|
INCLUDES= -Ilib/simde
|
||||||
OBJS= kthread.o kalloc.o misc.o bseq.o sketch.o sdust.o options.o index.o chain.o align.o hit.o map.o format.o pe.o esterr.o splitidx.o \
|
OBJS= kthread.o kalloc.o misc.o bseq.o sketch.o sdust.o options.o index.o lchain.o align.o hit.o map.o format.o pe.o seed.o esterr.o splitidx.o \
|
||||||
ksw2_extz2_simde.o ksw2_extd2_simde.o ksw2_exts2_simde.o ksw2_ll_simde.o
|
ksw2_extz2_simde.o ksw2_extd2_simde.o ksw2_exts2_simde.o ksw2_ll_simde.o
|
||||||
PROG= minimap2
|
PROG= minimap2
|
||||||
PROG_EXTRA= sdust minimap2-lite
|
PROG_EXTRA= sdust minimap2-lite
|
||||||
|
|||||||
@@ -1,3 +1,28 @@
|
|||||||
|
Release 2.22-r1101 (7 August 2021)
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
When choosing the best alignment, this release uses logarithm gap penalty and
|
||||||
|
query-specific mismatch penalty. It improves the sensitivity to long INDELs in
|
||||||
|
repetitive regions.
|
||||||
|
|
||||||
|
Other notable changes:
|
||||||
|
|
||||||
|
* Bugfix: fixed an indirect memory leak that may waste a large amount of
|
||||||
|
memory given highly repetitive reference such as a 16S RNA database (#749).
|
||||||
|
All versions of minimap2 have this issue.
|
||||||
|
|
||||||
|
* New feature: added --cap-kalloc to reduce the peak memory. This option is
|
||||||
|
not enabled by default but may become the default in future releases.
|
||||||
|
|
||||||
|
Known issue:
|
||||||
|
|
||||||
|
* Minimap2 may take a long time to map a read (#771). So far it is not clear
|
||||||
|
if this happens to v2.18 and earlier versions.
|
||||||
|
|
||||||
|
(2.22: 7 August 2021, r1101)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Release 2.21-r1071 (6 July 2021)
|
Release 2.21-r1071 (6 July 2021)
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
@@ -5,7 +30,7 @@ This release fixed a regression in short-read mapping introduced in v2.19
|
|||||||
(#776). It also fixed invalid comparisons of uninitialized variables, though
|
(#776). It also fixed invalid comparisons of uninitialized variables, though
|
||||||
these are harmless (#752). Long-read alignment should be identical to v2.20.
|
these are harmless (#752). Long-read alignment should be identical to v2.20.
|
||||||
|
|
||||||
(2.21: 6 July 2021)
|
(2.21: 6 July 2021, r1071)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,76 @@
|
|||||||
|
## mm2-fast
|
||||||
|
### Introduction
|
||||||
|
mm2-fast is an accelerated implementation of minimap2 on modern CPUs. mm2-fast accelerates all the three major modules of minimap2: (a) seeding, (b) chaining, and (c) pairwise alignment, achieving up to 1.8x speedup using AVX512 over minimap2.
|
||||||
|
mm2-fast is a drop-in replacement of minimap2, providing the same functionality with the exact same output.
|
||||||
|
In the current version, all the modules are optimized using **AVX-512** and **AVX2** vectorization. Detailed benchmark results are available in our [preprint](https://doi.org/10.1101/2021.07.21.453294).
|
||||||
|
|
||||||
|
### System requirement
|
||||||
|
Operating System: Linux
|
||||||
|
mm2-fast was tested using g++ (GCC) 9.2.0 and icpc version 19.1.3.304
|
||||||
|
Architecture: x86\_64 CPUs with [AVX512, AVX2](https://en.wikipedia.org/wiki/Advanced_Vector_Extensions)
|
||||||
|
Memory requirement: ~30GB for human genome
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
Clone the *fast-contrib-v2.22* branch from minimap2 github page. The source code can be compiled by using *make* command. It only takes a few seconds.
|
||||||
|
```
|
||||||
|
git clone --recursive https://github.com/lh3/minimap2.git -b fast-contrib-v2.22 mm2-fast
|
||||||
|
cd mm2-fast
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
The usage of mm2-fast is same as minimap2. Here is an example of mapping ONT reads with test data.
|
||||||
|
```sh
|
||||||
|
./minimap2 -ax map-ont test/MT-human.fa test/MT-orang.fa > mm2-fast_output
|
||||||
|
```
|
||||||
|
|
||||||
|
### Accuracy evaluation
|
||||||
|
As mm2-fast is an accelerated version of minimap2-v2.22, the output of mm2-fast can be verified against minimap2-v2.22. Note that the optimized chaining in mm2-fast is strictly required to be run with a chaining parameter *max-chain-skip=infinity*. Note that having parameter *max-chain-skip=infinity* leads to higher chaining precision. Therefore, for correctness verification, minimap2 should run with a larger value of *max-chain-skip* parameter. Follow the below steps to verify the accuracy of mm2-fast.
|
||||||
|
```sh
|
||||||
|
git clone --recursive https://github.com/lh3/minimap2.git -b fast-contrib-v2.22 mm2-fast
|
||||||
|
cd mm2-fast && make
|
||||||
|
./minimap2 -ax map-ont test/MT-human.fa test/MT-orang.fa --max-chain-skip=1000000 > mm2-fast_output
|
||||||
|
```
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/lh3/minimap2.git -b v2.22
|
||||||
|
cd minimap2 && make
|
||||||
|
./minimap2 -ax map-ont test/MT-human.fa test/MT-orang.fa --max-chain-skip=1000000 > minimap2_output
|
||||||
|
```
|
||||||
|
The output generated by minimap2 and mm2-fast should match.
|
||||||
|
```sh
|
||||||
|
diff minimap2_output mm2-fast_output > diff_result
|
||||||
|
```
|
||||||
|
The file ```diff_result``` should be empty, meaning a difference of 0 lines.
|
||||||
|
|
||||||
|
### Advanced options
|
||||||
|
The default compilation using make applies two optimizations: vectorized chaining and sequence alignment. The learned-indexes based seeding is disabled by default as it requires availability of [Rust](https://en.wikipedia.org/wiki/Rust_(programming_language)). This is because the learned hash-table uses an external training library that runs on Rust. Rust is trivial to install, see https://rustup.rs/ and add its path to .bashrc file. Rust installation only takes a few seconds. Following are the steps to enable learned hash table optimization in mm2-fast:
|
||||||
|
```sh
|
||||||
|
# Start by building learned hash table index for optimized seeding module
|
||||||
|
./build_rmi.sh test/MT-human.fa map-ont ##Takes two arguments: 1. path-to-reference-seq-file 2. preset.
|
||||||
|
##For human genome, this step should take around 2-3 minutes to finish.
|
||||||
|
|
||||||
|
# Next, compile and run the mapping phase
|
||||||
|
make clean && make lhash=1
|
||||||
|
./minimap2 -ax map-ont test/MT-human.fa test/MT-orang.fa > mm2-fast-lhash_output
|
||||||
|
```
|
||||||
|
To compile mm2-fast with all optimizations turned off and switch back to default minimap2, use the following command during compilation. This could be useful for debugging.
|
||||||
|
```sh
|
||||||
|
make clean && make no_opt=1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
We have observed up to 1.8x speedup across datasets (please refer to the paper for more details). For example, for the randomly sampled 100K reads from ["HG002\_GM24385\_1\_2\_3\_Guppy\_3.6.0\_prom.fastq.gz"](https://precision.fda.gov/challenges/10/view), minimap2 takes 92 seconds, while mm2-fast takes 54 seconds to map against the human genome on a 28 cores Intel® Xeon® Platinum 8280 CPUs. Our sampled datasets with 100K reads are available [here](https://drive.google.com/drive/folders/1131j7ejHdT7QZnjxLcTLi5qqwYcfFbuv).
|
||||||
|
|
||||||
|
### Future Plans
|
||||||
|
|
||||||
|
|
||||||
|
### Citations
|
||||||
|
["Accelerating long-read analysis on modern CPUs"](https://doi.org/10.1101/2021.07.21.453294); Saurabh Kalikar, Chirag Jain, Vasimuddin Md, Sanchit Misra; BioRxiv 2021
|
||||||
|
|
||||||
|
---
|
||||||
|
The original README content of minimap2 follows.
|
||||||
|
|
||||||
|
|
||||||
[](https://github.com/lh3/minimap2/releases)
|
[](https://github.com/lh3/minimap2/releases)
|
||||||
[](https://anaconda.org/bioconda/minimap2)
|
[](https://anaconda.org/bioconda/minimap2)
|
||||||
[](https://pypi.python.org/pypi/mappy)
|
[](https://pypi.python.org/pypi/mappy)
|
||||||
@@ -74,8 +147,8 @@ Detailed evaluations are available from the [minimap2 paper][doi] or the
|
|||||||
Minimap2 is optimized for x86-64 CPUs. You can acquire precompiled binaries from
|
Minimap2 is optimized for x86-64 CPUs. You can acquire precompiled binaries from
|
||||||
the [release page][release] with:
|
the [release page][release] with:
|
||||||
```sh
|
```sh
|
||||||
curl -L https://github.com/lh3/minimap2/releases/download/v2.21/minimap2-2.21_x64-linux.tar.bz2 | tar -jxvf -
|
curl -L https://github.com/lh3/minimap2/releases/download/v2.22/minimap2-2.22_x64-linux.tar.bz2 | tar -jxvf -
|
||||||
./minimap2-2.21_x64-linux/minimap2
|
./minimap2-2.22_x64-linux/minimap2
|
||||||
```
|
```
|
||||||
If you want to compile from the source, you need to have a C compiler, GNU make
|
If you want to compile from the source, you need to have a C compiler, GNU make
|
||||||
and zlib development files installed. Then type `make` in the source code
|
and zlib development files installed. Then type `make` in the source code
|
||||||
|
|||||||
@@ -5,6 +5,13 @@
|
|||||||
#include "minimap.h"
|
#include "minimap.h"
|
||||||
#include "mmpriv.h"
|
#include "mmpriv.h"
|
||||||
#include "ksw2.h"
|
#include "ksw2.h"
|
||||||
|
#include "ksw2_extd2_avx.h"
|
||||||
|
#include <x86intrin.h>
|
||||||
|
extern uint64_t avg;
|
||||||
|
extern uint64_t alignment_time;
|
||||||
|
extern void *km1;
|
||||||
|
extern uint64_t km_size;// = 500000000; // 500 MB
|
||||||
|
extern int km_top;
|
||||||
|
|
||||||
static void ksw_gen_simple_mat(int m, int8_t *mat, int8_t a, int8_t b, int8_t sc_ambi)
|
static void ksw_gen_simple_mat(int m, int8_t *mat, int8_t a, int8_t b, int8_t sc_ambi)
|
||||||
{
|
{
|
||||||
@@ -313,6 +320,7 @@ static void mm_append_cigar(mm_reg1_t *r, uint32_t n_cigar, uint32_t *cigar) //
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint8_t *qseq, int tlen, const uint8_t *tseq, const uint8_t *junc, const int8_t *mat, int w, int end_bonus, int zdrop, int flag, ksw_extz_t *ez)
|
static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint8_t *qseq, int tlen, const uint8_t *tseq, const uint8_t *junc, const int8_t *mat, int w, int end_bonus, int zdrop, int flag, ksw_extz_t *ez)
|
||||||
{
|
{
|
||||||
if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) {
|
if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) {
|
||||||
@@ -340,7 +348,65 @@ static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint
|
|||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint8_t *qseq, int tlen, const uint8_t *tseq, const uint8_t *junc, const int8_t *mat, int w, int end_bonus, int zdrop, int flag, ksw_extz_t *ez)
|
||||||
|
{
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
uint64_t align_start = __rdtsc();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) {
|
||||||
|
int i;
|
||||||
|
fprintf(stderr, "===> q=(%d,%d), e=(%d,%d), bw=%d, flag=%d, zdrop=%d <===\n", opt->q, opt->q2, opt->e, opt->e2, w, flag, opt->zdrop);
|
||||||
|
for (i = 0; i < tlen; ++i) fputc("ACGTN"[tseq[i]], stderr);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
for (i = 0; i < qlen; ++i) fputc("ACGTN"[qseq[i]], stderr);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
}
|
||||||
|
if (opt->max_sw_mat > 0 && (int64_t)tlen * qlen > opt->max_sw_mat) {
|
||||||
|
ksw_reset_extz(ez);
|
||||||
|
ez->zdropped = 1;
|
||||||
|
} else if (opt->flag & MM_F_SPLICE)
|
||||||
|
ksw_exts2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->noncan, zdrop, opt->junc_bonus, flag, junc, ez);
|
||||||
|
else if (opt->q == opt->q2 && opt->e == opt->e2)
|
||||||
|
ksw_extz2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, w, zdrop, end_bonus, flag, ez);
|
||||||
|
else{
|
||||||
|
#if defined (ALIGN_AVX) && (defined(__AVX512BW__) || (defined(__AVX2__) && defined(APPLY_AVX2)))
|
||||||
|
#ifdef __AVX512BW__
|
||||||
|
|
||||||
|
ksw_extd2_avx512(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->e2, w, zdrop, end_bonus, flag, ez);
|
||||||
|
#elif __AVX2__
|
||||||
|
avg = 0;
|
||||||
|
// uint64_t *ptr_km = (uint64_t *) km1;
|
||||||
|
// for(uint64_t itr = 0; itr < km_size/512; itr++){
|
||||||
|
// avg+=ptr_km[itr];
|
||||||
|
// }
|
||||||
|
|
||||||
|
//#ifdef MANUAL_PROFILING
|
||||||
|
// uint64_t align_start = __rdtsc();
|
||||||
|
//#endif
|
||||||
|
ksw_extd2_avx2(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->e2, w, zdrop, end_bonus, flag, ez);
|
||||||
|
//#ifdef MANUAL_PROFILING
|
||||||
|
// alignment_time += (__rdtsc() - align_start);
|
||||||
|
//#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
ksw_extd2_sse(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->e2, w, zdrop, end_bonus, flag, ez);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (mm_dbg_flag & MM_DBG_PRINT_ALN_SEQ) {
|
||||||
|
int i;
|
||||||
|
fprintf(stderr, "score=%d, cigar=", ez->score);
|
||||||
|
for (i = 0; i < ez->n_cigar; ++i)
|
||||||
|
fprintf(stderr, "%d%c", ez->cigar[i]>>4, "MIDN"[ez->cigar[i]&0xf]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
alignment_time += (__rdtsc() - align_start);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
static inline int mm_get_hplen_back(const mm_idx_t *mi, uint32_t rid, uint32_t x)
|
static inline int mm_get_hplen_back(const mm_idx_t *mi, uint32_t rid, uint32_t x)
|
||||||
{
|
{
|
||||||
int64_t i, off0 = mi->seq[rid].offset, off = off0 + x;
|
int64_t i, off0 = mi->seq[rid].offset, off = off0 + x;
|
||||||
|
|||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
ref_data=$1
|
||||||
|
preset=$2
|
||||||
|
|
||||||
|
make clean && make lhash_index=1
|
||||||
|
touch temp_read.fastq
|
||||||
|
./minimap2 -ax $2 $1 temp_read.fastq >/dev/null
|
||||||
|
|
||||||
|
kv_file=$1"_"$2"_minimizers_key_value_sorted"
|
||||||
|
|
||||||
|
full_path=`readlink -f $kv_file`
|
||||||
|
|
||||||
|
cd ./ext/TAL
|
||||||
|
make lisa_hash
|
||||||
|
./build-lisa-hash-index $full_path
|
||||||
|
|
||||||
|
rm ../../temp_read.fastq
|
||||||
+2
-2
@@ -31,8 +31,8 @@ To acquire the data used in this cookbook and to install minimap2 and paftools,
|
|||||||
please follow the command lines below:
|
please follow the command lines below:
|
||||||
```sh
|
```sh
|
||||||
# install minimap2 executables
|
# install minimap2 executables
|
||||||
curl -L https://github.com/lh3/minimap2/releases/download/v2.21/minimap2-2.21_x64-linux.tar.bz2 | tar jxf -
|
curl -L https://github.com/lh3/minimap2/releases/download/v2.22/minimap2-2.22_x64-linux.tar.bz2 | tar jxf -
|
||||||
cp minimap2-2.21_x64-linux/{minimap2,k8,paftools.js} . # copy executables
|
cp minimap2-2.22_x64-linux/{minimap2,k8,paftools.js} . # copy executables
|
||||||
export PATH="$PATH:"`pwd` # put the current directory on PATH
|
export PATH="$PATH:"`pwd` # put the current directory on PATH
|
||||||
# download example datasets
|
# download example datasets
|
||||||
curl -L https://github.com/lh3/minimap2/releases/download/v2.10/cookbook-data.tgz | tar zxf -
|
curl -L https://github.com/lh3/minimap2/releases/download/v2.10/cookbook-data.tgz | tar zxf -
|
||||||
|
|||||||
Submodule
+1
Submodule ext/TAL added at 2a97815a5f
@@ -14,6 +14,21 @@
|
|||||||
#include "mmpriv.h"
|
#include "mmpriv.h"
|
||||||
#include "kvec.h"
|
#include "kvec.h"
|
||||||
#include "khash.h"
|
#include "khash.h"
|
||||||
|
#include <map>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <x86intrin.h>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
extern uint64_t minimizer_lookup_time, alignment_time, dp_time, rmq_time, rmq_t1, rmq_t2, rmq_t3, rmq_t4;
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
#include "lisa_hash.h"
|
||||||
|
extern lisa_hash<uint64_t, uint64_t> *lh;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define idx_hash(a) ((a)>>1)
|
#define idx_hash(a) ((a)>>1)
|
||||||
#define idx_eq(a, b) ((a)>>1 == (b)>>1)
|
#define idx_eq(a, b) ((a)>>1 == (b)>>1)
|
||||||
@@ -52,9 +67,43 @@ mm_idx_t *mm_idx_init(int w, int k, int b, int flag)
|
|||||||
if (!(mm_dbg_flag & 1)) mi->km = km_init();
|
if (!(mm_dbg_flag & 1)) mi->km = km_init();
|
||||||
return mi;
|
return mi;
|
||||||
}
|
}
|
||||||
|
void mm_idx_destroy_mm_hash(mm_idx_t *mi)
|
||||||
|
{
|
||||||
|
//fprintf(stderr, "mm_destroy_hash\n");
|
||||||
|
uint32_t i;
|
||||||
|
if (mi == 0) return;
|
||||||
|
if (mi->h) kh_destroy(str, (khash_t(str)*)mi->h);
|
||||||
|
if (mi->B) {
|
||||||
|
for (i = 0; i < 1U<<mi->b; ++i) {
|
||||||
|
free(mi->B[i].p);
|
||||||
|
free(mi->B[i].a.a);
|
||||||
|
kh_destroy(idx, (idxhash_t*)mi->B[i].h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void mm_idx_destroy_seq(mm_idx_t *mi)
|
||||||
|
{
|
||||||
|
//fprintf(stderr, "mm_destroy_seq\n");
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
if (mi == 0) return;
|
||||||
|
if (mi->I) {
|
||||||
|
for (i = 0; i < mi->n_seq; ++i)
|
||||||
|
free(mi->I[i].a);
|
||||||
|
free(mi->I);
|
||||||
|
}
|
||||||
|
if (!mi->km) {
|
||||||
|
for (i = 0; i < mi->n_seq; ++i)
|
||||||
|
free(mi->seq[i].name);
|
||||||
|
free(mi->seq);
|
||||||
|
} else km_destroy(mi->km);
|
||||||
|
free(mi->B); free(mi->S); free(mi);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mm_idx_destroy(mm_idx_t *mi)
|
void mm_idx_destroy(mm_idx_t *mi)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if (mi == 0) return;
|
if (mi == 0) return;
|
||||||
if (mi->h) kh_destroy(str, (khash_t(str)*)mi->h);
|
if (mi->h) kh_destroy(str, (khash_t(str)*)mi->h);
|
||||||
@@ -96,6 +145,317 @@ const uint64_t *mm_idx_get(const mm_idx_t *mi, uint64_t minier, int *n)
|
|||||||
return &b->p[kh_val(h, k)>>32];
|
return &b->p[kh_val(h, k)>>32];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//Output minimap2's hash table entries
|
||||||
|
class hash_entry {
|
||||||
|
public:
|
||||||
|
uint64_t key;
|
||||||
|
uint64_t n;
|
||||||
|
uint64_t *p;
|
||||||
|
hash_entry(uint64_t k, uint64_t n_, uint64_t *p_){
|
||||||
|
key = k;
|
||||||
|
n = n_;
|
||||||
|
p = p_;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
bool key_sort( hash_entry i1, hash_entry i2)
|
||||||
|
{
|
||||||
|
return (i1.key < i2.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void mm_idx_load_key_value_lisa(const char* f_name, const mm_idx_t *mi)
|
||||||
|
{
|
||||||
|
uint64_t tic = __rdtsc();
|
||||||
|
std::vector<hash_entry> v_hash;
|
||||||
|
|
||||||
|
//ofstream f(f_name);
|
||||||
|
fprintf(stderr, "Building sorted key-val map\n");
|
||||||
|
|
||||||
|
uint32_t i,j;
|
||||||
|
uint64_t num_values = 0;
|
||||||
|
for (i = 0; i < 1U<<mi->b; ++i) {
|
||||||
|
|
||||||
|
|
||||||
|
//fprintf(stderr, "BucketID %lu \n", i);
|
||||||
|
idxhash_t *h = (idxhash_t*)mi->B[i].h;
|
||||||
|
khint_t k;
|
||||||
|
if (h == 0) continue;
|
||||||
|
for (k = 0; k < kh_end(h); ++k){
|
||||||
|
if (kh_exist(h, k)) {
|
||||||
|
uint64_t key = kh_key(h, k), bucket_id = i;
|
||||||
|
key = key>>1;
|
||||||
|
|
||||||
|
key = key<<mi->b | bucket_id;
|
||||||
|
|
||||||
|
if(kh_key(h, k)&1)
|
||||||
|
{
|
||||||
|
//print key value
|
||||||
|
//fprintf(stderr, "%llu %llu %llu\n", key, kh_val(h, k), 0);
|
||||||
|
v_hash.push_back(hash_entry(key, kh_val(h, k), NULL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // print key
|
||||||
|
uint32_t n = (uint32_t)kh_val(h, k);
|
||||||
|
//fprintf(stderr, "%llu %llu %llu ", key, kh_val(h, k), n);
|
||||||
|
// for 0 to lsb 32 val
|
||||||
|
// print b->p[msb 32 of val]
|
||||||
|
|
||||||
|
v_hash.push_back(hash_entry(key, n, &mi->B[i].p[(kh_val(h, k)>>32) + 0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort(v_hash.begin(), v_hash.end(), key_sort);
|
||||||
|
fprintf(stderr, "Sorted map building time = %lld \n", __rdtsc() - tic);
|
||||||
|
fprintf(stderr, "Storing hash to %s \n", f_name);
|
||||||
|
tic = __rdtsc();
|
||||||
|
|
||||||
|
int64_t itr_p = 0;
|
||||||
|
for( int i = 0; i < v_hash.size(); i++){
|
||||||
|
|
||||||
|
if(v_hash[i].p == NULL){
|
||||||
|
//f<<v_hash[i].key << " "<<1<<"\n"<<v_hash[i].n<<" \n";
|
||||||
|
|
||||||
|
lh->p[itr_p++] = v_hash[i].n;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//f<<v_hash[i].key << " "<<v_hash[i].n<<endl;
|
||||||
|
|
||||||
|
for(int j = 0; j < v_hash[i].n; j++){
|
||||||
|
// f<<v_hash[i].p[j]<<" ";
|
||||||
|
lh->p[itr_p++] = v_hash[i].p[j];
|
||||||
|
num_values++;
|
||||||
|
}
|
||||||
|
//f<<endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//f.close();
|
||||||
|
|
||||||
|
string size_file_name = (string) f_name + "_size";
|
||||||
|
ofstream size_f(size_file_name);
|
||||||
|
size_f<<v_hash.size()<<" "<<num_values;
|
||||||
|
size_f.close();
|
||||||
|
|
||||||
|
string prefix = (string)f_name + "_keys";
|
||||||
|
string keys_bin_file_name = prefix + ".uint64";
|
||||||
|
ofstream wf(keys_bin_file_name, ios::out | ios::binary);
|
||||||
|
wf.write((char*)&key_list[0], (key_list.size())*sizeof(uint64_t));
|
||||||
|
wf.close();
|
||||||
|
|
||||||
|
key_list.clear();
|
||||||
|
|
||||||
|
m.clear();
|
||||||
|
v_hash.clear();
|
||||||
|
|
||||||
|
fprintf(stderr, "Index store File IO time %lld \n", __rdtsc() - tic);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mm_idx_dump_hash(const char* f_name, const mm_idx_t *mi)
|
||||||
|
{
|
||||||
|
uint64_t tic = __rdtsc();
|
||||||
|
//std::map<uint64_t, vector<uint64_t>> m;
|
||||||
|
std::vector<hash_entry> v_hash;
|
||||||
|
|
||||||
|
//ofstream f(f_name);
|
||||||
|
fprintf(stderr, "Building sorted key-val map\n");
|
||||||
|
|
||||||
|
uint32_t i,j;
|
||||||
|
uint64_t num_values = 0;
|
||||||
|
for (i = 0; i < 1U<<mi->b; ++i) {
|
||||||
|
|
||||||
|
|
||||||
|
//fprintf(stderr, "BucketID %lu \n", i);
|
||||||
|
idxhash_t *h = (idxhash_t*)mi->B[i].h;
|
||||||
|
khint_t k;
|
||||||
|
if (h == 0) continue;
|
||||||
|
for (k = 0; k < kh_end(h); ++k){
|
||||||
|
if (kh_exist(h, k)) {
|
||||||
|
uint64_t key = kh_key(h, k), bucket_id = i;
|
||||||
|
key = key>>1;
|
||||||
|
|
||||||
|
key = key<<mi->b | bucket_id;
|
||||||
|
|
||||||
|
if(kh_key(h, k)&1)
|
||||||
|
{
|
||||||
|
//print key value
|
||||||
|
//fprintf(stderr, "%llu %llu %llu\n", key, kh_val(h, k), 0);
|
||||||
|
//m[key].push_back(kh_val(h, k));
|
||||||
|
v_hash.push_back(hash_entry(key, kh_val(h, k), NULL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // print key
|
||||||
|
uint32_t n = (uint32_t)kh_val(h, k);
|
||||||
|
//fprintf(stderr, "%llu %llu %llu ", key, kh_val(h, k), n);
|
||||||
|
// for 0 to lsb 32 val
|
||||||
|
// print b->p[msb 32 of val]
|
||||||
|
|
||||||
|
v_hash.push_back(hash_entry(key, n, &mi->B[i].p[(kh_val(h, k)>>32) + 0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort(v_hash.begin(), v_hash.end(), key_sort);
|
||||||
|
fprintf(stderr, "Sorted map building time = %lld \n", __rdtsc() - tic);
|
||||||
|
fprintf(stderr, "Storing hash to %s \n", f_name);
|
||||||
|
tic = __rdtsc();
|
||||||
|
|
||||||
|
vector<uint64_t> key_list;
|
||||||
|
vector<uint64_t> val_list;
|
||||||
|
vector<uint64_t> p_list;
|
||||||
|
/*
|
||||||
|
key_list.push_back(m.size());
|
||||||
|
for(auto k : m){
|
||||||
|
key_list.push_back(k.first);
|
||||||
|
f<<k.first << " "<<k.second.size()<<endl;
|
||||||
|
for(int j = 0; j < k.second.size(); j++){
|
||||||
|
f<<k.second[j]<<" ";
|
||||||
|
num_values++;
|
||||||
|
}
|
||||||
|
f<<endl;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
key_list.push_back(v_hash.size());
|
||||||
|
int64_t itr_p = 0;
|
||||||
|
uint64_t sum_pos = 0;
|
||||||
|
string f1_name = (string)f_name + "_pos_bin";
|
||||||
|
string f2_name = (string)f_name + "_val_bin";
|
||||||
|
ofstream f1(f1_name, ios::out | ios::binary);
|
||||||
|
ofstream f2(f2_name, ios::out | ios::binary);
|
||||||
|
for( int i = 0; i < v_hash.size(); i++){
|
||||||
|
key_list.push_back(v_hash[i].key);
|
||||||
|
if(v_hash[i].p == NULL){
|
||||||
|
//f<<v_hash[i].key << " "<<1<<"\n"<<v_hash[i].n<<" \n";
|
||||||
|
val_list.push_back(sum_pos<<32|(uint64_t)1);
|
||||||
|
sum_pos+=1;
|
||||||
|
p_list.push_back(v_hash[i].n);
|
||||||
|
num_values++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//f<<v_hash[i].key << " "<<v_hash[i].n<<endl;
|
||||||
|
val_list.push_back(sum_pos<<32|(uint64_t)v_hash[i].n);
|
||||||
|
sum_pos+=v_hash[i].n;
|
||||||
|
|
||||||
|
num_values+=v_hash[i].n;
|
||||||
|
|
||||||
|
|
||||||
|
for(int j = 0; j < v_hash[i].n; j++){
|
||||||
|
//f<<v_hash[i].p[j]<<" ";
|
||||||
|
p_list.push_back(v_hash[i].p[j]);
|
||||||
|
}
|
||||||
|
// f<<endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
f1.write((char*)&val_list[0], (val_list.size())*sizeof(uint64_t));
|
||||||
|
f2.write((char*)&p_list[0], (p_list.size())*sizeof(uint64_t));
|
||||||
|
f1.close();
|
||||||
|
f2.close();
|
||||||
|
fprintf(stderr, "Index sorted SoA time %lld \n", __rdtsc() - tic);
|
||||||
|
|
||||||
|
//f.close();
|
||||||
|
|
||||||
|
string size_file_name = (string) f_name + "_size";
|
||||||
|
ofstream size_f(size_file_name);
|
||||||
|
size_f<<v_hash.size()<<" "<<num_values;
|
||||||
|
size_f.close();
|
||||||
|
|
||||||
|
string prefix = (string)f_name + "_keys";
|
||||||
|
string keys_bin_file_name = prefix + ".uint64";
|
||||||
|
ofstream wf(keys_bin_file_name, ios::out | ios::binary);
|
||||||
|
wf.write((char*)&key_list[0], (key_list.size())*sizeof(uint64_t));
|
||||||
|
wf.close();
|
||||||
|
|
||||||
|
key_list.clear();
|
||||||
|
|
||||||
|
//m.clear();
|
||||||
|
v_hash.clear();
|
||||||
|
|
||||||
|
fprintf(stderr, "Index store File IO time %lld \n", __rdtsc() - tic);
|
||||||
|
|
||||||
|
}
|
||||||
|
void mm_idx_dump_hash_1(const char* f_name, const mm_idx_t *mi)
|
||||||
|
{
|
||||||
|
uint64_t tic = __rdtsc();
|
||||||
|
std::map<uint64_t, vector<uint64_t>> m;
|
||||||
|
|
||||||
|
ofstream f(f_name);
|
||||||
|
fprintf(stderr, "Building sorted key-val map\n");
|
||||||
|
|
||||||
|
uint32_t i,j;
|
||||||
|
uint64_t num_values = 0;
|
||||||
|
for (i = 0; i < 1U<<mi->b; ++i) {
|
||||||
|
|
||||||
|
|
||||||
|
//fprintf(stderr, "BucketID %lu \n", i);
|
||||||
|
idxhash_t *h = (idxhash_t*)mi->B[i].h;
|
||||||
|
khint_t k;
|
||||||
|
if (h == 0) continue;
|
||||||
|
for (k = 0; k < kh_end(h); ++k){
|
||||||
|
if (kh_exist(h, k)) {
|
||||||
|
uint64_t key = kh_key(h, k), bucket_id = i;
|
||||||
|
key = key>>1;
|
||||||
|
|
||||||
|
key = key<<mi->b | bucket_id;
|
||||||
|
|
||||||
|
if(kh_key(h, k)&1)
|
||||||
|
{
|
||||||
|
//print key value
|
||||||
|
//fprintf(stderr, "%llu %llu %llu\n", key, kh_val(h, k), 0);
|
||||||
|
m[key].push_back(kh_val(h, k));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // print key
|
||||||
|
uint32_t n = (uint32_t)kh_val(h, k);
|
||||||
|
//fprintf(stderr, "%llu %llu %llu ", key, kh_val(h, k), n);
|
||||||
|
// for 0 to lsb 32 val
|
||||||
|
// print b->p[msb 32 of val]
|
||||||
|
for(j = 0; j < n; j++)
|
||||||
|
{
|
||||||
|
//fprintf(stderr, "%llu ", mi->B[i].p[(kh_val(h, k)>>32) + j]);
|
||||||
|
m[key].push_back(mi->B[i].p[(kh_val(h, k)>>32) + j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Sorted map building time = %lld \n", __rdtsc() - tic);
|
||||||
|
fprintf(stderr, "Storing hash to %s \n", f_name);
|
||||||
|
tic = __rdtsc();
|
||||||
|
vector<uint64_t> key_list;
|
||||||
|
key_list.push_back(m.size());
|
||||||
|
for(auto k : m){
|
||||||
|
key_list.push_back(k.first);
|
||||||
|
f<<k.first << " "<<k.second.size()<<endl;
|
||||||
|
for(int j = 0; j < k.second.size(); j++){
|
||||||
|
f<<k.second[j]<<" ";
|
||||||
|
num_values++;
|
||||||
|
}
|
||||||
|
f<<endl;
|
||||||
|
}
|
||||||
|
f.close();
|
||||||
|
string size_file_name = (string) f_name + "_size";
|
||||||
|
ofstream size_f(size_file_name);
|
||||||
|
size_f<<m.size()<<" "<<num_values;
|
||||||
|
size_f.close();
|
||||||
|
|
||||||
|
string prefix = (string)f_name + "_keys";
|
||||||
|
string keys_bin_file_name = prefix + ".uint64";
|
||||||
|
ofstream wf(keys_bin_file_name, ios::out | ios::binary);
|
||||||
|
wf.write((char*)&key_list[0], (key_list.size())*sizeof(uint64_t));
|
||||||
|
wf.close();
|
||||||
|
|
||||||
|
key_list.clear();
|
||||||
|
m.clear();
|
||||||
|
fprintf(stderr, "Index store File IO time %lld \n", __rdtsc() - tic);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void mm_idx_stat(const mm_idx_t *mi)
|
void mm_idx_stat(const mm_idx_t *mi)
|
||||||
{
|
{
|
||||||
@@ -119,6 +479,7 @@ void mm_idx_stat(const mm_idx_t *mi)
|
|||||||
}
|
}
|
||||||
fprintf(stderr, "[M::%s::%.3f*%.2f] distinct minimizers: %d (%.2f%% are singletons); average occurrences: %.3lf; average spacing: %.3lf; total length: %ld\n",
|
fprintf(stderr, "[M::%s::%.3f*%.2f] distinct minimizers: %d (%.2f%% are singletons); average occurrences: %.3lf; average spacing: %.3lf; total length: %ld\n",
|
||||||
__func__, realtime() - mm_realtime0, cputime() / (realtime() - mm_realtime0), n, 100.0*n1/n, (double)sum / n, (double)len / sum, (long)len);
|
__func__, realtime() - mm_realtime0, cputime() / (realtime() - mm_realtime0), n, 100.0*n1/n, (double)sum / n, (double)len / sum, (long)len);
|
||||||
|
fprintf(stderr, "minimizer-lookup: %lld dp: %lld rmq: %lld rmq_t1: %lld rmq_t2: %lld rmq_t3: %lld rmq_t4: %lld alignment: %lld \n", minimizer_lookup_time, dp_time, rmq_time, rmq_t1, rmq_t2, rmq_t3, rmq_t4, alignment_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mm_idx_index_name(mm_idx_t *mi)
|
int mm_idx_index_name(mm_idx_t *mi)
|
||||||
|
|||||||
+2319
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
|||||||
|
/* The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018- Dana-Farber Cancer Institute
|
||||||
|
2017-2018 Broad Institute, Inc.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
Modified Copyright (C) 2021 Intel Corporation
|
||||||
|
Contacts: Saurabh Kalikar <saurabh.kalikar@intel.com>;
|
||||||
|
Vasimuddin Md <vasimuddin.md@intel.com>; Sanchit Misra <sanchit.misra@intel.com>;
|
||||||
|
Chirag Jain <chirag@iisc.ac.in>; Heng Li <hli@jimmy.harvard.edu>
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "ksw2.h"
|
||||||
|
#include <immintrin.h>
|
||||||
|
#include <x86intrin.h>
|
||||||
|
#include <smmintrin.h>
|
||||||
|
#include <emmintrin.h>
|
||||||
|
void ksw_extd2_avx512(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
|
||||||
|
int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez);
|
||||||
|
|
||||||
|
void ksw_extd2_avx2(void *km, int qlen, const uint8_t *query, int tlen, const uint8_t *target, int8_t m, const int8_t *mat,
|
||||||
|
int8_t q, int8_t e, int8_t q2, int8_t e2, int w, int zdrop, int end_bonus, int flag, ksw_extz_t *ez);
|
||||||
@@ -5,7 +5,16 @@
|
|||||||
#include "mmpriv.h"
|
#include "mmpriv.h"
|
||||||
#include "kalloc.h"
|
#include "kalloc.h"
|
||||||
#include "krmq.h"
|
#include "krmq.h"
|
||||||
|
#include <x86intrin.h>
|
||||||
|
//#include "simd_chain.h"
|
||||||
|
//#include "parallel_chaining_32_bit.h"
|
||||||
|
#include "parallel_chaining_v2_22.h"
|
||||||
|
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
extern uint64_t dp_time, rmq_time, rmq_t1, rmq_t2, rmq_t3, rmq_t4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern bool enable_vect_dp_chaining;
|
||||||
uint64_t *mg_chain_backtrack(void *km, int64_t n, const int32_t *f, const int64_t *p, int32_t *v, int32_t *t, int32_t min_cnt, int32_t min_sc, int32_t *n_u_, int32_t *n_v_)
|
uint64_t *mg_chain_backtrack(void *km, int64_t n, const int32_t *f, const int64_t *p, int32_t *v, int32_t *t, int32_t min_cnt, int32_t min_sc, int32_t *n_u_, int32_t *n_v_)
|
||||||
{
|
{
|
||||||
mm128_t *z;
|
mm128_t *z;
|
||||||
@@ -88,15 +97,65 @@ static mm128_t *compact_a(void *km, int32_t n_u, uint64_t *u, int32_t n_v, int32
|
|||||||
|
|
||||||
static inline int32_t comput_sc(const mm128_t *ai, const mm128_t *aj, int32_t max_dist_x, int32_t max_dist_y, int32_t bw, float chn_pen_gap, float chn_pen_skip, int is_cdna, int n_seg)
|
static inline int32_t comput_sc(const mm128_t *ai, const mm128_t *aj, int32_t max_dist_x, int32_t max_dist_y, int32_t bw, float chn_pen_gap, float chn_pen_skip, int is_cdna, int n_seg)
|
||||||
{
|
{
|
||||||
int32_t dq = (int32_t)ai->y - (int32_t)aj->y, dr, dd, dg, q_span, sc;
|
|
||||||
int32_t sidi = (ai->y & MM_SEED_SEG_MASK) >> MM_SEED_SEG_SHIFT;
|
uint64_t ai_x, ai_y, aj_x, aj_y;
|
||||||
int32_t sidj = (aj->y & MM_SEED_SEG_MASK) >> MM_SEED_SEG_SHIFT;
|
ai_x = ai->x; ai_y = ai->y; aj_x = aj->x; aj_y = aj->y;
|
||||||
if (dq <= 0 || dq > max_dist_x) return INT32_MIN;
|
|
||||||
dr = (int32_t)(ai->x - aj->x);
|
#ifdef CHAIN_DEBUG
|
||||||
if (sidi == sidj && (dr == 0 || dq > max_dist_y)) return INT32_MIN;
|
int32_t sc_vect = obj.comput_sc_vectorized_avx2_caller(ai_x, ai_y, aj_x, aj_y, aj->y>>32&0xff);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//if (sc_vect == 0) return INT32_MIN;
|
||||||
|
//else
|
||||||
|
//return sc_vect;
|
||||||
|
|
||||||
|
//fprintf(stderr, "%lld %lld %lld %lld \n", ai_x, ai_y, aj_x, aj_y);
|
||||||
|
//fprintf(stderr, "%lld %lld %lld %f %f %d %d\n", max_dist_x, max_dist_y, bw, chn_pen_gap, chn_pen_skip, is_cdna, n_seg);
|
||||||
|
int32_t dq = (int32_t)ai_y - (int32_t)aj_y, dr, dd, dg, q_span, sc;
|
||||||
|
int32_t sidi = (ai_y & MM_SEED_SEG_MASK) >> MM_SEED_SEG_SHIFT;
|
||||||
|
int32_t sidj = (aj_y & MM_SEED_SEG_MASK) >> MM_SEED_SEG_SHIFT;
|
||||||
|
if (dq <= 0 || dq > max_dist_x) {
|
||||||
|
|
||||||
|
#ifdef CHAIN_DEBUG
|
||||||
|
if(INT32_MIN != sc_vect){
|
||||||
|
//fprintf(stderr, "score mismatch %d -- %d", sc , sc_vect);
|
||||||
|
fprintf(stderr, "int-min exit: %llu, %llu, %llu, %llu : %d -- %d\n", ai_x, ai_y, aj_x, aj_y, sc, sc_vect);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return INT32_MIN;
|
||||||
|
}
|
||||||
|
dr = (int32_t)(ai_x - aj_x);
|
||||||
|
if (sidi == sidj && (dr == 0 || dq > max_dist_y)) {
|
||||||
|
|
||||||
|
#ifdef CHAIN_DEBUG
|
||||||
|
if(INT32_MIN != sc_vect){
|
||||||
|
//fprintf(stderr, "score mismatch %d -- %d", sc , sc_vect);
|
||||||
|
fprintf(stderr, "int-min exit: %llu, %llu, %llu, %llu : %d -- %d\n", ai_x, ai_y, aj_x, aj_y, sc, sc_vect);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return INT32_MIN;
|
||||||
|
}
|
||||||
dd = dr > dq? dr - dq : dq - dr;
|
dd = dr > dq? dr - dq : dq - dr;
|
||||||
if (sidi == sidj && dd > bw) return INT32_MIN;
|
if (sidi == sidj && dd > bw) {
|
||||||
if (n_seg > 1 && !is_cdna && sidi == sidj && dr > max_dist_y) return INT32_MIN;
|
|
||||||
|
#ifdef CHAIN_DEBUG
|
||||||
|
if(INT32_MIN != sc_vect){
|
||||||
|
//fprintf(stderr, "score mismatch %d -- %d", sc , sc_vect);
|
||||||
|
fprintf(stderr, "int-min exit: %llu, %llu, %llu, %llu : %d -- %d\n", ai_x, ai_y, aj_x, aj_y, sc, sc_vect);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return INT32_MIN;
|
||||||
|
}
|
||||||
|
if (n_seg > 1 && !is_cdna && sidi == sidj && dr > max_dist_y) {
|
||||||
|
|
||||||
|
#ifdef CHAIN_DEBUG
|
||||||
|
if(INT32_MIN != sc_vect){
|
||||||
|
//fprintf(stderr, "score mismatch %d -- %d", sc , sc_vect);
|
||||||
|
fprintf(stderr, "int-min exit: %llu, %llu, %llu, %llu : %d -- %d\n", ai_x, ai_y, aj_x, aj_y, sc, sc_vect);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return INT32_MIN;
|
||||||
|
}
|
||||||
dg = dr < dq? dr : dq;
|
dg = dr < dq? dr : dq;
|
||||||
q_span = aj->y>>32&0xff;
|
q_span = aj->y>>32&0xff;
|
||||||
sc = q_span < dg? q_span : dg;
|
sc = q_span < dg? q_span : dg;
|
||||||
@@ -110,6 +169,13 @@ static inline int32_t comput_sc(const mm128_t *ai, const mm128_t *aj, int32_t ma
|
|||||||
else sc -= (int)(lin_pen + .5f * log_pen);
|
else sc -= (int)(lin_pen + .5f * log_pen);
|
||||||
} else sc -= (int)(lin_pen + .5f * log_pen);
|
} else sc -= (int)(lin_pen + .5f * log_pen);
|
||||||
}
|
}
|
||||||
|
#ifdef CHAIN_DEBUG
|
||||||
|
|
||||||
|
if(sc != sc_vect ){
|
||||||
|
//fprintf(stderr, "score mismatch %d -- %d", sc , sc_vect);
|
||||||
|
fprintf(stderr, "outer: %llu, %llu, %llu, %llu : %d -- %d\n", ai_x, ai_y, aj_x, aj_y, sc, sc_vect);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,10 +190,18 @@ static inline int32_t comput_sc(const mm128_t *ai, const mm128_t *aj, int32_t ma
|
|||||||
mm128_t *mg_lchain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int max_iter, int min_cnt, int min_sc, float chn_pen_gap, float chn_pen_skip,
|
mm128_t *mg_lchain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int max_iter, int min_cnt, int min_sc, float chn_pen_gap, float chn_pen_skip,
|
||||||
int is_cdna, int n_seg, int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km)
|
int is_cdna, int n_seg, int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km)
|
||||||
{ // TODO: make sure this works when n has more than 32 bits
|
{ // TODO: make sure this works when n has more than 32 bits
|
||||||
int32_t *f, *t, *v, n_u, n_v, mmax_f = 0;
|
///fprintf(stderr, "chaining called\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
uint64_t align_start = __rdtsc();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int32_t *f, *t, *v, *v_1, *p_1, n_u, n_v, mmax_f = 0;
|
||||||
int64_t *p, i, j, max_ii, st = 0, n_iter = 0;
|
int64_t *p, i, j, max_ii, st = 0, n_iter = 0;
|
||||||
uint64_t *u;
|
uint64_t *u;
|
||||||
|
uint32_t* f_1;
|
||||||
if (_u) *_u = 0, *n_u_ = 0;
|
if (_u) *_u = 0, *n_u_ = 0;
|
||||||
if (n == 0 || a == 0) {
|
if (n == 0 || a == 0) {
|
||||||
kfree(km, a);
|
kfree(km, a);
|
||||||
@@ -136,16 +210,56 @@ mm128_t *mg_lchain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int
|
|||||||
if (max_dist_x < bw) max_dist_x = bw;
|
if (max_dist_x < bw) max_dist_x = bw;
|
||||||
if (max_dist_y < bw && !is_cdna) max_dist_y = bw;
|
if (max_dist_y < bw && !is_cdna) max_dist_y = bw;
|
||||||
KMALLOC(km, p, n);
|
KMALLOC(km, p, n);
|
||||||
|
KMALLOC(km, p_1, n);
|
||||||
KMALLOC(km, f, n);
|
KMALLOC(km, f, n);
|
||||||
|
KMALLOC(km, f_1, n);
|
||||||
KMALLOC(km, v, n);
|
KMALLOC(km, v, n);
|
||||||
|
KMALLOC(km, v_1, n);
|
||||||
KCALLOC(km, t, n);
|
KCALLOC(km, t, n);
|
||||||
|
|
||||||
|
//#ifdef PARALLEL_CHAINING
|
||||||
|
if(enable_vect_dp_chaining){
|
||||||
|
// Parallel chaining data-structures
|
||||||
|
anchor_t* anchors = (anchor_t*)malloc(n* sizeof(anchor_t));
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
uint64_t ri = a[i].x;
|
||||||
|
int32_t qi = (int32_t)a[i].y, q_span = a[i].y>>32&0xff; // NB: only 8 bits of span is used!!!
|
||||||
|
anchors[i].r = ri;
|
||||||
|
anchors[i].q = qi;
|
||||||
|
anchors[i].l = q_span;
|
||||||
|
}
|
||||||
|
num_bits_t *anchor_r, *anchor_q, *anchor_l;
|
||||||
|
create_SoA_Anchors_32_bit(anchors, n, anchor_r, anchor_q, anchor_l);
|
||||||
|
dp_chain obj(max_dist_x, max_dist_y, bw, max_skip, max_iter, min_cnt, min_sc, chn_pen_gap, chn_pen_skip, is_cdna, n_seg);
|
||||||
|
|
||||||
|
#ifdef PARALLEL_CHAINING
|
||||||
|
obj.mm_dp_vectorized(n, &anchors[0], anchor_r, anchor_q, anchor_l, f_1, p_1, v_1, max_dist_x, max_dist_y, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
// -16 is due to extra padding at the start of arrays
|
||||||
|
anchor_r -= 16; anchor_q -= 16; anchor_l -= 16;
|
||||||
|
free(anchor_r);
|
||||||
|
free(anchor_q);
|
||||||
|
free(anchor_l);
|
||||||
|
free(anchors);
|
||||||
|
for(int i = 0; i < n; i++){
|
||||||
|
#if 1
|
||||||
|
f[i] = f_1[i];
|
||||||
|
p[i] = p_1[i];
|
||||||
|
v[i] = v_1[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
} else {
|
||||||
|
//#else
|
||||||
|
|
||||||
// fill the score and backtrack arrays
|
// fill the score and backtrack arrays
|
||||||
for (i = 0, max_ii = -1; i < n; ++i) {
|
for (i = 0, max_ii = -1; i < n; ++i) {
|
||||||
int64_t max_j = -1, end_j;
|
int64_t max_j = -1, end_j;
|
||||||
int32_t max_f = a[i].y>>32&0xff, n_skip = 0;
|
int32_t max_f = a[i].y>>32&0xff, n_skip = 0;
|
||||||
while (st < i && (a[i].x>>32 != a[st].x>>32 || a[i].x > a[st].x + max_dist_x)) ++st;
|
while (st < i && (a[i].x>>32 != a[st].x>>32 || a[i].x > a[st].x + max_dist_x)) ++st;
|
||||||
if (i - st > max_iter) st = i - max_iter;
|
if (i - st > max_iter) st = i - max_iter;
|
||||||
|
int my_cnt = 0;
|
||||||
for (j = i - 1; j >= st; --j) {
|
for (j = i - 1; j >= st; --j) {
|
||||||
int32_t sc;
|
int32_t sc;
|
||||||
sc = comput_sc(&a[i], &a[j], max_dist_x, max_dist_y, bw, chn_pen_gap, chn_pen_skip, is_cdna, n_seg);
|
sc = comput_sc(&a[i], &a[j], max_dist_x, max_dist_y, bw, chn_pen_gap, chn_pen_skip, is_cdna, n_seg);
|
||||||
@@ -162,32 +276,62 @@ mm128_t *mg_lchain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int
|
|||||||
if (p[j] >= 0) t[p[j]] = i;
|
if (p[j] >= 0) t[p[j]] = i;
|
||||||
}
|
}
|
||||||
end_j = j;
|
end_j = j;
|
||||||
|
int debug_iter = 2057329;
|
||||||
|
|
||||||
if (max_ii < 0 || a[i].x - a[max_ii].x > (int64_t)max_dist_x) {
|
if (max_ii < 0 || a[i].x - a[max_ii].x > (int64_t)max_dist_x) {
|
||||||
int32_t max = INT32_MIN;
|
int32_t max = INT32_MIN;
|
||||||
max_ii = -1;
|
max_ii = -1;
|
||||||
for (j = i - 1; j >= st; --j)
|
for (j = i - 1; j >= st; --j) {
|
||||||
if (max < f[j]) max = f[j], max_ii = j;
|
if (max < (int32_t)f[j]) max = f[j], max_ii = j;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (max_ii >= 0 && max_ii < end_j) {
|
if (max_ii >= 0 && max_ii < end_j) {
|
||||||
int32_t tmp;
|
int32_t tmp;
|
||||||
tmp = comput_sc(&a[i], &a[max_ii], max_dist_x, max_dist_y, bw, chn_pen_gap, chn_pen_skip, is_cdna, n_seg);
|
tmp = comput_sc(&a[i], &a[max_ii], max_dist_x, max_dist_y, bw, chn_pen_gap, chn_pen_skip, is_cdna, n_seg);
|
||||||
if (tmp != INT32_MIN && max_f < tmp + f[max_ii])
|
// if (i == debug_iter) fprintf(stderr, "mm2: endj: %d max_ii: %d max_f: %d tmp_score: %d \n", end_j, max_ii, max_f, tmp);
|
||||||
|
|
||||||
|
|
||||||
|
if (tmp != INT32_MIN && max_f < tmp + f[max_ii]){
|
||||||
max_f = tmp + f[max_ii], max_j = max_ii;
|
max_f = tmp + f[max_ii], max_j = max_ii;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
f[i] = max_f, p[i] = max_j;
|
f[i] = max_f, p[i] = max_j;
|
||||||
v[i] = max_j >= 0 && v[max_j] > max_f? v[max_j] : max_f; // v[] keeps the peak score up to i; f[] is the score ending at i, not always the peak
|
v[i] = max_j >= 0 && v[max_j] > max_f? v[max_j] : max_f; // v[] keeps the peak score up to i; f[] is the score ending at i, not always the peak
|
||||||
|
|
||||||
if (max_ii < 0 || (a[i].x - a[max_ii].x <= (int64_t)max_dist_x && f[max_ii] < f[i]))
|
if (max_ii < 0 || (a[i].x - a[max_ii].x <= (int64_t)max_dist_x && f[max_ii] < f[i]))
|
||||||
max_ii = i;
|
max_ii = i;
|
||||||
if (mmax_f < max_f) mmax_f = max_f;
|
if (mmax_f < max_f) mmax_f = max_f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#ifdef CHAIN_DEBUG
|
||||||
|
|
||||||
|
for(int i = 0; i < n; i++){
|
||||||
|
if(f[i] != f_1[i] || p[i] != p_1[i] || v[i] !=v_1[i])
|
||||||
|
{
|
||||||
|
fprintf(stderr, "i:%d %d %d %d %d %d %d\n",i, f[i], f_1[i], p[i], p_1[i], v[i], v_1[i] );
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
f[i] = f_1[i];
|
||||||
|
p[i] = p_1[i];
|
||||||
|
v[i] = v_1[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
u = mg_chain_backtrack(km, n, f, p, v, t, min_cnt, min_sc, &n_u, &n_v);
|
u = mg_chain_backtrack(km, n, f, p, v, t, min_cnt, min_sc, &n_u, &n_v);
|
||||||
*n_u_ = n_u, *_u = u; // NB: note that u[] may not be sorted by score here
|
*n_u_ = n_u, *_u = u; // NB: note that u[] may not be sorted by score here
|
||||||
kfree(km, p); kfree(km, f); kfree(km, t);
|
kfree(km, p); kfree(km, p_1); kfree(km, f); kfree(km, f_1); kfree(km, t); kfree(km, v_1);
|
||||||
if (n_u == 0) {
|
if (n_u == 0) {
|
||||||
kfree(km, a); kfree(km, v);
|
kfree(km, a); kfree(km, v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
dp_time += __rdtsc() - align_start;
|
||||||
|
#endif
|
||||||
return compact_a(km, n_u, u, n_v, v, a);
|
return compact_a(km, n_u, u, n_v, v, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +369,11 @@ static inline int32_t comput_sc_simple(const mm128_t *ai, const mm128_t *aj, flo
|
|||||||
mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_skip, int cap_rmq_size, int min_cnt, int min_sc, float chn_pen_gap, float chn_pen_skip,
|
mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_skip, int cap_rmq_size, int min_cnt, int min_sc, float chn_pen_gap, float chn_pen_skip,
|
||||||
int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km)
|
int64_t n, mm128_t *a, int *n_u_, uint64_t **_u, void *km)
|
||||||
{
|
{
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
uint64_t start = __rdtsc();
|
||||||
|
#endif
|
||||||
|
uint64_t tim;
|
||||||
|
//fprintf(stderr, "rmq call \n");
|
||||||
int32_t *f,*t, *v, n_u, n_v, mmax_f = 0, max_rmq_size = 0;
|
int32_t *f,*t, *v, n_u, n_v, mmax_f = 0, max_rmq_size = 0;
|
||||||
int64_t *p, i, i0, st = 0, st_inner = 0, n_iter = 0;
|
int64_t *p, i, i0, st = 0, st_inner = 0, n_iter = 0;
|
||||||
uint64_t *u;
|
uint64_t *u;
|
||||||
@@ -252,6 +401,9 @@ mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_ski
|
|||||||
int32_t q_span = a[i].y>>32&0xff, max_f = q_span;
|
int32_t q_span = a[i].y>>32&0xff, max_f = q_span;
|
||||||
lc_elem_t s, *q, *r, lo, hi;
|
lc_elem_t s, *q, *r, lo, hi;
|
||||||
// add in-range anchors
|
// add in-range anchors
|
||||||
|
#ifdef MANUAL_PROFILING_RMQ
|
||||||
|
tim = __rdtsc();
|
||||||
|
#endif
|
||||||
if (i0 < i && a[i0].x != a[i].x) {
|
if (i0 < i && a[i0].x != a[i].x) {
|
||||||
int64_t j;
|
int64_t j;
|
||||||
for (j = i0; j < i; ++j) {
|
for (j = i0; j < i; ++j) {
|
||||||
@@ -266,7 +418,13 @@ mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_ski
|
|||||||
}
|
}
|
||||||
i0 = i;
|
i0 = i;
|
||||||
}
|
}
|
||||||
|
#ifdef MANUAL_PROFILING_RMQ
|
||||||
|
rmq_t1 += __rdtsc() - tim;
|
||||||
|
#endif
|
||||||
// get rid of active chains out of range
|
// get rid of active chains out of range
|
||||||
|
#ifdef MANUAL_PROFILING_RMQ
|
||||||
|
tim = __rdtsc();
|
||||||
|
#endif
|
||||||
while (st < i && (a[i].x>>32 != a[st].x>>32 || a[i].x > a[st].x + max_dist || krmq_size(head, root) > cap_rmq_size)) {
|
while (st < i && (a[i].x>>32 != a[st].x>>32 || a[i].x > a[st].x + max_dist || krmq_size(head, root) > cap_rmq_size)) {
|
||||||
s.y = (int32_t)a[st].y, s.i = st;
|
s.y = (int32_t)a[st].y, s.i = st;
|
||||||
if ((q = krmq_find(lc_elem, root, &s, 0)) != 0) {
|
if ((q = krmq_find(lc_elem, root, &s, 0)) != 0) {
|
||||||
@@ -275,6 +433,12 @@ mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_ski
|
|||||||
}
|
}
|
||||||
++st;
|
++st;
|
||||||
}
|
}
|
||||||
|
#ifdef MANUAL_PROFILING_RMQ
|
||||||
|
rmq_t2 += __rdtsc() - tim;
|
||||||
|
#endif
|
||||||
|
#ifdef MANUAL_PROFILING_RMQ
|
||||||
|
tim = __rdtsc();
|
||||||
|
#endif
|
||||||
if (max_dist_inner > 0) { // similar to the block above, but applied to the inner tree
|
if (max_dist_inner > 0) { // similar to the block above, but applied to the inner tree
|
||||||
while (st_inner < i && (a[i].x>>32 != a[st_inner].x>>32 || a[i].x > a[st_inner].x + max_dist_inner || krmq_size(head, root_inner) > cap_rmq_size)) {
|
while (st_inner < i && (a[i].x>>32 != a[st_inner].x>>32 || a[i].x > a[st_inner].x + max_dist_inner || krmq_size(head, root_inner) > cap_rmq_size)) {
|
||||||
s.y = (int32_t)a[st_inner].y, s.i = st_inner;
|
s.y = (int32_t)a[st_inner].y, s.i = st_inner;
|
||||||
@@ -285,6 +449,9 @@ mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_ski
|
|||||||
++st_inner;
|
++st_inner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef MANUAL_PROFILING_RMQ
|
||||||
|
rmq_t3 += __rdtsc() - tim;
|
||||||
|
#endif
|
||||||
// RMQ
|
// RMQ
|
||||||
lo.i = INT32_MAX, lo.y = (int32_t)a[i].y - max_dist;
|
lo.i = INT32_MAX, lo.y = (int32_t)a[i].y - max_dist;
|
||||||
hi.i = 0, hi.y = (int32_t)a[i].y;
|
hi.i = 0, hi.y = (int32_t)a[i].y;
|
||||||
@@ -304,6 +471,9 @@ mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_ski
|
|||||||
krmq_itr_t(lc_elem) itr;
|
krmq_itr_t(lc_elem) itr;
|
||||||
krmq_itr_find(lc_elem, root_inner, lo, &itr);
|
krmq_itr_find(lc_elem, root_inner, lo, &itr);
|
||||||
while ((q = krmq_at(&itr)) != 0) {
|
while ((q = krmq_at(&itr)) != 0) {
|
||||||
|
#ifdef MANUAL_PROFILING_RMQ
|
||||||
|
tim = __rdtsc();
|
||||||
|
#endif
|
||||||
if (q->y < (int32_t)a[i].y - max_dist_inner) break;
|
if (q->y < (int32_t)a[i].y - max_dist_inner) break;
|
||||||
++n_rmq_iter;
|
++n_rmq_iter;
|
||||||
j = q->i;
|
j = q->i;
|
||||||
@@ -319,11 +489,15 @@ mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_ski
|
|||||||
if (p[j] >= 0) t[p[j]] = i;
|
if (p[j] >= 0) t[p[j]] = i;
|
||||||
}
|
}
|
||||||
if (!krmq_itr_prev(lc_elem, &itr)) break;
|
if (!krmq_itr_prev(lc_elem, &itr)) break;
|
||||||
|
#ifdef MANUAL_PROFILING_RMQ
|
||||||
|
rmq_t4 += __rdtsc() - tim;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
n_iter += n_rmq_iter;
|
n_iter += n_rmq_iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set max
|
// set max
|
||||||
assert(max_j < 0 || (a[max_j].x < a[i].x && (int32_t)a[max_j].y < (int32_t)a[i].y));
|
assert(max_j < 0 || (a[max_j].x < a[i].x && (int32_t)a[max_j].y < (int32_t)a[i].y));
|
||||||
f[i] = max_f, p[i] = max_j;
|
f[i] = max_f, p[i] = max_j;
|
||||||
@@ -340,5 +514,8 @@ mm128_t *mg_lchain_rmq(int max_dist, int max_dist_inner, int bw, int max_chn_ski
|
|||||||
kfree(km, a); kfree(km, v);
|
kfree(km, a); kfree(km, v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
rmq_time += __rdtsc() - start;
|
||||||
|
#endif
|
||||||
return compact_a(km, n_u, u, n_v, v, a);
|
return compact_a(km, n_u, u, n_v, v, a);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,77 @@
|
|||||||
#include "minimap.h"
|
#include "minimap.h"
|
||||||
#include "mmpriv.h"
|
#include "mmpriv.h"
|
||||||
#include "ketopt.h"
|
#include "ketopt.h"
|
||||||
|
#include <x86intrin.h>
|
||||||
|
#include <immintrin.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "bseq.h"
|
||||||
|
#include "minimap.h"
|
||||||
|
#include "mmpriv.h"
|
||||||
|
#include "ketopt.h"
|
||||||
|
|
||||||
#define MM_VERSION "2.21-dev-r1094-dirty"
|
//#include "profile.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <x86intrin.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
uint64_t avg;
|
||||||
|
uint64_t minimizer_lookup_time, alignment_time, dp_time, rmq_time, rmq_t1, rmq_t2, rmq_t3, rmq_t4;
|
||||||
|
|
||||||
|
bool enable_vect_dp_chaining = false;
|
||||||
|
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
#include "lisa_hash.h"
|
||||||
|
lisa_hash<uint64_t, uint64_t> *lh;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// New memory allocation approach for alignment optimizations
|
||||||
|
//
|
||||||
|
void *km1;
|
||||||
|
uint64_t km_size = 500000000; // 500 MB
|
||||||
|
int km_top;
|
||||||
|
/*
|
||||||
|
void *kcalloc_(void* km, int count, int size)
|
||||||
|
{
|
||||||
|
assert(count*size < km_size);
|
||||||
|
km_top += count*size + 1024;
|
||||||
|
memset(km, 0, count * size);
|
||||||
|
|
||||||
|
// printf("km_top: %d\n", km_top);
|
||||||
|
return km;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *kmalloc_(void* km, int count) {
|
||||||
|
if(km_top + count >= km_size)
|
||||||
|
printf("count: %d\n", count);
|
||||||
|
assert(km_top + count < km_size);
|
||||||
|
void *mem = (void*) ((int8_t*) km + km_top);
|
||||||
|
km_top += count + 1024;
|
||||||
|
// printf("km_top: %d\n", km_top);
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void kfree_all() { km_top = 0;}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Memory for alignment end
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __rdtsc
|
||||||
|
#ifdef _rdtsc
|
||||||
|
#define __rdtsc _rdtsc
|
||||||
|
#else
|
||||||
|
#define __rdtsc __builtin_ia32_rdtsc
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MM_VERSION "2.22-r1101"
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
@@ -117,6 +186,12 @@ static inline void yes_or_no(mm_mapopt_t *opt, int64_t flag, int long_idx, const
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
// Memory allocation for alignment optimizations
|
||||||
|
//km1 = calloc(km_size, 1); // 10 MB init contg. alloc
|
||||||
|
#ifdef PARALLEL_CHAINING
|
||||||
|
enable_vect_dp_chaining = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *opt_str = "2aSDw:k:K:t:r:f:Vv:g:G:I:d:XT:s:x:Hcp:M:n:z:A:B:O:E:m:N:Qu:R:hF:LC:yYPo:e:U:";
|
const char *opt_str = "2aSDw:k:K:t:r:f:Vv:g:G:I:d:XT:s:x:Hcp:M:n:z:A:B:O:E:m:N:Qu:R:hF:LC:yYPo:e:U:";
|
||||||
ketopt_t o = KETOPT_INIT;
|
ketopt_t o = KETOPT_INIT;
|
||||||
mm_mapopt_t opt;
|
mm_mapopt_t opt;
|
||||||
@@ -131,9 +206,11 @@ int main(int argc, char *argv[])
|
|||||||
liftrlimit();
|
liftrlimit();
|
||||||
mm_realtime0 = realtime();
|
mm_realtime0 = realtime();
|
||||||
mm_set_opt(0, &ipt, &opt);
|
mm_set_opt(0, &ipt, &opt);
|
||||||
|
string preset_arg = "";
|
||||||
|
|
||||||
while ((c = ketopt(&o, argc, argv, 1, opt_str, long_options)) >= 0) { // test command line options and apply option -x/preset first
|
while ((c = ketopt(&o, argc, argv, 1, opt_str, long_options)) >= 0) { // test command line options and apply option -x/preset first
|
||||||
if (c == 'x') {
|
if (c == 'x') {
|
||||||
|
preset_arg += (string) o.arg;
|
||||||
if (mm_set_opt(o.arg, &ipt, &opt) < 0) {
|
if (mm_set_opt(o.arg, &ipt, &opt) < 0) {
|
||||||
fprintf(stderr, "[ERROR] unknown preset '%s'\n", o.arg);
|
fprintf(stderr, "[ERROR] unknown preset '%s'\n", o.arg);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -366,6 +443,7 @@ int main(int argc, char *argv[])
|
|||||||
fprintf(stderr, "[ERROR] incorrect input: in the sr mode, please specify no more than two query files.\n");
|
fprintf(stderr, "[ERROR] incorrect input: in the sr mode, please specify no more than two query files.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
preset_arg = (string)argv[o.ind] + "_" + preset_arg + "_minimizers_key_value_sorted";
|
||||||
idx_rdr = mm_idx_reader_open(argv[o.ind], &ipt, fnw);
|
idx_rdr = mm_idx_reader_open(argv[o.ind], &ipt, fnw);
|
||||||
if (idx_rdr == 0) {
|
if (idx_rdr == 0) {
|
||||||
fprintf(stderr, "[ERROR] failed to open file '%s': %s\n", argv[o.ind], strerror(errno));
|
fprintf(stderr, "[ERROR] failed to open file '%s': %s\n", argv[o.ind], strerror(errno));
|
||||||
@@ -408,10 +486,26 @@ int main(int argc, char *argv[])
|
|||||||
__func__, realtime() - mm_realtime0, cputime() / (realtime() - mm_realtime0), mi->n_seq);
|
__func__, realtime() - mm_realtime0, cputime() / (realtime() - mm_realtime0), mi->n_seq);
|
||||||
if (argc != o.ind + 1) mm_mapopt_update(&opt, mi);
|
if (argc != o.ind + 1) mm_mapopt_update(&opt, mi);
|
||||||
if (mm_verbose >= 3) mm_idx_stat(mi);
|
if (mm_verbose >= 3) mm_idx_stat(mi);
|
||||||
|
#ifdef LISA_INDEX
|
||||||
|
mm_idx_dump_hash(preset_arg.c_str(), mi);
|
||||||
|
#endif
|
||||||
if (junc_bed) mm_idx_bed_read(mi, junc_bed, 1);
|
if (junc_bed) mm_idx_bed_read(mi, junc_bed, 1);
|
||||||
if (alt_list) mm_idx_alt_read(mi, alt_list);
|
if (alt_list) mm_idx_alt_read(mi, alt_list);
|
||||||
if (argc - (o.ind + 1) == 0) continue; // no query files
|
if (argc - (o.ind + 1) == 0) {
|
||||||
|
mm_idx_destroy(mi);
|
||||||
|
continue; // no query files
|
||||||
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
fprintf(stderr, "Using LISA_HASH..\n");
|
||||||
|
mm_idx_destroy_mm_hash(mi);
|
||||||
|
char* prefix;
|
||||||
|
lh = new lisa_hash<uint64_t, uint64_t>(preset_arg, prefix);
|
||||||
|
fprintf(stderr, "Loading done.\n");
|
||||||
|
// total_time = __rdtsc();
|
||||||
|
// fprintf(stderr, "\nIndexing Real time: %.3f sec;\n", realtime() - mapping_time);
|
||||||
|
#endif
|
||||||
|
mm_realtime0 = realtime();
|
||||||
if (!(opt.flag & MM_F_FRAG_MODE)) {
|
if (!(opt.flag & MM_F_FRAG_MODE)) {
|
||||||
for (i = o.ind + 1; i < argc; ++i) {
|
for (i = o.ind + 1; i < argc; ++i) {
|
||||||
ret = mm_map_file(mi, argv[i], &opt, n_threads);
|
ret = mm_map_file(mi, argv[i], &opt, n_threads);
|
||||||
@@ -420,12 +514,17 @@ int main(int argc, char *argv[])
|
|||||||
} else {
|
} else {
|
||||||
ret = mm_map_file_frag(mi, argc - (o.ind + 1), (const char**)&argv[o.ind + 1], &opt, n_threads);
|
ret = mm_map_file_frag(mi, argc - (o.ind + 1), (const char**)&argv[o.ind + 1], &opt, n_threads);
|
||||||
}
|
}
|
||||||
mm_idx_destroy(mi);
|
//mm_idx_destroy(mi);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "ERROR: failed to map the query file\n");
|
fprintf(stderr, "ERROR: failed to map the query file\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
mm_idx_destroy_seq(mi);
|
||||||
|
#else
|
||||||
|
mm_idx_destroy(mi);
|
||||||
|
#endif
|
||||||
n_parts = idx_rdr->n_parts;
|
n_parts = idx_rdr->n_parts;
|
||||||
mm_idx_reader_close(idx_rdr);
|
mm_idx_reader_close(idx_rdr);
|
||||||
|
|
||||||
@@ -444,5 +543,10 @@ int main(int argc, char *argv[])
|
|||||||
fprintf(stderr, " %s", argv[i]);
|
fprintf(stderr, " %s", argv[i]);
|
||||||
fprintf(stderr, "\n[M::%s] Real time: %.3f sec; CPU: %.3f sec; Peak RSS: %.3f GB\n", __func__, realtime() - mm_realtime0, cputime(), peakrss() / 1024.0 / 1024.0 / 1024.0);
|
fprintf(stderr, "\n[M::%s] Real time: %.3f sec; CPU: %.3f sec; Peak RSS: %.3f GB\n", __func__, realtime() - mm_realtime0, cputime(), peakrss() / 1024.0 / 1024.0 / 1024.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "minimizer-lookup: %lld dp: %lld rmq: %lld rmq_t1: %lld rmq_t2: %lld rmq_t3: %lld rmq_t4: %lld alignment: %lld %lld\n", minimizer_lookup_time, dp_time, rmq_time, rmq_t1, rmq_t2, rmq_t3, rmq_t4, alignment_time, avg);
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
delete lh;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,12 @@
|
|||||||
#include "mmpriv.h"
|
#include "mmpriv.h"
|
||||||
#include "bseq.h"
|
#include "bseq.h"
|
||||||
#include "khash.h"
|
#include "khash.h"
|
||||||
|
#include <x86intrin.h>
|
||||||
|
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
extern uint64_t minimizer_lookup_time;
|
||||||
|
extern uint64_t rmq_time;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct mm_tbuf_s {
|
struct mm_tbuf_s {
|
||||||
void *km;
|
void *km;
|
||||||
@@ -173,6 +179,9 @@ static mm128_t *collect_seed_hits_heap(void *km, const mm_mapopt_t *opt, int max
|
|||||||
static mm128_t *collect_seed_hits(void *km, const mm_mapopt_t *opt, int max_occ, const mm_idx_t *mi, const char *qname, const mm128_v *mv, int qlen, int64_t *n_a, int *rep_len,
|
static mm128_t *collect_seed_hits(void *km, const mm_mapopt_t *opt, int max_occ, const mm_idx_t *mi, const char *qname, const mm128_v *mv, int qlen, int64_t *n_a, int *rep_len,
|
||||||
int *n_mini_pos, uint64_t **mini_pos)
|
int *n_mini_pos, uint64_t **mini_pos)
|
||||||
{
|
{
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
uint64_t lookup_start = __rdtsc();
|
||||||
|
#endif
|
||||||
int i, n_m;
|
int i, n_m;
|
||||||
mm_seed_t *m;
|
mm_seed_t *m;
|
||||||
mm128_t *a;
|
mm128_t *a;
|
||||||
@@ -205,6 +214,9 @@ static mm128_t *collect_seed_hits(void *km, const mm_mapopt_t *opt, int max_occ,
|
|||||||
}
|
}
|
||||||
kfree(km, m);
|
kfree(km, m);
|
||||||
radix_sort_128x(a, a + (*n_a));
|
radix_sort_128x(a, a + (*n_a));
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
minimizer_lookup_time += __rdtsc() - lookup_start;
|
||||||
|
#endif
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +288,12 @@ void mm_map_frag(const mm_idx_t *mi, int n_segs, const int *qlens, const char **
|
|||||||
if (opt->flag & MM_F_RMQ) {
|
if (opt->flag & MM_F_RMQ) {
|
||||||
a = mg_lchain_rmq(opt->max_gap, opt->rmq_inner_dist, opt->bw, opt->max_chain_skip, opt->rmq_size_cap, opt->min_cnt, opt->min_chain_score,
|
a = mg_lchain_rmq(opt->max_gap, opt->rmq_inner_dist, opt->bw, opt->max_chain_skip, opt->rmq_size_cap, opt->min_cnt, opt->min_chain_score,
|
||||||
opt->chain_gap_scale * 0.01 * mi->k, 0.0f, n_a, a, &n_regs0, &u, b->km);
|
opt->chain_gap_scale * 0.01 * mi->k, 0.0f, n_a, a, &n_regs0, &u, b->km);
|
||||||
|
// a = mg_lchain_dp(opt->max_gap, opt->rmq_inner_dist, opt->bw, opt->max_chain_skip, opt->rmq_size_cap, opt->min_cnt, opt->min_chain_score,
|
||||||
|
// opt->chain_gap_scale * 0.01 * mi->k, 0.0f, is_splice, n_segs, n_a, a, &n_regs0, &u, b->km);
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
//fprintf(stderr, "dp call - n_a = %lld\n", n_a);
|
||||||
a = mg_lchain_dp(max_chain_gap_ref, max_chain_gap_qry, opt->bw, opt->max_chain_skip, opt->max_chain_iter, opt->min_cnt, opt->min_chain_score,
|
a = mg_lchain_dp(max_chain_gap_ref, max_chain_gap_qry, opt->bw, opt->max_chain_skip, opt->max_chain_iter, opt->min_cnt, opt->min_chain_score,
|
||||||
opt->chain_gap_scale * 0.01 * mi->k, 0.0f, is_splice, n_segs, n_a, a, &n_regs0, &u, b->km);
|
opt->chain_gap_scale * 0.01 * mi->k, 0.0f, is_splice, n_segs, n_a, a, &n_regs0, &u, b->km);
|
||||||
}
|
}
|
||||||
@@ -284,12 +301,23 @@ void mm_map_frag(const mm_idx_t *mi, int n_segs, const int *qlens, const char **
|
|||||||
if (opt->bw_long > opt->bw && (opt->flag & (MM_F_SPLICE|MM_F_SR|MM_F_NO_LJOIN)) == 0 && n_segs == 1 && n_regs0 > 1) { // re-chain/long-join for long sequences
|
if (opt->bw_long > opt->bw && (opt->flag & (MM_F_SPLICE|MM_F_SR|MM_F_NO_LJOIN)) == 0 && n_segs == 1 && n_regs0 > 1) { // re-chain/long-join for long sequences
|
||||||
int32_t st = (int32_t)a[0].y, en = (int32_t)a[(int32_t)u[0] - 1].y;
|
int32_t st = (int32_t)a[0].y, en = (int32_t)a[(int32_t)u[0] - 1].y;
|
||||||
if (qlen_sum - (en - st) > opt->rmq_rescue_size || en - st > qlen_sum * opt->rmq_rescue_ratio) {
|
if (qlen_sum - (en - st) > opt->rmq_rescue_size || en - st > qlen_sum * opt->rmq_rescue_ratio) {
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
// uint64_t tim = __rdtsc();
|
||||||
|
#endif
|
||||||
|
// fprintf(stderr, "pre: rmq rechain call - n_a = %lld n_regs = %lld\n",n_a, n_regs0);
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
int64_t prev_n_a = n_a;
|
||||||
for (i = 0, n_a = 0; i < n_regs0; ++i) n_a += (int32_t)u[i];
|
for (i = 0, n_a = 0; i < n_regs0; ++i) n_a += (int32_t)u[i];
|
||||||
kfree(b->km, u);
|
kfree(b->km, u);
|
||||||
radix_sort_128x(a, a + n_a);
|
radix_sort_128x(a, a + n_a);
|
||||||
|
// fprintf(stderr, "post: rmq rechain call - prev_n_a = %lld n_a = %lld n_regs = %lld\n",prev_n_a, n_a, n_regs0);
|
||||||
|
// a = mg_lchain_dp(opt->max_gap, opt->rmq_inner_dist, opt->bw_long, opt->max_chain_skip, opt->rmq_size_cap, opt->min_cnt, opt->min_chain_score,
|
||||||
|
// opt->chain_gap_scale * 0.01 * mi->k, 0.0f, is_splice, n_segs, n_a, a, &n_regs0, &u, b->km);
|
||||||
a = mg_lchain_rmq(opt->max_gap, opt->rmq_inner_dist, opt->bw_long, opt->max_chain_skip, opt->rmq_size_cap, opt->min_cnt, opt->min_chain_score,
|
a = mg_lchain_rmq(opt->max_gap, opt->rmq_inner_dist, opt->bw_long, opt->max_chain_skip, opt->rmq_size_cap, opt->min_cnt, opt->min_chain_score,
|
||||||
opt->chain_gap_scale * 0.01 * mi->k, 0.0f, n_a, a, &n_regs0, &u, b->km);
|
opt->chain_gap_scale * 0.01 * mi->k, 0.0f, n_a, a, &n_regs0, &u, b->km);
|
||||||
|
#ifdef MANUAL_PROFILING
|
||||||
|
// rmq_time += __rdtsc() - tim;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} else if (opt->max_occ > opt->mid_occ && rep_len > 0 && !(opt->flag & MM_F_RMQ)) { // re-chain, mostly for short reads
|
} else if (opt->max_occ > opt->mid_occ && rep_len > 0 && !(opt->flag & MM_F_RMQ)) { // re-chain, mostly for short reads
|
||||||
int rechain = 0;
|
int rechain = 0;
|
||||||
@@ -563,6 +591,7 @@ static void *worker_pipeline(void *shared, int step, void *in)
|
|||||||
if ((p->opt->flag & MM_F_OUT_CS) && !(mm_dbg_flag & MM_DBG_NO_KALLOC)) km = km_init();
|
if ((p->opt->flag & MM_F_OUT_CS) && !(mm_dbg_flag & MM_DBG_NO_KALLOC)) km = km_init();
|
||||||
for (k = 0; k < s->n_frag; ++k) {
|
for (k = 0; k < s->n_frag; ++k) {
|
||||||
int seg_st = s->seg_off[k], seg_en = s->seg_off[k] + s->n_seg[k];
|
int seg_st = s->seg_off[k], seg_en = s->seg_off[k] + s->n_seg[k];
|
||||||
|
#ifndef DISABLE_OUTPUT
|
||||||
for (i = seg_st; i < seg_en; ++i) {
|
for (i = seg_st; i < seg_en; ++i) {
|
||||||
mm_bseq1_t *t = &s->seq[i];
|
mm_bseq1_t *t = &s->seq[i];
|
||||||
if (p->opt->split_prefix && p->n_parts == 0) { // then write to temporary files
|
if (p->opt->split_prefix && p->n_parts == 0) { // then write to temporary files
|
||||||
@@ -597,6 +626,7 @@ static void *worker_pipeline(void *shared, int step, void *in)
|
|||||||
mm_err_puts(p->str.s);
|
mm_err_puts(p->str.s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
for (i = seg_st; i < seg_en; ++i) {
|
for (i = seg_st; i < seg_en; ++i) {
|
||||||
for (j = 0; j < s->n_reg[i]; ++j) free(s->reg[i][j].p);
|
for (j = 0; j < s->n_reg[i]; ++j) free(s->reg[i][j].p);
|
||||||
free(s->reg[i]);
|
free(s->reg[i]);
|
||||||
|
|||||||
@@ -285,6 +285,13 @@ mm_idx_t *mm_idx_load(FILE *fp);
|
|||||||
*/
|
*/
|
||||||
void mm_idx_dump(FILE *fp, const mm_idx_t *mi);
|
void mm_idx_dump(FILE *fp, const mm_idx_t *mi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store hash table from minimap2 index into a file
|
||||||
|
* @param f_name File name for output file
|
||||||
|
* @param mi minimap2 index
|
||||||
|
*/
|
||||||
|
void mm_idx_dump_hash(const char* f_name, const mm_idx_t *mi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an index from strings in memory
|
* Create an index from strings in memory
|
||||||
*
|
*
|
||||||
@@ -313,6 +320,19 @@ void mm_idx_stat(const mm_idx_t *idx);
|
|||||||
* @param r minimap2 index
|
* @param r minimap2 index
|
||||||
*/
|
*/
|
||||||
void mm_idx_destroy(mm_idx_t *mi);
|
void mm_idx_destroy(mm_idx_t *mi);
|
||||||
|
/**
|
||||||
|
* Destroy/deallocate an hash table index
|
||||||
|
*
|
||||||
|
* @param r minimap2 index
|
||||||
|
*/
|
||||||
|
void mm_idx_destroy_mm_hash(mm_idx_t *mi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy/deallocate target sequences
|
||||||
|
*
|
||||||
|
* @param r minimap2 index
|
||||||
|
*/
|
||||||
|
void mm_idx_destroy_seq(mm_idx_t *mi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize a thread-local buffer for mapping
|
* Initialize a thread-local buffer for mapping
|
||||||
|
|||||||
+6
-1
@@ -1,4 +1,4 @@
|
|||||||
.TH minimap2 1 "6 July 2021" "minimap2-2.21 (r1071)" "Bioinformatics tools"
|
.TH minimap2 1 "7 August 2021" "minimap2-2.22 (r1101)" "Bioinformatics tools"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.PP
|
.PP
|
||||||
minimap2 - mapping and alignment between collections of DNA sequences
|
minimap2 - mapping and alignment between collections of DNA sequences
|
||||||
@@ -423,6 +423,11 @@ alignment.
|
|||||||
Skip alignment if the DP matrix size is above
|
Skip alignment if the DP matrix size is above
|
||||||
.IR NUM .
|
.IR NUM .
|
||||||
Set 0 to disable [100m].
|
Set 0 to disable [100m].
|
||||||
|
.TP
|
||||||
|
.BI --cap-kalloc \ NUM
|
||||||
|
Free thread-local kalloc memory reservoir if after the alignment the size of the reservoir above
|
||||||
|
.IR NUM .
|
||||||
|
Set 0 to disable [0].
|
||||||
.SS Input/output options
|
.SS Input/output options
|
||||||
.TP 10
|
.TP 10
|
||||||
.B -a
|
.B -a
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env k8
|
#!/usr/bin/env k8
|
||||||
|
|
||||||
var paftools_version = '2.21-r1071';
|
var paftools_version = '2.22-r1101';
|
||||||
|
|
||||||
/*****************************
|
/*****************************
|
||||||
***** Library functions *****
|
***** Library functions *****
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include "mmpriv.h"
|
#include "mmpriv.h"
|
||||||
|
extern bool enable_vect_dp_chaining;
|
||||||
void mm_idxopt_init(mm_idxopt_t *opt)
|
void mm_idxopt_init(mm_idxopt_t *opt)
|
||||||
{
|
{
|
||||||
memset(opt, 0, sizeof(mm_idxopt_t));
|
memset(opt, 0, sizeof(mm_idxopt_t));
|
||||||
@@ -94,6 +94,9 @@ int mm_set_opt(const char *preset, mm_idxopt_t *io, mm_mapopt_t *mo)
|
|||||||
mo->bw = mo->bw_long = 2000;
|
mo->bw = mo->bw_long = 2000;
|
||||||
mo->occ_dist = 0;
|
mo->occ_dist = 0;
|
||||||
} else if (strcmp(preset, "map10k") == 0 || strcmp(preset, "map-pb") == 0) {
|
} else if (strcmp(preset, "map10k") == 0 || strcmp(preset, "map-pb") == 0) {
|
||||||
|
#if defined (PARALLEL_CHAINING) && (defined(__AVX2__)) && (!defined(__AVX512BW__))
|
||||||
|
enable_vect_dp_chaining = false;
|
||||||
|
#endif
|
||||||
io->flag |= MM_I_HPC, io->k = 19;
|
io->flag |= MM_I_HPC, io->k = 19;
|
||||||
} else if (strcmp(preset, "ava-pb") == 0) {
|
} else if (strcmp(preset, "ava-pb") == 0) {
|
||||||
io->flag |= MM_I_HPC, io->k = 19, io->w = 5;
|
io->flag |= MM_I_HPC, io->k = 19, io->w = 5;
|
||||||
@@ -102,6 +105,9 @@ int mm_set_opt(const char *preset, mm_idxopt_t *io, mm_mapopt_t *mo)
|
|||||||
mo->bw_long = mo->bw;
|
mo->bw_long = mo->bw;
|
||||||
mo->occ_dist = 0;
|
mo->occ_dist = 0;
|
||||||
} else if (strcmp(preset, "map-hifi") == 0 || strcmp(preset, "map-ccs") == 0) {
|
} else if (strcmp(preset, "map-hifi") == 0 || strcmp(preset, "map-ccs") == 0) {
|
||||||
|
#if defined (PARALLEL_CHAINING) && (defined(__AVX2__)) && (!defined(__AVX512BW__))
|
||||||
|
enable_vect_dp_chaining = false;
|
||||||
|
#endif
|
||||||
io->flag = 0, io->k = 19, io->w = 19;
|
io->flag = 0, io->k = 19, io->w = 19;
|
||||||
mo->max_gap = 10000;
|
mo->max_gap = 10000;
|
||||||
mo->a = 1, mo->b = 4, mo->q = 6, mo->q2 = 26, mo->e = 2, mo->e2 = 1;
|
mo->a = 1, mo->b = 4, mo->q = 6, mo->q2 = 26, mo->e = 2, mo->e2 = 1;
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ cdef extern from "minimap.h":
|
|||||||
int anchor_ext_len, anchor_ext_shift
|
int anchor_ext_len, anchor_ext_shift
|
||||||
float max_clip_ratio
|
float max_clip_ratio
|
||||||
|
|
||||||
|
int rank_min_len
|
||||||
|
float rank_frac
|
||||||
|
|
||||||
int pe_ori, pe_bonus
|
int pe_ori, pe_bonus
|
||||||
|
|
||||||
float mid_occ_frac
|
float mid_occ_frac
|
||||||
@@ -53,6 +56,7 @@ cdef extern from "minimap.h":
|
|||||||
int32_t max_occ
|
int32_t max_occ
|
||||||
int64_t mini_batch_size
|
int64_t mini_batch_size
|
||||||
int64_t max_sw_mat
|
int64_t max_sw_mat
|
||||||
|
int64_t cap_kalloc
|
||||||
|
|
||||||
const char *split_prefix
|
const char *split_prefix
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ from libc.stdlib cimport free
|
|||||||
cimport cmappy
|
cimport cmappy
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
__version__ = '2.21'
|
__version__ = '2.22'
|
||||||
|
|
||||||
cmappy.mm_reset_timer()
|
cmappy.mm_reset_timer()
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,40 @@
|
|||||||
#include "mmpriv.h"
|
#include "mmpriv.h"
|
||||||
#include "kalloc.h"
|
#include "kalloc.h"
|
||||||
#include "ksort.h"
|
#include "ksort.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include<algorithm>
|
||||||
|
#include <x86intrin.h>
|
||||||
|
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
#include "lisa_hash.h"
|
||||||
|
extern lisa_hash<uint64_t, uint64_t> *lh;
|
||||||
|
#endif
|
||||||
|
extern uint64_t minimizer_lookup_time;
|
||||||
|
|
||||||
mm_seed_t *mm_seed_collect_all(void *km, const mm_idx_t *mi, const mm128_v *mv, int32_t *n_m_)
|
mm_seed_t *mm_seed_collect_all(void *km, const mm_idx_t *mi, const mm128_v *mv, int32_t *n_m_)
|
||||||
{
|
{
|
||||||
|
//#ifdef MANUAL_PROFILING
|
||||||
|
// uint64_t lookup_start = __rdtsc();
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
//-----------------------------------
|
||||||
|
uint64_t** cr_batch = (uint64_t**) malloc((mv->n)*sizeof(uint64_t*));
|
||||||
|
int* t_batch = (int*)malloc((mv->n)*sizeof(int));
|
||||||
|
uint64_t* minimizers = (uint64_t*) malloc((mv->n)*sizeof(uint64_t));
|
||||||
|
int64_t* lisa_pos = (int64_t*) malloc((max(32, (int)mv->n))* sizeof(int64_t));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mv->n; i++) {
|
||||||
|
mm128_t *p = &mv->a[i];
|
||||||
|
minimizers[i] = p->x>>8;
|
||||||
|
}
|
||||||
|
|
||||||
|
lh->mm_idx_get_batched(minimizers, mv->n, lisa_pos, cr_batch, t_batch);
|
||||||
|
//-----------------------------------
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
mm_seed_t *m;
|
mm_seed_t *m;
|
||||||
size_t i;
|
size_t i;
|
||||||
int32_t k;
|
int32_t k;
|
||||||
@@ -14,7 +45,12 @@ mm_seed_t *mm_seed_collect_all(void *km, const mm_idx_t *mi, const mm128_v *mv,
|
|||||||
mm128_t *p = &mv->a[i];
|
mm128_t *p = &mv->a[i];
|
||||||
uint32_t q_pos = (uint32_t)p->y, q_span = p->x & 0xff;
|
uint32_t q_pos = (uint32_t)p->y, q_span = p->x & 0xff;
|
||||||
int t;
|
int t;
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
t = t_batch[i];
|
||||||
|
cr = cr_batch[i];
|
||||||
|
#else
|
||||||
cr = mm_idx_get(mi, p->x>>8, &t);
|
cr = mm_idx_get(mi, p->x>>8, &t);
|
||||||
|
#endif
|
||||||
if (t == 0) continue;
|
if (t == 0) continue;
|
||||||
q = &m[k++];
|
q = &m[k++];
|
||||||
q->q_pos = q_pos, q->q_span = q_span, q->cr = cr, q->n = t, q->seg_id = p->y >> 32;
|
q->q_pos = q_pos, q->q_span = q_span, q->cr = cr, q->n = t, q->seg_id = p->y >> 32;
|
||||||
@@ -22,7 +58,16 @@ mm_seed_t *mm_seed_collect_all(void *km, const mm_idx_t *mi, const mm128_v *mv,
|
|||||||
if (i > 0 && p->x>>8 == mv->a[i - 1].x>>8) q->is_tandem = 1;
|
if (i > 0 && p->x>>8 == mv->a[i - 1].x>>8) q->is_tandem = 1;
|
||||||
if (i < mv->n - 1 && p->x>>8 == mv->a[i + 1].x>>8) q->is_tandem = 1;
|
if (i < mv->n - 1 && p->x>>8 == mv->a[i + 1].x>>8) q->is_tandem = 1;
|
||||||
}
|
}
|
||||||
|
#ifdef LISA_HASH
|
||||||
|
free(cr_batch);
|
||||||
|
free(t_batch);
|
||||||
|
free(minimizers);
|
||||||
|
free(lisa_pos);
|
||||||
|
#endif
|
||||||
*n_m_ = k;
|
*n_m_ = k;
|
||||||
|
//#ifdef MANUAL_PROFILING
|
||||||
|
// minimizer_lookup_time += __rdtsc() - lookup_start;
|
||||||
|
//#endif
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ def readme():
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name = 'mappy',
|
name = 'mappy',
|
||||||
version = '2.21',
|
version = '2.22',
|
||||||
url = 'https://github.com/lh3/minimap2',
|
url = 'https://github.com/lh3/minimap2',
|
||||||
description = 'Minimap2 python binding',
|
description = 'Minimap2 python binding',
|
||||||
long_description = readme(),
|
long_description = readme(),
|
||||||
|
|||||||
Reference in New Issue
Block a user