mirror of
https://github.com/lh3/minimap2.git
synced 2026-09-25 06:38:11 +08:00
Compare commits
24
Commits
dev
...
fast-contrib
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6e6811a0f | ||
|
|
b385748c40 | ||
|
|
7339801629 | ||
|
|
7fd30e15b8 | ||
|
|
4df2d259ee | ||
|
|
9cabb4a2b9 | ||
|
|
a5c14dd5f9 | ||
|
|
38075e82cc | ||
|
|
1ee40b0c32 | ||
|
|
b403cf3e6f | ||
|
|
84b1c201c8 | ||
|
|
f557d7fbd9 | ||
|
|
4bc645c31d | ||
|
|
609b430866 | ||
|
|
1c21888e94 | ||
|
|
34e273c8ee | ||
|
|
f68b4b22df | ||
|
|
e2e494de67 | ||
|
|
558be6b729 | ||
|
|
6da640e551 | ||
|
|
448341c96c | ||
|
|
a9ac74ffe1 | ||
|
|
b2ff8fbe92 | ||
|
|
0369874d4e |
@@ -1,3 +1,6 @@
|
||||
[submodule "lib/simde"]
|
||||
path = lib/simde
|
||||
url = https://github.com/nemequ/simde.git
|
||||
[submodule "ext/TAL"]
|
||||
path = ext/TAL
|
||||
url = https://github.com/IntelLabs/Trans-Omics-Acceleration-Library.git
|
||||
|
||||
@@ -1,14 +1,74 @@
|
||||
CFLAGS= -g -Wall -O2 -Wc++-compat #-Wextra
|
||||
CPPFLAGS= -DHAVE_KALLOC
|
||||
INCLUDES=
|
||||
|
||||
## /* 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>
|
||||
## */
|
||||
##
|
||||
CFLAGS= -Wall -O2 -Wc++-compat #-Wextra
|
||||
CPPFLAGS= -DHAVE_KALLOC -march=native
|
||||
|
||||
OPT_FLAGS= -DVECTORIZED_CHAINING -DALIGN_AVX
|
||||
|
||||
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= -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 chain.o align.o hit.o map.o format.o pe.o esterr.o splitidx.o ksw2_ll_sse.o
|
||||
PROG= minimap2
|
||||
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 ($(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
|
||||
OBJS+=ksw2_extz2_sse.o ksw2_extd2_sse.o ksw2_exts2_sse.o
|
||||
endif
|
||||
@@ -54,6 +114,17 @@ libminimap2.a:$(OBJS)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
ifeq ($(arm_neon),) # if arm_neon is defined, compile this target with the default setting (i.e. no -msse2)
|
||||
|
||||
@@ -1,3 +1,73 @@
|
||||
## 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 3.5x speedup 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** 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](https://en.wikipedia.org/wiki/AVX-512)
|
||||
Memory requirement: ~30GB for human genome
|
||||
|
||||
### Installation
|
||||
Clone the *fast-contrib* branch from minimap2 github page. The source code can be compiled by simple using *make* command. It only takes a few seconds.
|
||||
```
|
||||
git clone --recursive https://github.com/lh3/minimap2.git -b fast-contrib 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.18, the output of mm2-fast can be verified against minimap2-v2.18. Note that AVX512-based chaining in mm2-fast by default runs with a chaining parameter *max-skip=infinity* for higher chaining precision. Therefore, for correctness verification, minimap2 should run with a larger value of *max-skip* parameter. Follow the below steps to verify the accuracy of mm2-fast.
|
||||
```sh
|
||||
git clone https://github.com/lh3/minimap2.git -b v2.18
|
||||
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 show a clean-diff with the difference of 2 lines, i.e., the lines containing the command-line parameters for minimap2 and mm2-fast.
|
||||
|
||||
### Advanced options
|
||||
The default compilation using make applies two optimizations: AVX512 vectorized chaining and alignment, and 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 20-30 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
|
||||
```
|
||||
mm2-fast includes preliminary support for AVX2 architecture. Currently, chaining step is not optimized for AVX2 but the seeding and alignment steps are available. To try mm2-fast on AVX2 systems, use the following command to compile.
|
||||
```sh
|
||||
make clean && make lhash=1 use_avx2=1
|
||||
```
|
||||
### Performance
|
||||
We have observed up to 3.5x 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 80 seconds, while mm2-fast takes 38 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
|
||||
The current version of mm2-fast is based on minimap2-v2.18. We are planning to apply our optimizations to minimap2 master branch.
|
||||
### 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://anaconda.org/bioconda/minimap2)
|
||||
[](https://pypi.python.org/pypi/mappy)
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
/* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -5,7 +35,9 @@
|
||||
#include "minimap.h"
|
||||
#include "mmpriv.h"
|
||||
#include "ksw2.h"
|
||||
|
||||
#include "ksw2_extd2_avx.h"
|
||||
#include <x86intrin.h>
|
||||
extern uint64_t alignment_time;
|
||||
static void ksw_gen_simple_mat(int m, int8_t *mat, int8_t a, int8_t b, int8_t sc_ambi)
|
||||
{
|
||||
int i, j;
|
||||
@@ -312,6 +344,10 @@ static void mm_append_cigar(mm_reg1_t *r, uint32_t n_cigar, uint32_t *cigar) //
|
||||
|
||||
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);
|
||||
@@ -327,8 +363,18 @@ static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint
|
||||
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
|
||||
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__
|
||||
ksw_extd2_avx2(km, qlen, qseq, tlen, tseq, 5, mat, opt->q, opt->e, opt->q2, opt->e2, w, zdrop, end_bonus, flag, ez);
|
||||
#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);
|
||||
@@ -336,6 +382,9 @@ static void mm_align_pair(void *km, const mm_mapopt_t *opt, int qlen, const uint
|
||||
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
|
||||
}
|
||||
|
||||
static inline int mm_get_hplen_back(const mm_idx_t *mi, uint32_t rid, uint32_t x)
|
||||
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
ref_data=$1
|
||||
preset=$2
|
||||
|
||||
make clean && make no_opt=1
|
||||
touch temp_read.fastq
|
||||
./minimap2 -ax $2 $1 temp_read.fastq -Z 1 >/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
|
||||
@@ -1,3 +1,32 @@
|
||||
/* 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 <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -5,6 +34,10 @@
|
||||
#include "mmpriv.h"
|
||||
#include "kalloc.h"
|
||||
|
||||
#if defined(VECTORIZED_CHAINING) && defined(__AVX512BW__)
|
||||
#include "parallel_chaining_32_bit.h"
|
||||
#endif
|
||||
|
||||
static const char LogTable256[256] = {
|
||||
#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
|
||||
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
@@ -19,12 +52,13 @@ static inline int ilog2_32(uint32_t v)
|
||||
return (t = v>>8) ? 8 + LogTable256[t] : LogTable256[v];
|
||||
}
|
||||
|
||||
|
||||
mm128_t *mm_chain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int max_iter, int min_cnt, int min_sc, float gap_scale, int is_cdna, int n_segs, 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
|
||||
int32_t k, *f, *p, *t, *v, n_u, n_v;
|
||||
int64_t i, j, st = 0;
|
||||
uint64_t *u, *u2, sum_qspan = 0;
|
||||
float avg_qspan;
|
||||
int32_t k, *p, *t, *v, n_u, n_v;
|
||||
uint32_t *f;
|
||||
int64_t i, j;
|
||||
uint64_t *u, *u2;
|
||||
mm128_t *b, *w;
|
||||
|
||||
if (_u) *_u = 0, *n_u_ = 0;
|
||||
@@ -32,12 +66,40 @@ mm128_t *mm_chain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int m
|
||||
kfree(km, a);
|
||||
return 0;
|
||||
}
|
||||
f = (int32_t*)kmalloc(km, n * 4);
|
||||
f = (uint32_t*)kmalloc(km, n * 4);
|
||||
p = (int32_t*)kmalloc(km, n * 4);
|
||||
t = (int32_t*)kmalloc(km, n * 4);
|
||||
v = (int32_t*)kmalloc(km, n * 4);
|
||||
memset(t, 0, n * 4);
|
||||
#if defined(VECTORIZED_CHAINING) && defined(__AVX512BW__)
|
||||
/* Allocation for debugging
|
||||
f_avx = (uint32_t*)kmalloc(km, n * 4);
|
||||
p_avx = (int32_t*)kmalloc(km, n * 4);
|
||||
*/
|
||||
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, gap_scale, is_cdna, n_segs);
|
||||
obj.mm_dp_vectorized(n, &anchors[0], anchor_r, anchor_q, anchor_l, f, p, v, max_dist_x, max_dist_y, NULL, NULL);
|
||||
|
||||
// -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);
|
||||
#else
|
||||
int64_t st = 0;
|
||||
uint64_t sum_qspan = 0;
|
||||
float avg_qspan;
|
||||
for (i = 0; i < n; ++i) sum_qspan += a[i].y>>32&0xff;
|
||||
avg_qspan = (float)sum_qspan / n;
|
||||
|
||||
@@ -85,7 +147,46 @@ mm128_t *mm_chain_dp(int max_dist_x, int max_dist_y, int bw, int max_skip, int m
|
||||
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
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < n; ++i) {
|
||||
assert(f[i] == f_avx[i] && p[i] == p_avx[i]);
|
||||
|
||||
//if(! (f[i] == f_avx[i] && p[i] == p_avx[i]))
|
||||
{
|
||||
#if 0
|
||||
fprintf(stderr, "mm2-score:\n");
|
||||
for (int itt = 0; itt < n; ++itt) {
|
||||
fprintf(stderr, "%ld %ld \n", f[itt], p[itt]);
|
||||
}
|
||||
fprintf(stderr, "mm2-simd-score:\n");
|
||||
for (int itt = 0; itt < n; ++itt) {
|
||||
fprintf(stderr, "%ld %ld \n", f_avx[itt], p_avx[itt]);
|
||||
}
|
||||
fprintf(stderr, "anchors:\n");
|
||||
fprintf(stderr, "%lld\n", n);
|
||||
for (int itt = 0; itt < n; ++itt) {
|
||||
uint64_t ri = a[itt].x;
|
||||
int32_t qi = (int32_t)a[itt].y, q_span = a[itt].y>>32&0xff; // NB: only 8 bits of span is used!!!
|
||||
fprintf(stderr, "%llu %ld %ld\n", ri, qi, q_span);
|
||||
}
|
||||
//exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
#if 0
|
||||
fprintf(stderr, "%llu\n", n);
|
||||
for (int itt = 0; itt < n; ++itt) {
|
||||
uint64_t ri = a[itt].x;
|
||||
int32_t qi = (int32_t)a[itt].y, q_span = a[itt].y>>32&0xff; // NB: only 8 bits of span is used!!!
|
||||
fprintf(stderr, "%llu %ld %ld\n", ri, qi, q_span);
|
||||
}
|
||||
|
||||
#endif
|
||||
kfree(km, f_avx); kfree(km, p_avx);
|
||||
#endif
|
||||
#endif
|
||||
// find the ending positions of chains
|
||||
memset(t, 0, n * 4);
|
||||
for (i = 0; i < n; ++i)
|
||||
|
||||
Submodule
+1
Submodule ext/TAL added at 6f82aa4c6a
@@ -1,4 +1,37 @@
|
||||
/* 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 <stdlib.h>
|
||||
#include<map>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
using namespace std;
|
||||
#include <assert.h>
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#include <io.h> // for open(2)
|
||||
@@ -53,6 +86,37 @@ mm_idx_t *mm_idx_init(int w, int k, int b, int flag)
|
||||
return mi;
|
||||
}
|
||||
|
||||
|
||||
void mm_idx_destroy_mm_hash(mm_idx_t *mi)
|
||||
{
|
||||
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)
|
||||
{
|
||||
uint32_t i;
|
||||
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)
|
||||
{
|
||||
uint32_t i;
|
||||
@@ -97,6 +161,81 @@ const uint64_t *mm_idx_get(const mm_idx_t *mi, uint64_t minier, int *n)
|
||||
}
|
||||
}
|
||||
|
||||
//Output minimap2's hash table entries
|
||||
void mm_idx_dump_hash(const char* f_name, const mm_idx_t *mi)
|
||||
{
|
||||
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, "Storing hash to %s \n", f_name);
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void mm_idx_stat(const mm_idx_t *mi)
|
||||
{
|
||||
int n = 0, n1 = 0;
|
||||
|
||||
+1340
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);
|
||||
@@ -1,13 +1,54 @@
|
||||
/* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <errno.h>
|
||||
#include "bseq.h"
|
||||
#include "minimap.h"
|
||||
#include "mmpriv.h"
|
||||
#include "ketopt.h"
|
||||
#include <x86intrin.h>
|
||||
|
||||
#define MM_VERSION "2.18-r1015"
|
||||
using namespace std;
|
||||
|
||||
#ifdef MANUAL_PROFILING
|
||||
uint64_t num_reads = 0, minimizer_hit_time = 0, dp_chaining_time = 0, alignment_time = 0;
|
||||
#endif
|
||||
|
||||
#ifdef LISA_HASH
|
||||
#include "lisa_hash.h"
|
||||
lisa_hash<uint64_t, uint64_t> *lh;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/resource.h>
|
||||
@@ -108,11 +149,39 @@ static inline void yes_or_no(mm_mapopt_t *opt, int flag, int long_idx, const cha
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
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:";
|
||||
#ifdef LISA_HASH
|
||||
#if VECTORIZE && __AVX512BW__
|
||||
fprintf(stderr, "Using LISA hash with AVX512-vectorized last-mile search.\n");
|
||||
#else
|
||||
fprintf(stderr, "Using LISA hash with sequential last-mile search.\n");
|
||||
#endif
|
||||
#else
|
||||
fprintf(stderr, "Using default hash lookup.\n");
|
||||
#endif
|
||||
|
||||
#if defined(VECTORIZED_CHAINING) && defined(__AVX512BW__)
|
||||
fprintf(stderr, "Using AVX512-vectorized chaining.\n");
|
||||
#else
|
||||
fprintf(stderr, "Using default chaining.\n");
|
||||
#endif
|
||||
|
||||
|
||||
#if defined (ALIGN_AVX) && (defined(__AVX512BW__) || (defined(__AVX2__) && defined(APPLY_AVX2)))
|
||||
#ifdef __AVX512BW__
|
||||
fprintf(stderr, "Using AVX512-vectorized alignment.\n");
|
||||
#elif __AVX2__
|
||||
fprintf(stderr, "Using AVX2-vectorized alignment.\n");
|
||||
#endif
|
||||
#else
|
||||
fprintf(stderr, "Using default SSE-vectorized alignment.\n");
|
||||
#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:Z:";
|
||||
ketopt_t o = KETOPT_INIT;
|
||||
mm_mapopt_t opt;
|
||||
mm_idxopt_t ipt;
|
||||
int i, c, n_threads = 3, n_parts, old_best_n = -1;
|
||||
uint64_t total_time = 0;
|
||||
char *fnw = 0, *rg = 0, *junc_bed = 0, *s, *alt_list = 0;
|
||||
FILE *fp_help = stderr;
|
||||
mm_idx_reader_t *idx_rdr;
|
||||
@@ -121,10 +190,13 @@ int main(int argc, char *argv[])
|
||||
mm_verbose = 3;
|
||||
liftrlimit();
|
||||
mm_realtime0 = realtime();
|
||||
double mapping_time = realtime();
|
||||
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
|
||||
if (c == 'x') {
|
||||
preset_arg += (string) o.arg;
|
||||
if (mm_set_opt(o.arg, &ipt, &opt) < 0) {
|
||||
fprintf(stderr, "[ERROR] unknown preset '%s'\n", o.arg);
|
||||
return 1;
|
||||
@@ -141,6 +213,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
while ((c = ketopt(&o, argc, argv, 1, opt_str, long_options)) >= 0) {
|
||||
if (c == 'w') ipt.w = atoi(o.arg);
|
||||
else if (c == 'Z') opt.L_hash = atoi(o.arg);
|
||||
else if (c == 'k') ipt.k = atoi(o.arg);
|
||||
else if (c == 'H') ipt.flag |= MM_I_HPC;
|
||||
else if (c == 'd') fnw = o.arg; // the above are indexing related options, except -I
|
||||
@@ -345,7 +418,12 @@ int main(int argc, char *argv[])
|
||||
fprintf(stderr, "[ERROR] incorrect input: in the sr mode, please specify no more than two query files.\n");
|
||||
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);
|
||||
total_time = __rdtsc();
|
||||
if (idx_rdr == 0) {
|
||||
fprintf(stderr, "[ERROR] failed to open file '%s': %s\n", argv[o.ind], strerror(errno));
|
||||
return 1;
|
||||
@@ -387,9 +465,25 @@ int main(int argc, char *argv[])
|
||||
__func__, realtime() - mm_realtime0, cputime() / (realtime() - mm_realtime0), mi->n_seq);
|
||||
if (argc != o.ind + 1) mm_mapopt_update(&opt, mi);
|
||||
if (mm_verbose >= 3) mm_idx_stat(mi);
|
||||
if(opt.L_hash == 1) {
|
||||
fprintf(stderr, "Generating lisa-hash..\n");
|
||||
mm_idx_dump_hash(preset_arg.c_str(), mi);
|
||||
fprintf(stderr, "Lisa-hash saving done.. \n");
|
||||
exit(0);
|
||||
}
|
||||
if (junc_bed) mm_idx_bed_read(mi, junc_bed, 1);
|
||||
if (alt_list) mm_idx_alt_read(mi, alt_list);
|
||||
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
|
||||
mapping_time = realtime();
|
||||
if (!(opt.flag & MM_F_FRAG_MODE)) {
|
||||
for (i = o.ind + 1; i < argc; ++i) {
|
||||
ret = mm_map_file(mi, argv[i], &opt, n_threads);
|
||||
@@ -398,11 +492,15 @@ int main(int argc, char *argv[])
|
||||
} else {
|
||||
ret = mm_map_file_frag(mi, argc - (o.ind + 1), (const char**)&argv[o.ind + 1], &opt, n_threads);
|
||||
}
|
||||
mm_idx_destroy(mi);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "ERROR: failed to map the query file\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#ifdef LISA_HASH
|
||||
mm_idx_destroy_seq(mi);
|
||||
#else
|
||||
mm_idx_destroy(mi);
|
||||
#endif
|
||||
}
|
||||
n_parts = idx_rdr->n_parts;
|
||||
mm_idx_reader_close(idx_rdr);
|
||||
@@ -422,5 +520,14 @@ int main(int argc, char *argv[])
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
|
||||
#ifdef MANUAL_PROFILING
|
||||
fprintf(stderr, "\n Number of reads = %lld Minimizer hit time = %lld dp_chaining time = %lld alignment time = %lld total time = %lld \n", num_reads, minimizer_hit_time, dp_chaining_time, alignment_time, __rdtsc() - total_time);
|
||||
#endif
|
||||
fprintf(stderr, "Total ticks: %lld \n",__rdtsc() - total_time);
|
||||
fprintf(stderr, "\nMapping Real time: %.3f sec;\n", realtime() - mapping_time);
|
||||
#ifdef LISA_HASH
|
||||
delete lh;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
/* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@@ -9,6 +38,17 @@
|
||||
#include "mmpriv.h"
|
||||
#include "bseq.h"
|
||||
#include "khash.h"
|
||||
#include <x86intrin.h>
|
||||
|
||||
#ifdef LISA_HASH
|
||||
#include "lisa_hash.h"
|
||||
extern lisa_hash<uint64_t, uint64_t> *lh;
|
||||
#endif
|
||||
|
||||
#ifdef MANUAL_PROFILING
|
||||
extern uint64_t num_reads, minimizer_hit_time, dp_chaining_time, alignment_time;
|
||||
#endif
|
||||
|
||||
|
||||
struct mm_tbuf_s {
|
||||
void *km;
|
||||
@@ -87,6 +127,77 @@ typedef struct {
|
||||
const uint64_t *cr;
|
||||
} mm_match_t;
|
||||
|
||||
|
||||
#ifdef LISA_HASH
|
||||
static mm_match_t *collect_matches_lisa_hash(void *km, int *_n_m, int max_occ, const mm_idx_t *mi, const mm128_v *mv, int64_t *n_a, int *rep_len, int *n_mini_pos, uint64_t **mini_pos)
|
||||
{
|
||||
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));
|
||||
|
||||
int rep_st = 0, rep_en = 0, n_m;
|
||||
size_t i;
|
||||
mm_match_t *m;
|
||||
*n_mini_pos = 0;
|
||||
*mini_pos = (uint64_t*)kmalloc(km, mv->n * sizeof(uint64_t));
|
||||
m = (mm_match_t*)kmalloc(km, mv->n * sizeof(mm_match_t));
|
||||
|
||||
for (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);
|
||||
for (i = 0, n_m = 0, *rep_len = 0, *n_a = 0; i < mv->n; ++i) {
|
||||
const uint64_t *cr;
|
||||
mm128_t *p = &mv->a[i];
|
||||
uint32_t q_pos = (uint32_t)p->y, q_span = p->x & 0xff;
|
||||
int t;
|
||||
cr = cr_batch[i]; t = t_batch[i];
|
||||
/*Correctness check for lisa_hash*/
|
||||
#ifdef LISA_HASH_ASSERT
|
||||
int t_minimap2_original;
|
||||
const uint64_t *cr_minimap2_hash = mm_idx_get(mi, p->x>>8, &t);
|
||||
cr_minimap2_hash = mm_idx_get(mi, p->x>>8, &t_minimap2_original);
|
||||
assert(t == t_minimap2_original);
|
||||
#endif
|
||||
if (t >= max_occ) {
|
||||
|
||||
int en = (q_pos >> 1) + 1, st = en - q_span;
|
||||
if (st > rep_en) {
|
||||
*rep_len += rep_en - rep_st;
|
||||
rep_st = st, rep_en = en;
|
||||
} else rep_en = en;
|
||||
} else {
|
||||
#ifdef LISA_HASH_ASSERT
|
||||
//Correctness assertion
|
||||
for(int itr = 0; itr < t; itr++){
|
||||
assert((cr[itr] == cr_minimap2_hash[itr]));
|
||||
}
|
||||
#endif
|
||||
mm_match_t *q = &m[n_m++];
|
||||
q->q_pos = q_pos, q->q_span = q_span, q->cr = cr, q->n = t, q->seg_id = p->y >> 32;
|
||||
q->is_tandem = 0;
|
||||
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;
|
||||
*n_a += q->n;
|
||||
(*mini_pos)[(*n_mini_pos)++] = (uint64_t)q_span<<32 | q_pos>>1;
|
||||
}
|
||||
}
|
||||
|
||||
free(cr_batch);
|
||||
free(t_batch);
|
||||
free(minimizers);
|
||||
free(lisa_pos);
|
||||
|
||||
*rep_len += rep_en - rep_st;
|
||||
*_n_m = n_m;
|
||||
return m;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static mm_match_t *collect_matches(void *km, int *_n_m, int max_occ, const mm_idx_t *mi, const mm128_v *mv, int64_t *n_a, int *rep_len, int *n_mini_pos, uint64_t **mini_pos)
|
||||
{
|
||||
int rep_st = 0, rep_en = 0, n_m;
|
||||
@@ -146,6 +257,49 @@ static inline int skip_seed(int flag, uint64_t r, const mm_match_t *q, const cha
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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 i, n_m;
|
||||
mm_match_t *m;
|
||||
mm128_t *a;
|
||||
#ifndef LISA_HASH
|
||||
m = collect_matches(km, &n_m, max_occ, mi, mv, n_a, rep_len, n_mini_pos, mini_pos);
|
||||
#else
|
||||
m = collect_matches_lisa_hash(km, &n_m, max_occ, mi, mv, n_a, rep_len, n_mini_pos, mini_pos);
|
||||
#endif
|
||||
|
||||
a = (mm128_t*)kmalloc(km, *n_a * sizeof(mm128_t));
|
||||
for (i = 0, *n_a = 0; i < n_m; ++i) {
|
||||
|
||||
mm_match_t *q = &m[i];
|
||||
const uint64_t *r = q->cr;
|
||||
uint32_t k;
|
||||
for (k = 0; k < q->n; ++k) {
|
||||
uint64_t r_k = r[k];
|
||||
int32_t is_self, rpos = (uint32_t)r_k >> 1;
|
||||
mm128_t *p;
|
||||
if (skip_seed(opt->flag, r_k, q, qname, qlen, mi, &is_self)) continue;
|
||||
p = &a[(*n_a)++];
|
||||
if ((r_k&1) == (q->q_pos&1)) { // forward strand
|
||||
p->x = (r_k & 0xffffffff00000000ULL) | rpos;
|
||||
p->y = (uint64_t)q->q_span << 32 | q->q_pos >> 1;
|
||||
} else { // reverse strand
|
||||
p->x = 1ULL<<63 | (r_k & 0xffffffff00000000ULL) | rpos;
|
||||
p->y = (uint64_t)q->q_span << 32 | (qlen - ((q->q_pos>>1) + 1 - q->q_span) - 1);
|
||||
}
|
||||
p->y |= (uint64_t)q->seg_id << MM_SEED_SEG_SHIFT;
|
||||
if (q->is_tandem) p->y |= MM_SEED_TANDEM;
|
||||
if (is_self) p->y |= MM_SEED_SELF;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(km, m);
|
||||
radix_sort_128x(a, a + (*n_a));
|
||||
return a;
|
||||
}
|
||||
|
||||
static mm128_t *collect_seed_hits_heap(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)
|
||||
{
|
||||
@@ -212,40 +366,6 @@ static mm128_t *collect_seed_hits_heap(void *km, const mm_mapopt_t *opt, int max
|
||||
return a;
|
||||
}
|
||||
|
||||
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 i, n_m;
|
||||
mm_match_t *m;
|
||||
mm128_t *a;
|
||||
m = collect_matches(km, &n_m, max_occ, mi, mv, n_a, rep_len, n_mini_pos, mini_pos);
|
||||
a = (mm128_t*)kmalloc(km, *n_a * sizeof(mm128_t));
|
||||
for (i = 0, *n_a = 0; i < n_m; ++i) {
|
||||
mm_match_t *q = &m[i];
|
||||
const uint64_t *r = q->cr;
|
||||
uint32_t k;
|
||||
for (k = 0; k < q->n; ++k) {
|
||||
int32_t is_self, rpos = (uint32_t)r[k] >> 1;
|
||||
mm128_t *p;
|
||||
if (skip_seed(opt->flag, r[k], q, qname, qlen, mi, &is_self)) continue;
|
||||
p = &a[(*n_a)++];
|
||||
if ((r[k]&1) == (q->q_pos&1)) { // forward strand
|
||||
p->x = (r[k]&0xffffffff00000000ULL) | rpos;
|
||||
p->y = (uint64_t)q->q_span << 32 | q->q_pos >> 1;
|
||||
} else { // reverse strand
|
||||
p->x = 1ULL<<63 | (r[k]&0xffffffff00000000ULL) | rpos;
|
||||
p->y = (uint64_t)q->q_span << 32 | (qlen - ((q->q_pos>>1) + 1 - q->q_span) - 1);
|
||||
}
|
||||
p->y |= (uint64_t)q->seg_id << MM_SEED_SEG_SHIFT;
|
||||
if (q->is_tandem) p->y |= MM_SEED_TANDEM;
|
||||
if (is_self) p->y |= MM_SEED_SELF;
|
||||
}
|
||||
}
|
||||
kfree(km, m);
|
||||
radix_sort_128x(a, a + (*n_a));
|
||||
return a;
|
||||
}
|
||||
|
||||
static void chain_post(const mm_mapopt_t *opt, int max_chain_gap_ref, const mm_idx_t *mi, void *km, int qlen, int n_segs, const int *qlens, int *n_regs, mm_reg1_t *regs, mm128_t *a)
|
||||
{
|
||||
if (!(opt->flag & MM_F_ALL_CHAINS)) { // don't choose primary mapping(s)
|
||||
@@ -271,6 +391,11 @@ static mm_reg1_t *align_regs(const mm_mapopt_t *opt, const mm_idx_t *mi, void *k
|
||||
|
||||
void mm_map_frag(const mm_idx_t *mi, int n_segs, const int *qlens, const char **seqs, int *n_regs, mm_reg1_t **regs, mm_tbuf_t *b, const mm_mapopt_t *opt, const char *qname)
|
||||
{
|
||||
|
||||
#ifdef MANUAL_PROFILING
|
||||
num_reads++;
|
||||
#endif
|
||||
|
||||
int i, j, rep_len, qlen_sum, n_regs0, n_mini_pos;
|
||||
int max_chain_gap_qry, max_chain_gap_ref, is_splice = !!(opt->flag & MM_F_SPLICE), is_sr = !!(opt->flag & MM_F_SR);
|
||||
uint32_t hash;
|
||||
@@ -293,8 +418,18 @@ void mm_map_frag(const mm_idx_t *mi, int n_segs, const int *qlens, const char **
|
||||
|
||||
collect_minimizers(b->km, opt, mi, n_segs, qlens, seqs, &mv);
|
||||
if (opt->flag & MM_F_HEAP_SORT) a = collect_seed_hits_heap(b->km, opt, opt->mid_occ, mi, qname, &mv, qlen_sum, &n_a, &rep_len, &n_mini_pos, &mini_pos);
|
||||
else a = collect_seed_hits(b->km, opt, opt->mid_occ, mi, qname, &mv, qlen_sum, &n_a, &rep_len, &n_mini_pos, &mini_pos);
|
||||
else {
|
||||
|
||||
#ifdef MANUAL_PROFILING
|
||||
uint64_t mm_hit_start = __rdtsc();
|
||||
#endif
|
||||
|
||||
a = collect_seed_hits(b->km, opt, opt->mid_occ, mi, qname, &mv, qlen_sum, &n_a, &rep_len, &n_mini_pos, &mini_pos);
|
||||
|
||||
#ifdef MANUAL_PROFILING
|
||||
minimizer_hit_time += (__rdtsc() - mm_hit_start);
|
||||
#endif
|
||||
}
|
||||
if (mm_dbg_flag & MM_DBG_PRINT_SEED) {
|
||||
fprintf(stderr, "RS\t%d\n", rep_len);
|
||||
for (i = 0; i < n_a; ++i)
|
||||
@@ -312,9 +447,16 @@ void mm_map_frag(const mm_idx_t *mi, int n_segs, const int *qlens, const char **
|
||||
max_chain_gap_ref = opt->max_frag_len - qlen_sum;
|
||||
if (max_chain_gap_ref < opt->max_gap) max_chain_gap_ref = opt->max_gap;
|
||||
} else max_chain_gap_ref = opt->max_gap;
|
||||
|
||||
#ifdef MANUAL_PROFILING
|
||||
uint64_t dp_start = __rdtsc();
|
||||
#endif
|
||||
a = mm_chain_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, is_splice, n_segs, n_a, a, &n_regs0, &u, b->km);
|
||||
|
||||
|
||||
#ifdef MANUAL_PROFILING
|
||||
dp_chaining_time += (__rdtsc() - dp_start);
|
||||
#endif
|
||||
|
||||
if (opt->max_occ > opt->mid_occ && rep_len > 0) {
|
||||
int rechain = 0;
|
||||
if (n_regs0 > 0) { // test if the best chain has all the segments
|
||||
@@ -335,6 +477,7 @@ void mm_map_frag(const mm_idx_t *mi, int n_segs, const int *qlens, const char **
|
||||
kfree(b->km, mini_pos);
|
||||
if (opt->flag & MM_F_HEAP_SORT) a = collect_seed_hits_heap(b->km, opt, opt->max_occ, mi, qname, &mv, qlen_sum, &n_a, &rep_len, &n_mini_pos, &mini_pos);
|
||||
else a = collect_seed_hits(b->km, opt, opt->max_occ, mi, qname, &mv, qlen_sum, &n_a, &rep_len, &n_mini_pos, &mini_pos);
|
||||
|
||||
a = mm_chain_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, is_splice, n_segs, n_a, a, &n_regs0, &u, b->km);
|
||||
}
|
||||
}
|
||||
@@ -430,6 +573,7 @@ static void worker_for(void *_data, long i, int tid) // kt_for() callback
|
||||
int qlens[MM_MAX_SEG], j, off = s->seg_off[i], pe_ori = s->p->opt->pe_ori;
|
||||
const char *qseqs[MM_MAX_SEG];
|
||||
mm_tbuf_t *b = s->buf[tid];
|
||||
|
||||
assert(s->n_seg[i] <= MM_MAX_SEG);
|
||||
if (mm_dbg_flag & MM_DBG_PRINT_QNAME)
|
||||
fprintf(stderr, "QR\t%s\t%d\t%d\n", s->seq[off].name, tid, s->seq[off].l_seq);
|
||||
@@ -561,6 +705,7 @@ static void *worker_pipeline(void *shared, int step, void *in)
|
||||
else kt_for(p->n_threads, worker_for, in, ((step_t*)in)->n_frag);
|
||||
return in;
|
||||
} else if (step == 2) { // step 2: output
|
||||
|
||||
void *km = 0;
|
||||
step_t *s = (step_t*)in;
|
||||
const mm_idx_t *mi = p->mi;
|
||||
@@ -569,6 +714,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();
|
||||
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];
|
||||
#ifndef DISABLE_OUTPUT
|
||||
for (i = seg_st; i < seg_en; ++i) {
|
||||
mm_bseq1_t *t = &s->seq[i];
|
||||
if (p->opt->split_prefix && p->n_parts == 0) { // then write to temporary files
|
||||
@@ -603,6 +749,7 @@ static void *worker_pipeline(void *shared, int step, void *in)
|
||||
mm_err_puts(p->str.s);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (i = seg_st; i < seg_en; ++i) {
|
||||
for (j = 0; j < s->n_reg[i]; ++j) free(s->reg[i][j].p);
|
||||
free(s->reg[i]);
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
/* 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>
|
||||
*/
|
||||
#ifndef MINIMAP2_H
|
||||
#define MINIMAP2_H
|
||||
|
||||
@@ -153,6 +182,8 @@ typedef struct {
|
||||
int64_t max_sw_mat;
|
||||
|
||||
const char *split_prefix;
|
||||
// Store minimizer hash to a file as key and list of values
|
||||
int L_hash;
|
||||
} mm_mapopt_t;
|
||||
|
||||
// index reader
|
||||
@@ -267,6 +298,14 @@ mm_idx_t *mm_idx_load(FILE *fp);
|
||||
*/
|
||||
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
|
||||
*
|
||||
@@ -296,6 +335,21 @@ void mm_idx_stat(const mm_idx_t *idx);
|
||||
*/
|
||||
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
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user