Source file src/simd/internal/test_helpers/checkslices.go

     1  // Copyright 2025 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 && amd64
     6  
     7  package test_helpers
     8  
     9  import (
    10  	"math"
    11  	"testing"
    12  )
    13  
    14  type signed interface {
    15  	~int | ~int8 | ~int16 | ~int32 | ~int64
    16  }
    17  
    18  type integer interface {
    19  	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
    20  }
    21  
    22  type float interface {
    23  	~float32 | ~float64
    24  }
    25  
    26  type number interface {
    27  	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
    28  }
    29  
    30  func CheckSlices[T number](t *testing.T, got, want []T) bool {
    31  	t.Helper()
    32  	return CheckSlicesLogInput[T](t, got, want, 0.0, nil)
    33  }
    34  
    35  // CheckSlices compares two slices for equality,
    36  // reporting a test error if there is a problem,
    37  // and also consumes the two slices so that a
    38  // test/benchmark won't be dead-code eliminated.
    39  func CheckSlicesLogInput[T number](t *testing.T, got, want []T, flakiness float64, logInput func()) bool {
    40  	t.Helper()
    41  	var z T
    42  	for i := range want {
    43  		if got[i] != want[i] {
    44  			var ia any = got[i]
    45  			var ib any = want[i]
    46  			switch x := ia.(type) {
    47  			case float32:
    48  				y := ib.(float32)
    49  				if math.IsNaN(float64(x)) && math.IsNaN(float64(y)) {
    50  					continue
    51  				}
    52  				if flakiness > 0 {
    53  					if y == 0 {
    54  						if math.Abs(float64(x)) < flakiness {
    55  							continue
    56  						}
    57  					} else {
    58  						if math.Abs(float64((x-y)/y)) < flakiness {
    59  							continue
    60  						}
    61  					}
    62  				}
    63  			case float64:
    64  				y := ib.(float64)
    65  				if math.IsNaN(x) && math.IsNaN(y) {
    66  					continue
    67  				}
    68  				if flakiness > 0 {
    69  					if y == 0 {
    70  						if math.Abs(x) < flakiness {
    71  							continue
    72  						}
    73  					} else if math.Abs((x-y)/y) < flakiness {
    74  						continue
    75  					}
    76  				}
    77  
    78  			default:
    79  			}
    80  
    81  			t.Logf("For %T vector elements:", z)
    82  			t.Logf("got =%v", got)
    83  			t.Logf("want=%v", want)
    84  			if logInput != nil {
    85  				logInput()
    86  			}
    87  			t.Errorf("at index %d, got=%v, want=%v", i, got[i], want[i])
    88  			return false
    89  		} else if got[i] == 0 { // for floating point, 0.0 == -0.0 but a bitwise check can see the difference
    90  			var ia any = got[i]
    91  			var ib any = want[i]
    92  			switch x := ia.(type) {
    93  			case float32:
    94  				y := ib.(float32)
    95  				if math.Float32bits(x) != math.Float32bits(y) {
    96  					t.Logf("For %T vector elements:", z)
    97  					t.Logf("got =%v", got)
    98  					t.Logf("want=%v", want)
    99  					if logInput != nil {
   100  						logInput()
   101  					}
   102  					t.Errorf("at index %d, different signs of zero", i)
   103  					return false
   104  				}
   105  			case float64:
   106  				y := ib.(float64)
   107  				if math.Float64bits(x) != math.Float64bits(y) {
   108  					t.Logf("For %T vector elements:", z)
   109  					t.Logf("got =%v", got)
   110  					t.Logf("want=%v", want)
   111  					if logInput != nil {
   112  						logInput()
   113  					}
   114  					t.Errorf("at index %d, different signs of zero", i)
   115  					return false
   116  				}
   117  			default:
   118  			}
   119  
   120  		}
   121  	}
   122  	return true
   123  }
   124  

View as plain text