Skip to content

Commit

Permalink
asm/c128: Adding tests and benchmarks for dot functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kunde21 committed Aug 22, 2017
1 parent d04a8d7 commit 9a34c3c
Show file tree
Hide file tree
Showing 4 changed files with 352 additions and 0 deletions.
123 changes: 123 additions & 0 deletions internal/asm/c128/benchDot_bkprt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// Copyright ©2016 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build go1.5,!go1.7

package c128

import "testing"

func benchdotu(b *testing.B, n int64, fn func(x, y []complex128) complex128) {
x, y := x[:n], y[:n]
b.SetBytes(256 * n)
for i := 0; i < b.N; i++ {
_ = fn(x, y)
}
}

func BenchmarkDotcUnitary1(t *testing.B) { benchdotu(t, 1, DotcUnitary) }
func BenchmarkDotcUnitary2(t *testing.B) { benchdotu(t, 2, DotcUnitary) }
func BenchmarkDotcUnitary3(t *testing.B) { benchdotu(t, 3, DotcUnitary) }
func BenchmarkDotcUnitary4(t *testing.B) { benchdotu(t, 4, DotcUnitary) }
func BenchmarkDotcUnitary5(t *testing.B) { benchdotu(t, 5, DotcUnitary) }
func BenchmarkDotcUnitary10(t *testing.B) { benchdotu(t, 10, DotcUnitary) }
func BenchmarkDotcUnitary100(t *testing.B) { benchdotu(t, 100, DotcUnitary) }
func BenchmarkDotcUnitary1000(t *testing.B) { benchdotu(t, 1000, DotcUnitary) }
func BenchmarkDotcUnitary5000(t *testing.B) { benchdotu(t, 5000, DotcUnitary) }
func BenchmarkDotcUnitary10000(t *testing.B) { benchdotu(t, 10000, DotcUnitary) }
func BenchmarkDotcUnitary50000(t *testing.B) { benchdotu(t, 50000, DotcUnitary) }

func BenchmarkDotuUnitary1(t *testing.B) { benchdotu(t, 1, DotuUnitary) }
func BenchmarkDotuUnitary2(t *testing.B) { benchdotu(t, 2, DotuUnitary) }
func BenchmarkDotuUnitary3(t *testing.B) { benchdotu(t, 3, DotuUnitary) }
func BenchmarkDotuUnitary4(t *testing.B) { benchdotu(t, 4, DotuUnitary) }
func BenchmarkDotuUnitary5(t *testing.B) { benchdotu(t, 5, DotuUnitary) }
func BenchmarkDotuUnitary10(t *testing.B) { benchdotu(t, 10, DotuUnitary) }
func BenchmarkDotuUnitary100(t *testing.B) { benchdotu(t, 100, DotuUnitary) }
func BenchmarkDotuUnitary1000(t *testing.B) { benchdotu(t, 1000, DotuUnitary) }
func BenchmarkDotuUnitary5000(t *testing.B) { benchdotu(t, 5000, DotuUnitary) }
func BenchmarkDotuUnitary10000(t *testing.B) { benchdotu(t, 10000, DotuUnitary) }

func benchdoti(b *testing.B, ln, inc int, fn func(x, y []complex128, n, incX, incY, ix, iy int) complex128) {
b.SetBytes(int64(256 * ln))
var idx int
if inc < 0 {
idx = (-ln + 1) * inc
}
for i := 0; i < b.N; i++ {
_ = fn(x, y, ln, inc, inc, idx, idx)
}
}

func BenchmarkDotcInc_1_inc1(t *testing.B) { benchdoti(t, 1, 1, DotcInc) }

func BenchmarkDotcInc_2_inc1(t *testing.B) { benchdoti(t, 2, 1, DotcInc) }
func BenchmarkDotcInc_2_inc2(t *testing.B) { benchdoti(t, 2, 2, DotcInc) }
func BenchmarkDotcInc_2_inc4(t *testing.B) { benchdoti(t, 2, 4, DotcInc) }
func BenchmarkDotcInc_2_inc10(t *testing.B) { benchdoti(t, 2, 10, DotcInc) }

func BenchmarkDotcInc_3_inc1(t *testing.B) { benchdoti(t, 3, 1, DotcInc) }
func BenchmarkDotcInc_3_inc2(t *testing.B) { benchdoti(t, 3, 2, DotcInc) }
func BenchmarkDotcInc_3_inc4(t *testing.B) { benchdoti(t, 3, 4, DotcInc) }
func BenchmarkDotcInc_3_inc10(t *testing.B) { benchdoti(t, 3, 10, DotcInc) }

