| // Copyright 2026 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 | |
| package main | |
| import ( | |
| "flag" | |
| "fmt" | |
| "os" | |
| "reflect" | |
| "runtime" | |
| "strconv" | |
| "strings" | |
| "simd/archsimd" | |
| ) | |
| type row struct { | |
| name string | |
| value string | |
| } | |
| func main() { | |
| defaultHost := os.Getenv("GO_BUILDER_NAME") | |
| if defaultHost == "" { | |
| if h, err := os.Hostname(); err == nil && h != "" { | |
| defaultHost = h | |
| } else { | |
| defaultHost = "host" | |
| } | |
| } | |
| hostFlag := flag.String("host", defaultHost, "host or builder name to display in the table header") | |
| flag.Parse() | |
| var archName string | |
| var rows []row | |
| switch runtime.GOARCH { | |
| case "amd64": | |
| archName = "amd64" | |
| rows = reflectFeatures(archsimd.X86) | |
| case "arm64": | |
| archName = "arm64" | |
| rows = reflectFeatures(archsimd.ARM64) | |
| if bits, ok := sveVectorBits(); ok { | |
| rows = append(rows, row{name: "SVE vector size", value: strconv.Itoa(bits)}) | |
| } else { | |
| rows = append(rows, row{name: "SVE vector size", value: "n/a"}) | |
| } | |
| case "wasm": | |
| archName = "wasm" | |
| // Smoke check basic SIMD execution | |
| _ = archsimd.Int32x4{}.Add(archsimd.Int32x4{}) | |
| rows = append(rows, row{name: "SIMD128", value: "✔"}) | |
| default: | |
| archName = runtime.GOARCH | |
| rows = append(rows, row{name: "Supported", value: "✘"}) | |
| } | |
| printTable(archName, *hostFlag, rows) | |
| } | |
| func reflectFeatures(receiver any) []row { | |
| t := reflect.TypeOf(receiver) | |
| v := reflect.ValueOf(receiver) | |
| var rows []row | |
| for i := 0; i < t.NumMethod(); i++ { | |
| m := t.Method(i) | |
| res := m.Func.Call([]reflect.Value{v})[0].Bool() | |
| valStr := "✘" | |
| if res { | |
| valStr = "✔" | |
| } | |
| rows = append(rows, row{ | |
| name: m.Name, | |
| value: valStr, | |
| }) | |
| } | |
| return rows | |
| } | |
| func printTable(arch, host string, rows []row) { | |
| col1Width := len(arch) | |
| col2Width := len(host) | |
| for _, r := range rows { | |
| if len(r.name) > col1Width { | |
| col1Width = len(r.name) | |
| } | |
| if len(r.value) > col2Width { | |
| col2Width = len(r.value) | |
| } | |
| } | |
| header := fmt.Sprintf("| %-*s | %-*s |", col1Width, arch, col2Width, host) | |
| sep := fmt.Sprintf("| %s | %s |", strings.Repeat("-", col1Width), strings.Repeat("-", col2Width)) | |
| fmt.Println(header) | |
| fmt.Println(sep) | |
| for _, r := range rows { | |
| fmt.Printf("| %-*s | %-*s |\n", col1Width, r.name, col2Width, r.value) | |
| } | |
| } |