From 97ee4acfa1cd2c1ce9fec183500afadb9f99300a Mon Sep 17 00:00:00 2001 From: eb Date: Tue, 2 Oct 2007 21:32:19 +0000 Subject: Trial fix for ticket:189, gr_mpsk_receiver_cc problem. Added checking for SIMD alignment requirement on gr_complex (must be 8-byte aligned) so that future violations will throw an exception. Modified gr_mpsk_receiver_cc.h so that delay line being passed to gri_mmse_fir_interpolator_cc is 8-byte aligned. Added QA code for gri_mmse_fir_interpolator_cc. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@6575 221aa14e-8319-0410-a670-987f0aec2ac5 --- gnuradio-core/src/lib/filter/Makefile.am | 6 +- gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc | 5 +- gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc | 5 +- .../src/lib/filter/gri_mmse_fir_interpolator_cc.h | 6 +- gnuradio-core/src/lib/filter/qa_filter.cc | 4 +- .../lib/filter/qa_gri_mmse_fir_interpolator_cc.cc | 118 +++++++++++++++++++++ .../lib/filter/qa_gri_mmse_fir_interpolator_cc.h | 42 ++++++++ .../src/lib/general/gr_mpsk_receiver_cc.h | 4 +- 8 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc create mode 100644 gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.h (limited to 'gnuradio-core/src') diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am index 78c316fe5..83474ffff 100644 --- a/gnuradio-core/src/lib/filter/Makefile.am +++ b/gnuradio-core/src/lib/filter/Makefile.am @@ -196,7 +196,8 @@ libfilter_qa_la_common_SOURCES = \ qa_gr_fir_fff.cc \ qa_gr_fir_ccc.cc \ qa_gr_fir_scc.cc \ - qa_gri_mmse_fir_interpolator.cc + qa_gri_mmse_fir_interpolator.cc \ + qa_gri_mmse_fir_interpolator_cc.cc if MD_CPU_generic libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(generic_CODE) @@ -281,7 +282,8 @@ noinst_HEADERS = \ qa_gr_fir_fff.h \ qa_gr_fir_ccc.h \ qa_gr_fir_scc.h \ - qa_gri_mmse_fir_interpolator.h + qa_gri_mmse_fir_interpolator.h \ + qa_gri_mmse_fir_interpolator_cc.h diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc index 8868b1a59..44fdeacdf 100644 --- a/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc +++ b/gnuradio-core/src/lib/filter/gr_fir_ccc_simd.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002 Free Software Foundation, Inc. + * Copyright 2002,2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,6 +28,7 @@ #include #include #include +#include using std::cerr; using std::endl; @@ -105,6 +106,8 @@ gr_fir_ccc_simd::filter (const gr_complex input[]) if (ntaps () == 0) return 0.0; + if (((intptr_t) input & 0x7) != 0) + throw std::invalid_argument("gr_complex must be 8-byte aligned"); // Round input data address down to 16 byte boundary // NB: depending on the alignment of input[], memory diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc index 0862ba1f0..c20cd4e62 100644 --- a/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc +++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_simd.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002 Free Software Foundation, Inc. + * Copyright 2002,2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,6 +28,7 @@ #include #include #include +#include using std::cerr; using std::endl; @@ -103,6 +104,8 @@ gr_fir_ccf_simd::filter (const gr_complex input[]) if (ntaps () == 0) return 0.0; + if (((intptr_t) input & 0x7) != 0) + throw std::invalid_argument("gr_complex must be 8-byte aligned"); // Round input data address down to 16 byte boundary // NB: depending on the alignment of input[], memory diff --git a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h index 527c3ec3b..687498c3b 100644 --- a/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h +++ b/gnuradio-core/src/lib/filter/gri_mmse_fir_interpolator_cc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002 Free Software Foundation, Inc. + * Copyright 2002,2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -49,8 +49,10 @@ public: /*! * \brief compute a single interpolated output value. - * \p input must have ntaps() valid entries. + * + * \p input must have ntaps() valid entries and be 8-byte aligned. * input[0] .. input[ntaps() - 1] are referenced to compute the output value. + * \throws std::invalid_argument if input is not 8-byte aligned. * * \p mu must be in the range [0, 1] and specifies the fractional delay. * diff --git a/gnuradio-core/src/lib/filter/qa_filter.cc b/gnuradio-core/src/lib/filter/qa_filter.cc index 2a48636f6..e36fca45d 100644 --- a/gnuradio-core/src/lib/filter/qa_filter.cc +++ b/gnuradio-core/src/lib/filter/qa_filter.cc @@ -1,5 +1,5 @@ /* - * Copyright 2002 Free Software Foundation, Inc. + * Copyright 2002,2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -34,6 +34,7 @@ #include #include #include +#include CppUnit::TestSuite * qa_filter::suite () @@ -42,6 +43,7 @@ qa_filter::suite () s->addTest (qa_dotprod_suite ()); s->addTest (qa_gri_mmse_fir_interpolator::suite ()); + s->addTest (qa_gri_mmse_fir_interpolator_cc::suite ()); s->addTest (qa_gr_fir_fff::suite ()); s->addTest (qa_gr_fir_ccc::suite ()); s->addTest (qa_gr_fir_fcc::suite ()); diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc new file mode 100644 index 000000000..8695b4f8d --- /dev/null +++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc @@ -0,0 +1,118 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include + +#define NELEM(x) (sizeof (x) / sizeof (x[0])) + + +static float +test_fcn_sin(double index) +{ + return (2 * sin (index * 0.25 * 2 * M_PI + 0.125 * M_PI) + + 3 * sin (index * 0.077 * 2 * M_PI + 0.3 * M_PI)); +} + +static float +test_fcn_cos(double index) +{ + return (2 * cos (index * 0.25 * 2 * M_PI + 0.125 * M_PI) + + 3 * cos (index * 0.077 * 2 * M_PI + 0.3 * M_PI)); +} + +static gr_complex +test_fcn(double index) +{ + return gr_complex(test_fcn_cos(index), test_fcn_sin(index)); +} + + +void +qa_gri_mmse_fir_interpolator_cc::t1() +{ + static const unsigned N = 100; + gr_complex input[N + 10]; + + for (unsigned i = 0; i < NELEM(input); i++) + input[i] = test_fcn ((double) i); + + gri_mmse_fir_interpolator_cc intr; + float inv_nsteps = 1.0 / intr.nsteps (); + + for (unsigned i = 0; i < N; i++){ + for (unsigned imu = 0; imu <= intr.nsteps (); imu += 1){ + gr_complex expected = test_fcn ((i + 3) + imu * inv_nsteps); + gr_complex actual = intr.interpolate (&input[i], imu * inv_nsteps); + + CPPUNIT_ASSERT_COMPLEXES_EQUAL (expected, actual, 0.004); + // printf ("%9.6f %9.6f %9.6f\n", expected, actual, expected - actual); + } + } +} + + +/* + * Force bad alignment and confirm that it raises an exception + */ +void +qa_gri_mmse_fir_interpolator_cc::t2_body() +{ + static const unsigned N = 100; + float float_input[2*(N+10) + 1]; + gr_complex *input; + + // We require that gr_complex be aligned on an 8-byte boundary. + // Ensure that we ARE NOT ;) + + if (((intptr_t) float_input & 0x7) == 0) + input = reinterpret_cast(&float_input[1]); + else + input = reinterpret_cast(&float_input[0]); + + + for (unsigned i = 0; i < (N+10); i++) + input[i] = test_fcn ((double) i); + + gri_mmse_fir_interpolator_cc intr; + float inv_nsteps = 1.0 / intr.nsteps (); + + for (unsigned i = 0; i < N; i++){ + for (unsigned imu = 0; imu <= intr.nsteps (); imu += 1){ + gr_complex expected = test_fcn ((i + 3) + imu * inv_nsteps); + gr_complex actual = intr.interpolate (&input[i], imu * inv_nsteps); + + CPPUNIT_ASSERT_COMPLEXES_EQUAL (expected, actual, 0.004); + // printf ("%9.6f %9.6f %9.6f\n", expected, actual, expected - actual); + } + } +} + +void +qa_gri_mmse_fir_interpolator_cc::t2() +{ + CPPUNIT_ASSERT_THROW(t2_body(), std::invalid_argument); +} diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.h b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.h new file mode 100644 index 000000000..496f39702 --- /dev/null +++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.h @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef _QA_GRI_MMSE_FIR_INTERPOLATOR_CC_H_ +#define _QA_GRI_MMSE_FIR_INTERPOLATOR_CC_H_ + +#include +#include + +class qa_gri_mmse_fir_interpolator_cc : public CppUnit::TestCase { + + CPPUNIT_TEST_SUITE(qa_gri_mmse_fir_interpolator_cc); + CPPUNIT_TEST(t1); + // CPPUNIT_TEST(t2); + CPPUNIT_TEST_SUITE_END(); + + private: + void t1(); + void t2(); + void t2_body(); + +}; + +#endif /* _QA_GRI_MMSE_FIR_INTERPOLATOR_CC_H_ */ diff --git a/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.h b/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.h index f718b541e..b0ecb7c93 100644 --- a/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.h +++ b/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2007 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -297,7 +297,7 @@ protected: static const unsigned int DLLEN = 8; //! delay line plus some length for overflow protection - gr_complex d_dl[2*DLLEN]; + gr_complex d_dl[2*DLLEN] __attribute__ ((aligned(8))); //! index to delay line unsigned int d_dl_idx; -- cgit