Ipp multi-rate FIR filtering ippsFIRMR_32f, ippsFIRMR_32fc problem

Ipp multi-rate FIR filtering ippsFIRMR_32f, ippsFIRMR_32fc problem

Hi there,

I am using ippCore 2018.0.1 (r56998) and having some problem with Ipp32f (float) / Ipp32fc (complex) multi-rate FIR filtering. I tested the filter for upFactor = 1, downFactor = 1, number of filter coefficients tapsLen = 4 - 40,  the filter coefficients are the same - all ones / random,  the source vector is all ones / random and got the following results:

The filter coefficients are all ones and  the source vector is all ones work fine except first tapsLen-1 samples in the output buffer were corrupted for tapsLen = 5, 7, 9 for float data and tapsLen = 5, 6, 8 for complex data.

The filter coefficients are all ones and  the source vector is random work fine except first tapsLen-1 samples in the output buffer were corrupted for tapsLen = 5, 8, 10, 12, 14, 16, 18, 20, 22 and more for float data and tapsLen = 5, 6, 8 for complex data.

The filter coefficients are random and the source vector is random produced unexpected output.

My IDE Environment:

Win 7 Pro x64, Intel Core i7-6700 @ 3.40GHz, Ram 8.0 GB
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018.1.156\windows\ipp\include\
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018.1.156\windows\ipp\lib\ia32_win\
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018.1.156\windows\compiler\lib\ia32_win\
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2018.1.156\windows\redist\ia32_win\ipp\

Regards,
Vlad

 

 

19 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hi Vlad.

Could you provide small reproducer how you call ippsFIRMR ? 

Thanks for using IPP.

 

Hi Andrey,

This is my test project for verifying/profiling IPP multi-rate FIR filter in ZIP: Test_RatRateFloat Win attached.

This is MSVS C++ Community 2017 project. Use Debug version only. The bTest_nRatRateCplx function calls C multi-rate FIR nRatRateFl and IPP nRatRateFlIntel filters and compares outputs for differences.
You can dump data into the file to compare.
You can also control the following:

#define MIN_TAPS       4
#define MAX_TAPS      60
#define MAX_INTERP    10
#define MAX_DECIM     10
#define INPUT_VEC     ONES //RAND //ONES  RAMP
#define COEFF_VEC     ONES //RAND //ONES  RAMP

Regards,
Vlad

Attachments: 

AttachmentSize
Downloadapplication/zip Test_RatRateFloat Win.zip67.32 MB

Hi Vlad.

Thanks for your reproducer. I've tried to run it. It works. The garbage in beginning of output vector is non normal. According with documentation 

https://software.intel.com/en-us/ipp-dev-reference-firmr

"pDlyDst - Pointer to the array containing values for the destination delay line. The value can be NULL. If not NULL, the array length is defined as (tapsLen+upFactor-1)/upFactor."

ippsFIRMR_32f requires tapsLen elements in delay line pDlySrc if up==down==1. (not tapsLen-1 as in ippsFIRSR). It is necessary for some combinations of upFactor, downFactor and Phases. Try please to copy 1 additional element to delay line pDlySrc. 

Thanks.

 

Hi Andrey,

Tried to copy 1 additional element to delay line pDlySrc. Yes, It fixed the garbage in beginning of output vector when the filter coefficients are all ones and  the source vector is all ones.

But with filter coefficients are random and the source vector is random still got unexpected output.

Regards,
Vlad

Hi Vlad.

try do add 2 next modifications in your code for RAND and coeff_len=4 according with  IPP manual.

1. pDlySrc expects coeff_len elements from previous block, so first call is

     memcpy(pDlySrc, psFilter->pcfState, sizeof(float) * psFilter->nStates); 

     memcpy(pDlySrc+1, psFilter->pcfState, sizeof(float) * psFilter->nStates);

2. Filter coefficients should be inverted.

sStatus = ippsFIRMRInit_32f((Ipp32f*)afCoeffIntel, psFilter->nTaps, psFilter->nInterp, upPhase, psFilter->nDecim, downPhase, pSpec);

Ipp32f afCoeffIntel_inv[4] = { afCoeffIntel[3], afCoeffIntel[2], afCoeffIntel[1], afCoeffIntel[0] }; 

sStatus = ippsFIRMRInit_32f((Ipp32f*)afCoeffIntel_inv, psFilter->nTaps, psFilter->nInterp, upPhase, psFilter->nDecim, downPhase, pSpec);

 

I've added these 2 modifications. It produces correct result for RAND and coeff_len=4.  I hope these fixes will help you to modify your application for other cases too.

 

Thanks.

 

Hi Andrey,

I tried yours update with RAND filter coefficients and source vector and got much better results. The test ran fine and started failing for interp=1, decim=6 and more, taps=4 and more. The test failed for the first 1 - 5 samples.

The test also failed a lot when interp is more than 1.

Regards,
Vlad

Hi Andrey,

I got Intel update 3 for my IDE Environment, but still have problem with Ipp32f (float) / Ipp32fc (complex) multi-rate FIR filtering. I have problem with RAND filter coefficients and source vector for interpolation=1, decimation=6 and more, taps=4 and more. The test fails for the first 1 - 5 samples. The test also fails a lot when interpolation is more than 1.
Do you have problem in your test with RAND filter coefficients and source vector for interpolation=1-10, decimation=1-10, taps=4-60?

