Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

Ipp multi-rate FIR filtering ippsFIRMR_32f, ippsFIRMR_32fc problem

Ionen__Vlad
Beginner
2,014 Views

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

 

 

0 Kudos
18 Replies
Andrey_B_Intel
Employee
2,014 Views

Hi Vlad.

Could you provide small reproducer how you call ippsFIRMR ? 

Thanks for using IPP.

 

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

0 Kudos
Andrey_B_Intel
Employee
2,014 Views

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.

 

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

0 Kudos
Andrey_B_Intel
Employee
2,014 Views

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.
 
0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

 

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

0 Kudos
Andrey_B_Intel
Employee
2,014 Views

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.

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

0 Kudos
Andrey_B_Intel
Employee
2,014 Views

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.

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

Hi Andrey,

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

Regards,
Vlad

0 Kudos
Andrey_B_Intel
Employee
2,014 Views

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.

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

0 Kudos
Andrey_B_Intel
Employee
2,014 Views

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.

 

0 Kudos
Ionen__Vlad
Beginner
2,014 Views

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

0 Kudos
Andrey_B_Intel
Employee
2,014 Views
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.
0 Kudos
Reply