GCC Code Coverage Report


Directory: ./
File: kernels/volk/volk_32fc_deinterleave_imag_32f.h
Date: 2023-10-23 23:10:04
Exec Total Coverage
Lines: 63 63 100.0%
Functions: 4 4 100.0%
Branches: 14 14 100.0%

Line Branch Exec Source
1 /* -*- c++ -*- */
2 /*
3 * Copyright 2012, 2014 Free Software Foundation, Inc.
4 *
5 * This file is part of VOLK
6 *
7 * SPDX-License-Identifier: LGPL-3.0-or-later
8 */
9
10 /*!
11 * \page volk_32fc_deinterleave_imag_32f
12 *
13 * \b Overview
14 *
15 * Deinterleaves the complex floating point vector and return the imaginary
16 * part (quadrature) of the samples.
17 *
18 * <b>Dispatcher Prototype</b>
19 * \code
20 * void volk_32fc_deinterleave_image_32f(float* qBuffer, const lv_32fc_t* complexVector,
21 * unsigned int num_points) \endcode
22 *
23 * \b Inputs
24 * \li complexVector: The complex input vector.
25 * \li num_points: The number of complex data values to be deinterleaved.
26 *
27 * \b Outputs
28 * \li qBuffer: The Q buffer output data.
29 *
30 * \b Example
31 * Generate complex numbers around the top half of the unit circle and
32 * extract all of the imaginary parts to a float buffer.
33 * \code
34 * int N = 10;
35 * unsigned int alignment = volk_get_alignment();
36 * lv_32fc_t* in = (lv_32fc_t*)volk_malloc(sizeof(lv_32fc_t)*N, alignment);
37 * float* im = (float*)volk_malloc(sizeof(float)*N, alignment);
38 *
39 * for(unsigned int ii = 0; ii < N; ++ii){
40 * float real = 2.f * ((float)ii / (float)N) - 1.f;
41 * float imag = std::sqrt(1.f - real * real);
42 * in[ii] = lv_cmake(real, imag);
43 * }
44 *
45 * volk_32fc_deinterleave_imag_32f(im, in, N);
46 *
47 * printf(" imaginary part\n");
48 * for(unsigned int ii = 0; ii < N; ++ii){
49 * printf("out(%i) = %+.1f\n", ii, im[ii]);
50 * }
51 *
52 * volk_free(in);
53 * volk_free(im);
54 * \endcode
55 */
56
57 #ifndef INCLUDED_volk_32fc_deinterleave_imag_32f_a_H
58 #define INCLUDED_volk_32fc_deinterleave_imag_32f_a_H
59
60 #include <inttypes.h>
61 #include <stdio.h>
62
63 #ifdef LV_HAVE_AVX
64 #include <immintrin.h>
65
66 2 static inline void volk_32fc_deinterleave_imag_32f_a_avx(float* qBuffer,
67 const lv_32fc_t* complexVector,
68 unsigned int num_points)
69 {
70 2 unsigned int number = 0;
71 2 const unsigned int eighthPoints = num_points / 8;
72 2 const float* complexVectorPtr = (const float*)complexVector;
73 2 float* qBufferPtr = qBuffer;
74
75 __m256 cplxValue1, cplxValue2, complex1, complex2, qValue;
76
2/2
✓ Branch 0 taken 32766 times.
✓ Branch 1 taken 2 times.
32768 for (; number < eighthPoints; number++) {
77
78 32766 cplxValue1 = _mm256_load_ps(complexVectorPtr);
79 32766 complexVectorPtr += 8;
80
81 32766 cplxValue2 = _mm256_load_ps(complexVectorPtr);
82 32766 complexVectorPtr += 8;
83
84 32766 complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
85 32766 complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
86
87 // Arrange in q1q2q3q4 format
88 32766 qValue = _mm256_shuffle_ps(complex1, complex2, 0xdd);
89
90 _mm256_store_ps(qBufferPtr, qValue);
91
92 32766 qBufferPtr += 8;
93 }
94
95 2 number = eighthPoints * 8;
96
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 for (; number < num_points; number++) {
97 14 complexVectorPtr++;
98 14 *qBufferPtr++ = *complexVectorPtr++;
99 }
100 2 }
101 #endif /* LV_HAVE_AVX */
102
103 #ifdef LV_HAVE_SSE
104 #include <xmmintrin.h>
105
106 2 static inline void volk_32fc_deinterleave_imag_32f_a_sse(float* qBuffer,
107 const lv_32fc_t* complexVector,
108 unsigned int num_points)
109 {
110 2 unsigned int number = 0;
111 2 const unsigned int quarterPoints = num_points / 4;
112
113 2 const float* complexVectorPtr = (const float*)complexVector;
114 2 float* qBufferPtr = qBuffer;
115
116 __m128 cplxValue1, cplxValue2, iValue;
117
2/2
✓ Branch 0 taken 65534 times.
✓ Branch 1 taken 2 times.
65536 for (; number < quarterPoints; number++) {
118
119 65534 cplxValue1 = _mm_load_ps(complexVectorPtr);
120 65534 complexVectorPtr += 4;
121
122 65534 cplxValue2 = _mm_load_ps(complexVectorPtr);
123 65534 complexVectorPtr += 4;
124
125 // Arrange in q1q2q3q4 format
126 65534 iValue = _mm_shuffle_ps(cplxValue1, cplxValue2, _MM_SHUFFLE(3, 1, 3, 1));
127
128 _mm_store_ps(qBufferPtr, iValue);
129
130 65534 qBufferPtr += 4;
131 }
132
133 2 number = quarterPoints * 4;
134
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 for (; number < num_points; number++) {
135 6 complexVectorPtr++;
136 6 *qBufferPtr++ = *complexVectorPtr++;
137 }
138 2 }
139 #endif /* LV_HAVE_SSE */
140
141 #ifdef LV_HAVE_NEON
142 #include <arm_neon.h>
143
144 static inline void volk_32fc_deinterleave_imag_32f_neon(float* qBuffer,
145 const lv_32fc_t* complexVector,
146 unsigned int num_points)
147 {
148 unsigned int number = 0;
149 unsigned int quarter_points = num_points / 4;
150 const float* complexVectorPtr = (float*)complexVector;
151 float* qBufferPtr = qBuffer;
152 float32x4x2_t complexInput;
153
154 for (number = 0; number < quarter_points; number++) {
155 complexInput = vld2q_f32(complexVectorPtr);
156 vst1q_f32(qBufferPtr, complexInput.val[1]);
157 complexVectorPtr += 8;
158 qBufferPtr += 4;
159 }
160
161 for (number = quarter_points * 4; number < num_points; number++) {
162 complexVectorPtr++;
163 *qBufferPtr++ = *complexVectorPtr++;
164 }
165 }
166 #endif /* LV_HAVE_NEON */
167
168 #ifdef LV_HAVE_GENERIC
169
170 2 static inline void volk_32fc_deinterleave_imag_32f_generic(float* qBuffer,
171 const lv_32fc_t* complexVector,
172 unsigned int num_points)
173 {
174 2 unsigned int number = 0;
175 2 const float* complexVectorPtr = (float*)complexVector;
176 2 float* qBufferPtr = qBuffer;
177
2/2
✓ Branch 0 taken 262142 times.
✓ Branch 1 taken 2 times.
262144 for (number = 0; number < num_points; number++) {
178 262142 complexVectorPtr++;
179 262142 *qBufferPtr++ = *complexVectorPtr++;
180 }
181 2 }
182 #endif /* LV_HAVE_GENERIC */
183
184
185 #endif /* INCLUDED_volk_32fc_deinterleave_imag_32f_a_H */
186
187 #ifndef INCLUDED_volk_32fc_deinterleave_imag_32f_u_H
188 #define INCLUDED_volk_32fc_deinterleave_imag_32f_u_H
189
190 #include <inttypes.h>
191 #include <stdio.h>
192
193 #ifdef LV_HAVE_AVX
194 #include <immintrin.h>
195
196 2 static inline void volk_32fc_deinterleave_imag_32f_u_avx(float* qBuffer,
197 const lv_32fc_t* complexVector,
198 unsigned int num_points)
199 {
200 2 unsigned int number = 0;
201 2 const unsigned int eighthPoints = num_points / 8;
202 2 const float* complexVectorPtr = (const float*)complexVector;
203 2 float* qBufferPtr = qBuffer;
204
205 __m256 cplxValue1, cplxValue2, complex1, complex2, qValue;
206
2/2
✓ Branch 0 taken 32766 times.
✓ Branch 1 taken 2 times.
32768 for (; number < eighthPoints; number++) {
207
208 32766 cplxValue1 = _mm256_loadu_ps(complexVectorPtr);
209 32766 complexVectorPtr += 8;
210
211 32766 cplxValue2 = _mm256_loadu_ps(complexVectorPtr);
212 32766 complexVectorPtr += 8;
213
214 32766 complex1 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x20);
215 32766 complex2 = _mm256_permute2f128_ps(cplxValue1, cplxValue2, 0x31);
216
217 // Arrange in q1q2q3q4 format
218 32766 qValue = _mm256_shuffle_ps(complex1, complex2, 0xdd);
219
220 _mm256_storeu_ps(qBufferPtr, qValue);
221
222 32766 qBufferPtr += 8;
223 }
224
225 2 number = eighthPoints * 8;
226
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 for (; number < num_points; number++) {
227 14 complexVectorPtr++;
228 14 *qBufferPtr++ = *complexVectorPtr++;
229 }
230 2 }
231 #endif /* LV_HAVE_AVX */
232 #endif /* INCLUDED_volk_32fc_deinterleave_imag_32f_u_H */
233