Source file src/simd/archsimd/_gen/cmd/hostinfo/main.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build goexperiment.simd
     6  
     7  package main
     8  
     9  import (
    10  	"flag"
    11  	"fmt"
    12  	"os"
    13  	"reflect"
    14  	"runtime"
    15  	"strconv"
    16  	"strings"
    17  
    18  	"simd/archsimd"
    19  )
    20  
    21  type row struct {
    22  	name  string
    23  	value string
    24  }
    25  
    26  func main() {
    27  	defaultHost := os.Getenv("GO_BUILDER_NAME")
    28  	if defaultHost == "" {
    29  		if h, err := os.Hostname(); err == nil && h != "" {
    30  			defaultHost = h
    31  		} else {
    32  			defaultHost = "host"
    33  		}
    34  	}
    35  
    36  	hostFlag := flag.String("host", defaultHost, "host or builder name to display in the table header")
    37  	flag.Parse()
    38  
    39  	var archName string
    40  	var rows []row
    41  
    42  	switch runtime.GOARCH {
    43  	case "amd64":
    44  		archName = "amd64"
    45  		rows = reflectFeatures(archsimd.X86)
    46  	case "arm64":
    47  		archName = "arm64"
    48  		rows = reflectFeatures(archsimd.ARM64)
    49  		if bits, ok := sveVectorBits(); ok {
    50  			rows = append(rows, row{name: "SVE vector size", value: strconv.Itoa(bits)})
    51  		} else {
    52  			rows = append(rows, row{name: "SVE vector size", value: "n/a"})
    53  		}
    54  	case "wasm":
    55  		archName = "wasm"
    56  		// Smoke check basic SIMD execution
    57  		_ = archsimd.Int32x4{}.Add(archsimd.Int32x4{})
    58  		rows = append(rows, row{name: "SIMD128", value: "✔"})
    59  	default:
    60  		archName = runtime.GOARCH
    61  		rows = append(rows, row{name: "Supported", value: "✘"})
    62  	}
    63  
    64  	printTable(archName, *hostFlag, rows)
    65  }
    66  
    67  func reflectFeatures(receiver any) []row {
    68  	t := reflect.TypeOf(receiver)
    69  	v := reflect.ValueOf(receiver)
    70  
    71  	var rows []row
    72  	for i := 0; i < t.NumMethod(); i++ {
    73  		m := t.Method(i)
    74  		res := m.Func.Call([]reflect.Value{v})[0].Bool()
    75  		valStr := "✘"
    76  		if res {
    77  			valStr = "✔"
    78  		}
    79  		rows = append(rows, row{
    80  			name:  m.Name,
    81  			value: valStr,
    82  		})
    83  	}
    84  	return rows
    85  }
    86  
    87  func printTable(arch, host string, rows []row) {
    88  	col1Width := len(arch)
    89  	col2Width := len(host)
    90  
    91  	for _, r := range rows {
    92  		if len(r.name) > col1Width {
    93  			col1Width = len(r.name)
    94  		}
    95  		if len(r.value) > col2Width {
    96  			col2Width = len(r.value)
    97  		}
    98  	}
    99  
   100  	header := fmt.Sprintf("| %-*s | %-*s |", col1Width, arch, col2Width, host)
   101  	sep := fmt.Sprintf("| %s | %s |", strings.Repeat("-", col1Width), strings.Repeat("-", col2Width))
   102  
   103  	fmt.Println(header)
   104  	fmt.Println(sep)
   105  	for _, r := range rows {
   106  		fmt.Printf("| %-*s | %-*s |\n", col1Width, r.name, col2Width, r.value)
   107  	}
   108  }
   109  

View as plain text