mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.simd] simd: add tests for simd conversions to Int32/Uint32.
Change-Id: I71a6c6708e19d210f1fbdc72379f8215356ff02e Reviewed-on: https://go-review.googlesource.com/c/go/+/689718 Reviewed-by: Junyang Shao <shaojunyang@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
a24ffe3379
commit
09ff25e350
4 changed files with 145 additions and 3 deletions
|
|
@ -43,7 +43,7 @@ var allShapes = &shapes{
|
||||||
|
|
||||||
// these are the shapes that are currently converted to int32
|
// these are the shapes that are currently converted to int32
|
||||||
// (not all conversions are available, yet)
|
// (not all conversions are available, yet)
|
||||||
var toInt32Shapes = &shapes{
|
var convert32Shapes = &shapes{
|
||||||
vecs: []int{128, 256, 512},
|
vecs: []int{128, 256, 512},
|
||||||
floats: []int{32},
|
floats: []int{32},
|
||||||
}
|
}
|
||||||
|
|
@ -187,7 +187,7 @@ func test{{.Vec}}Unary(t *testing.T, f func(_ simd.{{.Vec}}) simd.{{.Vec}}, want
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
var unaryTemplateToInt32 = shapedTemplateOf(toInt32Shapes, "unary_int32_helpers", `
|
var unaryTemplateToInt32 = shapedTemplateOf(convert32Shapes, "unary_int32_helpers", `
|
||||||
// test{{.Vec}}Unary tests the simd unary method f against the expected behavior generated by want
|
// test{{.Vec}}Unary tests the simd unary method f against the expected behavior generated by want
|
||||||
func test{{.Vec}}UnaryToInt32(t *testing.T, f func(x simd.{{.Vec}}) simd.Int32x{{.Count}}, want func(x []{{.Type}}) []int32) {
|
func test{{.Vec}}UnaryToInt32(t *testing.T, f func(x simd.{{.Vec}}) simd.Int32x{{.Count}}, want func(x []{{.Type}}) []int32) {
|
||||||
n := {{.Count}}
|
n := {{.Count}}
|
||||||
|
|
@ -203,6 +203,22 @@ func test{{.Vec}}UnaryToInt32(t *testing.T, f func(x simd.{{.Vec}}) simd.Int32x{
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
var unaryTemplateToUint32 = shapedTemplateOf(convert32Shapes, "unary_uint32_helpers", `
|
||||||
|
// test{{.Vec}}Unary tests the simd unary method f against the expected behavior generated by want
|
||||||
|
func test{{.Vec}}UnaryToUint32(t *testing.T, f func(x simd.{{.Vec}}) simd.Uint32x{{.Count}}, want func(x []{{.Type}}) []uint32) {
|
||||||
|
n := {{.Count}}
|
||||||
|
t.Helper()
|
||||||
|
forSlice(t, {{.Type}}s, n, func(x []{{.Type}}) bool {
|
||||||
|
t.Helper()
|
||||||
|
a := simd.Load{{.Vec}}Slice(x)
|
||||||
|
g := make([]uint32, n)
|
||||||
|
f(a).StoreSlice(g)
|
||||||
|
w := want(x)
|
||||||
|
return checkSlicesLogInput(t, g, w, func() {t.Helper(); t.Logf("x=%v", x)})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
var binaryTemplate = templateOf("binary_helpers", `
|
var binaryTemplate = templateOf("binary_helpers", `
|
||||||
// test{{.Vec}}Binary tests the simd binary method f against the expected behavior generated by want
|
// test{{.Vec}}Binary tests the simd binary method f against the expected behavior generated by want
|
||||||
func test{{.Vec}}Binary(t *testing.T, f func(_, _ simd.{{.Vec}}) simd.{{.Vec}}, want func(_, _ []{{.Type}}) []{{.Type}}) {
|
func test{{.Vec}}Binary(t *testing.T, f func(_, _ simd.{{.Vec}}) simd.{{.Vec}}, want func(_, _ []{{.Type}}) []{{.Type}}) {
|
||||||
|
|
@ -295,7 +311,7 @@ func main() {
|
||||||
one(*sl, prologue, sliceTemplate)
|
one(*sl, prologue, sliceTemplate)
|
||||||
}
|
}
|
||||||
if *uh != "" {
|
if *uh != "" {
|
||||||
one(*uh, curryTestPrologue("unary simd methods"), unaryTemplate)
|
one(*uh, curryTestPrologue("unary simd methods"), unaryTemplate, unaryTemplateToInt32, unaryTemplateToUint32)
|
||||||
}
|
}
|
||||||
if *bh != "" {
|
if *bh != "" {
|
||||||
one(*bh, curryTestPrologue("binary simd methods"), binaryTemplate)
|
one(*bh, curryTestPrologue("binary simd methods"), binaryTemplate)
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,26 @@ func fma[T float](x, y, z T) T {
|
||||||
return T(math.FMA(float64(x), float64(y), float64(z)))
|
return T(math.FMA(float64(x), float64(y), float64(z)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toInt32[T number](x T) int32 {
|
||||||
|
return int32(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func toUint32[T number](x T) uint32 {
|
||||||
|
switch y := (any(x)).(type) {
|
||||||
|
case float32:
|
||||||
|
if y < 0 || y > float32(math.MaxUint32) || y != y {
|
||||||
|
return math.MaxUint32
|
||||||
|
}
|
||||||
|
case float64:
|
||||||
|
if y < 0 || y > float64(math.MaxUint32) || y != y {
|
||||||
|
return math.MaxUint32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uint32(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slice versions of all these elementwise operations
|
||||||
|
|
||||||
func addSlice[T number](x, y []T) []T {
|
func addSlice[T number](x, y []T) []T {
|
||||||
return map2[T](add)(x, y)
|
return map2[T](add)(x, y)
|
||||||
}
|
}
|
||||||
|
|
@ -202,3 +222,11 @@ func imaSlice[T integer](x, y, z []T) []T {
|
||||||
func fmaSlice[T float](x, y, z []T) []T {
|
func fmaSlice[T float](x, y, z []T) []T {
|
||||||
return map3[T](fma)(x, y, z)
|
return map3[T](fma)(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toInt32Slice[T number](x []T) []int32 {
|
||||||
|
return map1[T](toInt32)(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func toUint32Slice[T number](x []T) []uint32 {
|
||||||
|
return map1[T](toUint32)(x)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -432,3 +432,87 @@ func testFloat64x8Unary(t *testing.T, f func(_ simd.Float64x8) simd.Float64x8, w
|
||||||
return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
|
return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testFloat32x4Unary tests the simd unary method f against the expected behavior generated by want
|
||||||
|
func testFloat32x4UnaryToInt32(t *testing.T, f func(x simd.Float32x4) simd.Int32x4, want func(x []float32) []int32) {
|
||||||
|
n := 4
|
||||||
|
t.Helper()
|
||||||
|
forSlice(t, float32s, n, func(x []float32) bool {
|
||||||
|
t.Helper()
|
||||||
|
a := simd.LoadFloat32x4Slice(x)
|
||||||
|
g := make([]int32, n)
|
||||||
|
f(a).StoreSlice(g)
|
||||||
|
w := want(x)
|
||||||
|
return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// testFloat32x8Unary tests the simd unary method f against the expected behavior generated by want
|
||||||
|
func testFloat32x8UnaryToInt32(t *testing.T, f func(x simd.Float32x8) simd.Int32x8, want func(x []float32) []int32) {
|
||||||
|
n := 8
|
||||||
|
t.Helper()
|
||||||
|
forSlice(t, float32s, n, func(x []float32) bool {
|
||||||
|
t.Helper()
|
||||||
|
a := simd.LoadFloat32x8Slice(x)
|
||||||
|
g := make([]int32, n)
|
||||||
|
f(a).StoreSlice(g)
|
||||||
|
w := want(x)
|
||||||
|
return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// testFloat32x16Unary tests the simd unary method f against the expected behavior generated by want
|
||||||
|
func testFloat32x16UnaryToInt32(t *testing.T, f func(x simd.Float32x16) simd.Int32x16, want func(x []float32) []int32) {
|
||||||
|
n := 16
|
||||||
|
t.Helper()
|
||||||
|
forSlice(t, float32s, n, func(x []float32) bool {
|
||||||
|
t.Helper()
|
||||||
|
a := simd.LoadFloat32x16Slice(x)
|
||||||
|
g := make([]int32, n)
|
||||||
|
f(a).StoreSlice(g)
|
||||||
|
w := want(x)
|
||||||
|
return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// testFloat32x4Unary tests the simd unary method f against the expected behavior generated by want
|
||||||
|
func testFloat32x4UnaryToUint32(t *testing.T, f func(x simd.Float32x4) simd.Uint32x4, want func(x []float32) []uint32) {
|
||||||
|
n := 4
|
||||||
|
t.Helper()
|
||||||
|
forSlice(t, float32s, n, func(x []float32) bool {
|
||||||
|
t.Helper()
|
||||||
|
a := simd.LoadFloat32x4Slice(x)
|
||||||
|
g := make([]uint32, n)
|
||||||
|
f(a).StoreSlice(g)
|
||||||
|
w := want(x)
|
||||||
|
return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// testFloat32x8Unary tests the simd unary method f against the expected behavior generated by want
|
||||||
|
func testFloat32x8UnaryToUint32(t *testing.T, f func(x simd.Float32x8) simd.Uint32x8, want func(x []float32) []uint32) {
|
||||||
|
n := 8
|
||||||
|
t.Helper()
|
||||||
|
forSlice(t, float32s, n, func(x []float32) bool {
|
||||||
|
t.Helper()
|
||||||
|
a := simd.LoadFloat32x8Slice(x)
|
||||||
|
g := make([]uint32, n)
|
||||||
|
f(a).StoreSlice(g)
|
||||||
|
w := want(x)
|
||||||
|
return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// testFloat32x16Unary tests the simd unary method f against the expected behavior generated by want
|
||||||
|
func testFloat32x16UnaryToUint32(t *testing.T, f func(x simd.Float32x16) simd.Uint32x16, want func(x []float32) []uint32) {
|
||||||
|
n := 16
|
||||||
|
t.Helper()
|
||||||
|
forSlice(t, float32s, n, func(x []float32) bool {
|
||||||
|
t.Helper()
|
||||||
|
a := simd.LoadFloat32x16Slice(x)
|
||||||
|
g := make([]uint32, n)
|
||||||
|
f(a).StoreSlice(g)
|
||||||
|
w := want(x)
|
||||||
|
return checkSlicesLogInput(t, g, w, func() { t.Helper(); t.Logf("x=%v", x) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,3 +82,17 @@ func TestAbsolute(t *testing.T) {
|
||||||
testInt64x8Unary(t, simd.Int64x8.Absolute, map1[int64](abs))
|
testInt64x8Unary(t, simd.Int64x8.Absolute, map1[int64](abs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestToInt32(t *testing.T) {
|
||||||
|
testFloat32x4UnaryToInt32(t, simd.Float32x4.ConvertToInt32, toInt32Slice[float32])
|
||||||
|
testFloat32x8UnaryToInt32(t, simd.Float32x8.ConvertToInt32, toInt32Slice[float32])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestToUint32(t *testing.T) {
|
||||||
|
if !simd.HasAVX512() {
|
||||||
|
t.Skip("Needs AVX512")
|
||||||
|
}
|
||||||
|
testFloat32x4UnaryToUint32(t, simd.Float32x4.ConvertToUint32, toUint32Slice[float32])
|
||||||
|
testFloat32x8UnaryToUint32(t, simd.Float32x8.ConvertToUint32, toUint32Slice[float32])
|
||||||
|
testFloat32x16UnaryToUint32(t, simd.Float32x16.ConvertToUint32, toUint32Slice[float32])
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue