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