mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.simd] simd: added String() method to SIMD vectors.
this required a little plumbing to get access to the "good" floating point formatting. Change-Id: Iebec157c28a39df59351bade53b09a3729fc49c0 Reviewed-on: https://go-review.googlesource.com/c/go/+/711781 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
d03634f807
commit
c75965b666
7 changed files with 335 additions and 4 deletions
|
|
@ -49,11 +49,13 @@ var depsRules = `
|
|||
internal/coverage/uleb128,
|
||||
internal/coverage/calloc,
|
||||
internal/cpu,
|
||||
internal/ftoa,
|
||||
internal/goarch,
|
||||
internal/godebugs,
|
||||
internal/goexperiment,
|
||||
internal/goos,
|
||||
internal/goversion,
|
||||
internal/itoa,
|
||||
internal/nettrace,
|
||||
internal/platform,
|
||||
internal/profilerecord,
|
||||
|
|
@ -70,7 +72,7 @@ var depsRules = `
|
|||
internal/goarch < internal/abi;
|
||||
internal/byteorder, internal/cpu, internal/goarch < internal/chacha8rand;
|
||||
|
||||
internal/cpu < simd;
|
||||
internal/cpu, internal/ftoa, internal/itoa < simd;
|
||||
|
||||
# RUNTIME is the core runtime group of packages, all of them very light-weight.
|
||||
internal/abi,
|
||||
|
|
@ -81,13 +83,13 @@ var depsRules = `
|
|||
internal/godebugs,
|
||||
internal/goexperiment,
|
||||
internal/goos,
|
||||
internal/itoa,
|
||||
internal/profilerecord,
|
||||
internal/trace/tracev2,
|
||||
math/bits,
|
||||
structs
|
||||
< internal/bytealg
|
||||
< internal/stringslite
|
||||
< internal/itoa
|
||||
< internal/unsafeheader
|
||||
< internal/race
|
||||
< internal/msan
|
||||
|
|
@ -175,7 +177,7 @@ var depsRules = `
|
|||
MATH
|
||||
< runtime/metrics;
|
||||
|
||||
MATH, unicode/utf8
|
||||
MATH, unicode/utf8, internal/ftoa
|
||||
< strconv;
|
||||
|
||||
unicode !< strconv;
|
||||
|
|
|
|||
23
src/internal/ftoa/ftoa.go
Normal file
23
src/internal/ftoa/ftoa.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2025 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// A hook to get correct floating point conversion from strconv
|
||||
// in packages that cannot import strconv.
|
||||
|
||||
package ftoa
|
||||
|
||||
var formatFloatPtr func(f float64, fmt byte, prec, bitSize int) string
|
||||
|
||||
func FormatFloat(f float64, fmt byte, prec, bitSize int) string {
|
||||
if formatFloatPtr != nil {
|
||||
return formatFloatPtr(f, fmt, prec, bitSize)
|
||||
}
|
||||
return "internal/ftoa.formatFloatPtr called before strconv.init()"
|
||||
}
|
||||
|
||||
func SetFormatFloat(ff func(f float64, fmt byte, prec, bitSize int) string) {
|
||||
if formatFloatPtr == nil {
|
||||
formatFloatPtr = ff
|
||||
}
|
||||
}
|
||||
|
|
@ -263,6 +263,7 @@ func unsafePrologue(s string, out io.Writer) {
|
|||
package simd
|
||||
|
||||
import "unsafe"
|
||||
|
||||
`, s)
|
||||
}
|
||||
|
||||
|
|
@ -795,6 +796,15 @@ func (from {{.Base}}{{.WxC}}) ToMask() (to Mask{{.WxC}}) {
|
|||
}
|
||||
`)
|
||||
|
||||
var stringTemplate = shapedTemplateOf(allShapes, "String methods", `
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x {{.VType}}) String() string {
|
||||
var s [{{.Count}}]{{.Etype}}
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
`)
|
||||
|
||||
const TD = "internal/simd_test/"
|
||||
|
||||
func main() {
|
||||
|
|
@ -836,6 +846,7 @@ func main() {
|
|||
maskCvtTemplate,
|
||||
bitWiseIntTemplate,
|
||||
bitWiseUintTemplate,
|
||||
stringTemplate,
|
||||
)
|
||||
}
|
||||
if *ush != "" {
|
||||
|
|
|
|||
|
|
@ -1001,3 +1001,32 @@ func TestSelect2FromPairConstGroupedInt512(t *testing.T) {
|
|||
foo(lh, 0, 3)
|
||||
foo(hl, 2, 1)
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
x := simd.LoadUint32x4Slice([]uint32{0, 1, 2, 3})
|
||||
y := simd.LoadInt64x4Slice([]int64{-4, -5, -6, -7})
|
||||
z := simd.LoadFloat32x4Slice([]float32{0.5, 1.5, -2.5, 3.5e9})
|
||||
w := simd.LoadFloat64x4Slice([]float64{0.5, 1.5, -2.5, 3.5e9})
|
||||
|
||||
sx := "{0,1,2,3}"
|
||||
sy := "{-4,-5,-6,-7}"
|
||||
sz := "{0.5,1.5,-2.5,3.5e+09}"
|
||||
sw := sz
|
||||
|
||||
if x.String() != sx {
|
||||
t.Errorf("x=%s wanted %s", x, sx)
|
||||
}
|
||||
if y.String() != sy {
|
||||
t.Errorf("y=%s wanted %s", y, sy)
|
||||
}
|
||||
if z.String() != sz {
|
||||
t.Errorf("z=%s wanted %s", z, sz)
|
||||
}
|
||||
if w.String() != sw {
|
||||
t.Errorf("w=%s wanted %s", w, sw)
|
||||
}
|
||||
t.Logf("w=%s", w)
|
||||
t.Logf("x=%s", x)
|
||||
t.Logf("y=%s", y)
|
||||
t.Logf("z=%s", z)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -591,3 +591,213 @@ func (x Uint32x16) Not() Uint32x16 {
|
|||
func (x Uint64x8) Not() Uint64x8 {
|
||||
return x.Xor(x.Equal(x).AsInt64x8().AsUint64x8())
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int8x16) String() string {
|
||||
var s [16]int8
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int16x8) String() string {
|
||||
var s [8]int16
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int32x4) String() string {
|
||||
var s [4]int32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int64x2) String() string {
|
||||
var s [2]int64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint8x16) String() string {
|
||||
var s [16]uint8
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint16x8) String() string {
|
||||
var s [8]uint16
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint32x4) String() string {
|
||||
var s [4]uint32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint64x2) String() string {
|
||||
var s [2]uint64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Float32x4) String() string {
|
||||
var s [4]float32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Float64x2) String() string {
|
||||
var s [2]float64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int8x32) String() string {
|
||||
var s [32]int8
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int16x16) String() string {
|
||||
var s [16]int16
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int32x8) String() string {
|
||||
var s [8]int32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int64x4) String() string {
|
||||
var s [4]int64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint8x32) String() string {
|
||||
var s [32]uint8
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint16x16) String() string {
|
||||
var s [16]uint16
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint32x8) String() string {
|
||||
var s [8]uint32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint64x4) String() string {
|
||||
var s [4]uint64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Float32x8) String() string {
|
||||
var s [8]float32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Float64x4) String() string {
|
||||
var s [4]float64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int8x64) String() string {
|
||||
var s [64]int8
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int16x32) String() string {
|
||||
var s [32]int16
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int32x16) String() string {
|
||||
var s [16]int32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Int64x8) String() string {
|
||||
var s [8]int64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint8x64) String() string {
|
||||
var s [64]uint8
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint16x32) String() string {
|
||||
var s [32]uint16
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint32x16) String() string {
|
||||
var s [16]uint32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Uint64x8) String() string {
|
||||
var s [8]uint64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Float32x16) String() string {
|
||||
var s [16]float32
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
||||
// String returns a string representation of SIMD vector x
|
||||
func (x Float64x8) String() string {
|
||||
var s [8]float64
|
||||
x.Store(&s)
|
||||
return sliceToString(s[:])
|
||||
}
|
||||
|
|
|
|||
49
src/simd/string.go
Normal file
49
src/simd/string.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2025 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build goexperiment.simd && amd64
|
||||
|
||||
package simd
|
||||
|
||||
import (
|
||||
"internal/ftoa"
|
||||
"internal/itoa"
|
||||
)
|
||||
|
||||
type number interface {
|
||||
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
|
||||
}
|
||||
|
||||
func sliceToString[T number](x []T) string {
|
||||
s := ""
|
||||
pfx := "{"
|
||||
for _, y := range x {
|
||||
s += pfx
|
||||
pfx = ","
|
||||
switch e := any(y).(type) {
|
||||
case int8:
|
||||
s += itoa.Itoa(int(e))
|
||||
case int16:
|
||||
s += itoa.Itoa(int(e))
|
||||
case int32:
|
||||
s += itoa.Itoa(int(e))
|
||||
case int64:
|
||||
s += itoa.Itoa(int(e))
|
||||
case uint8:
|
||||
s += itoa.Uitoa(uint(e))
|
||||
case uint16:
|
||||
s += itoa.Uitoa(uint(e))
|
||||
case uint32:
|
||||
s += itoa.Uitoa(uint(e))
|
||||
case uint64:
|
||||
s += itoa.Uitoa(uint(e))
|
||||
case float32:
|
||||
s += ftoa.FormatFloat(float64(e), 'g', -1, 32)
|
||||
case float64:
|
||||
s += ftoa.FormatFloat(e, 'g', -1, 64)
|
||||
}
|
||||
}
|
||||
s += "}"
|
||||
return s
|
||||
}
|
||||
|
|
@ -10,7 +10,10 @@
|
|||
|
||||
package strconv
|
||||
|
||||
import "math"
|
||||
import (
|
||||
"internal/ftoa"
|
||||
"math"
|
||||
)
|
||||
|
||||
// TODO: move elsewhere?
|
||||
type floatInfo struct {
|
||||
|
|
@ -22,6 +25,10 @@ type floatInfo struct {
|
|||
var float32info = floatInfo{23, 8, -127}
|
||||
var float64info = floatInfo{52, 11, -1023}
|
||||
|
||||
func init() {
|
||||
ftoa.SetFormatFloat(FormatFloat)
|
||||
}
|
||||
|
||||
// FormatFloat converts the floating-point number f to a string,
|
||||
// according to the format fmt and precision prec. It rounds the
|
||||
// result assuming that the original was obtained from a floating-point
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue