Compare commits

...
17 Commits
Author SHA1 Message Date
Vasimuddin Md e88e6ea5d5 Update README.md 2021-11-29 08:39:00 -05:00
Vasimuddin 66c90fdb83 updated readme 2021-11-29 08:39:00 -05:00
Vasimuddin 3b2eca139a fixed AVX options in options.c 2021-11-29 08:39:00 -05:00
Vasimuddin 23d4edfa31 updated readme and build_index.sh 2021-11-27 10:42:22 -05:00
Vasimuddin 249c180b29 updated readme 2021-11-27 10:42:22 -05:00
Vasimuddin 798ea0a4a3 updated the readme 2021-11-27 10:42:22 -05:00
Saurabh bedd87f61f make multi 2021-11-27 10:42:22 -05:00
Saurabh 03540c47b3 disable chaining for avx2 - clr and hifi 2021-11-27 10:42:22 -05:00
Saurabh 3b1deac0a5 avx2 seg fault fixed 2021-11-27 10:42:22 -05:00
Saurabh de90f2e655 cleanup 2021-11-27 10:42:22 -05:00
Saurabh ba186a4c78 TAL submodule 2021-11-27 10:42:22 -05:00
Saurabh ba2f19ba37 mm2-fast-v2.22 init 2021-11-27 10:42:22 -05:00
Saurabh c7cdb758db init fast-contrib v2.22 2021-11-27 10:42:22 -05:00
Heng Li 7358a1ead1 Release minimap2-2.22 (r1101) 2021-08-07 11:30:31 -04:00
Heng Li 32f552957e Merge remote-tracking branch 'remotes/origin/master' 2021-08-07 10:40:02 -04:00
Ryan Lim 59488f0271 call mm_idx_destroy at the end of loop to fix memory leak 2021-07-26 18:25:08 -04:00
Jason Stajich 5cc3d2239f missing target object files from Makefile.simde to fix issue #779 2021-07-07 23:07:27 -04:00
23 changed files with 3381 additions and 31 deletions
+3
View File
@@ -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
+56 -3
View File
@@ -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
View File
@@ -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
+26 -1
View File
@@ -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)
+75 -2
View File
@@ -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.
[![GitHub Downloads](https://img.shields.io/github/downloads/lh3/minimap2/total.svg?style=social&logo=github&label=Download)](https://github.com/lh3/minimap2/releases) [![GitHub Downloads](https://img.shields.io/github/downloads/lh3/minimap2/total.svg?style=social&logo=github&label=Download)](https://github.com/lh3/minimap2/releases)
[![BioConda Install](https://img.shields.io/conda/dn/bioconda/minimap2.svg?style=flag&label=BioConda%20install)](https://anaconda.org/bioconda/minimap2) [![BioConda Install](https://img.shields.io/conda/dn/bioconda/minimap2.svg?style=flag&label=BioConda%20install)](https://anaconda.org/bioconda/minimap2)
[![PyPI](https://img.shields.io/pypi/v/mappy.svg?style=flat)](https://pypi.python.org/pypi/mappy) [![PyPI](https://img.shields.io/pypi/v/mappy.svg?style=flat)](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
+66
View File
@@ -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
View File
@@ -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
View File
@@ -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
+361
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+42
View File
@@ -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);
+191 -14
View File
@@ -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);
} }
+107 -3
View File
@@ -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;
} }
+30
View File
@@ -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]);
+20
View File
@@ -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
View File
@@ -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
View File
@@ -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 *****
+7 -1
View File
@@ -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;
+4
View File
@@ -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
View File
@@ -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()
+45
View File
@@ -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;
} }
+1 -1
View File
@@ -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(),