GNU Radio Manual and C++ API Reference  3.7.6.1
The Free & Open Software Radio Ecosystem
volk_32f_binary_slicer_32i.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2014 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_volk_32f_binary_slicer_32i_H
24 #define INCLUDED_volk_32f_binary_slicer_32i_H
25 
26 
27 #ifdef LV_HAVE_GENERIC
28 /*!
29  \brief Returns integer 1 if float input is greater than or equal to 0, 1 otherwise
30  \param cVector The int output (either 0 or 1)
31  \param aVector The float input
32  \param num_points The number of values in aVector and stored into cVector
33 */
34 static inline void volk_32f_binary_slicer_32i_generic(int* cVector, const float* aVector, unsigned int num_points){
35  int* cPtr = cVector;
36  const float* aPtr = aVector;
37  unsigned int number = 0;
38 
39  for(number = 0; number < num_points; number++){
40  if( *aPtr++ >= 0) {
41  *cPtr++ = 1;
42  }
43  else {
44  *cPtr++ = 0;
45  }
46  }
47 }
48 #endif /* LV_HAVE_GENERIC */
49 
50 
51 #ifdef LV_HAVE_GENERIC
52 /*!
53  \brief Returns integer 1 if float input is greater than or equal to 0, 1 otherwise
54  \param cVector The int output (either 0 or 1)
55  \param aVector The float input
56  \param num_points The number of values in aVector and stored into cVector
57 */
58 static inline void volk_32f_binary_slicer_32i_generic_branchless(int* cVector, const float* aVector, unsigned int num_points){
59  int* cPtr = cVector;
60  const float* aPtr = aVector;
61  unsigned int number = 0;
62 
63  for(number = 0; number < num_points; number++){
64  *cPtr++ = (*aPtr++ >= 0);
65  }
66 }
67 #endif /* LV_HAVE_GENERIC */
68 
69 
70 #ifdef LV_HAVE_SSE2
71 #include <emmintrin.h>
72 /*!
73  \brief Returns integer 1 if float input is greater than or equal to 0, 1 otherwise
74  \param cVector The int output (either 0 or 1)
75  \param aVector The float input
76  \param num_points The number of values in aVector and stored into cVector
77 */
78 static inline void volk_32f_binary_slicer_32i_a_sse2(int* cVector, const float* aVector, unsigned int num_points){
79  int* cPtr = cVector;
80  const float* aPtr = aVector;
81  unsigned int number = 0;
82 
83  unsigned int quarter_points = num_points / 4;
84  __m128 a_val, res_f;
85  __m128i res_i, binary_i;
86  __m128 zero_val;
87  zero_val = _mm_set1_ps (0.0f);
88 
89  for(number = 0; number < quarter_points; number++){
90  a_val = _mm_load_ps(aPtr);
91 
92  res_f = _mm_cmpge_ps (a_val, zero_val);
93  res_i = _mm_cvtps_epi32 (res_f);
94  binary_i = _mm_srli_epi32 (res_i, 31);
95 
96 
97  _mm_store_si128((__m128i*)cPtr, binary_i);
98 
99 
100  cPtr += 4;
101  aPtr += 4;
102  }
103 
104  for(number = quarter_points * 4; number < num_points; number++){
105  if( *aPtr++ >= 0) {
106  *cPtr++ = 1;
107  }
108  else {
109  *cPtr++ = 0;
110  }
111  }
112 }
113 #endif /* LV_HAVE_SSE2 */
114 
115 
116 #ifdef LV_HAVE_AVX
117 #include <immintrin.h>
118 /*!
119  \brief Returns integer 1 if float input is greater than or equal to 0, 1 otherwise
120  \param cVector The int output (either 0 or 1)
121  \param aVector The float input
122  \param num_points The number of values in aVector and stored into cVector
123 */
124 static inline void volk_32f_binary_slicer_32i_a_avx(int* cVector, const float* aVector, unsigned int num_points){
125  int* cPtr = cVector;
126  const float* aPtr = aVector;
127  unsigned int number = 0;
128 
129  unsigned int quarter_points = num_points / 8;
130  __m256 a_val, res_f, binary_f;
131  __m256i binary_i;
132  __m256 zero_val, one_val;
133  zero_val = _mm256_set1_ps (0.0f);
134  one_val = _mm256_set1_ps (1.0f);
135 
136  for(number = 0; number < quarter_points; number++){
137  a_val = _mm256_load_ps(aPtr);
138 
139  res_f = _mm256_cmp_ps (a_val, zero_val, 13);
140  binary_f = _mm256_and_ps (res_f, one_val);
141  binary_i = _mm256_cvtps_epi32(binary_f);
142 
143 
144 
145  _mm256_store_si256((__m256i *)cPtr, binary_i);
146 
147 
148  cPtr += 8;
149  aPtr += 8;
150  }
151 
152  for(number = quarter_points * 8; number < num_points; number++){
153  if( *aPtr++ >= 0) {
154  *cPtr++ = 1;
155  }
156  else {
157  *cPtr++ = 0;
158  }
159  }
160 }
161 #endif /* LV_HAVE_AVX */
162 
163 
164 #ifdef LV_HAVE_SSE2
165 #include <emmintrin.h>
166 /*!
167  \brief Returns integer 1 if float input is greater than or equal to 0, 1 otherwise
168  \param cVector The int output (either 0 or 1)
169  \param aVector The float input
170  \param num_points The number of values in aVector and stored into cVector
171 */
172 static inline void volk_32f_binary_slicer_32i_u_sse2(int* cVector, const float* aVector, unsigned int num_points){
173  int* cPtr = cVector;
174  const float* aPtr = aVector;
175  unsigned int number = 0;
176 
177  unsigned int quarter_points = num_points / 4;
178  __m128 a_val, res_f;
179  __m128i res_i, binary_i;
180  __m128 zero_val;
181  zero_val = _mm_set1_ps (0.0f);
182 
183  for(number = 0; number < quarter_points; number++){
184  a_val = _mm_loadu_ps(aPtr);
185 
186  res_f = _mm_cmpge_ps (a_val, zero_val);
187  res_i = _mm_cvtps_epi32 (res_f);
188  binary_i = _mm_srli_epi32 (res_i, 31);
189 
190 
191  _mm_storeu_si128((__m128i*)cPtr, binary_i);
192 
193 
194  cPtr += 4;
195  aPtr += 4;
196  }
197 
198  for(number = quarter_points * 4; number < num_points; number++){
199  if( *aPtr++ >= 0) {
200  *cPtr++ = 1;
201  }
202  else {
203  *cPtr++ = 0;
204  }
205  }
206 }
207 #endif /* LV_HAVE_SSE2 */
208 
209 
210 #ifdef LV_HAVE_AVX
211 #include <immintrin.h>
212 /*!
213  \brief Returns integer 1 if float input is greater than or equal to 0, 1 otherwise
214  \param cVector The int output (either 0 or 1)
215  \param aVector The float input
216  \param num_points The number of values in aVector and stored into cVector
217 */
218 static inline void volk_32f_binary_slicer_32i_u_avx(int* cVector, const float* aVector, unsigned int num_points){
219  int* cPtr = cVector;
220  const float* aPtr = aVector;
221  unsigned int number = 0;
222 
223  unsigned int quarter_points = num_points / 8;
224  __m256 a_val, res_f, binary_f;
225  __m256i binary_i;
226  __m256 zero_val, one_val;
227  zero_val = _mm256_set1_ps (0.0f);
228  one_val = _mm256_set1_ps (1.0f);
229 
230  for(number = 0; number < quarter_points; number++){
231  a_val = _mm256_loadu_ps(aPtr);
232 
233  res_f = _mm256_cmp_ps (a_val, zero_val, 13);
234  binary_f = _mm256_and_ps (res_f, one_val);
235  binary_i = _mm256_cvtps_epi32(binary_f);
236 
237 
238 
239  _mm256_storeu_si256((__m256i*)cPtr, binary_i);
240 
241 
242  cPtr += 8;
243  aPtr += 8;
244  }
245 
246  for(number = quarter_points * 8; number < num_points; number++){
247  if( *aPtr++ >= 0) {
248  *cPtr++ = 1;
249  }
250  else {
251  *cPtr++ = 0;
252  }
253  }
254 }
255 #endif /* LV_HAVE_AVX */
256 
257 
258 
259 #endif /* INCLUDED_volk_32f_binary_slicer_32i_H */