github.com/grailbio/base@v0.0.11/simd/multibyte_appengine.go (about) 1 // Copyright 2018 GRAIL, Inc. All rights reserved. 2 // Use of this source code is governed by the Apache-2.0 3 // license that can be found in the LICENSE file. 4 5 // +build appengine 6 7 package simd 8 9 // This file contains functions which operate on slices of 2- or 4-byte 10 // elements (typically small structs or integers) in ways that differ from the 11 // corresponding operations on single-byte elements. 12 // In this context, there is little point in making the interface based on 13 // []byte, since the caller will need to unsafely cast to it. Instead, most 14 // functions take unsafe.Pointer(s) and a count, and have names ending in 15 // 'Raw'; the caller should write safe wrappers around them when appropriate. 16 // We provide sample wrappers for the int16 and uint16 cases. (Originally did 17 // this for int32/uint32, but turns out the compiler has hardcoded 18 // optimizations for those cases which are currently missing for {u}int16.) 19 20 // RepeatI16 fills dst[] with the given int16. 21 func RepeatI16(dst []int16, val int16) { 22 for i := range dst { 23 dst[i] = val 24 } 25 } 26 27 // RepeatU16 fills dst[] with the given uint16. 28 func RepeatU16(dst []uint16, val uint16) { 29 for i := range dst { 30 dst[i] = val 31 } 32 } 33 34 // ReverseI16Inplace reverses a []int16 in-place. 35 func ReverseI16Inplace(main []int16) { 36 nElem := len(main) 37 nElemDiv2 := nElem >> 1 38 for i, j := 0, nElem-1; i != nElemDiv2; i, j = i+1, j-1 { 39 main[i], main[j] = main[j], main[i] 40 } 41 } 42 43 // ReverseU16Inplace reverses a []uint16 in-place. 44 func ReverseU16Inplace(main []uint16) { 45 nElem := len(main) 46 nElemDiv2 := nElem >> 1 47 for i, j := 0, nElem-1; i != nElemDiv2; i, j = i+1, j-1 { 48 main[i], main[j] = main[j], main[i] 49 } 50 } 51 52 // ReverseI16 sets dst[len(src) - 1 - pos] := src[pos] for each position in 53 // src. It panics if len(src) != len(dst). 54 func ReverseI16(dst, src []int16) { 55 if len(dst) != len(src) { 56 panic("ReverseI16() requires len(src) == len(dst).") 57 } 58 nElemMinus1 := len(dst) - 1 59 for i := range dst { 60 dst[i] = src[nElemMinus1-i] 61 } 62 } 63 64 // ReverseU16 sets dst[len(src) - 1 - pos] := src[pos] for each position in 65 // src. It panics if len(src) != len(dst). 66 func ReverseU16(dst, src []uint16) { 67 if len(dst) != len(src) { 68 panic("ReverseU16() requires len(src) == len(dst).") 69 } 70 nElemMinus1 := len(dst) - 1 71 for i := range dst { 72 dst[i] = src[nElemMinus1-i] 73 } 74 } 75 76 // Benchmark results suggest that Reverse32Raw is unimportant.