Regards,
Vlad

 

These are my test results for Ipp32f (float) / Ipp32fc (complex) multi-rate FIR filtering attached. The test compares the for Ipp32f (float) / Ipp32fc (complex) filters output with C versions and reports the error if the outputs are different.  As you can see I have a lot of failed cases in both tests. I am very sure in my C codes. I suspect Ipp library is wrong. Please help me to fine my problems.

Regards,

Vlad

Attachments: 

AttachmentSize
Downloadtext/plain Ipp32fcTest.txt19.31 MB
Downloadtext/plain Ipp32fTest.txt54.19 MB

Hi Vlad.

I've tried to debug you app. I think it is necessary to replace sizeof(complex) with sizeof(float) to prevent overwrite:

// The Intel filter state is not at the start of the pfIn data

   memcpy(afInIntel, afIn + sFilterIntel.nStates, (nIn+nTaps) * sizeof(complex));

 Also check please that you invert taps in cycle (not static array as in previous my message). 

#if 0
    sStatus = ippsFIRMRInit_32f((Ipp32f*)afCoeffIntel, psFilter->nTaps, psFilter->nInterp, upPhase, psFilter->nDecim, downPhase, pSpec);
#else
    Ipp32f* afCoeffIntel_inv=ippsMalloc_32f(psFilter->nTaps);
    int nn;
    for (nn = 0; nn < psFilter->nTaps; nn++) {
        afCoeffIntel_inv[nn] = afCoeffIntel[psFilter->nTaps - 1 - nn];
    }
    sStatus = ippsFIRMRInit_32f((Ipp32f*)afCoeffIntel_inv, psFilter->nTaps, psFilter->nInterp, upPhase, psFilter->nDecim, downPhase, pSpec);
    ippsFree(afCoeffIntel_inv);
#endif

Send me please your final C file to sync our versions in case of wrong results again.

 

 

Thanks.

Hi Andrey,

I think I fixed all bug you found in my C code. Thanks a lot for help and cooperation.
But I still have problem in test with RAND filter coefficients and source vector for interpolation=1-10, decimation=1-10, taps=4-60.
I attached my latest test project and test result.

Regards,
Vlad

Attachments: 

Hi Andrey,

Please set the Intel filter state in the test as:
#define FILT_ST_INTEL(taps,interp)    ((taps+interp-1) / (interp)).

Also ignore my last test result because it was done for Intel filter state as
#define FILT_ST_INTEL(taps,interp)    ((taps - 1) / (interp))

The result is better with this fix, but still have errors.

Regards,
Vlad

Hi Vlad.

I'm attaching file with new function nRatRateFl_ref that calculates firmr. The result if this function  is  the same with ippsFIRMR_32f. This function demonstrates what upFactor and downFactor is in terms of IPP. All tests are passed now. I hope this function  will help you to use ippsFIRMR properly .

Thanks.

Attachments: 

AttachmentSize
Downloadtext/x-c++src Test_RatRateFloat.cpp24.34 KB

Hi Andrey,

The new function nRatRateFl_ref works fine. Do you have C version of Ipp32fc (complex) ippsFIRMR?

Regards,
Vlad

No I don't. But it is easy to modify C code of 32f FIRMR to 32fc FIRMR just replacing of all operations from real to complex.

Hi Andrey,
I got two problems with new function nRatRateFl_ref when ran test with RAND filter coefficients and source vector using MAX_TRIALS    10:
         1.    The test start failing a lot after interp=5, decim=8, taps=36 and trial =9;
         2.    The test got crashed because of ippsMalloc_32f function did not allocate upBuf for in=100, interp=5, decim=8, taps=44 and set the pointer to 0 in vFilterCore_ref function.
Can you try MAX_TRIALS    10 in your setup.
Regards,
Vlad

Hi Vlad.

Could you please modify vFilterCore_ref function according with your application? This function is very simple for debugging. When all test pass we replace it with actual ippsFIRMR function.

Thanks.

 

Hi Andrey,

Our company is widely using nRatRateFl for float and nRatRateCpx for complex C functions for multi-rate FIR filtering for a long time and they are correct. I used these functions as references for Ipp32f (float) / Ipp32fc (complex) functions test at the beginning. I am surprised you suggest different C version of multi-rate FIR filter for test.  I think Ipp32f (float) / Ipp32fc (complex) functions should work as ours FIR filters that I used at the beginning.

Regards,
Vlad

Hi Vlad.
ippsFIRMR function uses FIR API aligned with Matlab system. The chapter "description" by link https://se.mathworks.com/help/dsp/ref/firrateconversion.html items 1, 2, 3 explain FIR MR pipeline. "Sample Offset, D" by link https://se.mathworks.com/help/dsp/ref/downsample.html is analog of IPP downPhase. upPhase is position of non-zero element during upsampling. Attached C version is not IPP production code. It is just very simple reference code that demonstrates ippsFIRMR API as easy as possible for debug.
Thanks.

Leave a Comment

Please sign in to add a comment. Not a member? Join today