native: avoid allocation in Dormlq
@@ -60,10 +60,14 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
return
}
- const nbmax = 64
+ const (
+ nbmax = 64
+ ldt = nbmax
+ tsize = nbmax * ldt
+ )
opts := string(side) + string(trans)
nb := min(nbmax, impl.Ilaenv(1, "DORMLQ", opts, m, n, k, -1))
- lworkopt := max(1, nw) * nb
+ lworkopt := max(1, nw)*nb + tsize
if lwork == -1 {
work[0] = float64(lworkopt)
return
@@ -71,21 +75,22 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
nbmin := 2
if 1 < nb && nb < k {
- iws := nw * nb
+ iws := nw*nb + tsize
if lwork < iws {
- nb = lwork / nw
+ nb = (lwork - tsize) / nw
nbmin = max(2, impl.Ilaenv(2, "DORMLQ", opts, m, n, k, -1))
}
}
- ldwork := nb
if nb < nbmin || k <= nb {
// Call unblocked code.
impl.Dorml2(side, trans, m, n, k, a, lda, tau, c, ldc, work)
work[0] = float64(lworkopt)
return
}
- ldt := nb
- t := make([]float64, nb*ldt)
+
+ t := work[:tsize]
+ wrk := work[tsize:]
+ ldwrk := nb
notran := trans == blas.NoTrans
transt := blas.NoTrans
@@ -105,7 +110,7 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
a[i*lda+i:], lda,
t, ldt,
c[i*ldc:], ldc,
- work, ldwork)
+ wrk, ldwrk)
}
case left && !notran:
@@ -119,7 +124,7 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
a[i*lda+i:], lda,
t, ldt,
c[i*ldc:], ldc,
- work, ldwork)
+ wrk, ldwrk)
}
case !left && notran:
@@ -133,7 +138,7 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
a[i*lda+i:], lda,
t, ldt,
c[i:], ldc,
- work, ldwork)
+ wrk, ldwrk)
}
case !left && !notran:
@@ -147,7 +152,7 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
a[i*lda+i:], lda,
t, ldt,
c[i:], ldc,
- work, ldwork)
+ wrk, ldwrk)
}
}
work[0] = float64(lworkopt)
