This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C66x DSPLIB: DSPF_sp_fircirc

Genius 5785 points

Hello,

I'll use DSPF_sp_fircirc function in dsplib_c66x_3_4_0_0.

C:\ti\dsplib_c66x_3_4_0_0\packages\ti\dsplib\src\DSPF_sp_fircirc\c66\DSPF_sp_fircirc_66_LE_ELF

It seems an unmatch result between DSPF_sp_fircirc and DSPF_sp_fircirc_cn. I saw the different value between ptr_y_i and ptr_y_cn. But the test program of DSPF_sp_fircirc_d.c got "Result Successful" because I think the following condition is wrong.

if (abs((ptr_y_i[i]) > FLT_THRES) || (abs(ptr_y_cn[i]) > FLT_THRES)) /* original - incorrect */
if ((abs(ptr_y_i[i]) > FLT_THRES) || (abs(ptr_y_cn[i]) > FLT_THRES)) /* modified - correct */

ptr_y_i
BF6A9B05 BF019F6B BF8D3E32 BFCBF7BC BF4C14CE BF5633A4 BF6A9B05 BF681BA9
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ptr_y_cn
BF4C14CE BF5633A4 BF6A9B05 BF681BA9 BF4C14CE BF5633A4 BF6A9B05 BF681BA9
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

I also think DSPF_sp_fircirc is not correct because a variable "i" is not initialized in the function. Please give me some advice.

