Source file src/simd/internal/simd_test/slicepart_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"
    11  	"testing"
    12  )
    13  
    14  func TestSlicePartInt8x16(t *testing.T) {
    15  	Do(t, 16, func(a, c []int8) {
    16  		u := simd.LoadInt8x16SlicePart(a)
    17  		u.StoreSlice(c)
    18  	})
    19  }
    20  
    21  func TestSlicePartInt8x32(t *testing.T) {
    22  	a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    23  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    24  	b := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    25  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    26  	for i := 32; i >= 0; i-- {
    27  		u := simd.LoadInt8x32SlicePart(a[:i])
    28  		c := make([]int8, 32, 32)
    29  		u.StoreSlice(c)
    30  		checkSlices(t, c, b)
    31  		if i > 0 {
    32  			b[i-1] = 0
    33  		}
    34  	}
    35  }
    36  
    37  func TestSlicePartUint8x16(t *testing.T) {
    38  	a := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    39  	b := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    40  	for i := 16; i >= 0; i-- {
    41  		u := simd.LoadUint8x16SlicePart(a[:i])
    42  		c := make([]uint8, 32, 32)
    43  		u.StoreSlice(c)
    44  		checkSlices(t, c, b)
    45  		if i > 0 {
    46  			b[i-1] = 0
    47  		}
    48  	}
    49  }
    50  
    51  func TestSlicePartUint8x32(t *testing.T) {
    52  	a := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    53  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    54  	b := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
    55  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
    56  	for i := 32; i >= 0; i-- {
    57  		u := simd.LoadUint8x32SlicePart(a[:i])
    58  		c := make([]uint8, 32, 32)
    59  		u.StoreSlice(c)
    60  		checkSlices(t, c, b)
    61  		if i > 0 {
    62  			b[i-1] = 0
    63  		}
    64  	}
    65  }
    66  
    67  func TestSlicePartInt16x8(t *testing.T) {
    68  	a := []int16{1, 2, 3, 4, 5, 6, 7, 8}
    69  	b := []int16{1, 2, 3, 4, 5, 6, 7, 8}
    70  	for i := 8; i >= 0; i-- {
    71  		u := simd.LoadInt16x8SlicePart(a[:i])
    72  		c := make([]int16, 16, 16)
    73  		u.StoreSlice(c)
    74  		checkSlices(t, c, b)
    75  		if i > 0 {
    76  			b[i-1] = 0
    77  		}
    78  	}
    79  }
    80  
    81  func TestSlicePartInt16x16(t *testing.T) {
    82  	a := []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    83  	b := []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    84  	for i := 16; i >= 0; i-- {
    85  		u := simd.LoadInt16x16SlicePart(a[:i])
    86  		c := make([]int16, 16, 16)
    87  		u.StoreSlice(c)
    88  		checkSlices(t, c, b)
    89  		if i > 0 {
    90  			b[i-1] = 0
    91  		}
    92  	}
    93  }
    94  
    95  func TestSlicesPartStoreInt8x16(t *testing.T) {
    96  	a := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    97  	b := []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
    98  	for i := 16; i >= 0; i-- {
    99  		v := simd.LoadInt8x16Slice(a)
   100  		c := make([]int8, 32, 32)
   101  		v.StoreSlicePart(c[:i])
   102  		checkSlices(t, c, b)
   103  		if i > 0 {
   104  			b[i-1] = 0
   105  		}
   106  	}
   107  }
   108  
   109  func TestSlicesPartStoreInt16x8(t *testing.T) {
   110  	a := []int16{1, 2, 3, 4, 5, 6, 7, 8}
   111  	b := []int16{1, 2, 3, 4, 5, 6, 7, 8}
   112  	for i := 8; i >= 0; i-- {
   113  		v := simd.LoadInt16x8Slice(a)
   114  		c := make([]int16, 32, 32)
   115  		v.StoreSlicePart(c[:i])
   116  		checkSlices(t, c, b)
   117  		if i > 0 {
   118  			b[i-1] = 0
   119  		}
   120  	}
   121  }
   122  
   123  func TestSlicesPartStoreInt16x16(t *testing.T) {
   124  	a := []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   125  	b := []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   126  	for i := 16; i >= 0; i-- {
   127  		v := simd.LoadInt16x16Slice(a)
   128  		c := make([]int16, 32, 32)
   129  		v.StoreSlicePart(c[:i])
   130  		checkSlices(t, c, b)
   131  		if i > 0 {
   132  			b[i-1] = 0
   133  		}
   134  	}
   135  }
   136  
   137  func TestSlicesPartStoreUint8x16(t *testing.T) {
   138  	a := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   139  	b := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   140  	for i := 16; i >= 0; i-- {
   141  		v := simd.LoadUint8x16Slice(a)
   142  		c := make([]uint8, 32, 32)
   143  		v.StoreSlicePart(c[:i])
   144  		checkSlices(t, c, b)
   145  		if i > 0 {
   146  			b[i-1] = 0
   147  		}
   148  	}
   149  }
   150  
   151  func TestSlicesPartStoreUint16x16(t *testing.T) {
   152  	a := []uint16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   153  	b := []uint16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
   154  	for i := 16; i >= 0; i-- {
   155  		v := simd.LoadUint16x16Slice(a)
   156  		c := make([]uint16, 32, 32)
   157  		v.StoreSlicePart(c[:i])
   158  		checkSlices(t, c, b)
   159  		if i > 0 {
   160  			b[i-1] = 0
   161  		}
   162  	}
   163  }
   164  
   165  func TestSlicesPartStoreUint8x32(t *testing.T) {
   166  	a := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
   167  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
   168  	b := []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
   169  		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
   170  	for i := 32; i >= 0; i-- {
   171  		v := simd.LoadUint8x32Slice(a)
   172  		c := make([]uint8, 32, 32)
   173  		v.StoreSlicePart(c[:i])
   174  		checkSlices(t, c, b)
   175  		if i > 0 {
   176  			b[i-1] = 0
   177  		}
   178  	}
   179  }
   180  
   181  func TestSlicePartInt32(t *testing.T) {
   182  	// 32x4
   183  	L := 4
   184  	c := []int32{1, 2, 3, 4, 5, -1, -1, -1, -1}
   185  	a := c[:L+1]
   186  	for i := range a {
   187  		// Test the load first
   188  		// e is a partial slice.
   189  		e := a[i:]
   190  		v := simd.LoadInt32x4SlicePart(e)
   191  		// d contains what a ought to contain
   192  		d := make([]int32, L)
   193  		for j := 0; j < len(e) && j < len(d); j++ {
   194  			d[j] = e[j]
   195  		}
   196  
   197  		b := make([]int32, L)
   198  		v.StoreSlice(b)
   199  		// test the load
   200  		checkSlices(t, d, b)
   201  
   202  		// Test the store
   203  		f := make([]int32, L+1)
   204  		for i := range f {
   205  			f[i] = 99
   206  		}
   207  
   208  		v.StoreSlicePart(f[:len(e)])
   209  		if len(e) < len(b) {
   210  			checkSlices(t, f, b[:len(e)])
   211  		} else {
   212  			checkSlices(t, f, b)
   213  		}
   214  		for i := len(e); i < len(f); i++ {
   215  			if f[i] != 99 {
   216  				t.Errorf("StoreSlicePart altered f[%d], expected 99, saw %d", i, f[i])
   217  			}
   218  		}
   219  	}
   220  }
   221  
   222  func TestSlicePartUint64(t *testing.T) {
   223  	// 64x4
   224  	L := 4
   225  	c := []uint64{1, 2, 3, 4, 5, 86, 86, 86, 86}
   226  	a := c[:L+1]
   227  	for i := range a {
   228  		// Test the load first
   229  		// e is a partial slice.
   230  		e := a[i:]
   231  		v := simd.LoadUint64x4SlicePart(e)
   232  		// d contains what a ought to contain
   233  		d := make([]uint64, L)
   234  		for j := 0; j < len(e) && j < len(d); j++ {
   235  			d[j] = e[j]
   236  		}
   237  
   238  		b := make([]uint64, L)
   239  		v.StoreSlice(b)
   240  		// test the load
   241  		checkSlices(t, d, b)
   242  
   243  		// Test the store
   244  		f := make([]uint64, L+1)
   245  		for i := range f {
   246  			f[i] = 99
   247  		}
   248  
   249  		v.StoreSlicePart(f[:len(e)])
   250  		if len(e) < len(b) {
   251  			checkSlices(t, f, b[:len(e)])
   252  		} else {
   253  			checkSlices(t, f, b)
   254  		}
   255  		for i := len(e); i < len(f); i++ {
   256  			if f[i] != 99 {
   257  				t.Errorf("StoreSlicePart altered f[%d], expected 99, saw %d", i, f[i])
   258  			}
   259  		}
   260  	}
   261  }
   262  
   263  func TestSlicePartFloat64(t *testing.T) {
   264  	// 64x2
   265  	L := 2
   266  	c := []float64{1, 2, 3, 86, 86, 86, 86}
   267  	a := c[:L+1]
   268  	for i := range a {
   269  		// Test the load first
   270  		// e is a partial slice.
   271  		e := a[i:]
   272  		v := simd.LoadFloat64x2SlicePart(e)
   273  		// d contains what a ought to contain
   274  		d := make([]float64, L)
   275  		for j := 0; j < len(e) && j < len(d); j++ {
   276  			d[j] = e[j]
   277  		}
   278  
   279  		b := make([]float64, L)
   280  		v.StoreSlice(b)
   281  		// test the load
   282  		checkSlices(t, d, b)
   283  
   284  		// Test the store
   285  		f := make([]float64, L+1)
   286  		for i := range f {
   287  			f[i] = 99
   288  		}
   289  
   290  		v.StoreSlicePart(f[:len(e)])
   291  		if len(e) < len(b) {
   292  			checkSlices(t, f, b[:len(e)])
   293  		} else {
   294  			checkSlices(t, f, b)
   295  		}
   296  		for i := len(e); i < len(f); i++ {
   297  			if f[i] != 99 {
   298  				t.Errorf("StoreSlicePart altered f[%d], expected 99, saw %v", i, f[i])
   299  			}
   300  		}
   301  	}
   302  }
   303  
   304  func TestSlicePartFloat32(t *testing.T) {
   305  	// 32x8
   306  	L := 8
   307  	c := []float32{1, 2, 3, 4, 5, 6, 7, 8, 86, 86, 86, 86}
   308  	a := c[:L+1]
   309  	for i := range a {
   310  		// Test the load first
   311  		// e is a partial slice.
   312  		e := a[i:]
   313  		v := simd.LoadFloat32x8SlicePart(e)
   314  		// d contains what a ought to contain
   315  		d := make([]float32, L)
   316  		for j := 0; j < len(e) && j < len(d); j++ {
   317  			d[j] = e[j]
   318  		}
   319  
   320  		b := make([]float32, L)
   321  		v.StoreSlice(b)
   322  		// test the load
   323  		checkSlices(t, d, b)
   324  
   325  		// Test the store
   326  		f := make([]float32, L+1)
   327  		for i := range f {
   328  			f[i] = 99
   329  		}
   330  
   331  		v.StoreSlicePart(f[:len(e)])
   332  		if len(e) < len(b) {
   333  			checkSlices(t, f, b[:len(e)])
   334  		} else {
   335  			checkSlices(t, f, b)
   336  		}
   337  		for i := len(e); i < len(f); i++ {
   338  			if f[i] != 99 {
   339  				t.Errorf("StoreSlicePart altered f[%d], expected 99, saw %v", i, f[i])
   340  			}
   341  		}
   342  	}
   343  }
   344  
   345  // 512-bit load
   346  
   347  func TestSlicePartInt64(t *testing.T) {
   348  	if !simd.X86.AVX512() {
   349  		t.Skip("Test requires X86.AVX512, not available on this hardware")
   350  		return
   351  	}
   352  
   353  	L := 8
   354  	c := []int64{1, 2, 3, 4, 5, 6, 7, 8, 86, 86, 86, 86}
   355  	a := c[:L+1]
   356  	for i := range a {
   357  		// Test the load first
   358  		// e is a partial slice.
   359  		e := a[i:]
   360  		v := simd.LoadInt64x8SlicePart(e)
   361  		// d contains what a ought to contain
   362  		d := make([]int64, L)
   363  		for j := 0; j < len(e) && j < len(d); j++ {
   364  			d[j] = e[j]
   365  		}
   366  
   367  		b := make([]int64, L)
   368  		v.StoreSlice(b)
   369  		// test the load
   370  		checkSlicesLogInput(t, b, d, 0.0, func() { t.Helper(); t.Logf("Len(e)=%d", len(e)) })
   371  
   372  		// Test the store
   373  		f := make([]int64, L+1)
   374  		for i := range f {
   375  			f[i] = 99
   376  		}
   377  
   378  		v.StoreSlicePart(f[:len(e)])
   379  		if len(e) < len(b) {
   380  			checkSlices(t, f, b[:len(e)])
   381  		} else {
   382  			checkSlices(t, f, b)
   383  		}
   384  		for i := len(e); i < len(f); i++ {
   385  			if f[i] != 99 {
   386  				t.Errorf("StoreSlicePart altered f[%d], expected 99, saw %v", i, f[i])
   387  			}
   388  		}
   389  	}
   390  }
   391  

View as plain text