• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2022 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "tools/common/statistic_utils.h"
18 #if defined(ENABLE_AVX) && defined(__linux__)
19 #include "nnacl/intrinsics/ms_simd_cpu_info.h"
20 #ifdef _MSC_VER
21 #include <immintrin.h>
22 #else
23 #include <x86intrin.h>
24 #endif
25 #endif
26 
27 namespace mindspore::lite {
28 #if defined(ENABLE_AVX) && defined(__linux__)
GetFloatMinMaxValueWithSSE(const float * data,int size)29 std::pair<float, float> GetFloatMinMaxValueWithSSE(const float *data, int size) {
30   MS_ASSERT(data != nullptr);
31   MS_ASSERT(size > 0);
32   const int block_size = 4;
33 
34   float min_output[4];
35   float max_output[4];
36   __m128 load_data;
37   const float *p = data;
38 
39   __m128 min_vals = _mm_set1_ps(FLT_MAX);
40   __m128 max_vals = _mm_set1_ps(-FLT_MAX);
41 
42   int index = 0;
43   int block_max_size = size - block_size + 1;
44   for (; index < block_max_size; index += block_size) {
45     load_data = _mm_loadu_ps(p + index);
46     min_vals = _mm_min_ps(min_vals, load_data);
47     max_vals = _mm_max_ps(max_vals, load_data);
48   }
49   _mm_store_ps(min_output, min_vals);
50   _mm_store_ps(max_output, max_vals);
51 
52   float min_val = min_output[0];
53   float max_val = max_output[0];
54   for (int i = 1; i < block_size; i++) {
55     min_val = min_val < min_output[i] ? min_val : min_output[i];
56     max_val = max_val > max_output[i] ? max_val : max_output[i];
57   }
58   for (; index < size; index++) {
59     min_val = min_val < p[index] ? min_val : p[index];
60     max_val = max_val > p[index] ? max_val : p[index];
61   }
62   return {min_val, max_val};
63 }
64 #endif
65 
GetFloatMinMaxValue(const float * data,int size)66 std::pair<float, float> GetFloatMinMaxValue(const float *data, int size) {
67 #if defined(ENABLE_AVX) && defined(__linux__)
68   if (IntelX86CpuInfoInit() == RET_OK && X86_Sse_Support() && size > 64) {
69     return GetFloatMinMaxValueWithSSE(data, size);
70   } else {
71     return GetMinMaxValue(data, size);
72   }
73 #else
74   return GetMinMaxValue(data, size);
75 #endif
76 }
77 }  // namespace mindspore::lite
78