Regards,
Kazu

  • Hi,

    Thanks for your post.

    In my opinion, the _cn ending means natural C code which is the reference code not using intrinsics.

    I believe, you would need to choose the C-File with the intrinsics to make a meaningful comparison.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • Hello Sivaraj,

    Thank you for your reply. Sorry it's hard to understand. I think that a result of DSPF_sp_fircirc_cn is correct, but a result of DSPF_sp_fircirc is not correct. I can't get correct result using DSPF_sp_fircirc.

    Regards,
    Kazu

  • Kazu,
    I ran the DSPF_sp_fircirc_66_LE_ELF project from DSP library version dsplib_c66x_3_4_0_0 on CCS and thememory output from DSPF_sp_fircirc and DSPF_sp_fircirc_cn function exactly matches in memory.

    ptr_y_i
    BF4C14CE BF5633A4 BF6A9B05 BF681BA9 BF4C14CE BF5633A4 BF6A9B05 BF681BA9
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    ptr_y_cn
    BF4C14CE BF5633A4 BF6A9B05 BF681BA9 BF4C14CE BF5633A4 BF6A9B05 BF681BA9
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

    The test bench is also correct and the function abstract is below.
    if (abs((ptr_y_i[i]) > FLT_THRES) || (abs(ptr_y_cn[i]) > FLT_THRES))

    Regards,
    Asheesh

    Please verify the answer.
  • I categorically disagree with TI analysis. Are you seriously suggesting that taking absolute value of result of comparison is intentional? Note that result of comparison if boolean, i.e. it's either 0 or 1, so that its absolute value is itself. This means that abs() can actually be omitted, so that what is executed is equivalent of if ((ptr_y_i[i] > FLT_THRES) || (abs(ptr_y_cn[i]) > FLT_THRES)). Note that given presented values, bunch of negatives and zeros, the first condition is always true. So that what is executed is equivalent of if ((abs(ptr_y_cn[i]) > FLT_THRES)).

    As for not being able to confirm discrepancy reported in the originating post, which explicitly mentions uninitialized variable in DSPF_sp_fircirc. Kazu's analysis is totally correct. And the thing about uninitialized variables is that they can happen to have correct value in some situations. Probability varies with compiler version, optimization flags, call history... The fact that it happens to be correct in simplest test project doesn't mean that it will always work in real life.

  • Andy Polyakov said:
    Note that given presented values, bunch of negatives and zeros, the first condition is always true. So that what is executed is equivalent of if ((abs(ptr_y_cn[i]) > FLT_THRES)).

    I meant to write "the fist condition is always false". If it was always true, then second abs would never even execute and equivalent code would have been if (1). Once again, this is for presented data, not universal case.

  • Hello Andy,

    Thank you for your post with same opinion. Actually I got chances to get correct and incorrect value when I ran the function. I want to investigate the cause of the difference.

    Regards, Kazu

  • Kazu,
    The results are matching between the natural C and optimized C code. It seems the first four values in your natural C code is wrong because they donot match with my natural C and optimised code outputs. I think something got messed up in your code. Please check the outputs in the memory window. I have used the little endian project as mentioned earlier on the post.

    The equation below checks whether the absolute value is within the margin for the threshold of 1 e -20 of precision and then calculate the error. The value is very low and not enough to find the difference. The error is then verified with difference in the two values.
  • Hello Asheesh,

    Thank you for your comment. Could you try the following program? I put a dummy code. I think A20 register is used by "i" in  DSPF_sp_fircirc library. You will see a different value between ptr_y_i and ptr_y_cn.

    clock_t time_i(int nh, int ny)
    {
        clock_t t_start, t_stop;
       
        /* ------------------------------------------------------------------- */
        /* Measure the cycle count                                             */
        /* ------------------------------------------------------------------- */
        t_start = _itoll(TSCH, TSCL);
        asm(" mvk 15, a20");
        DSPF_sp_fircirc(ptr_x, ptr_h, ptr_y_i, 0, NC, nh, ny);
        t_stop = _itoll(TSCH, TSCL);
     
        return t_stop - t_start;
    }

    Regards,
    Kazu

  • Hello Asheesh,

    Could you give me your reply?

    Regards,
    Kazu

  • Kazu,

    I just want to remind that register allocation can depend on compiler version and even compiler flags, so that suggestion to initialize any particular register doesn't necessarily make problem universally reproducible. It's probably more appropriate to state which exact compiler version was used and upload project (so that compiler flags are known) with actual binary (so that they can actually see what you see for themselves). Well, you have to recognize that I have no influence on what TI does. I can only tell what makes sense to me. But to me original report alone provided more than enough details, so that it probably doesn't matter what makes sense to me.

  • Kazu,
    The code in DSPlib is all C code and there is no assembly. The compiler do not change any register values used for the variable used outside the function. I hope you are on Compiler version 7.4x or 7.6x. The default DSP library code does not has any such issues unless you have made some code changes.

    All the source code are available as part of the release, You can include the files in the project and debug inside the functions on the CCS debugger on your modified code. You can see all the register values on the CCS.
    Regards,
    Asheesh
  • It occurred to me that we have remained blind to another problem with mentioned conditional statement in DSPF_sp_fircirc_d.c. I mean originally mentioned

    if (abs((ptr_y_i[i]) > FLT_THRES) || (abs(ptr_y_cn[i]) > FLT_THRES))

    And the problem is that abs() calculates absolute value of an integer. This means that if you pass floating point value, compiler will convert it to integer, or simply put omit fraction part, prior passing value to abs(). So that 0.9 as well as -0.9 becomes 0, 1.9 becomes 1, -1.9 becomes -1, etc. And then integer number is compared to 1E-20. Well, it could have been compared to any number less than 1. The fact that it's compared to small floating point number can't mean anything else but that intention was to compare absolute value of a floating point number, not one converted to integer.

    If we again have closer look at presented data, we'll see that ptr_y_i consists of a number of negative numbers and zeros. As already discussed, this means that first term of condition is always false. And if we look at ptr_y_cn, we'll see that it too consists of same amount of negative numbers and zeros. And the thing is that neither of absolute values of those non-zero numbers in ptr_y_cn are larger than or equal to 1. This means that even second term of condition is always false. And as both terms are always false, pct_diff is never assigned non-zero value, consequently max_pct_diff is never assigned non-zero value, consequently result for given inputs is always reported as successful. Once again, for presented data set.

    It should be noted that half-fixed first condition, i.e. abs((ptr_y_i[i]) > FLT_THRES) -> (abs(ptr_y_i[i]) > FLT_THRES), exposes difference exclusively because absolute values of couple of ptr_y_i elements are larger than 1. If absolute values of all elements were less than one, even suggested modification wouldn't report difference.

    Bottom line is that intended conditional statement has to be:

    if ((fabsf(ptr_y_i[i]) > FLT_THRES) || (fabsf(ptr_y_cn[i]) > FLT_THRES))

    But we shouldn't forget that even though this is glaring problem, the real problem remains uninitialized value in DSPF_sp_fircirc.c. Real in sense that it's the one that will affect real-life application. I mean DSPF_sp_fircirc_d.c is just a test program which is supposed to convince you that high-performance DSPF_sp_fircirc.c produces sensible result.

  • Hello Asheesh,

    I upload my project. Could you check it? My compiler version is v7.4.12. I just link a pre-build library. I think that A20 register is used as "i" in DSPF_sp_fircirc. My application (DSPF_sp_fircirc_d.c) used A20 register explicitly for test. In effect, our application will use freely each register. I mean that A20 register data may be changed by our application. Once again, "i" should be initialized in DSPF_sp_fircirc.

    Regards,
    Kazu

    c66x_dsplib.zip