Source file src/simd/archsimd/internal/simd_test/slicepart_wider_test.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 simd_test
     8  
     9  import (
    10  	"simd/archsimd"
    11  	"testing"
    12  )
    13  
    14  func TestPartInt8x32(t *testing.T) {
    15  	a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    16  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    17  	b := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    18  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    19  	for i := 32; i >= 0; i-- {
    20  		u, _ := archsimd.LoadInt8x32Part(a[:i])
    21  		c := make([]int8, 32, 32)
    22  		u.Store(c)
    23  		checkSlices(t, c, b)
    24  		if i > 0 {
    25  			b[i-1] = 0
    26  		}
    27  	}
    28  }
    29  
    30  func xTestPartUint8x16(t *testing.T) {
    31  	a := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    32  	b := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    33  	for i := 16; i >= 0; i-- {
    34  		u, _ := archsimd.LoadUint8x16Part(a[:i])
    35  		c := make([]uint8, 32, 32)
    36  		u.Store(c)
    37  		checkSlices(t, c, b)
    38  		if i > 0 {
    39  			b[i-1] = 0
    40  		}
    41  	}
    42  }
    43  
    44  func TestPartUint8x32(t *testing.T) {
    45  	a := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    46  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    47  	b := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    48  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    49  	for i := 32; i >= 0; i-- {
    50  		u, _ := archsimd.LoadUint8x32Part(a[:i])
    51  		c := make([]uint8, 32, 32)
    52  		u.Store(c)
    53  		checkSlices(t, c, b)
    54  		if i > 0 {
    55  			b[i-1] = 0
    56  		}
    57  	}
    58  }
    59  
    60  func xTestPartInt16x8(t *testing.T) {
    61  	a := []int16{1, 2, 3, 4, 5, 6, 7, 8}
    62  	b := []int16{1, 2, 3, 4, 5, 6, 7, 8}
    63  	for i := 8; i >= 0; i-- {
    64  		u, _ := archsimd.LoadInt16x8Part(a[:i])
    65  		c := make([]int16, 16, 16)
    66  		u.Store(c)
    67  		checkSlices(t, c, b)
    68  		if i > 0 {
    69  			b[i-1] = 0
    70  		}
    71  	}
    72  }
    73  
    74  func TestPartInt16x16(t *testing.T) {
    75  	a := []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    76  	b := []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    77  	for i := 16; i >= 0; i-- {
    78  		u, _ := archsimd.LoadInt16x16Part(a[:i])
    79  		c := make([]int16, 16, 16)
    80  		u.Store(c)
    81  		checkSlices(t, c, b)
    82  		if i > 0 {
    83  			b[i-1] = 0
    84  		}
    85  	}
    86  }
    87  
    88  func xTestSlicesPartStoreInt8x16(t *testing.T) {
    89  	a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    90  	b := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    91  	for i := 16; i >= 0; i-- {
    92  		v := archsimd.LoadInt8x16(a)
    93  		c := make([]int8, 32, 32)
    94  		v.StorePart(c[:i])
    95  		checkSlices(t, c, b)
    96  		if i > 0 {
    97  			b[i-1] = 0
    98  		}
    99  	}
   100  }
   101  
   102  func xTestSlicesPartStoreInt16x8(t *testing.T) {
   103  	a := []int16{1, 2, 3, 4, 5, 6, 7, 8}
   104  	b := []int16{1, 2, 3, 4, 5, 6, 7, 8}
   105  	for i := 8; i >= 0; i-- {
   106  		v := archsimd.LoadInt16x8(a)
   107  		c := make([]int16, 32, 32)
   108  		v.StorePart(c[:i])
   109  		checkSlices(t, c, b)
   110  		if i > 0 {
   111  			b[i-1] = 0
   112  		}
   113  	}
   114  }
   115  
   116  func TestSlicesPartStoreInt16x16(t *testing.T) {
   117  	a := []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   118  	b := []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   119  	for i := 16; i >= 0; i-- {
   120  		v := archsimd.LoadInt16x16(a)
   121  		c := make([]int16, 32, 32)
   122  		v.StorePart(c[:i])
   123  		checkSlices(t, c, b)
   124  		if i > 0 {
   125  			b[i-1] = 0
   126  		}
   127  	}
   128  }
   129  
   130  func xTestSlicesPartStoreUint8x16(t *testing.T) {
   131  	a := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   132  	b := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   133  	for i := 16; i >= 0; i-- {
   134  		v := archsimd.LoadUint8x16(a)
   135  		c := make([]uint8, 32, 32)
   136  		v.StorePart(c[:i])
   137  		checkSlices(t, c, b)
   138  		if i > 0 {
   139  			b[i-1] = 0
   140  		}
   141  	}
   142  }
   143  
   144  func TestSlicesPartStoreUint16x16(t *testing.T) {
   145  	a := []uint16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   146  	b := []uint16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   147  	for i := 16; i >= 0; i-- {
   148  		v := archsimd.LoadUint16x16(a)
   149  		c := make([]uint16, 32, 32)
   150  		v.StorePart(c[:i])
   151  		checkSlices(t, c, b)
   152  		if i > 0 {
   153  			b[i-1] = 0
   154  		}
   155  	}
   156  }
   157  
   158  func TestSlicesPartStoreUint8x32(t *testing.T) {
   159  	a := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
   160  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
   161  	b := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
   162  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
   163  	for i := 32; i >= 0; i-- {
   164  		v := archsimd.LoadUint8x32(a)
   165  		c := make([]uint8, 32, 32)
   166  		v.StorePart(c[:i])
   167  		checkSlices(t, c, b)
   168  		if i > 0 {
   169  			b[i-1] = 0
   170  		}
   171  	}
   172  }
   173  
   174  func TestPartUint64(t *testing.T) {
   175  	// 64x4
   176  	L := 4
   177  	c := []uint64{1, 2, 3, 4, 5, 86, 86, 86, 86}
   178  	a := c[:L+1]
   179  	for i := range a {
   180  		// Test the load first
   181  		// e is a partial slice.
   182  		e := a[i:]
   183  		v, _ := archsimd.LoadUint64x4Part(e)
   184  		// d contains what a ought to contain
   185  		d := make([]uint64, L)
   186  		for j := 0; j < len(e) && j < len(d); j++ {
   187  			d[j] = e[j]
   188  		}
   189  
   190  		b := make([]uint64, L)
   191  		v.Store(b)
   192  		// test the load
   193  		checkSlices(t, d, b)
   194  
   195  		// Test the store
   196  		f := make([]uint64, L+1)
   197  		for i := range f {
   198  			f[i] = 99
   199  		}
   200  
   201  		v.StorePart(f[:len(e)])
   202  		if len(e) < len(b) {
   203  			checkSlices(t, f, b[:len(e)])
   204  		} else {
   205  			checkSlices(t, f, b)
   206  		}
   207  		for i := len(e); i < len(f); i++ {
   208  			if f[i] != 99 {
   209  				t.Errorf("StorePart altered f[%d], expected 99, saw %d", i, f[i])
   210  			}
   211  		}
   212  	}
   213  }
   214  
   215  func TestPartFloat32(t *testing.T) {
   216  	// 32x8
   217  	L := 8
   218  	c := []float32{1, 2, 3, 4, 5, 6, 7, 8, 86, 86, 86, 86}
   219  	a := c[:L+1]
   220  	for i := range a {
   221  		// Test the load first
   222  		// e is a partial slice.
   223  		e := a[i:]
   224  		v, _ := archsimd.LoadFloat32x8Part(e)
   225  		// d contains what a ought to contain
   226  		d := make([]float32, L)
   227  		for j := 0; j < len(e) && j < len(d); j++ {
   228  			d[j] = e[j]
   229  		}
   230  
   231  		b := make([]float32, L)
   232  		v.Store(b)
   233  		// test the load
   234  		checkSlices(t, d, b)
   235  
   236  		// Test the store
   237  		f := make([]float32, L+1)
   238  		for i := range f {
   239  			f[i] = 99
   240  		}
   241  
   242  		v.StorePart(f[:len(e)])
   243  		if len(e) < len(b) {
   244  			checkSlices(t, f, b[:len(e)])
   245  		} else {
   246  			checkSlices(t, f, b)
   247  		}
   248  		for i := len(e); i < len(f); i++ {
   249  			if f[i] != 99 {
   250  				t.Errorf("StorePart altered f[%d], expected 99, saw %v", i, f[i])
   251  			}
   252  		}
   253  	}
   254  }
   255  
   256  // 512-bit load
   257  
   258  func TestPartInt64(t *testing.T) {
   259  	if !archsimd.X86.AVX512() {
   260  		t.Skip("Test requires X86.AVX512, not available on this hardware")
   261  		return
   262  	}
   263  
   264  	L := 8
   265  	c := []int64{1, 2, 3, 4, 5, 6, 7, 8, 86, 86, 86, 86}
   266  	a := c[:L+1]
   267  	for i := range a {
   268  		// Test the load first
   269  		// e is a partial slice.
   270  		e := a[i:]
   271  		v, _ := archsimd.LoadInt64x8Part(e)
   272  		// d contains what a ought to contain
   273  		d := make([]int64, L)
   274  		for j := 0; j < len(e) && j < len(d); j++ {
   275  			d[j] = e[j]
   276  		}
   277  
   278  		b := make([]int64, L)
   279  		v.Store(b)
   280  		// test the load
   281  		checkSlicesLogInput(t, b, d, 0.0, func() { t.Helper(); t.Logf("Len(e)=%d", len(e)) })
   282  
   283  		// Test the store
   284  		f := make([]int64, L+1)
   285  		for i := range f {
   286  			f[i] = 99
   287  		}
   288  
   289  		v.StorePart(f[:len(e)])
   290  		if len(e) < len(b) {
   291  			checkSlices(t, f, b[:len(e)])
   292  		} else {
   293  			checkSlices(t, f, b)
   294  		}
   295  		for i := len(e); i < len(f); i++ {
   296  			if f[i] != 99 {
   297  				t.Errorf("StorePart altered f[%d], expected 99, saw %v", i, f[i])
   298  			}
   299  		}
   300  	}
   301  }
   302  

View as plain text