Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/bathsearch.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ serial_master(ESL_GETOPTS *go, struct cfg_s *cfg)
info[i].hw = p7_hmmwindow_CreateList();
info[i].gcode = gcode;
info[i].wrk = esl_gencode_WorkstateCreate(go, gcode);
info[i].wrk->orf_block = esl_sq_CreateDigitalBlock(BLOCK_SIZE, abcAA);
info[i].wrk->orf_block = esl_gencode_OrfBlockCreate(BLOCK_SIZE);
info[i].th = p7_tophits_Create();
info[i].om = p7_oprofile_Clone(om);
info[i].gm = p7_profile_Clone(gm);
Expand Down Expand Up @@ -923,7 +923,7 @@ serial_master(ESL_GETOPTS *go, struct cfg_s *cfg)
p7_hmmwindow_DestroyList(info[i].hw);
if(info[i].wrk->orf_block != NULL)
{
esl_sq_DestroyBlock(info[i].wrk->orf_block);
esl_gencode_OrfBlockDestroy(info[i].wrk->orf_block);
info[i].wrk->orf_block = NULL;
esl_gencode_WorkstateDestroy(info[i].wrk);
}
Expand Down Expand Up @@ -1098,7 +1098,7 @@ serial_loop(WORKER_INFO *info, ID_LENGTH_LIST *id_length_list, ESL_SQFILE *dbfp,
p7_Pipeline_BATH(info->pli, info->om, info->gm, info->om_fs3, info->om_fs5, info->gm_fs5, info->scoredata, info->bg, info->th, info->pli->nseqs, dbsq_dna, info->wrk->orf_block, info->gcode, info->hw, p7_NOCOMPLEMENT);
p7_pipeline_Reuse_BATH(info->pli); // prepare for next search

esl_sq_ReuseBlock(info->wrk->orf_block);
esl_gencode_OrfBlockReuse(info->wrk->orf_block);
}

if (info->pli->strands != p7_STRAND_TOPONLY)
Expand All @@ -1112,7 +1112,7 @@ serial_loop(WORKER_INFO *info, ID_LENGTH_LIST *id_length_list, ESL_SQFILE *dbfp,
p7_Pipeline_BATH(info->pli, info->om, info->gm, info->om_fs3, info->om_fs5, info->gm_fs5, info->scoredata, info->bg, info->th, info->pli->nseqs, dbsq_dna, info->wrk->orf_block, info->gcode, info->hw, p7_COMPLEMENT);
p7_pipeline_Reuse_BATH(info->pli); // prepare for next search

esl_sq_ReuseBlock(info->wrk->orf_block);
esl_gencode_OrfBlockReuse(info->wrk->orf_block);

/* Reverse sequence back to original */
esl_sq_ReverseComplement(dbsq_dna);
Expand Down Expand Up @@ -1283,7 +1283,7 @@ pipeline_thread(void *arg)
p7_Pipeline_BATH(info->pli, info->om, info->gm, info->om_fs3, info->om_fs5, info->gm_fs5, info->scoredata, info->bg, info->th, block->first_seqidx + i, dnaSeq, info->wrk->orf_block, info->gcode, info->hw, p7_NOCOMPLEMENT);
p7_pipeline_Reuse_BATH(info->pli); // prepare for next search

esl_sq_ReuseBlock(info->wrk->orf_block);
esl_gencode_OrfBlockReuse(info->wrk->orf_block);
}

