jj1bdx/airspy-fmradion

VOLK 3.1.0 does not work on Ubuntu 22.04.3 x86_64 with airspy-fmradion 20231212-1

jj1bdx opened this issue · 7 comments

jj1bdx commented

Synopsis:

airspy-fmradion with multipath filter enabled for broadcast FM generates -NaN output on ppm and AF level monitor output when compiled and running with Ubuntu 22.04.3 x86_64 and VOLK 3.1.0, both compiled by GCC 12.3.0.

Reported at:

Findings so far:

  • volk_32fc_x2_s32fc_multiply_conjugate_add_32fc of VOLK v3.1.0 worked OK on macOS 14.2 (Homebrew) with airspy-fmradion MultipathFilter::update_coeff().
  • Either volk_32fc_x2_s32fc_multiply_conjugate_add_32fc or volk_32fc_x2_s32fc_multiply_conjugate_add2_32fc of VOLK v3.1.0 did not work (no compilation error, but the calculation failed), in generic kernel (no CPU optimization) on airspy-fmradion MultipathFilter::update_coeff() running on Ubuntu 22.04.3 x86_64 compiled with gcc version 11.4.0. I had to fall back to VOLK 3.0.0, which worked OK. Also, airspy-fmradion compiled with VOLK 2.5.1 of Ubuntu 22.04.3's apt repository worked OK.

Workaround:

  • Use VOLK 3.0.0 or 2.5.2 for Ubuntu 22.04.3 (documented on airspy-fmradion 20231212-1)

Status:

I still don't know why the code works OK on macOS and fails on Ubuntu.
-> reason: macOS on Apple Silicon does not depend on the affected VOLK kernels (only using the polynomial or generic kernels) for volk_s32c_s32f_atan2_s32f().

jj1bdx commented

Need to apply valgrind for uninitialized memory check. Reference: gnuradio/volk#695 (comment)

jj1bdx commented

Fixed by #43 by @argilo. Thanks @argilo!

jj1bdx commented

Note: this is a wrong conclusion. The correct reason was that PhaseDiscriminator::process emitted NaN for 0+0j input.

The calculation failure was caused by one or more NaNs being in the PhaseDiscriminator calculation result. The result propagated in the later stages to prevent normal output. The multipath filter was working even if the NaNs were output because the reason for NaN was presumably the 0+0j output value of the multipath filter. The 0+0j output will not happen in the real-world input, although there's no guarantee that it will not happen. So, I decided to reset the multipath filter calculation if 0+0j output is found in the calculation result. This filter reset hack presumably solved the root cause.
See

// Quick hack to prevent zero output
// so that it would not cause NaN
// in volk_32fc_s32f_atan2_32f() of PhaseDiscriminator
if ((output.real() == 0) && (output.imag() == 0)) {
return false;
}
for the fixed code.

jj1bdx commented

I conclude that the calculation failure is not related to updating the VOLK.

jj1bdx commented

I've proposed the root cause fix to VOLK.
Reference:

jj1bdx commented

My proposed fix is merged. I'll close this issue.