github.com/apache/arrow/go/v14@v14.0.2/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  }