#include "utils/commons.h"
#include "system/mm_allocator.h"
#include "wavefront_extend.h"
#include "wavefront_extend_kernels.h"
#include "wavefront_extend_kernels_avx.h"
#include "wavefront_compute.h"
#include "wavefront_termination.h"
#ifdef WFA_PARALLEL
#include <omp.h>
#endif
void wavefront_extend_end2end_dispatcher_seq(
wavefront_aligner_t* const wf_aligner,
wavefront_t* const mwavefront,
const int score,
const int lo,
const int hi) {
wavefront_sequences_t* const seqs = &wf_aligner->sequences;
if (seqs->mode == wf_sequences_ascii) {
wavefront_extend_matches_packed_end2end(wf_aligner,mwavefront,lo,hi);
} else {
wf_offset_t dummy;
wavefront_extend_matches_custom(wf_aligner,mwavefront,score,lo,hi,false,&dummy);
}
}
void wavefront_extend_end2end_dispatcher_threads(
wavefront_aligner_t* const wf_aligner,
wavefront_t* const mwavefront,
const int score) {
const int lo = mwavefront->lo;
const int hi = mwavefront->hi;
const int num_threads = wavefront_compute_num_threads(wf_aligner,lo,hi);
if (num_threads == 1) {
wavefront_extend_end2end_dispatcher_seq(wf_aligner,mwavefront,score,lo,hi);
} else {
#ifdef WFA_PARALLEL
#pragma omp parallel num_threads(num_threads)
{
int t_lo, t_hi;
wavefront_compute_thread_limits(omp_get_thread_num(),omp_get_num_threads(),lo,hi,&t_lo,&t_hi);
wavefront_extend_end2end_dispatcher_seq(wf_aligner,mwavefront,score,t_lo,t_hi);
}
#endif
}
}
int wavefront_extend_end2end(
wavefront_aligner_t* const wf_aligner,
const int score) {
const bool memory_modular = wf_aligner->wf_components.memory_modular;
const int max_score_scope = wf_aligner->wf_components.max_score_scope;
const int score_mod = (memory_modular) ? score % max_score_scope : score;
wavefront_t* const mwavefront = wf_aligner->wf_components.mwavefronts[score_mod];
if (mwavefront == NULL) {
if (wf_aligner->align_status.num_null_steps > wf_aligner->wf_components.max_score_scope) {
wf_aligner->align_status.status = WF_STATUS_END_UNREACHABLE;
wf_aligner->align_status.score = score;
return 1; }
return 0; }
wavefront_extend_end2end_dispatcher_threads(wf_aligner,mwavefront,score);
const bool end_reached = wavefront_termination_end2end(wf_aligner,mwavefront,score,score_mod);
if (end_reached) {
wf_aligner->align_status.status = WF_STATUS_END_REACHED;
wf_aligner->align_status.score = score;
return 1; }
if (wf_aligner->heuristic.strategy != wf_heuristic_none) {
if (wavefront_heuristic_cufoff(wf_aligner,score,score_mod)) {
wf_aligner->align_status.status = WF_STATUS_END_UNREACHABLE;
wf_aligner->align_status.score = score;
return 1; }
}
return 0; }
wf_offset_t wavefront_extend_end2end_max_dispatcher_seq(
wavefront_aligner_t* const wf_aligner,
wavefront_t* const mwavefront,
const int score,
const int lo,
const int hi) {
wavefront_sequences_t* const seqs = &wf_aligner->sequences;
if (seqs->mode == wf_sequences_ascii) {
return wavefront_extend_matches_packed_end2end_max(wf_aligner,mwavefront,lo,hi);
} else {
wf_offset_t max_antidiag;
wavefront_extend_matches_custom(wf_aligner,mwavefront,score,lo,hi,false,&max_antidiag);
return max_antidiag;
}
}
wf_offset_t wavefront_extend_end2end_max_dispatcher_threads(
wavefront_aligner_t* const wf_aligner,
wavefront_t* const mwavefront,
const int score) {
const int lo = mwavefront->lo;
const int hi = mwavefront->hi;
wf_offset_t max_antidiag = 0;
const int num_threads = wavefront_compute_num_threads(wf_aligner,lo,hi);
if (num_threads == 1) {
max_antidiag = wavefront_extend_end2end_max_dispatcher_seq(wf_aligner,mwavefront,score,lo,hi);
} else {
#ifdef WFA_PARALLEL
#pragma omp parallel num_threads(num_threads)
{
int t_lo, t_hi;
wavefront_compute_thread_limits(omp_get_thread_num(),omp_get_num_threads(),lo,hi,&t_lo,&t_hi);
wf_offset_t t_max_antidiag = wavefront_extend_end2end_max_dispatcher_seq(wf_aligner,mwavefront,score,t_lo,t_hi);
#pragma omp critical
{
if (t_max_antidiag > max_antidiag) max_antidiag = t_max_antidiag;
}
}
#endif
}
return max_antidiag;
}
int wavefront_extend_end2end_max(
wavefront_aligner_t* const wf_aligner,
const int score,
int* const max_antidiagonal) {
const bool memory_modular = wf_aligner->wf_components.memory_modular;
const int max_score_scope = wf_aligner->wf_components.max_score_scope;
const int score_mod = (memory_modular) ? score % max_score_scope : score;
*max_antidiagonal = 0; wavefront_t* const mwavefront = wf_aligner->wf_components.mwavefronts[score_mod];
if (mwavefront == NULL) {
if (wf_aligner->align_status.num_null_steps > wf_aligner->wf_components.max_score_scope) {
wf_aligner->align_status.status = WF_STATUS_END_UNREACHABLE;
wf_aligner->align_status.score = score;
return 1; }
return 0; }
const wf_offset_t max_ak = wavefront_extend_end2end_max_dispatcher_threads(wf_aligner,mwavefront,score);
const bool end_reached = wavefront_termination_end2end(wf_aligner,mwavefront,score,score_mod);
if (end_reached) {
wf_aligner->align_status.status = WF_STATUS_END_REACHED;
wf_aligner->align_status.score = score;
return 1; }
if (wf_aligner->heuristic.strategy != wf_heuristic_none) {
if (wavefront_heuristic_cufoff(wf_aligner,score,score_mod)) {
wf_aligner->align_status.status = WF_STATUS_END_UNREACHABLE;
wf_aligner->align_status.score = score;
return 1; }
}
*max_antidiagonal = max_ak;
return 0; }
bool wavefront_extend_endsfree_dispatcher_seq(
wavefront_aligner_t* const wf_aligner,
wavefront_t* const mwavefront,
const int score,
const int lo,
const int hi) {
wavefront_sequences_t* const seqs = &wf_aligner->sequences;
if (seqs->mode == wf_sequences_ascii) {
return wavefront_extend_matches_packed_endsfree(wf_aligner,mwavefront,score,lo,hi);
} else {
wf_offset_t dummy;
return wavefront_extend_matches_custom(wf_aligner,mwavefront,score,lo,hi,true,&dummy);
}
}
bool wavefront_extend_endsfree_dispatcher_threads(
wavefront_aligner_t* const wf_aligner,
wavefront_t* const mwavefront,
const int score) {
const int lo = mwavefront->lo;
const int hi = mwavefront->hi;
bool end_reached = false;
const int num_threads = wavefront_compute_num_threads(wf_aligner,lo,hi);
if (num_threads == 1) {
end_reached = wavefront_extend_endsfree_dispatcher_seq(wf_aligner,mwavefront,score,lo,hi);
} else {
#ifdef WFA_PARALLEL
#pragma omp parallel num_threads(num_threads)
{
int t_lo, t_hi;
wavefront_compute_thread_limits(omp_get_thread_num(),omp_get_num_threads(),lo,hi,&t_lo,&t_hi);
if (wavefront_extend_endsfree_dispatcher_seq(wf_aligner,mwavefront,score,t_lo,t_hi)) {
end_reached = true;
}
}
#endif
}
return end_reached;
}
int wavefront_extend_endsfree(
wavefront_aligner_t* const wf_aligner,
const int score) {
const bool memory_modular = wf_aligner->wf_components.memory_modular;
const int max_score_scope = wf_aligner->wf_components.max_score_scope;
const int score_mod = (memory_modular) ? score % max_score_scope : score;
wavefront_t* const mwavefront = wf_aligner->wf_components.mwavefronts[score_mod];
if (mwavefront == NULL) {
if (wf_aligner->align_status.num_null_steps > wf_aligner->wf_components.max_score_scope) {
wf_aligner->align_status.status = WF_STATUS_END_UNREACHABLE;
wf_aligner->align_status.score = score;
return 1; }
return 0; }
const bool end_reached = wavefront_extend_endsfree_dispatcher_threads(wf_aligner,mwavefront,score);
if (end_reached) {
wf_aligner->align_status.status = WF_STATUS_END_REACHED;
wf_aligner->align_status.score = score;
return 1; }
if (wf_aligner->heuristic.strategy != wf_heuristic_none) {
if (wavefront_heuristic_cufoff(wf_aligner,score,score_mod)) {
wf_aligner->align_status.status = WF_STATUS_END_UNREACHABLE;
wf_aligner->align_status.score = score;
return 1; }
}
return 0; }