func BenchmarkDotcInc_4_inc1(t *testing.B) { benchdoti(t, 4, 1, DotcInc) }
func BenchmarkDotcInc_4_inc2(t *testing.B) { benchdoti(t, 4, 2, DotcInc) }
func BenchmarkDotcInc_4_inc4(t *testing.B) { benchdoti(t, 4, 4, DotcInc) }
func BenchmarkDotcInc_4_inc10(t *testing.B) { benchdoti(t, 4, 10, DotcInc) }

func BenchmarkDotcInc_10_inc1(t *testing.B) { benchdoti(t, 10, 1, DotcInc) }
func BenchmarkDotcInc_10_inc2(t *testing.B) { benchdoti(t, 10, 2, DotcInc) }
func BenchmarkDotcInc_10_inc4(t *testing.B) { benchdoti(t, 10, 4, DotcInc) }
func BenchmarkDotcInc_10_inc10(t *testing.B) { benchdoti(t, 10, 10, DotcInc) }

func BenchmarkDotcInc_1000_inc1(t *testing.B) { benchdoti(t, 1000, 1, DotcInc) }
func BenchmarkDotcInc_1000_inc2(t *testing.B) { benchdoti(t, 1000, 2, DotcInc) }
func BenchmarkDotcInc_1000_inc4(t *testing.B) { benchdoti(t, 1000, 4, DotcInc) }
func BenchmarkDotcInc_1000_inc10(t *testing.B) { benchdoti(t, 1000, 10, DotcInc) }

func BenchmarkDotcInc_100000_inc1(t *testing.B) { benchdoti(t, 100000, 1, DotcInc) }
func BenchmarkDotcInc_100000_inc2(t *testing.B) { benchdoti(t, 100000, 2, DotcInc) }
func BenchmarkDotcInc_100000_inc4(t *testing.B) { benchdoti(t, 100000, 4, DotcInc) }
func BenchmarkDotcInc_100000_inc10(t *testing.B) { benchdoti(t, 100000, 10, DotcInc) }

func BenchmarkDotcInc_100000_incM1(t *testing.B) { benchdoti(t, 100000, -1, DotcInc) }
func BenchmarkDotcInc_100000_incM2(t *testing.B) { benchdoti(t, 100000, -2, DotcInc) }
func BenchmarkDotcInc_100000_incM4(t *testing.B) { benchdoti(t, 100000, -4, DotcInc) }

func BenchmarkDotuInc_1_inc1(t *testing.B) { benchdoti(t, 1, 1, DotuInc) }

func BenchmarkDotuInc_2_inc1(t *testing.B) { benchdoti(t, 2, 1, DotuInc) }
func BenchmarkDotuInc_2_inc2(t *testing.B) { benchdoti(t, 2, 2, DotuInc) }
func BenchmarkDotuInc_2_inc4(t *testing.B) { benchdoti(t, 2, 4, DotuInc) }
func BenchmarkDotuInc_2_inc10(t *testing.B) { benchdoti(t, 2, 10, DotuInc) }

func BenchmarkDotuInc_3_inc1(t *testing.B) { benchdoti(t, 3, 1, DotuInc) }
func BenchmarkDotuInc_3_inc2(t *testing.B) { benchdoti(t, 3, 2, DotuInc) }
func BenchmarkDotuInc_3_inc4(t *testing.B) { benchdoti(t, 3, 4, DotuInc) }
func BenchmarkDotuInc_3_inc10(t *testing.B) { benchdoti(t, 3, 10, DotuInc) }

func BenchmarkDotuInc_4_inc1(t *testing.B) { benchdoti(t, 4, 1, DotuInc) }
func BenchmarkDotuInc_4_inc2(t *testing.B) { benchdoti(t, 4, 2, DotuInc) }
func BenchmarkDotuInc_4_inc4(t *testing.B) { benchdoti(t, 4, 4, DotuInc) }
func BenchmarkDotuInc_4_inc10(t *testing.B) { benchdoti(t, 4, 10, DotuInc) }

func BenchmarkDotuInc_10_inc1(t *testing.B) { benchdoti(t, 10, 1, DotuInc) }
func BenchmarkDotuInc_10_inc2(t *testing.B) { benchdoti(t, 10, 2, DotuInc) }
func BenchmarkDotuInc_10_inc4(t *testing.B) { benchdoti(t, 10, 4, DotuInc) }
func BenchmarkDotuInc_10_inc10(t *testing.B) { benchdoti(t, 10, 10, DotuInc) }

