1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_absmin_no_idx_f16.c
4 * Description: Minimum value of absolute values of a floating-point vector
5 *
6 * $Date: 16 November 2021
7 * $Revision: V1.10.0
8 *
9 * Target Processor: Cortex-M and Cortex-A cores
10 * -------------------------------------------------------------------- */
11 /*
12 * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
13 *
14 * SPDX-License-Identifier: Apache-2.0
15 *
16 * Licensed under the Apache License, Version 2.0 (the License); you may
17 * not use this file except in compliance with the License.
18 * You may obtain a copy of the License at
19 *
20 * www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28
29 #include "dsp/statistics_functions_f16.h"
30
31 #if defined(ARM_FLOAT16_SUPPORTED)
32
33
34 #if (defined(ARM_MATH_NEON) || defined(ARM_MATH_MVEF)) && !defined(ARM_MATH_AUTOVECTORIZE)
35 #include <limits.h>
36 #endif
37
38
39 /**
40 @ingroup groupStats
41 */
42
43 /**
44 @addtogroup AbsMin
45 @{
46 */
47
48 /**
49 @brief Minimum value of absolute values of a floating-point vector.
50 @param[in] pSrc points to the input vector
51 @param[in] blockSize number of samples in input vector
52 @param[out] pResult minimum value returned here
53 */
54
55 #if defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE)
56
57 #include "arm_helium_utils.h"
arm_absmin_no_idx_f16(const float16_t * pSrc,uint32_t blockSize,float16_t * pResult)58 ARM_DSP_ATTRIBUTE void arm_absmin_no_idx_f16(
59 const float16_t * pSrc,
60 uint32_t blockSize,
61 float16_t * pResult)
62 {
63 int32_t blkCnt; /* loop counters */
64 f16x8_t vecSrc;
65 float16_t const *pSrcVec;
66 f16x8_t curExtremValVec = vdupq_n_f16(F16_ABSMAX);
67 float16_t minValue = F16_ABSMAX;
68 mve_pred16_t p0;
69
70
71 pSrcVec = (float16_t const *) pSrc;
72 blkCnt = blockSize >> 3;
73 while (blkCnt > 0)
74 {
75 vecSrc = vld1q(pSrcVec);
76 pSrcVec += 8;
77 /*
78 * update per-lane min.
79 */
80 curExtremValVec = vminnmaq(vecSrc, curExtremValVec);
81 /*
82 * Decrement the blockSize loop counter
83 */
84 blkCnt--;
85 }
86 /*
87 * tail
88 * (will be merged thru tail predication)
89 */
90 blkCnt = blockSize & 7;
91 if (blkCnt > 0)
92 {
93 vecSrc = vld1q(pSrcVec);
94 pSrcVec += 8;
95 p0 = vctp16q(blkCnt);
96 /*
97 * Get current min per lane and current index per lane
98 * when a min is selected
99 */
100 curExtremValVec = vminnmaq_m(curExtremValVec, vecSrc, p0);
101 }
102 /*
103 * Get min value across the vector
104 */
105 minValue = vminnmavq(minValue, curExtremValVec);
106 *pResult = minValue;
107 }
108
109 #else
110 #if defined(ARM_MATH_LOOPUNROLL)
arm_absmin_no_idx_f16(const float16_t * pSrc,uint32_t blockSize,float16_t * pResult)111 ARM_DSP_ATTRIBUTE void arm_absmin_no_idx_f16(
112 const float16_t * pSrc,
113 uint32_t blockSize,
114 float16_t * pResult)
115 {
116 float16_t cur_absmin, out; /* Temporary variables to store the output value. */\
117 uint32_t blkCnt; /* Loop counter */ \
118 \
119 \
120 /* Load first input value that act as reference value for comparision */ \
121 out = *pSrc++; \
122 out = ((_Float16)out > 0.0f16) ? out : -(_Float16)out; \
123 \
124 \
125 /* Loop unrolling: Compute 4 outputs at a time */ \
126 blkCnt = (blockSize - 1U) >> 2U; \
127 \
128 while (blkCnt > 0U) \
129 { \
130 /* Initialize cur_absmin to next consecutive values one by one */ \
131 cur_absmin = *pSrc++; \
132 cur_absmin = ((_Float16)cur_absmin > 0.0f16) ? cur_absmin : -(_Float16)cur_absmin; \
133 /* compare for the extrema value */ \
134 if ((_Float16)cur_absmin < (_Float16)out) \
135 { \
136 /* Update the extrema value and it's index */ \
137 out = cur_absmin; \
138 } \
139 \
140 cur_absmin = *pSrc++; \
141 cur_absmin = ((_Float16)cur_absmin > 0.0f16) ? cur_absmin : -(_Float16)cur_absmin; \
142 if ((_Float16)cur_absmin < (_Float16)out) \
143 { \
144 out = cur_absmin; \
145 } \
146 \
147 cur_absmin = *pSrc++; \
148 cur_absmin = ((_Float16)cur_absmin > 0.0f16) ? cur_absmin : -(_Float16)cur_absmin; \
149 if ((_Float16)cur_absmin < (_Float16)out) \
150 { \
151 out = cur_absmin; \
152 } \
153 \
154 cur_absmin = *pSrc++; \
155 cur_absmin = ((_Float16)cur_absmin > 0.0f16) ? cur_absmin : -(_Float16)cur_absmin; \
156 if ((_Float16)cur_absmin < (_Float16)out) \
157 { \
158 out = cur_absmin; \
159 } \
160 \
161 \
162 /* Decrement loop counter */ \
163 blkCnt--; \
164 } \
165 \
166 /* Loop unrolling: Compute remaining outputs */ \
167 blkCnt = (blockSize - 1U) % 4U; \
168 \
169 \
170 while (blkCnt > 0U) \
171 { \
172 cur_absmin = *pSrc++; \
173 cur_absmin = ((_Float16)cur_absmin > 0.0f16) ? cur_absmin : -(_Float16)cur_absmin; \
174 if ((_Float16)cur_absmin < (_Float16)out) \
175 { \
176 out = cur_absmin; \
177 } \
178 \
179 /* Decrement loop counter */ \
180 blkCnt--; \
181 } \
182 \
183 /* Store the extrema value and it's index into destination pointers */ \
184 *pResult = out; \
185 }
186 #else
arm_absmin_no_idx_f16(const float16_t * pSrc,uint32_t blockSize,float16_t * pResult)187 ARM_DSP_ATTRIBUTE void arm_absmin_no_idx_f16(
188 const float16_t * pSrc,
189 uint32_t blockSize,
190 float16_t * pResult)
191 {
192 float16_t minVal, out; /* Temporary variables to store the output value. */
193 uint32_t blkCnt; /* Loop counter */
194
195
196
197 /* Load first input value that act as reference value for comparision */
198 out = (_Float16)fabsf((float32_t)*pSrc++);
199
200 /* Initialize blkCnt with number of samples */
201 blkCnt = (blockSize - 1U);
202
203 while (blkCnt > 0U)
204 {
205 /* Initialize minVal to the next consecutive values one by one */
206 minVal = (_Float16)fabsf((float32_t)*pSrc++);
207
208 /* compare for the minimum value */
209 if ((_Float16)out > (_Float16)minVal)
210 {
211 /* Update the minimum value and it's index */
212 out = minVal;
213 }
214
215 /* Decrement loop counter */
216 blkCnt--;
217 }
218
219 /* Store the minimum value and it's index into destination pointers */
220 *pResult = out;
221 }
222 #endif /* defined(ARM_MATH_LOOPUNROLL) */
223 #endif /* defined(ARM_MATH_MVE_FLOAT16) && !defined(ARM_MATH_AUTOVECTORIZE) */
224 /**
225 @} end of AbsMin group
226 */
227
228 #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
229
230