if (info->pli->strands != p7_STRAND_TOPONLY) {
Expand All @@ -1294,7 +1294,7 @@ pipeline_thread(void *arg)
p7_Pipeline_BATH(info->pli, info->om, info->gm, info->om_fs3, info->om_fs5, info->gm_fs5, info->scoredata, info->bg, info->th, block->first_seqidx + i, dnaSeq, info->wrk->orf_block, info->gcode, info->hw, p7_COMPLEMENT);
p7_pipeline_Reuse_BATH(info->pli); // prepare for next search

esl_sq_ReuseBlock(info->wrk->orf_block);
esl_gencode_OrfBlockReuse(info->wrk->orf_block);
esl_sq_ReverseComplement(dnaSeq);
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/hmmer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,7 @@ typedef struct p7_pipeline_s {
enum p7_pipemodes_e mode; /* p7_SCAN_MODELS | p7_SEARCH_SEQS */
int spliced; /* TRUE if user uses --splice slaf to enable spliced alignments */
int fs_pipe; /* TRUE if bathsearch is allowed to use the frameshift aware pipeline branch (use --fs flag) */
uint16_t *ssv_cut; /* ssv_cut[L]: lowest SSV maximum at which an ORF of length L is not rejected by SSV alone; 0 if not yet known */
int std_pipe; /* TRUE if bathsearch is allowed to use the standard translation pipeline (do not use --fsonly flag) */
int strands; /* p7_STRAND_TOPONLY | p7_STRAND_BOTTOMONLY | p7_STRAND_BOTH */
int W; /* window length for nhmmer scan - essentially maximum length of model that we expect to find*/
Expand Down Expand Up @@ -1393,7 +1394,7 @@ extern int p7_tracealign_getMSAandStats(P7_HMM *hmm, ESL_SQ **sq, int N, ESL_MS
/* p7_alidisplay.c */
extern P7_ALIDISPLAY *p7_alidisplay_Create(const P7_TRACE *tr, int which, const P7_OPROFILE *om, const ESL_SQ *sq, const ESL_SQ *ntsq);
extern P7_ALIDISPLAY *p7_alidisplay_fs_Create(const P7_TRACE *tr, int which, const P7_FS_PROFILE *gm_fs5, const ESL_SQ *sq, int show_cigar);
extern P7_ALIDISPLAY *p7_alidisplay_nonfs_Create(const P7_TRACE *tr, int which, const P7_OPROFILE *om, const ESL_SQ *sq, const ESL_SQ *orfsq, int orf_pos, int show_cigar);
extern P7_ALIDISPLAY *p7_alidisplay_nonfs_Create(const P7_TRACE *tr, int which, const P7_OPROFILE *om, const ESL_SQ *sq, const ESL_ORF *orfsq, int orf_pos, int show_cigar);
extern P7_ALIDISPLAY *p7_alidisplay_splice_Create(const P7_TRACE *tr, int which, const P7_OPROFILE *om, const ESL_SQ *target_seq, const ESL_SQ *amino_sq, int amino_pos, int splice_cnt, int show_cigar);
extern P7_ALIDISPLAY *p7_alidisplay_splice_fs_Create(const P7_TRACE *tr, int which, const P7_FS_PROFILE *gm_fs, const ESL_SQ *sq, ESL_DSQ *nuc_dsq, int64_t *nuc_index, int nuc_pos, int splice_cnt, int show_cigar);
extern P7_ALIDISPLAY *p7_alidisplay_Create_empty();
Expand Down Expand Up @@ -1459,7 +1460,7 @@ extern int p7_domaindef_DumpPosteriors(FILE *ofp, P7_DOMAINDEF *ddef);
extern void p7_domaindef_Destroy_BATH(P7_DOMAINDEF *ddef);

extern int p7_domaindef_ByPosteriorHeuristics_Frameshift_BATH(P7_PIPELINE *pli, ESL_SQ *windowsq, P7_FS_OPROFILE *om_fs5, P7_FS_PROFILE *gm_fs5, P7_BG *bg, const ESL_GENCODE *gcode);
extern int p7_domaindef_ByPosteriorHeuristics_BATH(const ESL_SQ *orfsq, const ESL_SQ *sq, const int64_t ntsqlen, P7_OPROFILE *om, P7_PROFILE *gm, P7_OMX *oxf, P7_OMX *oxb, P7_OMX *fwd, P7_OMX *bck, P7_DOMAINDEF *ddef);
extern int p7_domaindef_ByPosteriorHeuristics_BATH(const ESL_ORF *orfsq, const ESL_SQ *sq, const int64_t ntsqlen, P7_OPROFILE *om, P7_PROFILE *gm, P7_OMX *oxf, P7_OMX *oxb, P7_OMX *fwd, P7_OMX *bck, P7_DOMAINDEF *ddef);

/* p7_gmx.c */
extern P7_GMX *p7_gmx_Create (int allocM, int allocL, int allocLx, int nscells);
Expand Down Expand Up @@ -1576,9 +1577,9 @@ extern int p7_pli_DomainIncludable (P7_PIPELINE *pli, float dom_score, double l
extern int p7_pli_NewModel (P7_PIPELINE *pli, const P7_OPROFILE *om, P7_BG *bg);
extern int p7_pli_NewModelThresholds(P7_PIPELINE *pli, const P7_OPROFILE *om);
extern int p7_pli_NewSeq (P7_PIPELINE *pli, const ESL_SQ *sq);
extern int p7_pli_computeAliScores_BATH(P7_DOMAIN *dom, P7_TRACE *tr, const ESL_SQ *orfsq, const P7_PROFILE *gm);
extern int p7_pli_computeAliScores_BATH(P7_DOMAIN *dom, P7_TRACE *tr, const ESL_ORF *orfsq, const P7_PROFILE *gm);
extern int p7_pli_computeAliScores_Frameshift_BATH(P7_DOMAIN *dom, P7_TRACE *tr, const ESL_SQ *seq, const P7_FS_PROFILE *gm_fs);
extern int p7_Pipeline_BATH (P7_PIPELINE *pli, P7_OPROFILE *om, P7_PROFILE *gm, P7_FS_OPROFILE *om_fs3, P7_FS_OPROFILE *om_fs5, P7_FS_PROFILE *gm_fs5, P7_SCOREDATA *data, P7_BG *bg, P7_TOPHITS *hitlist, int64_t seqidx, ESL_SQ *dnasq, ESL_SQ_BLOCK *orf_block, ESL_GENCODE *gcode, P7_HMM_WINDOWLIST *splcing_windows, int complementarity);
extern int p7_Pipeline_BATH (P7_PIPELINE *pli, P7_OPROFILE *om, P7_PROFILE *gm, P7_FS_OPROFILE *om_fs3, P7_FS_OPROFILE *om_fs5, P7_FS_PROFILE *gm_fs5, P7_SCOREDATA *data, P7_BG *bg, P7_TOPHITS *hitlist, int64_t seqidx, ESL_SQ *dnasq, ESL_ORF_BLOCK *orf_block, ESL_GENCODE *gcode, P7_HMM_WINDOWLIST *splcing_windows, int complementarity);

extern int p7_pli_Statistics(FILE *ofp, P7_PIPELINE *pli, ESL_STOPWATCH *w);

Expand Down
8 changes: 8 additions & 0 deletions src/impl_avx/impl_avx.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "esl_alphabet.h"
#include "esl_random.h"
#include "esl_cpu.h"
#include "esl_gencode.h" /* ESL_ORF */

#ifdef eslENABLE_SSE
#include <xmmintrin.h> /* SSE */
Expand Down Expand Up @@ -784,11 +785,18 @@ extern int (*p7_SSVFilter)(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, flo
/* ssvfilter_sse.c — SSE implementation */
#ifdef eslENABLE_SSE
extern int p7_SSVFilter_sse(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, float *ret_sc);
extern void p7_SSVFilter_OrfBlock_sse(const P7_OPROFILE *om, const ESL_ORF *orf, int n, uint8_t *xE);
#endif
/* ssvfilter_avx.c — AVX2 implementation */
#ifdef eslENABLE_AVX
extern int p7_SSVFilter_avx(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, float *ret_sc);
extern void p7_SSVFilter_OrfBlock_avx(const P7_OPROFILE *om, const ESL_ORF *orf, int n, uint8_t *xE);
#endif
/* SSV over a block of ORFs: the pipeline can take each ORF's SSV maximum from
* one call, and turn it into the SSV filter's status and score itself */
#define p7_SSV_ORFBLOCK 1
extern int p7_SSVFilter_OrfBlock(const P7_OPROFILE *om, const ESL_ORF *orf, int n, uint8_t *xE);
extern int p7_SSVFilter_FromXE(int xE, const P7_OPROFILE *om, float *ret_sc);

/* stotrace.c — self-patching dispatcher */
extern int (*p7_StochasticTrace)(ESL_RANDOMNESS *rng, const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, const P7_OMX *ox, P7_TRACE *tr);
Expand Down
79 changes: 79 additions & 0 deletions src/impl_avx/ssvfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,82 @@ p7_SSVFilter_Dispatcher(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, float
return eslENORESULT;
#endif
}


/* Function: p7_SSVFilter_FromXE()
* Synopsis: The SSV filter's result, from the SSV matrix's highest cell.
*
* Purpose: <xE> is the highest cell of the SSV matrix of a sequence against
* <om>, as p7_SSVFilter_OrfBlock() gives it. Return what
* p7_SSVFilter() returns for that sequence, and its score in
* <*ret_sc>; <om> must be configured for the sequence's length.
*
* Returns: <eslOK>, <eslENORESULT> or <eslERANGE>, as p7_SSVFilter().
*/
int
p7_SSVFilter_FromXE(int xE_in, const P7_OPROFILE *om, float *ret_sc)
{
uint16_t xE = (uint16_t) xE_in;
uint16_t xJ;

if (om->tjb_b + om->tbm_b + om->tec_b + om->bias_b >= 127)
return eslENORESULT;

/* Saturation floors every diagonal at the begin score (128), so a
* max of 128 means no diagonal scored above it and the true best
* may be lower; let the full MSV filter compute it. */
if (xE <= 128) return eslENORESULT;

if (xE >= 255 - om->bias_b) {
*ret_sc = eslINFINITY;

if (om->base_b - om->tjb_b - om->tbm_b < 128)
return eslENORESULT;

return eslERANGE;
}

xE += om->base_b - om->tjb_b - om->tbm_b;
xE -= 128;

if (xE >= 255 - om->bias_b) {
*ret_sc = eslINFINITY;
return eslERANGE;
}

xJ = xE - om->tec_b;

if (xJ > om->base_b) return eslENORESULT;

*ret_sc = ((float)(xJ - om->tjb_b) - (float) om->base_b);
*ret_sc /= om->scale_b;
*ret_sc -= 3.0f;

return eslOK;
}


/* Function: p7_SSVFilter_OrfBlock()
* Synopsis: SSV maximum of every ORF in a block.
*
* Purpose: For each of the <n> ORFs in <orf>, store in <xE[i]> the highest
* cell of its SSV matrix against <om>. It does not depend on the
* length <om> is configured for; p7_SSVFilter_FromXE() makes the
* filter's status and score from it.
*
* Returns: <eslOK> on success; <eslENORESULT> if there is no SIMD
* implementation, and <xE> is unset.
*/
int
p7_SSVFilter_OrfBlock(const P7_OPROFILE *om, const ESL_ORF *orf, int n, uint8_t *xE)
{
#ifdef eslENABLE_AVX
if (esl_cpu_has_avx()) { p7_SSVFilter_OrfBlock_avx(om, orf, n, xE); return eslOK; }
#endif
#ifdef eslENABLE_SSE
p7_SSVFilter_OrfBlock_sse(om, orf, n, xE);
return eslOK;
#else
return eslENORESULT;
#endif
}
89 changes: 48 additions & 41 deletions src/impl_avx/ssvfilter_avx.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,18 @@ calc_band_18(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, int q, __m256i be
* 2. p7_SSVFilter_avx()
*****************************************************************/

/* the band function for each band width */
static __m256i (* const fs[MAX_BANDS + 1])(const ESL_DSQ *, int, const P7_OPROFILE *, int, register __m256i, __m256i)
= { NULL
, calc_band_1, calc_band_2, calc_band_3, calc_band_4, calc_band_5, calc_band_6
#if MAX_BANDS > 6
, calc_band_7, calc_band_8, calc_band_9, calc_band_10, calc_band_11, calc_band_12, calc_band_13, calc_band_14
#endif
#if MAX_BANDS > 14
, calc_band_15, calc_band_16, calc_band_17, calc_band_18
#endif
};

static uint8_t
get_xE_avx(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om)
{
Expand All @@ -448,17 +460,6 @@ get_xE_avx(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om)
int last_q = 0;
int i;

__m256i (*fs[MAX_BANDS + 1])(const ESL_DSQ *, int, const P7_OPROFILE *, int, register __m256i, __m256i)
= { NULL
, calc_band_1, calc_band_2, calc_band_3, calc_band_4, calc_band_5, calc_band_6
#if MAX_BANDS > 6
, calc_band_7, calc_band_8, calc_band_9, calc_band_10, calc_band_11, calc_band_12, calc_band_13, calc_band_14
#endif
#if MAX_BANDS > 14
, calc_band_15, calc_band_16, calc_band_17, calc_band_18
#endif
};

beginv = _mm256_set1_epi8(-128);
xEv = beginv;

Expand Down Expand Up @@ -497,45 +498,51 @@ get_xE_avx(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om)
int
p7_SSVFilter_avx(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, float *ret_sc)
{
uint16_t xE;
uint16_t xJ;

if (om->tjb_b + om->tbm_b + om->tec_b + om->bias_b >= 127)
return eslENORESULT;

xE = get_xE_avx(dsq, L, om);

/* Saturation floors every diagonal at the begin score (128), so a
* max of 128 means no diagonal scored above it and the true best
* may be lower; let the full MSV filter compute it. */
if (xE <= 128) return eslENORESULT;

if (xE >= 255 - om->bias_b) {
*ret_sc = eslINFINITY;
return p7_SSVFilter_FromXE(get_xE_avx(dsq, L, om), om, ret_sc);
}

if (om->base_b - om->tjb_b - om->tbm_b < 128)
return eslENORESULT;

return eslERANGE;
/* Function: p7_SSVFilter_OrfBlock_avx()
* Synopsis: SSV maximum of every ORF in a block, AVX2 path.
*
* Purpose: See p7_SSVFilter_OrfBlock(). <xE[i]> is what get_xE_avx() gives
* for ORF <i>. The bands depend only on the model, so they are laid
* out once for the block.
*/
#define SSV_BLOCK_BANDS 64 /* bands laid out up front; enough for a model of 28,672 positions */
void
p7_SSVFilter_OrfBlock_avx(const P7_OPROFILE *om, const ESL_ORF *orf, int n, uint8_t *xE)
{
__m256i beginv = _mm256_set1_epi8(-128);
__m256i xEv;
int Q = p7O_NQB_AVX(om->M);
int bands = (Q + MAX_BANDS - 1) / MAX_BANDS;
int q0[SSV_BLOCK_BANDS]; /* first vector of each band */
int w[SSV_BLOCK_BANDS]; /* its width */
int last_q = 0;
int q, b, i;

if (bands > SSV_BLOCK_BANDS) {
for (i = 0; i < n; i++) xE[i] = get_xE_avx(orf[i].dsq, (int) orf[i].n, om);
return;
}

xE += om->base_b - om->tjb_b - om->tbm_b;
xE -= 128;

if (xE >= 255 - om->bias_b) {
*ret_sc = eslINFINITY;
return eslERANGE;
for (b = 0; b < bands; b++) {
q = (Q * (b + 1)) / bands;
q0[b] = last_q;
w[b] = q - last_q;
last_q = q;
}

xJ = xE - om->tec_b;

if (xJ > om->base_b) return eslENORESULT;

*ret_sc = ((float)(xJ - om->tjb_b) - (float) om->base_b);
*ret_sc /= om->scale_b;
*ret_sc -= 3.0f;

return eslOK;
for (i = 0; i < n; i++) {
xEv = beginv;
for (b = 0; b < bands; b++)
xEv = fs[w[b]](orf[i].dsq, (int) orf[i].n, om, q0[b], beginv, xEv);
xE[i] = esl_avx_hmax_epu8(xEv);
}
}

#endif /* eslENABLE_AVX */
46 changes: 13 additions & 33 deletions src/impl_avx/ssvfilter_sse.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,45 +500,25 @@ get_xE_sse(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om)
int
p7_SSVFilter_sse(const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, float *ret_sc)
{
uint16_t xE;
uint16_t xJ;

if (om->tjb_b + om->tbm_b + om->tec_b + om->bias_b >= 127)
return eslENORESULT;

xE = get_xE_sse(dsq, L, om);

/* Saturation floors every diagonal at the begin score (128), so a
* max of 128 means no diagonal scored above it and the true best
* may be lower; let the full MSV filter compute it. */
if (xE <= 128) return eslENORESULT;

if (xE >= 255 - om->bias_b) {
*ret_sc = eslINFINITY;

if (om->base_b - om->tjb_b - om->tbm_b < 128)
return eslENORESULT;

return eslERANGE;
}

xE += om->base_b - om->tjb_b - om->tbm_b;
xE -= 128;

if (xE >= 255 - om->bias_b) {
*ret_sc = eslINFINITY;
return eslERANGE;
}

xJ = xE - om->tec_b;
return p7_SSVFilter_FromXE(get_xE_sse(dsq, L, om), om, ret_sc);
}

if (xJ > om->base_b) return eslENORESULT;

*ret_sc = ((float)(xJ - om->tjb_b) - (float) om->base_b);
*ret_sc /= om->scale_b;
*ret_sc -= 3.0f;
/* Function: p7_SSVFilter_OrfBlock_sse()
* Synopsis: SSV maximum of every ORF in a block, SSE path.
*
* Purpose: See p7_SSVFilter_OrfBlock(). <xE[i]> is what get_xE_sse() gives
* for ORF <i>.
*/
void
p7_SSVFilter_OrfBlock_sse(const P7_OPROFILE *om, const ESL_ORF *orf, int n, uint8_t *xE)
{
int i;

return eslOK;
for (i = 0; i < n; i++) xE[i] = get_xE_sse(orf[i].dsq, (int) orf[i].n, om);
}

#endif /* eslENABLE_SSE */
5 changes: 5 additions & 0 deletions src/impl_sse/impl_sse.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,11 @@ extern void p7_oprofile_DestroyBlock(P7_OM_BLOCK *block);

/* ssvfilter.c */
extern int p7_SSVFilter (const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, float *ret_sc);
/* SSV over a block of ORFs: the pipeline can take each ORF's SSV maximum from
* one call, and turn it into the SSV filter's status and score itself */
#define p7_SSV_ORFBLOCK 1
extern int p7_SSVFilter_OrfBlock(const P7_OPROFILE *om, const ESL_ORF *orf, int n, uint8_t *xE);
extern int p7_SSVFilter_FromXE(int xE, const P7_OPROFILE *om, float *ret_sc);

/* msvfilter.c */
extern int p7_MSVFilter (const ESL_DSQ *dsq, int L, const P7_OPROFILE *om, P7_OMX *ox, float *ret_sc);
Expand Down
Loading
Loading