func BenchmarkDotuInc_1000_inc1(t *testing.B) { benchdoti(t, 1000, 1, DotuInc) }
func BenchmarkDotuInc_1000_inc2(t *testing.B) { benchdoti(t, 1000, 2, DotuInc) }
func BenchmarkDotuInc_1000_inc4(t *testing.B) { benchdoti(t, 1000, 4, DotuInc) }
func BenchmarkDotuInc_1000_inc10(t *testing.B) { benchdoti(t, 1000, 10, DotuInc) }

func BenchmarkDotuInc_100000_inc1(t *testing.B) { benchdoti(t, 100000, 1, DotuInc) }
func BenchmarkDotuInc_100000_inc2(t *testing.B) { benchdoti(t, 100000, 2, DotuInc) }
func BenchmarkDotuInc_100000_inc4(t *testing.B) { benchdoti(t, 100000, 4, DotuInc) }
func BenchmarkDotuInc_100000_inc10(t *testing.B) { benchdoti(t, 100000, 10, DotuInc) }

func BenchmarkDotuInc_100000_incM1(t *testing.B) { benchdoti(t, 100000, -1, DotuInc) }
func BenchmarkDotuInc_100000_incM2(t *testing.B) { benchdoti(t, 100000, -2, DotuInc) }
func BenchmarkDotuInc_100000_incM4(t *testing.B) { benchdoti(t, 100000, -4, DotuInc) }
57 changes: 57 additions & 0 deletions internal/asm/c128/benchDot_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright ©2017 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build go1.7

package c128

import (
"fmt"
"testing"
)

func BenchmarkDotUnitary(t *testing.B) {
for _, test := range []struct {
name string
f func(x, y []complex128) complex128
}{
{"DotcUnitary", DotcUnitary},
{"DotuUnitary", DotuUnitary},
} {
for _, v := range []int64{1, 2, 3, 4, 5, 10, 100, 1e3, 5e3, 1e4, 5e4} {
t.Run(fmt.Sprintf("%s-%d", test.name, v), func(b *testing.B) {
x, y := x[:v], y[:v]
b.SetBytes(256 * v)
for i := 0; i < b.N; i++ {
_ = test.f(x, y)
}
})
}
}
}

func BenchmarkDotInc(t *testing.B) {
for _, test := range []struct {
name string
f func(x, y []complex128, n, incX, incY, ix, iy uintptr) complex128
}{
{"DotcInc", DotcInc},
{"DotuInc", DotuInc},
} {
for _, ln := range []int{1, 2, 3, 4, 5, 10, 100, 1e3, 5e3, 1e4, 5e4} {
for _, inc := range []int{1, 2, 4, 10, -1, -2, -4, -10} {
t.Run(fmt.Sprintf("%s-%d-inc%d", test.name, ln, inc), func(b *testing.B) {
b.SetBytes(int64(256 * ln))
var idx int
if inc < 0 {
idx = (-ln + 1) * inc
}
for i := 0; i < b.N; i++ {
_ = test.f(x, y, uintptr(ln), uintptr(inc), uintptr(inc), uintptr(idx), uintptr(idx))
}
})
}
}
}
}
168 changes: 168 additions & 0 deletions internal/asm/c128/dot_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
// Copyright ©2017 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package c128

import (
"fmt"
"testing"
)

var dotTests = []struct {
x, y []complex128
exu, exc complex128
exuRev, excRev complex128
n int
}{
{
x: []complex128{},
y: []complex128{},
n: 0,
exu: 0, exc: 0,
exuRev: 0, excRev: 0,
},
{
x: []complex128{1 + 1i},
y: []complex128{1 + 1i},
n: 1,
exu: 0 + 2i, exc: 2,
exuRev: 0 + 2i, excRev: 2,
},
{
x: []complex128{1 + 2i},
y: []complex128{1 + 1i},
n: 1,
exu: -1 + 3i, exc: 3 - 1i,
exuRev: -1 + 3i, excRev: 3 - 1i,
},
{
x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i},
y: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i},
n: 10,
exu: -210 + 2860i, exc: 2870 + 0i,
exuRev: -210 + 1540i, excRev: 1550 + 0i,
},
{
x: []complex128{1 + 1i, 1 + 1i, 1 + 2i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 3i, 1 + 1i, 1 + 1i, 1 + 4i},
y: []complex128{1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i},
n: 10,
exu: -22 + 36i, exc: 42 + 4i,
exuRev: -22 + 36i, excRev: 42 + 4i,
},
{
x: []complex128{1 + 1i, 1 + 1i, 2 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 2 + 1i},
y: []complex128{1 + 2i, 1 + 2i, 1 + 3i, 1 + 2i, 1 + 3i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i},
n: 10,
exu: -10 + 37i, exc: 34 + 17i,
exuRev: -10 + 36i, excRev: 34 + 16i,
},
{
x: []complex128{1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, complex(inf, 1), 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i, 1 + 1i},
y: []complex128{1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i, 1 + 2i},
n: 10,
exu: complex(inf, inf), exc: complex(inf, inf),
exuRev: complex(inf, inf), excRev: complex(inf, inf),
},
}

