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
17package utils
18
19import (
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
27func int32MinMax(values []int32) (min, max int32) {
28	min = math.MaxInt32
29	max = math.MinInt32
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
42func uint32MinMax(values []uint32) (min, max uint32) {
43	min = math.MaxUint32
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
57func int64MinMax(values []int64) (min, max int64) {
58	min = math.MaxInt64
59	max = math.MinInt64
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
72func uint64MinMax(values []uint64) (min, max uint64) {
73	min = math.MaxUint64
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
87var minmaxFuncs = struct {
88	i32  func([]int32) (int32, int32)
89	ui32 func([]uint32) (uint32, uint32)
90	i64  func([]int64) (int64, int64)
91	ui64 func([]uint64) (uint64, uint64)
92}{}
93
94// GetMinMaxInt32 returns the min and max for a int32 slice, using AVX2 or
95// SSE4 cpu extensions if available, falling back to a pure go implementation
96// if they are unavailable or built with the noasm tag.
97func GetMinMaxInt32(v []int32) (min, max int32) {
98	return minmaxFuncs.i32(v)
99}
100
101// GetMinMaxUint32 returns the min and max for a uint32 slice, using AVX2 or
102// SSE4 cpu extensions if available, falling back to a pure go implementation
103// if they are unavailable or built with the noasm tag.
104func GetMinMaxUint32(v []uint32) (min, max uint32) {
105	return minmaxFuncs.ui32(v)
106}
107
108// GetMinMaxInt64 returns the min and max for a int64 slice, using AVX2 or
109// SSE4 cpu extensions if available, falling back to a pure go implementation
110// if they are unavailable or built with the noasm tag.
111func GetMinMaxInt64(v []int64) (min, max int64) {
112	return minmaxFuncs.i64(v)
113}
114
115// GetMinMaxUint64 returns the min and max for a uint64 slice, using AVX2 or
116// SSE4 cpu extensions if available, falling back to a pure go implementation
117// if they are unavailable or built with the noasm tag.
118func GetMinMaxUint64(v []uint64) (min, max uint64) {
119	return minmaxFuncs.ui64(v)
120}
121