52 template <u
int32 ALN_IDX,
typename AlignerType,
typename PipelineType>
76 const PipelineType _pipeline,
77 const AlignerType _aligner,
117 context->mate = alignment.
mate();
118 context->read_rc = alignment.
is_rc();
119 context->read_id = context->idx;
120 context->read_range =
base_type::m_pipeline.get_reads( context->mate ).get_range( context->read_id );
122 const uint32 read_len = context->read_range.y - context->read_range.x;
126 const uint32 g_pos = paired_opposite_alignment ?
129 const uint32 g_len = paired_opposite_alignment ?
133 context->genome_begin = g_pos;
145 const uint32 cigar_len = context->backtracer.size;
155 for (
uint32 i = 0; i < cigar_len; ++i)
156 cigar[i] = context->cigar[i];
160 base_type::m_pipeline.cigar_coords[ context->read_id ] = make_uint2( context->alignment.source.x + (context->alignment.source.y << 16), context->backtracer.size );
161 NVBIO_CUDA_DEBUG_PRINT_IF(
base_type::m_params.debug.show_traceback( context->read_id ),
"BestTracebackStream<%u>:\n mate[%u], cigar-coords[%u:%u,%u]\n", ALN_IDX, context->mate, context->alignment.source.x, context->alignment.source.y, context->backtracer.size );
164 NVBIO_CUDA_DEBUG_CHECK_IF(
base_type::m_params.debug.show_traceback( context->read_id ), context->alignment.score == context->min_score,
"\nerror:\n %s backtrack(): score %d different from previously calculated value %d!\n read[%u], rc[%u], mate[%u]\n",
mate_string(
m_mate_type ), context->alignment.score, context->min_score, context->read_id, context->read_rc, context->mate );
166 NVBIO_CUDA_ASSERT_IF(
base_type::m_params.debug.asserts, context->alignment.score == context->min_score,
"%s backtrack(): score %d different from previously calculated value %d!\n read[%u], rc[%u], mate[%u]\n",
mate_string(
m_mate_type ), context->alignment.score, context->min_score, context->read_id, context->read_rc, context->mate );
169 read_cigar_length( cigar, context->backtracer.size ) == context->read_range.y - context->read_range.x,
170 "%s backtrack(): CIGAR length != read length\n read[%u]\n cigar len: %u\n read len: %u\n source: (%u, %u)\n sink: (%u, %u)\n",
mate_string(
m_mate_type ),
171 context->read_id,
read_cigar_length( cigar, context->backtracer.size ), context->read_range.y - context->read_range.x, context->alignment.source.x, context->alignment.source.y, context->alignment.sink.x, context->alignment.sink.y );
185 aln.
m_align = context->genome_begin;
188 aln.
m_score = score < 0 ? -score : score;
190 NVBIO_CUDA_DEBUG_PRINT_IF(
base_type::m_params.debug.show_traceback( context->read_id ),
"BestTracebackStream<%u>:\n mate[%u], ed[%u], score[%d], pos[%u], rc[%u]\n", ALN_IDX, aln.
mate(), aln.
ed(), aln.
score(), aln.
alignment(),
uint32( aln.
is_rc() ));
204 template <u
int32 ALN_IDX,
typename aligner_type,
typename pipeline_type>
212 const pipeline_type& pipeline,
213 const aligner_type aligner,
216 const uint32 static_band_len =
217 (band_len < 4) ? 3u :
218 (band_len < 8) ? 7u :
219 (band_len < 16) ? 15u :
241 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
243 else if (band_len < 8)
247 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
249 else if (band_len < 16)
253 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
259 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
266 template <u
int32 ALN_IDX,
typename aligner_type,
typename pipeline_type>
273 const pipeline_type& pipeline,
274 const aligner_type aligner,
294 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
302 template <
typename AlignerType,
typename PipelineType>
322 const uint32 _buffer_offset,
323 const uint32 _buffer_size,
326 const PipelineType _pipeline,
327 const AlignerType _aligner,
329 base_type( _pipeline, _aligner, _params ),
371 context->mate = alignment.
mate();
372 context->read_rc = alignment.
is_rc();
374 context->read_range =
base_type::m_pipeline.get_reads( context->mate ).get_range( context->read_id );
376 const uint32 read_len = context->read_range.y - context->read_range.x;
382 context->genome_begin = g_pos;
394 const uint32 cigar_len = context->backtracer.size;
400 NVBIO_CUDA_ASSERT_IF(
base_type::m_params.debug.asserts, cigar != NULL,
"%s backtrack(): unable to allocate CIGAR!\n aln[%u], read[%u], mate[%u], cigar: %u!\n",
mate_string(
m_mate_type ), context->idx, context->read_id, context->mate, cigar_len );
404 for (
uint32 i = 0; i < cigar_len; ++i)
405 cigar[i] = context->cigar[i];
409 base_type::m_pipeline.cigar_coords[ context->idx ] = make_uint2( context->alignment.source.x + (context->alignment.source.y << 16), context->backtracer.size );
410 NVBIO_CUDA_DEBUG_PRINT_IF(
base_type::m_params.debug.show_traceback( context->read_id ),
"AllTracebackStream:\n mate[%u], cigar-coords[%u:%u,%u]\n", context->mate, context->alignment.source.x, context->alignment.source.y, context->backtracer.size );
412 NVBIO_CUDA_DEBUG_CHECK_IF(
base_type::m_params.debug.show_traceback( context->read_id ), context->alignment.sink.x !=
uint32(-1) && context->alignment.sink.y !=
uint32(-1),
"\nerror:\n backtrack(): failed to re-align!\n read[%u], rc[%u], mate[%u] (expected score: %d)\n", context->read_id, context->read_rc, context->mate, context->min_score );
413 NVBIO_CUDA_DEBUG_CHECK_IF(
base_type::m_params.debug.show_traceback( context->read_id ), context->alignment.score == context->min_score,
"\nerror:\n backtrack(): score %d different from previously calculated value %d!\n read[%u], rc[%u], mate[%u]\n", context->alignment.score, context->min_score, context->read_id, context->read_rc, context->mate );
414 NVBIO_CUDA_ASSERT_IF(
base_type::m_params.debug.asserts, context->alignment.sink.x !=
uint32(-1) && context->alignment.sink.y !=
uint32(-1),
"backtrack(): failed to re-align!\n read[%u], rc[%u], mate[%u] (expected score: %d)\n", context->read_id, context->read_rc, context->mate, context->min_score );
415 NVBIO_CUDA_ASSERT_IF(
base_type::m_params.debug.asserts, context->alignment.score == context->min_score,
"backtrack(): score %d different from previously calculated value %d!\n read[%u], rc[%u], mate[%u]\n", context->alignment.score, context->min_score, context->read_id, context->read_rc, context->mate );
418 read_cigar_length( cigar, context->backtracer.size ) == context->read_range.y - context->read_range.x,
419 "backtrack(): CIGAR length != read length\n read[%u]\n cigar len: %u\n read len: %u\n source: (%u, %u)\n sink: (%u, %u)\n",
420 context->read_id,
read_cigar_length( cigar, context->backtracer.size ), context->read_range.y - context->read_range.x, context->alignment.source.x, context->alignment.source.y, context->alignment.sink.x, context->alignment.sink.y );
438 context->genome_begin,
441 in_alignment.
is_rc(),
445 NVBIO_CUDA_DEBUG_PRINT_IF(
base_type::m_params.debug.show_traceback( context->read_id ),
"finish-alignment:\n mate[%u], ed[%u], score[%d], pos[%u], rc[%u]\n", context->mate, out_alignment.
ed(), out_alignment.
score(), out_alignment.
alignment(),
uint32( out_alignment.
is_rc() ));
460 template <
typename aligner_type,
typename pipeline_type>
464 const uint32 buffer_offset,
468 const pipeline_type& pipeline,
469 const aligner_type aligner,
472 const uint32 static_band_len =
473 (band_len < 4) ? 3u :
474 (band_len < 8) ? 7u :
475 (band_len < 16) ? 15u :
497 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
499 else if (band_len < 8)
503 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
505 else if (band_len < 16)
509 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
515 batch.
enact( stream, pipeline.dp_buffer_size, pipeline.dp_buffer );
523 template <
typename stream_type,
typename scheme_type,
typename pipeline_type> __global__
526 pipeline_type pipeline,
527 const scheme_type scoring_scheme,
531 if (work_id >= stream.size())
return;
533 typedef typename stream_type::aligner_type aligner_type;
534 typedef typename stream_type::context_type context_type;
535 typedef typename stream_type::strings_type strings_type;
538 context_type context;
539 if (stream.init_context( work_id, &context ) ==
false)
543 const uint32 read_len = stream.pattern_length( work_id, &context );
546 strings_type strings;
547 stream.load_strings( work_id, 0, read_len, &context, &strings );
549 const uint2 cigar_coord = pipeline.cigar_coords[ context.idx ];
550 const uint32 cigar_offset = cigar_coord.x & 0xFFFF;
551 const uint32 cigar_length = cigar_coord.y;
558 const io::Cigar* cigar_vector = pipeline.cigar[ context.idx ];
561 if (cigar_vector == NULL)
572 const uint32 MDS_LMEM = 2048;
573 uint8 mds_local[MDS_LMEM];
582 const uint32 g_len = strings.text.length();
584 for (
uint32 i = 0, j = 0, k = cigar_offset; i < cigar_length; ++i)
586 const uint32 l = cigar_vector[ cigar_length - i - 1u ].
m_len;
587 const uint32 t = cigar_vector[ cigar_length - i - 1u ].
m_type;
589 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, (t == io::Cigar::SUBSTITUTION) || (t == io::Cigar::DELETION) || (t == io::Cigar::INSERTION) || (t == io::Cigar::SOFT_CLIPPING),
"finish_alignment(%s): unknown op!\n read[%u], mate[%u], op[%u]: %u\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, context.mate, i, t );
591 const uint8 t_mask = 1u << t;
594 if (t_mask & (INS_MASK | DEL_MASK | CLP_MASK))
597 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, mds_len+2 < MDS_LMEM,
"finish_alignment(%s): exceeded MDS length!\n read[%u], mate[%u], mds: %u!\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, context.mate, mds_len+2 );
599 mds_local[ mds_len++ ] = mds_op;
600 mds_local[ mds_len++ ] = l;
603 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, l,
"finish_alignment(%s): zero-length MDS[%u:%u] (%c)\n", context.read_id, mds_len-1, t_mask & DEL_MASK ?
'D' :
'I', l);
606 for (
uint32 n = 0; n < l; ++n)
609 j += (t_mask & (SUB_MASK | INS_MASK | CLP_MASK)) ? 1u : 0u;
610 k += (t_mask & (SUB_MASK | DEL_MASK)) ? 1u : 0u;
611 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, (j <= read_len) && (k <= g_len),
"finish_alignment(%s): coordinates out-of-bounds!\n read[%u], mate[%u], (%u,%u) > (%u,%u) @ %u\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, context.mate, j, k, read_len, g_len, context.genome_begin );
612 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, (t_mask & (SUB_MASK | INS_MASK | CLP_MASK)) ? (j > 0) :
true,
"finish_alignment(%s): accessed read at -1!\n read[%u], mate[%u]\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, context.mate );
613 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, (t_mask & (SUB_MASK | DEL_MASK)) ? (k > 0) :
true,
"finish_alignment(%s): accessed genome at -1!\n read[%u], mate[%u]\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, context.mate );
615 const uint8 readc = j > 0 ? strings.pattern[j-1] : 255u;
616 const uint8 refc = k > 0 ? strings.text[k-1] : 255u;
618 if (t_mask == SUB_MASK)
622 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, mds_len < MDS_LMEM,
"finish_alignment(%s): exceeded MDS length!\n read[%u], mds: %u!\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, mds_len+2 );
625 if (mds_op ==
io::MDS_MATCH && (mds_local[ mds_len-1 ] < 255))
628 mds_local[ mds_len-1 ]++;
634 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, mds_len+2 < MDS_LMEM,
"finish_alignment(%s): exceeded MDS length!\n read[%u], mds: %u!\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, mds_len+2 );
636 mds_local[ mds_len++ ] = 1;
643 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, mds_len+2 < MDS_LMEM,
"finish_alignment(%s): exceeded MDS length!\n read[%u], mds: %u!\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, mds_len+2 );
645 mds_local[ mds_len++ ] = readc;
653 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, mds_len+1 < MDS_LMEM,
"finish_alignment(%s): exceeded MDS length!\n read[%u], mds: %u!\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.read_id, mds_len+1 );
654 mds_local[ mds_len++ ] = t_mask & DEL_MASK ? refc : readc;
656 if (t_mask != CLP_MASK)
662 if (t_mask == SUB_MASK)
665 const uint8 q = strings.quals[j-1];
666 const int32 delta = scoring_scheme.score( readc, 1u << refc, q );
677 #if defined(NVBIO_CUDA_DEBUG)
688 for (
uint32 i = 0; i < read_len; ++i)
689 mm_string[i] =
'0' -
int32( scoring_scheme.mismatch( strings.quals[i] ) );
690 mm_string[read_len] =
'\0';
693 for (
uint32 i = 0; i < cigar_coord.y; ++i)
695 const uint32 l = cigar_vector[ cigar_coord.y - i - 1u ].
m_len;
696 const uint32 t = cigar_vector[ cigar_coord.y - i - 1u ].
m_type;
697 for (
uint32 n = 0; n < l; ++n)
698 cigar_str[j++] =
"MID"[t];
701 NVBIO_CUDA_DEBUG_PRINT(
"\nfinish_alignment:\n score: %d, %d, ed: %u, (genome offset: %u)\n read : %s\n genome: %s\n quals : %s\n cigar : %s\n mds len: %u\n", alignment.score(), score, ed, cigar_offset, read_str, gen_str, mm_string, cigar_str, mds_len);
707 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, mds_len < 65536,
"finish_alignment(%s): exceeded representable MDS length!\n aln[%u], read[%u], mate[%u], mds: %u!\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.idx, context.read_id, context.mate, mds_len );
708 mds_local[0] =
uint8( mds_len & 0xFF );
709 mds_local[1] =
uint8( mds_len >> 8 );
712 uint8* mds_vector = pipeline.mds.alloc( context.idx, mds_len );
713 NVBIO_CUDA_ASSERT_IF( params.
debug.
asserts, mds_vector != NULL,
"finish_alignment(%s): unable to allocate MDS!\n aln[%u], read[%u], mate[%u], mds: %u!\n", stream.mate_type() ==
OppositeMate ?
"opposite" :
"anchor", context.idx, context.read_id, context.mate, mds_len );
717 for (
uint32 i = 0; i < mds_len; ++i)
718 mds_vector[i] = mds_local[i];
722 stream.finish( work_id, &context, ed, score );
728 template <u
int32 ALN_IDX,
typename scheme_type,
typename pipeline_type>
736 const pipeline_type& pipeline,
737 const scheme_type scoring_scheme,
740 const uint32 static_band_len =
741 (band_len < 4) ? 3u :
742 (band_len < 8) ? 7u :
743 (band_len < 16) ? 15u :
746 typedef typename pipeline_type::scheme_type::local_aligner_type aligner_type;
758 pipeline.scoring_scheme.local_aligner(),
763 finish_alignment_kernel<<<n_blocks, BLOCKDIM>>>(
777 template <
typename scheme_type,
typename pipeline_type>
781 const uint32 buffer_offset,
785 const pipeline_type& pipeline,
786 const scheme_type scoring_scheme,
789 const uint32 static_band_len =
790 (band_len < 4) ? 3u :
791 (band_len < 8) ? 7u :
792 (band_len < 16) ? 15u :
795 typedef typename pipeline_type::scheme_type::local_aligner_type aligner_type;
807 pipeline.scoring_scheme.local_aligner(),
812 finish_alignment_kernel<<<n_blocks, BLOCKDIM>>>(
832 template <u
int32 ALN_IDX,
typename pipeline_type>
839 const pipeline_type& pipeline,
844 detail::banded_traceback_best<ALN_IDX>(
852 pipeline.scoring_scheme.local_aligner(),
857 detail::banded_traceback_best<ALN_IDX>(
865 pipeline.scoring_scheme.end_to_end_aligner(),
873 template <u
int32 ALN_IDX,
typename pipeline_type>
879 const pipeline_type& pipeline,
884 detail::traceback_best<ALN_IDX>(
891 pipeline.scoring_scheme.local_aligner(),
896 detail::traceback_best<ALN_IDX>(
903 pipeline.scoring_scheme.end_to_end_aligner(),
911 template <
typename pipeline_type>
915 const uint32 buffer_offset,
919 const pipeline_type& pipeline,
932 pipeline.scoring_scheme.local_aligner(),
945 pipeline.scoring_scheme.end_to_end_aligner(),
953 template <u
int32 ALN_IDX,
typename scoring_scheme_type,
typename pipeline_type>
960 const pipeline_type& pipeline,
961 const scoring_scheme_type scoring_scheme,
964 detail::finish_alignment_best<ALN_IDX>(
979 template <u
int32 ALN_IDX,
typename scoring_scheme_type,
typename pipeline_type>
986 const pipeline_type& pipeline,
987 const scoring_scheme_type scoring_scheme,
990 detail::finish_alignment_best<ALN_IDX>(
1005 template <
typename scoring_scheme_type,
typename pipeline_type>
1009 const uint32 buffer_offset,
1010 const uint32 buffer_size,
1013 const pipeline_type& pipeline,
1014 const scoring_scheme_type scoring_scheme,