Reduce memory allocation events

Former-commit-id: fbdb2afc857b02adc2593e2278d3bd838e99b0b2
This commit is contained in:
Eric Coissac
2024-06-22 21:01:53 +02:00
parent 54a138196c
commit e6b87ecd02
19 changed files with 166 additions and 75 deletions

View File

@ -124,25 +124,26 @@ func BuildAlignment(seqA, seqB *obiseq.BioSequence,
// In that case arenas will be allocated by the function but, they will not
// be reusable for other alignments and desallocated at the BuildQualityConsensus
// return.
func BuildQualityConsensus(seqA, seqB *obiseq.BioSequence, path []int, statOnMismatch bool) (*obiseq.BioSequence, int) {
func BuildQualityConsensus(seqA, seqB *obiseq.BioSequence, path []int, statOnMismatch bool,
arenaAlign PEAlignArena) (*obiseq.BioSequence, int) {
bufferSA := obiseq.GetSlice(seqA.Len())
bufferSB := obiseq.GetSlice(seqB.Len())
defer obiseq.RecycleSlice(&bufferSB)
bufferSA := arenaAlign.pointer.aligneSeqA
bufferSB := arenaAlign.pointer.aligneSeqB
// defer obiseq.RecycleSlice(&bufferSB)
bufferQA := obiseq.GetSlice(seqA.Len())
bufferQB := obiseq.GetSlice(seqB.Len())
defer obiseq.RecycleSlice(&bufferQB)
bufferQA := arenaAlign.pointer.aligneQualA
bufferQB := arenaAlign.pointer.aligneQualB
// defer obiseq.RecycleSlice(&bufferQB)
_BuildAlignment(seqA.Sequence(), seqB.Sequence(), path, ' ',
&bufferSA, &bufferSB)
bufferSA, bufferSB)
// log.Printf("#1 %s--> la : %d,%p lb : %d,%p qa : %d,%p qb : %d,%p\n", stamp,
// len(*bufferSA), bufferSA, len(*bufferSB), bufferSB,
// len(*bufferQA), bufferQA, len(*bufferQB), bufferQB)
_BuildAlignment(seqA.Qualities(), seqB.Qualities(), path, byte(0),
&bufferQA, &bufferQB)
bufferQA, bufferQB)
// log.Printf("#2 %s--> la : %d,%p lb : %d,%p qa : %d,%p qb : %d,%p\n", stamp,
// len(*bufferSA), bufferSA, len(*bufferSB), bufferSB,
@ -157,10 +158,10 @@ func BuildQualityConsensus(seqA, seqB *obiseq.BioSequence, path []int, statOnMis
match := 0
for i, qA = range bufferQA {
nA := bufferSA[i]
nB := bufferSB[i]
qB = bufferQB[i]
for i, qA = range *bufferQA {
nA := (*bufferSA)[i]
nB := (*bufferSB)[i]
qB = (*bufferQB)[i]
if statOnMismatch && nA != nB && nA != ' ' && nB != ' ' {
mismatches[strings.ToUpper(fmt.Sprintf("(%c:%02d)->(%c:%02d)", nA, qA, nB, qB))] = i + 1
@ -171,13 +172,13 @@ func BuildQualityConsensus(seqA, seqB *obiseq.BioSequence, path []int, statOnMis
qm = qB
}
if qB > qA {
bufferSA[i] = bufferSB[i]
(*bufferSA)[i] = (*bufferSB)[i]
qM = qB
qm = qA
}
if qB == qA && nA != nB {
nuc := _FourBitsBaseCode[nA&31] | _FourBitsBaseCode[nB&31]
bufferSA[i] = _FourBitsBaseDecode[nuc]
(*bufferSA)[i] = _FourBitsBaseDecode[nuc]
}
q := qA + qB
@ -195,15 +196,15 @@ func BuildQualityConsensus(seqA, seqB *obiseq.BioSequence, path []int, statOnMis
q = 90
}
bufferQA[i] = q
(*bufferQA)[i] = q
}
consSeq := obiseq.NewBioSequence(
seqA.Id(),
bufferSA,
*bufferSA,
seqA.Definition(),
)
consSeq.SetQualities(bufferQA)
consSeq.SetQualities(*bufferQA)
if statOnMismatch && len(mismatches) > 0 {
consSeq.SetAttribute("pairing_mismatches", mismatches)

View File

@ -13,6 +13,10 @@ type _PeAlignArena struct {
path []int
fastIndex [][]int
fastBuffer []byte
aligneSeqA *[]byte
aligneSeqB *[]byte
aligneQualA *[]byte
aligneQualB *[]byte
}
// PEAlignArena defines memory arena usable by the
@ -30,12 +34,21 @@ var NilPEAlignArena = PEAlignArena{nil}
// MakePEAlignArena makes a new arena for the alignment of two paired sequences
// of maximum length indicated by lseqA and lseqB.
func MakePEAlignArena(lseqA, lseqB int) PEAlignArena {
aligneSeqA := make([]byte, 0, lseqA+lseqB)
aligneSeqB := make([]byte, 0, lseqA+lseqB)
aligneQualA := make([]byte, 0, lseqA+lseqB)
aligneQualB := make([]byte, 0, lseqA+lseqB)
a := _PeAlignArena{
scoreMatrix: make([]int, 0, (lseqA+1)*(lseqB+1)),
pathMatrix: make([]int, 0, (lseqA+1)*(lseqB+1)),
path: make([]int, 2*(lseqA+lseqB)),
fastIndex: make([][]int, 256),
fastBuffer: make([]byte, 0, lseqA),
aligneSeqA: &aligneSeqA,
aligneSeqB: &aligneSeqB,
aligneQualA: &aligneQualA,
aligneQualB: &aligneQualB,
}
return PEAlignArena{&a}
@ -352,7 +365,7 @@ func PERightAlign(seqA, seqB *obiseq.BioSequence, gap, scale float64,
func PEAlign(seqA, seqB *obiseq.BioSequence,
gap, scale float64, fastAlign bool, delta int, fastScoreRel bool,
arena PEAlignArena) (int, []int, int, int, float64) {
arena PEAlignArena, shift_buff *map[int]int) (int, []int, int, int, float64) {
var score, shift int
var startA, startB int
var partLen, over int
@ -374,7 +387,7 @@ func PEAlign(seqA, seqB *obiseq.BioSequence,
&arena.pointer.fastIndex,
&arena.pointer.fastBuffer)
shift, fastCount, fastScore = obikmer.FastShiftFourMer(index, seqA.Len(), seqB, fastScoreRel, nil)
shift, fastCount, fastScore = obikmer.FastShiftFourMer(index, shift_buff, seqA.Len(), seqB, fastScoreRel, nil)
if shift > 0 {
over = seqA.Len() - shift