native,testlapack: fix wrong work stride in Dormlq
MODIFY
native/dormlq.go
native/dormlq.go
@@ -73,7 +73,6 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
}
nbmin := 2
- ldwork := nb
if nb > 1 && nb < k {
iws := nw * nb
if lwork < iws {
@@ -81,6 +80,7 @@ func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k
nbmin = max(2, impl.Ilaenv(2, "DORMLQ", opts, m, n, k, -1))
}
}
+ ldwork := nb
if nb < nbmin || nb >= k {
// Call unblocked code.
impl.Dorml2(side, trans, m, n, k, a, lda, tau, c, ldc, work)

MODIFY
testlapack/dormbr.go
testlapack/dormbr.go
@@ -42,6 +42,8 @@ func DormbrTest(t *testing.T, impl Dormbrer) {
{4, 5, 3, 10, 12},
{5, 3, 4, 10, 12},
{5, 4, 3, 10, 12},
+
+ {150, 140, 130, 0, 0},
} {
m := test.m
n := test.n

MODIFY
testlapack/dormlq.go
testlapack/dormlq.go
package testlapack
import (
- "fmt"
"math/rand"
"testing"
@@ -22,6 +21,7 @@ func DormlqTest(t *testing.T, impl Dormlqer) {
rnd := rand.New(rand.NewSource(1))
for _, side := range []blas.Side{blas.Left, blas.Right} {
for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} {
+ for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} {
for _, test := range []struct {
common, adim, cdim, lda, ldc int
}{
@@ -94,55 +94,34 @@ func DormlqTest(t *testing.T, impl Dormlqer) {
ans := make([]float64, len(c))
copy(ans, cCopy)
+ var nw int
if side == blas.Left {
- work = make([]float64, nc)
+ nw = nc
} else {
- work = make([]float64, mc)
+ nw = mc
}
+ work = make([]float64, nw)
impl.Dorml2(side, trans, mc, nc, k, a, lda, tau, ans, ldc, work)
- // Make sure Dorml2 and Dormlq match with small work
- for i := range work {
- work[i] = rnd.Float64()
- }
- lwork := len(work)
- copy(c, cCopy)
- impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, lwork)
- if !floats.EqualApprox(c, ans, 1e-12) {
- t.Errorf("Dormqr and Dorm2r mismatch for small work")
- }
-
- // Try with the optimum amount of work
- copy(c, cCopy)
+ var lwork int
+ switch wl {
+ case minimumWork:
+ lwork = nw
+ case optimumWork:
impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, -1)
- work = make([]float64, int(work[0]))
- lwork = len(work)
- for i := range work {
- work[i] = rnd.Float64()
+ lwork = int(work[0])
+ case mediumWork:
+ work := make([]float64, 1)
+ impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, -1)
+ lwork = (int(work[0]) + nw) / 2
}
+ lwork = max(1, lwork)
+ work = make([]float64, lwork)
+
impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, lwork)
- if !floats.EqualApprox(c, ans, 1e-12) {
- t.Errorf("Dormqr and Dorm2r mismatch for full work")
- fmt.Println("ccopy")
- for i := 0; i < mc; i++ {
- fmt.Println(cCopy[i*ldc : (i+1)*ldc])
- }
- fmt.Println("ans =")
- for i := 0; i < mc; i++ {
- fmt.Println(ans[i*ldc : (i+1)*ldc])
+ if !floats.EqualApprox(c, ans, 1e-13) {
+ t.Errorf("Dormqr and Dorm2r results mismatch")
}
- fmt.Println("c =")
- for i := 0; i < mc; i++ {
- fmt.Println(c[i*ldc : (i+1)*ldc])
- }
- }
- // Try with less than the optimum amount of work
- copy(c, cCopy)
- work = work[1:]
- lwork--
- impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, lwork)
- if !floats.EqualApprox(c, ans, 1e-12) {
- t.Errorf("Dormqr and Dorm2r mismatch for medium work")
}
}
}

native,testlapack: fix wrong work stride in Dormlq