EddyRivasLab/infernal

Inconsistent results from qsort callback

Closed this issue · 2 comments

yugr commented

Hi,

qsort callback hit_sorter_by_evalue may return random result when input structs have all compared fields equal. This in turn may causes inconsistent order or even crashes in some qsort implementations.

The issue has been detected when running standard testsuite under SortChecker:

cmsearch[23540]: qsort: comparison function is not symmetric (comparison function 0x4ab689 (/home/yugr/build/infernal-1.1.1/src/cmsearch+0x4ab689), called from 0x4abb66 (/home/yugr/build/infernal-1.1.1/src/cmsearch+0x4abb66), cmdline is "../src/cmsearch -E 0.1 --tblout esltmpaa22822.OUTFILES.tbl esltmpaa22822.OUTFILES.cm esltmpaa22822.OUTFILES.fa")

Closer examination in debugger reveals that hit_sorter_by_evalue returns returns the same value for equal results:

(gdb) p hit_sorter_by_evalue(&h->hit[2], &h->hit[3])
$15 = -1
(gdb) p hit_sorter_by_evalue(&h->hit[3], &h->hit[2])
$16 = -1

The fix is simply to replace final comparison

return  (h1->pass_idx < h2->pass_idx ? 1 : -1 ); /* fourth key, pass_idx, high to low */

with

return  (h1->pass_idx < h2->pass_idx ? 1 : h1->pass_idx > h2->pass_idx ? -1 : 0); /* fourth key, pass_idx, high to low */

A similar issue seems to exist in most other hit_sorter* callbacks .

Thanks, I agree. We'll have a look.

Thanks, yugr. This has been fixed in the develop branch as of commit 2c83262. The fix will be included as part of the next release (which will be the next commit on master), but it is currently unclear when that will be.

For changes responsible for the fix, see:
5e095af...2c83262

Ignore the addition of the bug-i47.pl script -- that is unrelated.