1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package utils
import (
"math"
)
// this file contains pure go implementations of the min_max functions that are
// SIMD accelerated so that we can fallback to these if the cpu doesn't support
// AVX2 or SSE4 instructions.
func int8MinMax(values []int8) (min, max int8) {
min = math.MaxInt8
max = math.MinInt8
for _, v := range values {
if min > v {
min = v
}
if max < v {
max = v
}
}
return
}
func uint8MinMax(values []uint8) (min, max uint8) {
min = math.MaxUint8
max = 0
for _, v := range values {
if min > v {
min = v
}
if max < v {
max = v
}
}
return
}
func int16MinMax(values []int16) (min, max int16) {
min = math.MaxInt16
max = math.MinInt16
for _, v := range values {
if min > v {
min = v
}
if max < v {
max = v
}
}
return
}
func uint16MinMax(values []uint16) (min, max uint16) {
min = math.MaxUint16
max = 0
for _, v := range values {
if min > v {
min = v
}
if max < v {
max = v
}
}
return
}
func int32MinMax(values []int32) (min, max int32) {
min = math.MaxInt32
max = math.MinInt32
for _, v := range values {
if min > v {
min = v
}
if max < v {
max = v
}
}
return
}
func uint32MinMax(values []uint32) (min, max uint32) {
min = math.MaxUint32
max = 0
for _, v := range values {
if min > v {
min = v
}
if max < v {
max = v
}
}
return
}
func int64MinMax(values []int64) (min, max int64) {
min = math.MaxInt64
max = math.MinInt64
for _, v := range values {
if min > v {
min = v
}
if max < v {
max = v
}
}
return
}
func uint64MinMax(values []uint64) (min, max uint64) {
min = math.MaxUint64
max = 0
for _, v := range values {
if min > v {
min = v
}
if max < v {
max = v
}
}
return
}
var minmaxFuncs = struct {
i8 func([]int8) (int8, int8)
ui8 func([]uint8) (uint8, uint8)
i16 func([]int16) (int16, int16)
ui16 func([]uint16) (uint16, uint16)
i32 func([]int32) (int32, int32)
ui32 func([]uint32) (uint32, uint32)
i64 func([]int64) (int64, int64)
ui64 func([]uint64) (uint64, uint64)
}{}
// GetMinMaxInt8 returns the min and max for a int8 slice, using AVX2 or
// SSE4 cpu extensions if available, falling back to a pure go implementation
// if they are unavailable or built with the noasm tag.
func GetMinMaxInt8(v []int8) (min, max int8) {
return minmaxFuncs.i8(v)
}
// GetMinMaxUint8 returns the min and max for a uint8 slice, using AVX2 or
// SSE4 cpu extensions if available, falling back to a pure go implementation
// if they are unavailable or built with the noasm tag.
func GetMinMaxUint8(v []uint8) (min, max uint8) {
return minmaxFuncs.ui8(v)
}
// GetMinMaxInt16 returns the min and max for a int16 slice, using AVX2 or
// SSE4 cpu extensions if available, falling back to a pure go implementation
// if they are unavailable or built with the noasm tag.
func GetMinMaxInt16(v []int16) (min, max int16) {
return minmaxFuncs.i16(v)
}
// GetMinMaxUint16 returns the min and max for a uint16 slice, using AVX2 or
// SSE4 cpu extensions if available, falling back to a pure go implementation
// if they are unavailable or built with the noasm tag.
func GetMinMaxUint16(v []uint16) (min, max uint16) {
return minmaxFuncs.ui16(v)
}
// GetMinMaxInt32 returns the min and max for a int32 slice, using AVX2 or
// SSE4 cpu extensions if available, falling back to a pure go implementation
// if they are unavailable or built with the noasm tag.
func GetMinMaxInt32(v []int32) (min, max int32) {
return minmaxFuncs.i32(v)
}
// GetMinMaxUint32 returns the min and max for a uint32 slice, using AVX2 or
// SSE4 cpu extensions if available, falling back to a pure go implementation
// if they are unavailable or built with the noasm tag.
func GetMinMaxUint32(v []uint32) (min, max uint32) {
return minmaxFuncs.ui32(v)
}
// GetMinMaxInt64 returns the min and max for a int64 slice, using AVX2 or
// SSE4 cpu extensions if available, falling back to a pure go implementation
// if they are unavailable or built with the noasm tag.
func GetMinMaxInt64(v []int64) (min, max int64) {
return minmaxFuncs.i64(v)
}
// GetMinMaxUint64 returns the min and max for a uint64 slice, using AVX2 or
// SSE4 cpu extensions if available, falling back to a pure go implementation
// if they are unavailable or built with the noasm tag.
func GetMinMaxUint64(v []uint64) (min, max uint64) {
return minmaxFuncs.ui64(v)
}
|