func TestDotcUnitary(t *testing.T) {
const gd = 1 + 5i
for i, test := range dotTests {
for _, align := range align2 {
prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y)
xgLn, ygLn := 4+align.x, 4+align.y
xg, yg := guardVector(test.x, gd, xgLn), guardVector(test.y, gd, ygLn)
x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn]
res := DotcUnitary(x, y)
if !same(res, test.exc) {
t.Errorf(msgVal, prefix, i, res, test.exc)
}
if !isValidGuard(xg, gd, xgLn) {
t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:])
}
if !isValidGuard(yg, gd, ygLn) {
t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:])
}
}
}
}

func TestDotcInc(t *testing.T) {
const gd, gdLn = 2 + 5i, 4
for i, test := range dotTests {
for _, inc := range newIncSet(1, 2, 5, 10, -1, -2, -5, -10) {
xg, yg := guardIncVector(test.x, gd, inc.x, gdLn), guardIncVector(test.y, gd, inc.y, gdLn)
x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn]
want := test.exc
var ix, iy int
if inc.x < 0 {
ix, want = -inc.x*(test.n-1), test.excRev
}
if inc.y < 0 {
iy, want = -inc.y*(test.n-1), test.excRev
}
prefix := fmt.Sprintf("Test %v (x:%v y:%v) (ix:%v iy:%v)", i, inc.x, inc.y, ix, iy)
res := DotcInc(x, y, uintptr(test.n), uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy))
if inc.x*inc.y > 0 {
want = test.exc
}
if !same(res, want) {
t.Errorf(msgVal, prefix, i, res, want)
t.Error(x, y)
}
checkValidIncGuard(t, xg, gd, inc.x, gdLn)
checkValidIncGuard(t, yg, gd, inc.y, gdLn)
}
}
}

func TestDotuUnitary(t *testing.T) {
const gd = 1 + 5i
for i, test := range dotTests {
for _, align := range align2 {
prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y)
xgLn, ygLn := 4+align.x, 4+align.y
xg, yg := guardVector(test.x, gd, xgLn), guardVector(test.y, gd, ygLn)
x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn]
res := DotuUnitary(x, y)
if !same(res, test.exu) {
t.Errorf(msgVal, prefix, i, res, test.exu)
}
if !isValidGuard(xg, gd, xgLn) {
t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:])
}
if !isValidGuard(yg, gd, ygLn) {
t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:])
}
}
}
}

func TestDotuInc(t *testing.T) {
const gd, gdLn = 1 + 5i, 4
for i, test := range dotTests {
for _, inc := range newIncSet(1, 2, 5, 10, -1, -2, -5, -10) {
prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, inc.x, inc.y)
xg, yg := guardIncVector(test.x, gd, inc.x, gdLn), guardIncVector(test.y, gd, inc.y, gdLn)
x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn]
want := test.exc
var ix, iy int
if inc.x < 0 {
ix, want = -inc.x*(test.n-1), test.exuRev
}
if inc.y < 0 {
iy, want = -inc.y*(test.n-1), test.exuRev
}
res := DotuInc(x, y, uintptr(test.n), uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy))
if inc.x*inc.y > 0 {
want = test.exu
}
if !same(res, want) {
t.Errorf(msgVal, prefix, i, res, want)
}
checkValidIncGuard(t, xg, gd, inc.x, gdLn)
checkValidIncGuard(t, yg, gd, inc.y, gdLn)
}
}
}
4 changes: 4 additions & 0 deletions internal/asm/c128/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const (
msgGuard = "%v: Guard violated in %s vector %v %v"
)

var (
inf = math.Inf(1)
)

func same(x, y complex128) bool {
return (x == y ||
math.IsNaN(real(x)) && math.IsNaN(real(y)) && imag(x) == imag(y) ||
Expand Down

0 comments on commit 9a34c3c

Please sign in to comment.