Coverage Report

Created: 2026-07-21 07:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Simd/src/Simd/SimdSse41DescrInt.cpp
Line
Count
Source
1
/*
2
* Simd Library (http://ermig1979.github.io/Simd).
3
*
4
* Copyright (c) 2011-2026 Yermalayeu Ihar.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to deal
8
* in the Software without restriction, including without limitation the rights
9
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
12
*
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* SOFTWARE.
23
*/
24
#include "Simd/SimdMemory.h"
25
#include "Simd/SimdStore.h"
26
#include "Simd/SimdExtract.h"
27
#include "Simd/SimdArray.h"
28
#include "Simd/SimdUnpack.h"
29
#include "Simd/SimdDescrInt.h"
30
#include "Simd/SimdDescrIntCommon.h"
31
#include "Simd/SimdCpu.h"
32
#include "Simd/SimdFloat16.h"
33
#include "Simd/SimdMax.h"
34
35
namespace Simd
36
{
37
#ifdef SIMD_SSE41_ENABLE    
38
    namespace Sse41
39
    {
40
        static void MinMax32f(const float* src, size_t size, float& min, float& max)
41
0
        {
42
0
            assert(size % 8 == 0);
43
0
            __m128 _min = _mm_set1_ps(FLT_MAX);
44
0
            __m128 _max = _mm_set1_ps(-FLT_MAX);
45
0
            size_t i = 0;
46
0
            for (; i < size; i += 4)
47
0
            {
48
0
                __m128 _src = _mm_loadu_ps(src + i);
49
0
                _min = _mm_min_ps(_src, _min);
50
0
                _max = _mm_max_ps(_src, _max);
51
0
            }
52
0
            MinVal32f(_min, min);
53
0
            MaxVal32f(_max, max);
54
0
        }
55
56
        //-------------------------------------------------------------------------------------------------
57
58
        static void MinMax16f(const uint16_t* src, size_t size, float& min, float& max)
59
0
        {
60
0
            assert(size % 8 == 0);
61
0
            __m128 _min = _mm_set1_ps(FLT_MAX);
62
0
            __m128 _max = _mm_set1_ps(-FLT_MAX);
63
0
            size_t i = 0;
64
0
            for (; i < size; i += 4)
65
0
            {
66
0
                __m128i f16 = _mm_loadl_epi64((__m128i*)(src + i));
67
0
                __m128 _src = Float16ToFloat32(UnpackU16<0>(f16));
68
0
                _min = _mm_min_ps(_src, _min);
69
0
                _max = _mm_max_ps(_src, _max);
70
0
            }
71
0
            MinVal32f(_min, min);
72
0
            MaxVal32f(_max, max);
73
0
        }
74
75
        //-------------------------------------------------------------------------------------------------
76
77
        static void UnpackNormA(size_t count, const uint8_t* const* src, float* dst, size_t stride)
78
0
        {
79
0
            for (size_t i = 0; i < count; ++i)
80
0
                _mm_storeu_si128((__m128i*)dst + i, _mm_loadu_si128((__m128i*)src[i]));
81
0
        }
82
83
        //-------------------------------------------------------------------------------------------------
84
85
        static void UnpackNormB(size_t count, const uint8_t* const* src, float* dst, size_t stride)
86
0
        {
87
0
            size_t count4 = AlignLo(count, 4), i = 0;
88
0
            for (; i < count4; i += 4, src += 4, dst += 4)
89
0
            {
90
0
                __m128 s0 = _mm_loadu_ps((float*)src[0]);
91
0
                __m128 s1 = _mm_loadu_ps((float*)src[1]);
92
0
                __m128 s2 = _mm_loadu_ps((float*)src[2]);
93
0
                __m128 s3 = _mm_loadu_ps((float*)src[3]);
94
0
                __m128 s00 = _mm_unpacklo_ps(s0, s2);
95
0
                __m128 s01 = _mm_unpacklo_ps(s1, s3);
96
0
                __m128 s10 = _mm_unpackhi_ps(s0, s2);
97
0
                __m128 s11 = _mm_unpackhi_ps(s1, s3);
98
0
                _mm_storeu_ps(dst + 0 * stride, _mm_unpacklo_ps(s00, s01));
99
0
                _mm_storeu_ps(dst + 1 * stride, _mm_unpackhi_ps(s00, s01));
100
0
                _mm_storeu_ps(dst + 2 * stride, _mm_unpacklo_ps(s10, s11));
101
0
                _mm_storeu_ps(dst + 3 * stride, _mm_unpackhi_ps(s10, s11));
102
0
            }
103
0
            for (; i < count; i++, src++, dst++)
104
0
            {
105
0
                dst[0 * stride] = ((float*)src[0])[0];
106
0
                dst[1 * stride] = ((float*)src[0])[1];
107
0
                dst[2 * stride] = ((float*)src[0])[2];
108
0
                dst[3 * stride] = ((float*)src[0])[3];
109
0
            }
110
0
        }
111
112
        //-------------------------------------------------------------------------------------------------
113
114
        DescrInt::DescrInt(size_t size, size_t depth)
115
0
            : Base::DescrInt(size, depth)
116
0
        {
117
0
            _minMax32f = MinMax32f;
118
0
            _minMax16f = MinMax16f;
119
0
            _encode32f = GetEncode32f(_depth);
120
0
            _encode16f = GetEncode16f(_depth);
121
122
0
            _decode32f = GetDecode32f(_depth);
123
0
            _decode16f = GetDecode16f(_depth);
124
125
0
            _cosineDistance = GetCosineDistance(_depth);
126
0
            _macroCosineDistancesDirect = GetMacroCosineDistancesDirect(_depth);
127
0
            _microMd = 2;
128
0
            _microNd = 4;
129
130
0
            _unpackNormA = UnpackNormA;
131
0
            _unpackNormB = UnpackNormB;
132
0
            _unpackDataA = GetUnpackData(_depth, false);
133
0
            _unpackDataB = GetUnpackData(_depth, true);
134
0
            _macroCosineDistancesUnpack = GetMacroCosineDistancesUnpack(_depth);
135
0
            _unpSize = _size * (_depth == 8 ? 2 : 1);
136
0
            _microMu = _depth == 8 ? 6 : 5;
137
0
            _microNu = 8;
138
0
        }
139
140
        //-------------------------------------------------------------------------------------------------
141
142
        void* DescrIntInit(size_t size, size_t depth)
143
0
        {
144
0
            if (!Base::DescrInt::Valid(size, depth))
145
0
                return NULL;
146
0
            return new Sse41::DescrInt(size, depth);
147
0
        }
148
    }
149
#endif
150
}